update
This commit is contained in:
parent
46533bbd62
commit
15d3ac574d
128 changed files with 347 additions and 322 deletions
389
src/modules/04_registryPerson/components/DialogAddData.vue
Normal file
389
src/modules/04_registryPerson/components/DialogAddData.vue
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, watch, reactive } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
|
||||
import type { DataType } from "@/modules/04_registryPerson/interface/response/Main";
|
||||
import type {
|
||||
FormAddPerson,
|
||||
MyObjectRef,
|
||||
} from "@/modules/04_registryPerson/interface/request/Main";
|
||||
import { useProfileDataStore } from "@/modules/04_registryPerson/stores/profile";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
/** importStore*/
|
||||
import { useRegistryNewDataStore } from "@/modules/04_registryPerson/store";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
const profileStore = useProfileDataStore();
|
||||
const $q = useQuasar();
|
||||
const store = useRegistryNewDataStore();
|
||||
const {
|
||||
dialogConfirm,
|
||||
success,
|
||||
messageError,
|
||||
hideLoader,
|
||||
dialogMessageNotify,
|
||||
date2Thai,
|
||||
} = useCounterMixin();
|
||||
const { calculateAge } = profileStore;
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const empType = defineModel<string>("empType", { required: true });
|
||||
|
||||
const props = defineProps({
|
||||
fetchData: { type: Function },
|
||||
fetchType: { type: Function },
|
||||
});
|
||||
|
||||
const prefixOps = ref<DataOption[]>([]);
|
||||
const rankOps = ref<DataOption[]>([]);
|
||||
const levelOps = ref<DataType[]>([]);
|
||||
const age = ref<string | null>("");
|
||||
const formData = reactive<FormAddPerson>({
|
||||
prefix: "",
|
||||
firstName: "",
|
||||
lastName: "",
|
||||
citizenId: "",
|
||||
position: "",
|
||||
posTypeId: "",
|
||||
posLevelId: "",
|
||||
rank: "",
|
||||
birthDate: null,
|
||||
});
|
||||
|
||||
function fetchPrefix() {
|
||||
http
|
||||
.get(config.API.orgPrefix)
|
||||
.then((res) => {
|
||||
prefixOps.value = res.data.result.map((v: any) => ({
|
||||
id: v.name,
|
||||
name: v.name,
|
||||
}));
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
}
|
||||
function fetchRank() {
|
||||
http
|
||||
.get(config.API.orgRank)
|
||||
.then((res) => {
|
||||
rankOps.value = res.data.result.map((v: any) => ({
|
||||
id: v.name,
|
||||
name: v.name,
|
||||
}));
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function ตรวจสอบเลขประจำตัวประชาชน
|
||||
* @param citizenId เลขประจำตัวประชาชน
|
||||
*/
|
||||
function changeCardID(citizenId: string | number | null) {
|
||||
if (citizenId != null && typeof citizenId == "string") {
|
||||
if (citizenId.length == 13 && citizenId) {
|
||||
http
|
||||
.put(config.API.profileNewCitizenId(citizenId), {
|
||||
citizenId: citizenId,
|
||||
})
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
if (err.response.data.status === 500) {
|
||||
dialogMessageNotify($q, err.response.data.message);
|
||||
} else {
|
||||
messageError($q, err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fetchLevel(id: string) {
|
||||
const listLevel = store.posTypeMain.find((e: DataType) => e.id === id);
|
||||
levelOps.value = listLevel?.posLevels;
|
||||
|
||||
const checkLevel = levelOps.value.filter(
|
||||
(e: DataType) => e.id === formData.posLevelId
|
||||
);
|
||||
if (checkLevel.length === 0) {
|
||||
formData.posLevelId = "";
|
||||
}
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
clearFormData();
|
||||
}
|
||||
|
||||
const calculateMaxDate = () => {
|
||||
const today = new Date();
|
||||
today.setFullYear(today.getFullYear() - 18);
|
||||
return today;
|
||||
};
|
||||
|
||||
function clearFormData() {
|
||||
formData.prefix = "";
|
||||
formData.firstName = "";
|
||||
formData.lastName = "";
|
||||
formData.citizenId = "";
|
||||
formData.position = "";
|
||||
formData.posTypeId = "";
|
||||
formData.posLevelId = "";
|
||||
formData.rank = "";
|
||||
age.value = "";
|
||||
formData.birthDate = null;
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
dialogConfirm($q, async () => {
|
||||
const type = empType.value !== "officer" ? "-employee" : "";
|
||||
await http
|
||||
.post(config.API.registryNew(type), formData)
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
props.fetchData?.();
|
||||
closeDialog();
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => modal.value,
|
||||
() => {
|
||||
if (modal.value) {
|
||||
fetchPrefix();
|
||||
fetchRank();
|
||||
props.fetchType?.();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => formData.birthDate,
|
||||
(v) => {
|
||||
if (v) {
|
||||
age.value = calculateAge(v);
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 350px">
|
||||
<q-form @submit.prevent @validation-success="onSubmit()" greedy>
|
||||
<DialogHeader tittle="เพิ่มข้อมูล" :close="closeDialog" />
|
||||
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-md q-col-gutter-md">
|
||||
<div class="row q-gutter-sm">
|
||||
<div class="col">
|
||||
<q-select
|
||||
bg-color="white"
|
||||
v-model="formData.prefix"
|
||||
label="คำนำหน้าชื่อ"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
:options="prefixOps"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
map-options
|
||||
hide-bottom-space
|
||||
:rules="[
|
||||
(val) => {
|
||||
return val.length > 0 || 'กรุณาเลือกคำนำหน้าชื่อ';
|
||||
},
|
||||
]"
|
||||
emit-value
|
||||
/>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
bg-color="white"
|
||||
v-model="formData.rank"
|
||||
label="ยศ"
|
||||
outlined
|
||||
dense
|
||||
:options="rankOps"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
map-options
|
||||
hide-bottom-space
|
||||
emit-value
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<q-input
|
||||
bg-color="white"
|
||||
outlined
|
||||
v-model="formData.firstName"
|
||||
label="ชื่อ"
|
||||
dense
|
||||
lazy-rules
|
||||
borderless
|
||||
:rules="[(val) => val.length > 0 || 'กรุณากรอกชื่อ']"
|
||||
hide-bottom-space
|
||||
/>
|
||||
<q-input
|
||||
bg-color="white"
|
||||
outlined
|
||||
v-model="formData.lastName"
|
||||
label="นามสกุล"
|
||||
dense
|
||||
lazy-rules
|
||||
borderless
|
||||
:rules="[(val) => val.length > 0 || 'กรุณากรอกนามสกุล']"
|
||||
hide-bottom-space
|
||||
/>
|
||||
<q-input
|
||||
bg-color="white"
|
||||
outlined
|
||||
v-model="formData.citizenId"
|
||||
label="เลขประจำตัวประชาชน"
|
||||
dense
|
||||
lazy-rules
|
||||
borderless
|
||||
:rules="[
|
||||
(val: string) => !!val || `${'กรุณากรอกเลขประจำตัวประชาชน'}`,
|
||||
(val: string) =>
|
||||
val.length >= 13 ||
|
||||
`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,
|
||||
]"
|
||||
maxlength="13"
|
||||
hide-bottom-space
|
||||
mask="#############"
|
||||
@update:model-value="changeCardID"
|
||||
/>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
autoApply
|
||||
borderless
|
||||
week-start="0"
|
||||
:max-date="calculateMaxDate()"
|
||||
:enableTimePicker="false"
|
||||
menu-class-name="modalfix"
|
||||
v-model="formData.birthDate"
|
||||
:locale="'th'"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
for="inputDatereceive"
|
||||
outlined
|
||||
dense
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
:model-value="
|
||||
formData.birthDate != null
|
||||
? date2Thai(formData.birthDate)
|
||||
: null
|
||||
"
|
||||
label="วัน/เดือน/ปี เกิด"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`,
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
readonly
|
||||
class="inputgreen"
|
||||
v-model="age"
|
||||
label="อายุ"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<q-input
|
||||
bg-color="white"
|
||||
outlined
|
||||
v-model="formData.position"
|
||||
label="ตำแหน่งในสายงาน"
|
||||
dense
|
||||
lazy-rules
|
||||
borderless
|
||||
:rules="[(val) => val.length > 0 || 'กรุณากรอกตำแหน่ง']"
|
||||
hide-bottom-space
|
||||
/>
|
||||
<q-select
|
||||
bg-color="white"
|
||||
v-model="formData.posTypeId"
|
||||
label="ตำแหน่งประเภท"
|
||||
outlined
|
||||
:options="store.posTypeOps"
|
||||
dense
|
||||
options-cover
|
||||
map-options
|
||||
emit-value
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || 'กรุณาเลือกตำแหน่งประเภท']"
|
||||
@update:model-value="fetchLevel"
|
||||
/>
|
||||
<q-select
|
||||
bg-color="white"
|
||||
v-model="formData.posLevelId"
|
||||
label="ระดับ"
|
||||
:options="levelOps"
|
||||
outlined
|
||||
dense
|
||||
map-options
|
||||
emit-value
|
||||
option-label="posLevelName"
|
||||
option-value="id"
|
||||
options-cover
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || 'กรุณาเลือกระดับ']"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
id="onSubmit"
|
||||
type="submit"
|
||||
label="บันทึก"
|
||||
color="public"
|
||||
class="q-px-md"
|
||||
>
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
437
src/modules/04_registryPerson/components/DialogHistory.vue
Normal file
437
src/modules/04_registryPerson/components/DialogHistory.vue
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useRouter } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
/**
|
||||
* importType*
|
||||
*/
|
||||
import type { QTableProps } from "quasar";
|
||||
import type { QForm } from "quasar";
|
||||
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
|
||||
import type {
|
||||
HistoryPos,
|
||||
Position,
|
||||
} from "@/modules/04_registryPerson/interface/response/History";
|
||||
|
||||
/**
|
||||
* import components
|
||||
*/
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
/**
|
||||
* importStore
|
||||
*/
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
/**
|
||||
* use
|
||||
*/
|
||||
const myForm = ref<QForm>();
|
||||
const router = useRouter();
|
||||
const $q = useQuasar();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = useCounterMixin();
|
||||
|
||||
/**
|
||||
* props
|
||||
*/
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
|
||||
/**
|
||||
* ตัวแปร
|
||||
*/
|
||||
const employeeClass = ref<string>("");
|
||||
const typeKeyword = ref<string>("");
|
||||
const Keyword = ref<string>("");
|
||||
const positionKeyword = ref<string>("");
|
||||
const employeeClassOps = ref<DataOption[]>([
|
||||
{ id: "officer", name: "ข้าราชการ กทม.สามัญ" },
|
||||
{ id: "perm", name: "ลูกจ้างประจำ" },
|
||||
]);
|
||||
const typeKeywordOps = ref<DataOption[]>([
|
||||
{ id: "no", name: "ตำแหน่งเลขที่" },
|
||||
{ id: "position", name: "ตำแหน่ง" },
|
||||
]);
|
||||
const positionOps = ref<DataOption[]>([]);
|
||||
const options = ref<DataOption[]>([]);
|
||||
|
||||
/**
|
||||
* Table
|
||||
*/
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
label: "ลำดับ",
|
||||
field: "no",
|
||||
align: "left",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "citizenId",
|
||||
align: "left",
|
||||
label: "เลขประจำตัวประชาชน",
|
||||
field: "citizenId",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
align: "left",
|
||||
label: "ชื่อ - นามสกุล",
|
||||
field: "name",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "posNo",
|
||||
align: "left",
|
||||
label: "ตำแหน่งเลขที่",
|
||||
field: "posNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "position",
|
||||
align: "left",
|
||||
label: "ตำแหน่ง",
|
||||
field: "position",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่ถือครอง",
|
||||
field: "date",
|
||||
format: (val, row) => `${date2Thai(val)}`,
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
]);
|
||||
const rows = ref<HistoryPos[]>([]);
|
||||
|
||||
/**
|
||||
* function fetch ข้อมูลตำแหน่ง ข้าราชการ
|
||||
*/
|
||||
function fecthPositionOfficer() {
|
||||
http
|
||||
.get(config.API.listPositionPathHistory)
|
||||
.then((res) => {
|
||||
let data = res.data.result.items;
|
||||
|
||||
positionOps.value = data.map((e: Position) => ({
|
||||
id: e.id,
|
||||
name: e.name,
|
||||
}));
|
||||
options.value = positionOps.value;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function fetch ข้อมูลตำแหน่ง ลูกจ้างประจำ
|
||||
*/
|
||||
function fetchPositionPerm() {
|
||||
http
|
||||
.get(config.API.listPositionEmployeePositionHistory)
|
||||
.then((res) => {
|
||||
let data = res.data.result.items;
|
||||
console.log(data);
|
||||
|
||||
positionOps.value = data.map((e: Position) => ({
|
||||
id: e.id,
|
||||
name: e.name,
|
||||
}));
|
||||
options.value = positionOps.value;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function เปลี่ยนประเภท
|
||||
*/
|
||||
function changeEmployeeClass() {
|
||||
typeKeyword.value = "";
|
||||
Keyword.value = "";
|
||||
positionKeyword.value = "";
|
||||
rows.value = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* function เลือกฟิลด์ที่จะค้นหา
|
||||
* @param typeKeyword ประเภทฟิลด์
|
||||
*/
|
||||
function selectTypeKeyword(typeKeyword: string) {
|
||||
positionOps.value = [];
|
||||
positionKeyword.value = "";
|
||||
Keyword.value = "";
|
||||
|
||||
if (typeKeyword == "position" && employeeClass.value === "officer") {
|
||||
fecthPositionOfficer();
|
||||
} else if (typeKeyword == "position" && employeeClass.value === "perm") {
|
||||
fetchPositionPerm();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* function ค้นหาประวัติถือครองตำแหน่ง
|
||||
* @param type ประเภทข่าราชการ
|
||||
*/
|
||||
function clickSearch(type: string) {
|
||||
myForm.value!.validate().then((result: boolean) => {
|
||||
if (result) {
|
||||
showLoader();
|
||||
let body = {};
|
||||
if (typeKeyword.value === "no") {
|
||||
Object.assign(body, {
|
||||
posNo: Keyword.value,
|
||||
});
|
||||
} else if (typeKeyword.value === "position") {
|
||||
Object.assign(body, {
|
||||
position: positionKeyword.value,
|
||||
});
|
||||
}
|
||||
const empType = type === "officer" ? "" : "-employee";
|
||||
http
|
||||
.post(config.API.registryNew(empType) + `/search/history/oc`, body)
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
if (data.length !== 0) {
|
||||
rows.value = data.map((e: HistoryPos) => ({
|
||||
id: e.id,
|
||||
citizenId: e.citizenId,
|
||||
name: e.fullName,
|
||||
posNo: e.posNo,
|
||||
position: e.position,
|
||||
date: e.date,
|
||||
}));
|
||||
} else {
|
||||
rows.value = [];
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
rows.value = [];
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function ค้นหาข่อมูล Optiion
|
||||
* @param val คำค้นหา
|
||||
* @param update function
|
||||
*/
|
||||
function filterFn(val: string, update: Function) {
|
||||
if (val === "") {
|
||||
update(() => {
|
||||
options.value = positionOps.value;
|
||||
});
|
||||
return;
|
||||
} else {
|
||||
update(() => {
|
||||
options.value = positionOps.value.filter(
|
||||
(e) => e.name.search(val) !== -1
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* function redirect ไปทะเบียนประวัติ
|
||||
* @param id
|
||||
*/
|
||||
function clickRedirect(id: string) {
|
||||
const url =
|
||||
employeeClass.value === "officer" ? "registry-person" : "registry-employee";
|
||||
router.push(`${url}/${id}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* function ปิด popup
|
||||
*/
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
employeeClass.value = "";
|
||||
typeKeyword.value = "";
|
||||
Keyword.value = "";
|
||||
positionKeyword.value = "";
|
||||
rows.value = [];
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal">
|
||||
<q-card style="width: 850px; max-width: 80vw">
|
||||
<DialogHeader :tittle="'ประวัติถือครองตำแหน่ง'" :close="closeDialog" />
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-section class="q-pa-sm">
|
||||
<q-form ref="myForm">
|
||||
<div class="col-12 bg-grey-2 q-pa-sm">
|
||||
<div class="col-12 row q-pb-sm q-col-gutter-sm items-center"></div>
|
||||
<div class="q-col-gutter-xs row no-wrap">
|
||||
<div class="col-4">
|
||||
<q-select
|
||||
hide-bottom-space
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก ประเภท'}`]"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="employeeClass"
|
||||
emit-value
|
||||
map-options
|
||||
:options="employeeClassOps"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
:label="`${'ประเภท'}`"
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@update:model-value="changeEmployeeClass"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<q-select
|
||||
hide-bottom-space
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก ฟิลด์ที่จะค้น'}`]"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="typeKeyword"
|
||||
emit-value
|
||||
map-options
|
||||
:options="typeKeywordOps"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
:label="`${' เลือกฟิลด์ที่จะค้น'}`"
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@update:model-value="selectTypeKeyword(typeKeyword)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col" v-if="typeKeyword === 'no'">
|
||||
<q-input
|
||||
borderless
|
||||
outlined
|
||||
dense
|
||||
debounce="300"
|
||||
v-model="Keyword"
|
||||
placeholder="ตำแหน่งเลขที่"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอก ตำแหน่งเลขที่'}`]"
|
||||
hide-bottom-space
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="col" v-if="typeKeyword === 'position'">
|
||||
<q-select
|
||||
hide-bottom-space
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก ตำแหน่ง'}`]"
|
||||
outlined
|
||||
dense
|
||||
v-model="positionKeyword"
|
||||
emit-value
|
||||
map-options
|
||||
:options="options"
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
:label="`${' เลือกตำแหน่ง'}`"
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@filter="filterFn"
|
||||
behavior="menu"
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
ไม่มีข้อมูล
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template></q-select
|
||||
>
|
||||
</div>
|
||||
|
||||
<q-space />
|
||||
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-magnify"
|
||||
label="ค้นหา"
|
||||
@click="clickSearch(employeeClass)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 q-mt-sm">
|
||||
<d-table
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
row-key="order"
|
||||
no-data-label="ไม่มีข้อมูล"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
>
|
||||
<div class="text-grey-7 text-weight-medium">
|
||||
<span class="row">{{ col.label }}</span>
|
||||
</div>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<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 === 'citizenId'"
|
||||
class="text-primary"
|
||||
@click="clickRedirect(props.row.id)"
|
||||
>
|
||||
{{ props.row.citizenId ?? "-" }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="col.name === 'name'"
|
||||
class="text-primary"
|
||||
@click="clickRedirect(props.row.id)"
|
||||
>
|
||||
{{ props.row.name ?? "-" }}
|
||||
</div>
|
||||
<div v-else class="table_ellipsis2">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</div>
|
||||
</q-form>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
555
src/modules/04_registryPerson/components/TableView.vue
Normal file
555
src/modules/04_registryPerson/components/TableView.vue
Normal file
|
|
@ -0,0 +1,555 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
/** importType*/
|
||||
import type { QTableProps } from "quasar";
|
||||
import type { FormFilter } from "@/modules/04_registryPerson/interface/request/Main";
|
||||
|
||||
/** importComponent*/
|
||||
import DialogAddData from "@/modules/04_registryPerson/components/DialogAddData.vue";
|
||||
import DialogHistory from "@/modules/04_registryPerson/components/DialogHistory.vue";
|
||||
|
||||
/** importStore*/
|
||||
import { useRegistryNewDataStore } from "@/modules/04_registryPerson/store";
|
||||
|
||||
const store = useRegistryNewDataStore();
|
||||
const router = useRouter();
|
||||
|
||||
const formFilter = defineModel<FormFilter>("formFilter", { required: true });
|
||||
const maxPage = defineModel<Number>("maxPage", { required: true });
|
||||
const empType = defineModel<string>("empType", { required: true });
|
||||
const props = defineProps({
|
||||
rows: { type: Array },
|
||||
fetchData: { type: Function },
|
||||
fetchType: { type: Function },
|
||||
total: { type: Number },
|
||||
// empType: { type: String },
|
||||
});
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
align: "left",
|
||||
label: "ลำดับ",
|
||||
sortable: true,
|
||||
field: "no",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "fullName",
|
||||
align: "left",
|
||||
label: "ชื่อ - นามสกุล",
|
||||
sortable: true,
|
||||
field: "fullName",
|
||||
headerStyle: "font-size: 14px; min-width: 200px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "posNo",
|
||||
align: "left",
|
||||
label: "ตำแหน่งเลขที่",
|
||||
sortable: true,
|
||||
field: "posNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "position",
|
||||
align: "left",
|
||||
label: "ตำแหน่งในสายงาน",
|
||||
sortable: true,
|
||||
field: "position",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "posPath",
|
||||
align: "left",
|
||||
label: "ตำแหน่งประเภท",
|
||||
sortable: true,
|
||||
field: "posType",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "posLevel",
|
||||
align: "left",
|
||||
label: "ระดับ",
|
||||
sortable: true,
|
||||
field: "posLevel",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format(val, row) {
|
||||
return row.posTypeShortName
|
||||
? row.posTypeShortName + " " + row.posLevel
|
||||
: row.posLevel;
|
||||
},
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "org",
|
||||
align: "left",
|
||||
label: "สังกัด",
|
||||
sortable: true,
|
||||
field: "org",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
// {
|
||||
// name: "year",
|
||||
// align: "left",
|
||||
// label: "ปีงบประมาณ",
|
||||
// sortable: true,
|
||||
// field: "year",
|
||||
// headerStyle: "font-size: 14px",
|
||||
// style: "font-size: 14px",
|
||||
// sort: (a: string, b: string) =>
|
||||
// a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
// },
|
||||
// {
|
||||
// name: "salary",
|
||||
// align: "left",
|
||||
// label: "ค่าจ้าง",
|
||||
// sortable: true,
|
||||
// field: "salary",
|
||||
// headerStyle: "font-size: 14px",
|
||||
// style: "font-size: 14px",
|
||||
// sort: (a: string, b: string) =>
|
||||
// a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
// },
|
||||
]);
|
||||
|
||||
const visibleColumns = ref<string[]>([
|
||||
"no",
|
||||
"fullName",
|
||||
"posNo",
|
||||
"position",
|
||||
"posPath",
|
||||
"posType",
|
||||
"posLevel",
|
||||
"org",
|
||||
]);
|
||||
|
||||
function updatePagePagination() {
|
||||
props.fetchData?.();
|
||||
}
|
||||
|
||||
function updatePageSizePagination(newPagination: any) {
|
||||
formFilter.value.page = 1;
|
||||
formFilter.value.pageSize = newPagination.rowsPerPage;
|
||||
}
|
||||
|
||||
const pagination = ref({
|
||||
page: formFilter.value.page,
|
||||
rowsPerPage: formFilter.value.pageSize,
|
||||
});
|
||||
|
||||
const modalDialogAdd = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
function onClickAddData() {
|
||||
modalDialogAdd.value = !modalDialogAdd.value;
|
||||
}
|
||||
|
||||
function onClickHistory() {
|
||||
modalHistory.value = !modalHistory.value;
|
||||
}
|
||||
|
||||
function onClickViewDetail(id: string) {
|
||||
if (empType.value === "officer") {
|
||||
router.push(`/registry-person/${id}`);
|
||||
} else {
|
||||
router.push(`/registry-employee/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* function redirect ไปหน้ารายการคำร้องขอแก้ไขข้อมูล
|
||||
*/
|
||||
function redirectToPagePetition() {
|
||||
router.push(`/registry-person/request-edit`);
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formFilter.value.pageSize,
|
||||
() => {
|
||||
props.fetchData?.();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="col-12 row q-pb-sm q-col-gutter-sm items-center">
|
||||
<div class="row q-gutter-sm">
|
||||
<q-btn
|
||||
v-if="empType === 'officer'"
|
||||
color="primary"
|
||||
label="รายการคำร้องขอแก้ไข"
|
||||
@click="redirectToPagePetition()"
|
||||
>
|
||||
<q-tooltip>รายการคำร้องขอแก้ไข</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
round
|
||||
flat
|
||||
dense
|
||||
color="blue"
|
||||
icon="mdi-history"
|
||||
@click="onClickHistory"
|
||||
>
|
||||
<q-tooltip>ประวัติถือครองตำแหน่ง</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
<q-space />
|
||||
<q-select
|
||||
v-if="store.mode === 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
class="full-height"
|
||||
hide-bottom-space
|
||||
/>
|
||||
<div>
|
||||
<q-btn-toggle
|
||||
v-model="store.mode"
|
||||
dense
|
||||
class="my-custom-toggle no-shadow"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
class="q-px-sm q-py-xs"
|
||||
size="22px"
|
||||
:style="{
|
||||
color: store.mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="22px"
|
||||
class="q-px-sm q-py-xs"
|
||||
:style="{
|
||||
color: store.mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:card-container-class="store.mode === 'card' ? 'q-col-gutter-md' : ''"
|
||||
:columns="columns"
|
||||
:rows="props.rows"
|
||||
:grid="store.mode === 'card'"
|
||||
:paging="true"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
@update:pagination="updatePageSizePagination"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<span class="text-weight-medium" v-if="col.name === 'posLevel'">{{
|
||||
empType === "officer" ? col.label : "ระดับชั้นงาน"
|
||||
}}</span>
|
||||
<span class="text-weight-medium" v-else-if="col.name === 'posPath'">{{
|
||||
empType === "officer" ? col.label : "กลุ่มงาน"
|
||||
}}</span>
|
||||
<span
|
||||
class="text-weight-medium"
|
||||
v-else-if="col.name === 'position'"
|
||||
>{{ empType === "officer" ? col.label : "ตำแหน่ง" }}</span
|
||||
>
|
||||
|
||||
<span class="text-weight-medium" v-else>{{ col.label }}</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="store.mode === 'table'">
|
||||
<q-tr :props="props">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="col.name == 'fullName'">
|
||||
<div class="row col-12 wrap items-center">
|
||||
<q-item>
|
||||
<q-item-section avatar>
|
||||
<q-avatar size="50px" class="bg-grey-2">
|
||||
<q-img :src="props.row.avatar" />
|
||||
</q-avatar>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<div
|
||||
class="text-weight-medium text-primary cursor-pointer"
|
||||
@click="onClickViewDetail(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ดูทะเบียนประวัติ</q-tooltip>
|
||||
{{
|
||||
`${props.row.prefix ? props.row.prefix : ""}${
|
||||
props.row.firstName
|
||||
} ${props.row.lastName}`
|
||||
}}
|
||||
</div>
|
||||
<div class="text-weight-light">{{ props.row.citizenId }}</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-4 col-md-3">
|
||||
<q-card flat bordered class="">
|
||||
<q-card-section class="text-center q-pb-none">
|
||||
<q-avatar size="80px" class="bg-grey-2">
|
||||
<q-img :src="props.row.avatar" />
|
||||
</q-avatar>
|
||||
|
||||
<div class="text-weight-medium q-mt-md">
|
||||
{{
|
||||
`${props.row.prefix ? props.row.prefix : ""}${
|
||||
props.row.firstName
|
||||
} ${props.row.lastName}`
|
||||
}}
|
||||
</div>
|
||||
<div class="text-weight-light full-width text-center">
|
||||
{{ props.row.citizenId }}
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-card-section class="q-pa-sm">
|
||||
<q-card bordered class="bg-grey-13">
|
||||
<q-card-section>
|
||||
<div class="text-grey">ตำแหน่งเลขที่</div>
|
||||
<div class="text-subtitle2 text-black q-ml-sm">
|
||||
{{ props.row.posNo ? props.row.posNo : "-" }}
|
||||
</div>
|
||||
|
||||
<div class="text-grey">
|
||||
{{ empType === "officer" ? `ตำแหน่งในสายงาน` : `ตำแหน่ง` }}
|
||||
</div>
|
||||
<div class="text-subtitle2 text-black q-ml-sm">
|
||||
{{ props.row.position ? props.row.position : "-" }}
|
||||
</div>
|
||||
|
||||
<div class="text-grey">
|
||||
{{ empType === "officer" ? "ตำแหน่งประเภท" : "กลุ่มงาน" }}
|
||||
</div>
|
||||
<div class="text-subtitle2 text-black q-ml-sm">
|
||||
{{ props.row.posType ? props.row.posType : "-" }}
|
||||
</div>
|
||||
|
||||
<div class="text-grey">
|
||||
{{ empType === "officer" ? "ระดับ" : "ระดับชั้นงาน" }}
|
||||
</div>
|
||||
<div class="text-subtitle2 text-black q-ml-sm">
|
||||
{{
|
||||
props.row.posLevel
|
||||
? props.row.posTypeShortName
|
||||
? `${props.row.posTypeShortName} ${props.row.posLevel}`
|
||||
: props.row.posLevel
|
||||
: "-"
|
||||
}}
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<!-- <q-list dense class="q-py-sm"> -->
|
||||
<!-- <q-item dense>
|
||||
<q-item-section>
|
||||
<q-item-label caption>ตำแหน่งเลขที่</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption class="text-black">{{
|
||||
props.row.posNo ? props.row.posNo : "-"
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item> -->
|
||||
|
||||
<!-- <q-item dense>
|
||||
<q-item-section>
|
||||
<q-item-label caption>{{
|
||||
empType === "officer" ? `ตำแหน่งในสายงาน` : `ตำแหน่ง`
|
||||
}}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption class="text-black">
|
||||
{{
|
||||
props.row.position ? props.row.position : "-"
|
||||
}}</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item> -->
|
||||
|
||||
<!-- <q-item dense>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
{{
|
||||
empType === "officer" ? "ตำแหน่งประเภท" : "กลุ่มงาน"
|
||||
}}</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption class="text-black">
|
||||
{{
|
||||
props.row.posType ? props.row.posType : "-"
|
||||
}}</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item> -->
|
||||
|
||||
<!-- <q-item dense>
|
||||
<q-item-section>
|
||||
<q-item-label caption>
|
||||
{{
|
||||
empType === "officer" ? "ระดับ" : "ระดับชั้นงาน"
|
||||
}}</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label caption class="text-black">
|
||||
{{
|
||||
props.row.posLevel
|
||||
? props.row.posTypeShortName
|
||||
? `${props.row.posTypeShortName} ${props.row.posLevel}`
|
||||
: props.row.posLevel
|
||||
: "-"
|
||||
}}</q-item-label
|
||||
>
|
||||
</q-item-section>
|
||||
</q-item> -->
|
||||
<!-- </q-list> -->
|
||||
</q-card>
|
||||
</q-card-section>
|
||||
<q-separator inset />
|
||||
<q-btn
|
||||
flat
|
||||
color="black"
|
||||
label="ดูเพิ่มเติม"
|
||||
class="hover-button full-width q-pa-md"
|
||||
@click="onClickViewDetail(props.row.id)"
|
||||
/>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:pagination="scope">
|
||||
ทั้งหมด {{ props.total }} รายการ
|
||||
<q-pagination
|
||||
v-model="formFilter.page"
|
||||
active-color="primary"
|
||||
color="dark"
|
||||
:max="Number(maxPage)"
|
||||
:max-pages="5"
|
||||
size="sm"
|
||||
boundary-links
|
||||
direction-links
|
||||
@update:model-value="updatePagePagination()"
|
||||
></q-pagination>
|
||||
</template>
|
||||
<template v-slot:no-data="{ icon, message, filter }">
|
||||
<div class="full-width row flex-center text-accent q-gutter-sm">
|
||||
<span
|
||||
><div
|
||||
style="
|
||||
height: 50vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
"
|
||||
class="text-grey-5"
|
||||
>
|
||||
<q-icon name="search" size="4rem" />
|
||||
|
||||
<span>ไม่พบข้อมูล</span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<DialogAddData
|
||||
v-model:modal="modalDialogAdd"
|
||||
:fetchData="props.fetchData"
|
||||
:fetchType="props.fetchType"
|
||||
:empType="empType"
|
||||
/>
|
||||
|
||||
<DialogHistory v-model:modal="modalHistory" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hover-button:hover {
|
||||
background-color: #089cfc;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
.my-card {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.bg-grey-13 {
|
||||
background: #f1f2f496 !important;
|
||||
}
|
||||
|
||||
.my-custom-toggle {
|
||||
border: 1px solid #d0d0d2;
|
||||
}
|
||||
.cardRO {
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.cardRO:hover {
|
||||
cursor: pointer;
|
||||
background: #dcdcdc33 !important;
|
||||
}
|
||||
.cardRO:hover .textName {
|
||||
color: #02a998;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,785 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import dialogHeader from "@/components/DialogHeader.vue";
|
||||
import type { QTableProps } from "quasar";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { QForm, useQuasar } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
import type { RequestItemsObject } from "@/modules/04_registryPerson/interface/request/ProfesLicense";
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/ProfesLicense";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
const mixin = useCounterMixin();
|
||||
const $q = useQuasar();
|
||||
const {
|
||||
dialogConfirm,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
success,
|
||||
date2Thai,
|
||||
} = mixin;
|
||||
|
||||
const historyDialog = ref<boolean>(false);
|
||||
const mode = ref<string>("table");
|
||||
const dialog = ref<boolean>(false);
|
||||
const route = useRoute();
|
||||
const id = ref<string>(route.params.id.toString());
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const dialogStatus = ref<string>("create");
|
||||
const editId = ref<string>("");
|
||||
const keyword = ref<string>("");
|
||||
const historyKeyword = ref<string>("");
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "certificateType",
|
||||
align: "left",
|
||||
label: "ชื่อใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "certificateType",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "issuer",
|
||||
align: "left",
|
||||
label: "หน่วยงานผู้ออกใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "issuer",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "certificateNo",
|
||||
align: "left",
|
||||
label: "เลขที่ใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "certificateNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "issueDate",
|
||||
align: "left",
|
||||
label: "วันที่ออกใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "issueDate",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "expireDate",
|
||||
align: "left",
|
||||
label: "วันที่หมดอายุ",
|
||||
sortable: true,
|
||||
format: (v) => date2Thai(v),
|
||||
field: "expireDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const historyColumns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "certificateType",
|
||||
align: "left",
|
||||
label: "ชื่อใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "certificateType",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "issuer",
|
||||
align: "left",
|
||||
label: "หน่วยงานผู้ออกใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "issuer",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "certificateNo",
|
||||
align: "left",
|
||||
label: "เลขที่ใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "certificateNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "issueDate",
|
||||
align: "left",
|
||||
label: "วันที่ออกใบอนุญาต",
|
||||
sortable: true,
|
||||
field: "issueDate",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "expireDate",
|
||||
align: "left",
|
||||
label: "วันที่หมดอายุ",
|
||||
sortable: true,
|
||||
format: (v) => date2Thai(v),
|
||||
field: "expireDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const profesLicenseData = reactive<RequestItemsObject>({
|
||||
certificateType: "",
|
||||
issuer: "",
|
||||
certificateNo: "",
|
||||
issueDate: new Date(),
|
||||
expireDate: null,
|
||||
profileId: id.value,
|
||||
});
|
||||
|
||||
const rows = ref<ResponseObject[]>([]);
|
||||
const historyRows = ref<ResponseObject[]>([]);
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const visibleColumns = ref<string[]>([
|
||||
"certificateType",
|
||||
"issuer",
|
||||
"certificateNo",
|
||||
"issueDate",
|
||||
"expireDate",
|
||||
]);
|
||||
|
||||
const historyVisibleColumns = ref<string[]>([
|
||||
"certificateType",
|
||||
"issuer",
|
||||
"certificateNo",
|
||||
"issueDate",
|
||||
"expireDate",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
async function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
dialogStatus.value === "create" ? addData() : editData(editId.value);
|
||||
closeDialog();
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
dialog.value = false;
|
||||
}
|
||||
function closeHistoryDialog() {
|
||||
historyDialog.value = false;
|
||||
}
|
||||
|
||||
async function fetchData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewCertificateByProfileId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
profesLicenseData.expireDate = null;
|
||||
profesLicenseData.issueDate = new Date();
|
||||
profesLicenseData.certificateNo = "";
|
||||
profesLicenseData.certificateType = "";
|
||||
profesLicenseData.issuer = "";
|
||||
}
|
||||
|
||||
function editForm(row: any) {
|
||||
dialogStatus.value = "edit";
|
||||
editId.value = row.id;
|
||||
profesLicenseData.certificateType = row.certificateType;
|
||||
profesLicenseData.certificateNo = row.certificateNo;
|
||||
profesLicenseData.issuer = row.issuer;
|
||||
profesLicenseData.issueDate = row.issueDate;
|
||||
profesLicenseData.expireDate = row.expireDate;
|
||||
dialog.value = true;
|
||||
}
|
||||
|
||||
async function addData() {
|
||||
await http
|
||||
.post(config.API.profileNewCertificate(empType.value), {
|
||||
...profesLicenseData,
|
||||
profileId: empType.value === "" ? id.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? id.value : undefined,
|
||||
})
|
||||
.then(() => {
|
||||
fetchData(id.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function editData(idData: string) {
|
||||
await http
|
||||
.patch(
|
||||
config.API.profileNewCertificateByCertificateId(idData, empType.value),
|
||||
{
|
||||
...profesLicenseData,
|
||||
profileId: undefined,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
fetchData(id.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
// function deleteData(idData: string) {
|
||||
// dialogRemove($q, () =>
|
||||
// http
|
||||
// .delete(config.API.profileNewCertificateByCertificateId(idData))
|
||||
// .then(() => {
|
||||
// fetchData(id.value);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// messageError($q, err);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// hideLoader();
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
async function fetchHistoryData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewCertificateHisByCertificateId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
historyRows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData(id.value);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn
|
||||
round
|
||||
flat
|
||||
color="primary"
|
||||
icon="add"
|
||||
dense
|
||||
@click="
|
||||
dialogStatus = 'create';
|
||||
clearForm();
|
||||
dialog = true;
|
||||
"
|
||||
>
|
||||
<q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input dense outlined v-model="keyword" label="ค้นหา">
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="mode === 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
<d-table
|
||||
:grid="mode === 'card'"
|
||||
ref="table"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
row-key="name"
|
||||
flat
|
||||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
:filter="keyword"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
class="custom-header-table"
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
<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" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
icon="mdi-pencil-outline"
|
||||
clickable
|
||||
@click="
|
||||
() => {
|
||||
editForm(props.row);
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="
|
||||
() => (fetchHistoryData(props.row.id), (historyDialog = true))
|
||||
"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขใบอนุญาตประกอบวิชาชีพ</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- <q-btn
|
||||
color="red"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-delete"
|
||||
clickable
|
||||
@click.stop="deleteData(props.row.id)"
|
||||
v-close-popup
|
||||
>
|
||||
<q-tooltip>ลบข้อมูล</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div
|
||||
class="q-pa-xs col-xs-12 col-sm-6 col-md-6 col-lg-6 grid-style-transition"
|
||||
>
|
||||
<q-card bordered>
|
||||
<q-card-actions align="right" class="bg-grey-3">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="edit"
|
||||
@click="editForm(props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
size="14px"
|
||||
@click="
|
||||
() => (fetchHistoryData(props.row.id), (historyDialog = true))
|
||||
"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขใบอนุญาตประกอบวิชาชีพ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<q-separator />
|
||||
<q-list>
|
||||
<div
|
||||
:class="`row q-pa-sm`"
|
||||
:style="`background-color: ${index % 2 !== 0 ? '#FAFAFA' : ''}`"
|
||||
v-for="(col, index) in props.cols"
|
||||
:key="col.name"
|
||||
>
|
||||
<div></div>
|
||||
<div class="col label-color">
|
||||
<div>{{ col.label }}</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div>{{ col.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-list>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="dialog" class="dialog" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit()">
|
||||
<dialog-header
|
||||
:tittle="
|
||||
dialogStatus == 'edit'
|
||||
? 'แก้ไขข้อมูลใบอนุญาตประกอบวิชาชีพ'
|
||||
: 'เพิ่มข้อมูลใบอนุญาตประกอบวิชาชีพ'
|
||||
"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-sm q-pb-sm">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="profesLicenseData.certificateType"
|
||||
label="ชื่อใบอนุญาต"
|
||||
bg-color="white"
|
||||
dense
|
||||
class="inputgreen"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกชื่อใบอนุญาต'}`]"
|
||||
hide-bottom-space
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="profesLicenseData.issuer"
|
||||
label="หน่วยงานผู้ออกใบอนุญาต"
|
||||
bg-color="white"
|
||||
dense
|
||||
class="inputgreen"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณากรอกหน่วยงานผู้ออกใบอนุญาต'}`,
|
||||
]"
|
||||
hide-bottom-space
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row q-col-gutter-sm q-pb-sm">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
v-model="profesLicenseData.certificateNo"
|
||||
label="เลขที่ใบอนุญาต"
|
||||
bg-color="white"
|
||||
class="inputgreen"
|
||||
dense
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกเลขที่ใบอนุญาต'}`]"
|
||||
hide-bottom-space
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="profesLicenseData.issueDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
class="col"
|
||||
:enableTimePicker="false"
|
||||
@update:modelValue="profesLicenseData.issueDate"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
class="inputgreen"
|
||||
outlined
|
||||
bg-color="white"
|
||||
hide-bottom-space
|
||||
:model-value="
|
||||
profesLicenseData.issueDate
|
||||
? date2Thai(profesLicenseData.issueDate)
|
||||
: ''
|
||||
"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณาเลือกวันที่ออกใบอนุญาต'}`,
|
||||
]"
|
||||
:label="`${'วันที่ออกใบอนุญาต'}`"
|
||||
>
|
||||
<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>
|
||||
<div class="row q-gutter-sm q-pb-sm">
|
||||
<div class="col">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="profesLicenseData.expireDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
@update:modelValue="profesLicenseData.expireDate"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
bg-color="white"
|
||||
class="inputgreen"
|
||||
clearable
|
||||
@clear="() => (profesLicenseData.expireDate = null)"
|
||||
hide-bottom-space
|
||||
:model-value="
|
||||
profesLicenseData.expireDate
|
||||
? date2Thai(profesLicenseData.expireDate)
|
||||
: ''
|
||||
"
|
||||
:label="`${'วันที่หมดอายุ'}`"
|
||||
@update:modelValue="profesLicenseData.expireDate = null"
|
||||
>
|
||||
<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>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="historyDialog" class="dialog" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<dialog-header
|
||||
tittle="ประวัติแก้ไขใบอนุญาตประกอบวิชาชีพ"
|
||||
:close="closeHistoryDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
bg-color="white"
|
||||
v-model="historyKeyword"
|
||||
label="ค้นหา"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-select
|
||||
v-model="historyVisibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
bg-color="white"
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="historyColumns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
:columns="historyColumns"
|
||||
:rows="historyRows"
|
||||
row-key="name"
|
||||
flat
|
||||
:filter="historyKeyword"
|
||||
v-model:pagination="historyPagination"
|
||||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
class="custom-header-table"
|
||||
:visible-columns="historyVisibleColumns"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
<q-th auto-width />
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.bg-color {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.label-color {
|
||||
color: #747474cc;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,835 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import type { QTableProps, QForm } from "quasar";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import type { RequestItemsObject } from "@/modules/04_registryPerson/interface/request/DeclarationHonor";
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/DeclarationHonor";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
success,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
dialogConfirm,
|
||||
} = mixin;
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const id = ref<string>("");
|
||||
const issueDateYear = ref<number>(0);
|
||||
const declHonorForm = reactive<RequestItemsObject>({
|
||||
isDate: "false",
|
||||
issuer: "",
|
||||
detail: "",
|
||||
issueDate: null,
|
||||
refCommandNo: "",
|
||||
refCommandDate: null,
|
||||
});
|
||||
|
||||
const isEdit = ref<boolean>(false);
|
||||
const modal = ref<boolean>(false);
|
||||
const modeView = ref<string>("table");
|
||||
const filterSearch = ref("");
|
||||
const filterHistory = ref<string>("");
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const rowsHistory = ref<ResponseObject[]>([]);
|
||||
|
||||
const rows = ref<ResponseObject[]>([]);
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "issueDate",
|
||||
align: "left",
|
||||
label: "วันที่ได้รับ",
|
||||
sortable: true,
|
||||
field: (v) =>
|
||||
v.isDate
|
||||
? date2Thai(v.issueDate)
|
||||
: new Date(v.issueDate).getFullYear() + 543,
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "issuer",
|
||||
align: "left",
|
||||
label: "ผู้มีอำนาจลงนาม",
|
||||
sortable: true,
|
||||
field: "issuer",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
const columnsHistory = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "issueDate",
|
||||
align: "left",
|
||||
label: "วันที่ได้รับ",
|
||||
sortable: true,
|
||||
field: (v) =>
|
||||
v.isDate
|
||||
? date2Thai(v.issueDate)
|
||||
: new Date(v.issueDate).getFullYear() + 543,
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "issuer",
|
||||
align: "left",
|
||||
label: "ผู้มีอำนาจลงนาม",
|
||||
sortable: true,
|
||||
field: "issuer",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"issuer",
|
||||
"detail",
|
||||
"issueDate",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
]);
|
||||
|
||||
const visibleColumnsHistory = ref<String[]>([
|
||||
"issuer",
|
||||
"detail",
|
||||
"issueDate",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
async function fetchData() {
|
||||
if (!profileId.value) return;
|
||||
|
||||
showLoader();
|
||||
try {
|
||||
const res = await http.get(
|
||||
config.API.profileNewHonorByProfileId(profileId.value, empType.value)
|
||||
);
|
||||
rows.value = res.data.result;
|
||||
} catch (error) {
|
||||
messageError($q, error);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
async function addEditData(editStatus: boolean = false) {
|
||||
if (!profileId.value) return;
|
||||
|
||||
const url = editStatus
|
||||
? config.API.profileNewHonorById(id.value, empType.value)
|
||||
: config.API.profileNewHonor(empType.value);
|
||||
const method = editStatus ? "patch" : "post";
|
||||
const reqBody: RequestItemsObject = {
|
||||
...declHonorForm,
|
||||
profileEmployeeId:
|
||||
!editStatus && empType.value !== "" ? profileId.value : undefined,
|
||||
profileId:
|
||||
!editStatus && empType.value === "" ? profileId.value : undefined,
|
||||
isDate: declHonorForm.isDate === "true" ? true : false,
|
||||
issueDate:
|
||||
declHonorForm.isDate === "true"
|
||||
? declHonorForm.issueDate
|
||||
: new Date(`${issueDateYear.value}-01-01`),
|
||||
};
|
||||
|
||||
try {
|
||||
await http[method](url, reqBody);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
await fetchData();
|
||||
} catch (e) {
|
||||
messageError($q, e);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
function onClickOpenDialog(editStatus: boolean = false, row?: ResponseObject) {
|
||||
modal.value = true;
|
||||
isEdit.value = editStatus;
|
||||
|
||||
if (editStatus && row) {
|
||||
id.value = row.id;
|
||||
|
||||
issueDateYear.value = new Date(row.issueDate).getFullYear();
|
||||
declHonorForm.issuer = row.issuer;
|
||||
declHonorForm.detail = row.detail;
|
||||
declHonorForm.issueDate = row.issueDate;
|
||||
declHonorForm.refCommandNo = row.refCommandNo;
|
||||
declHonorForm.refCommandDate = row.refCommandDate;
|
||||
declHonorForm.isDate = row.isDate ? "true" : "false";
|
||||
} else {
|
||||
clearData();
|
||||
}
|
||||
}
|
||||
|
||||
async function clickClose() {
|
||||
clearData();
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
async function clickHistory(row: ResponseObject) {
|
||||
modalHistory.value = true;
|
||||
filterSearch.value = "";
|
||||
|
||||
showLoader();
|
||||
try {
|
||||
const res = await http.get(
|
||||
config.API.profileNewHonorHisById(row.id, empType.value)
|
||||
);
|
||||
rowsHistory.value = res.data.result;
|
||||
} catch (e) {
|
||||
messageError($q, e);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
addEditData(isEdit.value);
|
||||
modal.value = false;
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
id.value = "";
|
||||
issueDateYear.value = new Date().getFullYear();
|
||||
declHonorForm.issuer = "";
|
||||
declHonorForm.detail = "";
|
||||
declHonorForm.issueDate = new Date();
|
||||
declHonorForm.refCommandNo = "";
|
||||
declHonorForm.refCommandDate = null;
|
||||
declHonorForm.isDate = "false";
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn
|
||||
dense
|
||||
color="primary"
|
||||
icon="add"
|
||||
flat
|
||||
round
|
||||
@click="onClickOpenDialog()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterSearch"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterSearch == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterSearch = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterSearch"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterSearch = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="modeView == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="modeView"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modeView === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modeView === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:columns="columns"
|
||||
:filter="filterSearch"
|
||||
:grid="modeView === 'card'"
|
||||
v-model:pagination="pagination"
|
||||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:card-container-class="modeView === 'card' ? 'q-col-gutter-md' : ''"
|
||||
>
|
||||
<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" v-if="modeView === 'table'">
|
||||
<q-tr :props="props">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="clickHistory(props.row)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขประกาศเกียรติคุณ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<div class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-card bordered>
|
||||
<q-card-actions class="bg-grey-3" align="right">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก่ไขข้อมุล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
@click.stop.prevent="clickHistory(props.row)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขประกาศเกียรติคุณ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<q-separator />
|
||||
<div>
|
||||
<q-item
|
||||
v-for="(col, index) in props.cols.filter(
|
||||
(col) => col.name !== 'desc'
|
||||
)"
|
||||
:key="col.name"
|
||||
:class="index % 2 !== 0 ? 'bg-grey-1' : ''"
|
||||
>
|
||||
<q-item-section class="col-7 text-grey-6">
|
||||
<q-item-label>{{ col.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section class="text-dark">
|
||||
<q-item-label>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
:tittle="
|
||||
isEdit
|
||||
? 'แก้ไขข้อมูลประกาศเกียรติคุณ'
|
||||
: 'เพิ่มข้อมูลประกาศเกียรติคุณ'
|
||||
"
|
||||
:close="clickClose"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="row col-12 q-gutter-md q-py-sm text-grey-7">
|
||||
<q-radio
|
||||
v-model="(declHonorForm.isDate as string)"
|
||||
dense
|
||||
checked-icon="task_alt"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
val="false"
|
||||
label="ปี"
|
||||
/>
|
||||
<q-radio
|
||||
v-model="(declHonorForm.isDate as string)"
|
||||
checked-icon="task_alt"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
val="true"
|
||||
label="วัน/เดือน/ปี"
|
||||
dense
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
autoApply
|
||||
year-picker
|
||||
v-model="issueDateYear"
|
||||
week-start="0"
|
||||
menu-class-name="modalfix"
|
||||
:locale="'th'"
|
||||
:enableTimePicker="false"
|
||||
@update:modelValue="
|
||||
(v:number) =>
|
||||
(declHonorForm.issueDate = new Date(
|
||||
`${v}-01-01T00:00:02.010+07:00`
|
||||
))
|
||||
"
|
||||
v-if="declHonorForm.isDate === 'false'"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
:model-value="issueDateYear + 543"
|
||||
:rules="[
|
||||
(val:string) =>
|
||||
!!val ||
|
||||
`${'กรุณาเลือกปีที่ได้รับ'}`,
|
||||
]"
|
||||
:label="`${'ปีที่ได้รับ'}`"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
<datepicker
|
||||
autoApply
|
||||
borderless
|
||||
v-else
|
||||
week-start="0"
|
||||
menu-class-name="modalfix"
|
||||
v-model="declHonorForm.issueDate"
|
||||
:locale="'th'"
|
||||
:enableTimePicker="false"
|
||||
@update:modelValue="
|
||||
(v: Date) =>
|
||||
(issueDateYear = parseInt(
|
||||
v.toString().slice(11, 15)
|
||||
))
|
||||
"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
hide-bottom-space
|
||||
for="inputDatereceive"
|
||||
ref="dateReceivedRef"
|
||||
class="inputgreen"
|
||||
:model-value="date2Thai(declHonorForm.issueDate)"
|
||||
:label="`${'วันที่ได้รับ'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่ได้รับ'}`]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="declHonorForm.issuer"
|
||||
:label="`${'ผู้มีอำนาจลงนาม'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="declHonorForm.detail"
|
||||
:label="`${'รายละเอียด'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="declHonorForm.refCommandNo"
|
||||
:label="`${'เลขที่คำสั่ง'}`"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="mdi-file" class="cursor-pointer" />
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
autoApply
|
||||
borderless
|
||||
week-start="0"
|
||||
menu-class-name="modalfix"
|
||||
v-model="declHonorForm.refCommandDate"
|
||||
:locale="'th'"
|
||||
:enableTimePicker="false"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
clearable
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
:model-value="
|
||||
declHonorForm.refCommandDate == null
|
||||
? null
|
||||
: date2Thai(declHonorForm.refCommandDate)
|
||||
"
|
||||
:label="`${'เอกสารอ้างอิง (ลงวันที่)'}`"
|
||||
@clear="declHonorForm.refCommandDate = null"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator color="grey-4" />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<q-card-section class="flex justify-between" style="padding: 0">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขประกาศเกียรติคุณ"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section class="q-p-sm">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterHistory"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterHistory == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterHistory"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumnsHistory"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columnsHistory"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columnsHistory"
|
||||
:rows="rowsHistory"
|
||||
:paging="true"
|
||||
v-model:pagination="historyPagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumnsHistory"
|
||||
:filter="filterHistory"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,847 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, watch, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import type { QTableProps, QForm } from "quasar";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useResultsPerformDataStore } from "@/modules/04_registryPerson/stores/ResultsPerformance";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import type { RequestItemsObject } from "@/modules/04_registryPerson/interface/request/ResultsPerformance";
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/ResultsPerformance";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const store = useResultsPerformDataStore();
|
||||
const { textRangePoint, textPoint } = store;
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
success,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
dialogConfirm,
|
||||
} = mixin;
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const id = ref<string>("");
|
||||
const resPerformForm = reactive<RequestItemsObject>({
|
||||
name: "",
|
||||
point1Total: 0,
|
||||
point1: 0,
|
||||
point2Total: 0,
|
||||
point2: 0,
|
||||
pointSumTotal: 0,
|
||||
pointSum: 0,
|
||||
date: null,
|
||||
});
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const currentPageHistory = ref<number>(1);
|
||||
const maxPageHistory = ref<number>(1);
|
||||
const isEdit = ref<boolean>(false);
|
||||
const modal = ref<boolean>(false);
|
||||
const modeView = ref<string>("table");
|
||||
const filterSearch = ref("");
|
||||
const filterHistory = ref<string>("");
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const rowsHistory = ref<ResponseObject[]>([]);
|
||||
|
||||
const rows = ref<ResponseObject[]>([]);
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่ได้รับ",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
{
|
||||
name: "point1Total",
|
||||
align: "left",
|
||||
label: "ส่วนที่1 (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "point1Total",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "point1",
|
||||
align: "left",
|
||||
label: "ผลประเมินส่วนที่1 (คะแนน)",
|
||||
sortable: true,
|
||||
field: "point1",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "point2Total",
|
||||
align: "left",
|
||||
label: "ส่วนที่2 (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "point2Total",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "point2",
|
||||
align: "left",
|
||||
label: "ผลประเมินส่วนที่2 (คะแนน)",
|
||||
sortable: true,
|
||||
field: "point2",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "pointSumTotal",
|
||||
align: "left",
|
||||
label: "ผลรวม (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "pointSumTotal",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "pointSum",
|
||||
align: "left",
|
||||
label: "ผลประเมินรวม (คะแนน)",
|
||||
sortable: true,
|
||||
field: "pointSum",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
align: "left",
|
||||
label: "ผลประเมิน",
|
||||
sortable: true,
|
||||
field: (v) => `${textPoint(v.pointSum)} ${textRangePoint(v.pointSum)}`,
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
const columnsHistory = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่ได้รับ",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
{
|
||||
name: "point1Total",
|
||||
align: "left",
|
||||
label: "ส่วนที่1 (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "point1Total",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "point1",
|
||||
align: "left",
|
||||
label: "ผลประเมินส่วนที่1 (คะแนน)",
|
||||
sortable: true,
|
||||
field: "point1",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "point2Total",
|
||||
align: "left",
|
||||
label: "ส่วนที่2 (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "point2Total",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "point2",
|
||||
align: "left",
|
||||
label: "ผลประเมินส่วนที่2 (คะแนน)",
|
||||
sortable: true,
|
||||
field: "point2",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "pointSumTotal",
|
||||
align: "left",
|
||||
label: "ผลรวม (น้ำหนัก)",
|
||||
sortable: true,
|
||||
field: "pointSumTotal",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "pointSum",
|
||||
align: "left",
|
||||
label: "ผลประเมินรวม (คะแนน)",
|
||||
sortable: true,
|
||||
field: "pointSum",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "name",
|
||||
align: "left",
|
||||
label: "ผลประเมิน",
|
||||
sortable: true,
|
||||
field: (v) => `${textPoint(v.pointSum)} ${textRangePoint(v.pointSum)}`,
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
const visibleColumnsHistory = ref<String[]>([
|
||||
"point1Total",
|
||||
"point1",
|
||||
"point2Total",
|
||||
"point2",
|
||||
"pointSumTotal",
|
||||
"pointSum",
|
||||
"name",
|
||||
"date",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"point1Total",
|
||||
"point1",
|
||||
"point2Total",
|
||||
"point2",
|
||||
"pointSumTotal",
|
||||
"pointSum",
|
||||
"name",
|
||||
"date",
|
||||
]);
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
async function fetchData() {
|
||||
if (!profileId.value) return;
|
||||
|
||||
showLoader();
|
||||
try {
|
||||
const res = await http.get(
|
||||
config.API.profileNewAssessmentsByProfileId(
|
||||
profileId.value,
|
||||
empType.value
|
||||
)
|
||||
);
|
||||
rows.value = res.data.result;
|
||||
} catch (error) {
|
||||
messageError($q, error);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
async function addEditData(editStatus: boolean = false) {
|
||||
if (!profileId.value) return;
|
||||
|
||||
const url = editStatus
|
||||
? config.API.profileNewAssessmentsById(id.value, empType.value)
|
||||
: config.API.profileNewAssessments(empType.value);
|
||||
const method = editStatus ? "patch" : "post";
|
||||
const reqBody: RequestItemsObject = {
|
||||
...resPerformForm,
|
||||
profileEmployeeId:
|
||||
!editStatus && empType.value !== "" ? profileId.value : undefined,
|
||||
profileId:
|
||||
!editStatus && empType.value === "" ? profileId.value : undefined,
|
||||
};
|
||||
|
||||
try {
|
||||
await http[method](url, reqBody);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
await fetchData();
|
||||
} catch (e) {
|
||||
messageError($q, e);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
function onClickOpenDialog(editStatus: boolean = false, row?: ResponseObject) {
|
||||
modal.value = true;
|
||||
isEdit.value = editStatus;
|
||||
|
||||
if (editStatus && row) {
|
||||
id.value = row.id;
|
||||
resPerformForm.name = row.name;
|
||||
resPerformForm.point1Total = row.point1Total;
|
||||
resPerformForm.point1 = row.point1;
|
||||
resPerformForm.point2Total = row.point2Total;
|
||||
resPerformForm.point2 = row.point2;
|
||||
resPerformForm.pointSumTotal = row.pointSumTotal;
|
||||
resPerformForm.pointSum = row.pointSum;
|
||||
resPerformForm.date = row.date;
|
||||
} else {
|
||||
clearData();
|
||||
}
|
||||
}
|
||||
|
||||
async function clickClose() {
|
||||
clearData();
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
async function clickHistory(row: ResponseObject) {
|
||||
modalHistory.value = true;
|
||||
filterSearch.value = "";
|
||||
|
||||
showLoader();
|
||||
try {
|
||||
const res = await http.get(
|
||||
config.API.profileNewAssessmentsHisById(row.id, empType.value)
|
||||
);
|
||||
|
||||
rowsHistory.value = res.data.result;
|
||||
} catch (e) {
|
||||
messageError($q, e);
|
||||
} finally {
|
||||
hideLoader();
|
||||
}
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
addEditData(isEdit.value);
|
||||
modal.value = false;
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
function clearData() {
|
||||
(id.value = ""),
|
||||
(resPerformForm.name = ""),
|
||||
(resPerformForm.point1Total = 0),
|
||||
(resPerformForm.point1 = 0),
|
||||
(resPerformForm.point2Total = 0),
|
||||
(resPerformForm.point2 = 0),
|
||||
(resPerformForm.pointSumTotal = 0),
|
||||
(resPerformForm.pointSum = 0),
|
||||
(resPerformForm.date = null);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn
|
||||
dense
|
||||
color="primary"
|
||||
icon="add"
|
||||
flat
|
||||
round
|
||||
@click="onClickOpenDialog()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterSearch"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterSearch == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterSearch = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterSearch"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterSearch = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="modeView == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="modeView"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modeView === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modeView === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
flat
|
||||
dense
|
||||
bordered
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:columns="columns"
|
||||
:filter="filterSearch"
|
||||
v-model:pagination="pagination"
|
||||
:grid="modeView === 'card'"
|
||||
:visible-columns="visibleColumns"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:card-container-class="modeView === 'card' ? 'q-col-gutter-md' : ''"
|
||||
>
|
||||
<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" v-if="modeView === 'table'">
|
||||
<q-tr :props="props">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="clickHistory(props.row)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขผลการประเมินการปฏิบัติราชการ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td
|
||||
v-for="col in props.cols"
|
||||
:key="col.name"
|
||||
:props="props"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
<div class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-card bordered>
|
||||
<q-card-actions class="bg-grey-3" align="right">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click.stop.prevent="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก่ไขข้อมุล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
@click="clickHistory(props.row)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขเครื่องราชอิสริยาภรณ์</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<q-separator />
|
||||
<div>
|
||||
<q-item
|
||||
v-for="(col, index) in props.cols.filter(
|
||||
(col) => col.name !== 'desc'
|
||||
)"
|
||||
:key="col.name"
|
||||
:class="index % 2 !== 0 ? 'bg-grey-1' : ''"
|
||||
>
|
||||
<q-item-section class="text-grey-6">
|
||||
<q-item-label>{{ col.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section class="text-dark">
|
||||
<q-item-label>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
:tittle="
|
||||
isEdit
|
||||
? 'แก้ไขผลการประเมินการปฏิบัติราชการ'
|
||||
: 'เพิ่มผลการประเมินการปฏิบัติราชการ'
|
||||
"
|
||||
:close="clickClose"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-12">
|
||||
<datepicker
|
||||
autoApply
|
||||
borderless
|
||||
week-start="0"
|
||||
menu-class-name="modalfix"
|
||||
v-model="resPerformForm.date"
|
||||
:locale="'th'"
|
||||
:enableTimePicker="false"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
for="inputDatereceive"
|
||||
ref="dateReceivedRef"
|
||||
class="inputgreen"
|
||||
hide-bottom-space
|
||||
:model-value="date2Thai(resPerformForm.date as Date)"
|
||||
:label="`${'วันที่ได้รับ'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่ได้รับ'}`]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="resPerformForm.point1Total"
|
||||
input-class="text-right "
|
||||
:label="`${'ส่วนที่1 (น้ำหนัก)'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกส่วนที่1 (น้ำหนัก)'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="resPerformForm.point1"
|
||||
input-class="text-right"
|
||||
:label="`${'ผลประเมินส่วนที่1 (คะแนน)'}`"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณากรอกผลประเมินส่วนที่1 (คะแนน)'}`,
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="resPerformForm.point2Total"
|
||||
input-class="text-right"
|
||||
:label="`${'ส่วนที่2 (น้ำหนัก)'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกส่วนที่2 (น้ำหนัก)'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="resPerformForm.point2"
|
||||
input-class="text-right"
|
||||
:label="`${'ผลประเมินส่วนที่2 (คะแนน)'}`"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณากรอกผลประเมินส่วนที่2 (คะแนน)'}`,
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="resPerformForm.pointSumTotal"
|
||||
input-class="text-right"
|
||||
:label="`${'ผลรวม (น้ำหนัก)'}`"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกผลรวม (น้ำหนัก)'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="resPerformForm.pointSum"
|
||||
class="inputgreen"
|
||||
input-class="text-right"
|
||||
:label="`${'ผลประเมินรวม (คะแนน)'}`"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณากรอกผลประเมินรวม (คะแนน)'}`,
|
||||
]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12 row items-center q-pt-md justify-center">
|
||||
ผลการประเมิน:
|
||||
<div class="text-bold items-center q-px-sm">
|
||||
{{ textPoint(resPerformForm.pointSum) }}
|
||||
</div>
|
||||
{{ textRangePoint(resPerformForm.pointSum) }}
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขผลการประเมินการปฏิบัติราชการ"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterHistory"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterHistory == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterHistory"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumnsHistory"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columnsHistory"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columnsHistory"
|
||||
v-model:pagination="historyPagination"
|
||||
:rows="rowsHistory"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumnsHistory"
|
||||
:filter="filterHistory"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
/** importComponents*/
|
||||
import ProfessionalLicense from "@/modules/04_registryPerson/components/detail/Achievement/01_ProfessionalLicense.vue";
|
||||
import Train from "@/modules/04_registryPerson/components/detail/Achievement/02_Train.vue";
|
||||
import Insignia from "@/modules/04_registryPerson/components/detail/Achievement/03_Insignia.vue";
|
||||
import DeclarationHonor from "@/modules/04_registryPerson/components/detail/Achievement/04_DeclarationHonor.vue";
|
||||
import ResultsPerformance from "@/modules/04_registryPerson/components/detail/Achievement/05_ResultsPerformance.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">
|
||||
ข้อมูลผลงานและเครื่องราชฯ
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ใบอนุญาตประกอบวิชาชีพ" />
|
||||
<q-tab name="2" label="การฝึกอบรม/ดูงาน" />
|
||||
<q-tab name="3" label="เครื่องราชอิสริยาภรณ์" />
|
||||
<q-tab name="4" label="ประกาศเกียรติคุณ" />
|
||||
<q-tab name="5" label="ผลการประเมินการปฏิบัติราชการ" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<ProfessionalLicense />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<Train />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="3">
|
||||
<Insignia />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="4">
|
||||
<DeclarationHonor />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="4">
|
||||
<PerformSpecialWork />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="5">
|
||||
<ResultsPerformance />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,633 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, watch, ref, reactive } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type { FormEmployee } from "@/modules/04_registryPerson/interface/request/Employee";
|
||||
import type {
|
||||
EmployeeHistory,
|
||||
ResEmployee,
|
||||
} from "@/modules/04_registryPerson/interface/response/Employee";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import type { QTableColumn } from "quasar";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const {
|
||||
success,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
date2Thai,
|
||||
messageError,
|
||||
dialogConfirm,
|
||||
dialogMessageNotify,
|
||||
} = useCounterMixin();
|
||||
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
|
||||
/** ข้อมูลลูกจ้างชั่วคราว*/
|
||||
const modalEdit = ref<boolean>(false);
|
||||
const dataEmployee = reactive<ResEmployee>({
|
||||
id: "",
|
||||
positionEmployeeGroupId: "",
|
||||
positionEmployeeLineId: "",
|
||||
positionEmployeePositionId: "",
|
||||
employeeOc: "",
|
||||
employeeTypeIndividual: "",
|
||||
employeeWage: "",
|
||||
employeeMoneyIncrease: "",
|
||||
employeeMoneyAllowance: "",
|
||||
employeeMoneyEmployee: "",
|
||||
employeeMoneyEmployer: "",
|
||||
});
|
||||
const formData = reactive<FormEmployee>({
|
||||
positionEmployeeGroupId: "",
|
||||
positionEmployeeLineId: "",
|
||||
positionEmployeePositionId: "",
|
||||
employeeOc: "",
|
||||
employeeTypeIndividual: "",
|
||||
employeeWage: "",
|
||||
employeeMoneyIncrease: "",
|
||||
employeeMoneyAllowance: "",
|
||||
employeeMoneyEmployee: "",
|
||||
employeeMoneyEmployer: "",
|
||||
});
|
||||
|
||||
/** function fetch ข้อมูลลูกจ้างชั่วคราว*/
|
||||
function fetchData() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.informationEmployee(profileId.value))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
dataEmployee.positionEmployeeGroupId = data.positionEmployeeGroupId;
|
||||
dataEmployee.positionEmployeeLineId = data.positionEmployeeLineId;
|
||||
dataEmployee.positionEmployeePositionId = data.positionEmployeePositionId;
|
||||
dataEmployee.employeeOc = data.employeeOc;
|
||||
dataEmployee.employeeTypeIndividual = data.employeeTypeIndividual;
|
||||
dataEmployee.employeeWage = data.employeeWage;
|
||||
dataEmployee.employeeMoneyIncrease = data.employeeMoneyIncrease;
|
||||
dataEmployee.employeeMoneyAllowance = data.employeeMoneyAllowance;
|
||||
dataEmployee.employeeMoneyEmployee = data.employeeMoneyEmployee;
|
||||
dataEmployee.employeeMoneyEmployer = data.employeeMoneyEmployer;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/** function เปิด Dialog แก้ไขมูลลูกจ้างชั่วคราว*/
|
||||
function onClickEdit() {
|
||||
modalEdit.value = true;
|
||||
formData.positionEmployeeGroupId = dataEmployee.positionEmployeeGroupId;
|
||||
formData.positionEmployeeLineId = dataEmployee.positionEmployeeLineId;
|
||||
formData.positionEmployeePositionId = dataEmployee.positionEmployeePositionId;
|
||||
formData.employeeOc = dataEmployee.employeeOc;
|
||||
formData.employeeTypeIndividual = dataEmployee.employeeTypeIndividual;
|
||||
formData.employeeWage = dataEmployee.employeeWage;
|
||||
formData.employeeMoneyIncrease = dataEmployee.employeeMoneyIncrease;
|
||||
formData.employeeMoneyAllowance = dataEmployee.employeeMoneyAllowance;
|
||||
formData.employeeMoneyEmployee = dataEmployee.employeeMoneyEmployee;
|
||||
formData.employeeMoneyEmployer = dataEmployee.employeeMoneyEmployer;
|
||||
}
|
||||
|
||||
/** function ปิด Dialog แก้ไขมูลลูกจ้างชั่วคราว*/
|
||||
function onCloseDialog() {
|
||||
modalEdit.value = false;
|
||||
formData.positionEmployeeGroupId = "";
|
||||
formData.positionEmployeeLineId = "";
|
||||
formData.positionEmployeePositionId = "";
|
||||
formData.employeeOc = "";
|
||||
formData.employeeTypeIndividual = "";
|
||||
formData.employeeWage = "";
|
||||
formData.employeeMoneyIncrease = "";
|
||||
formData.employeeMoneyAllowance = "";
|
||||
formData.employeeMoneyEmployee = "";
|
||||
formData.employeeMoneyEmployer = "";
|
||||
}
|
||||
|
||||
/** function บันทึกแก้ไขมูลลูกจ้างชั่วคราว*/
|
||||
function onSubmit() {
|
||||
dialogConfirm($q, () => {
|
||||
showLoader();
|
||||
http
|
||||
.put(config.API.informationEmployee(profileId.value), formData)
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
fetchData();
|
||||
onCloseDialog();
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** ประวัติข้อมูลลูกจ้างชั่วคราว */
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const filter = ref<string>("");
|
||||
const rows = ref<EmployeeHistory[]>([]);
|
||||
const columns = ref<QTableColumn[]>([
|
||||
{
|
||||
name: "positionEmployeeGroupId",
|
||||
align: "left",
|
||||
label: "กลุ่มงาน",
|
||||
sortable: true,
|
||||
field: "positionEmployeeGroupId",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionEmployeeLineId",
|
||||
align: "left",
|
||||
label: "สายงาน",
|
||||
sortable: true,
|
||||
field: "positionEmployeeLineId",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionEmployeePositionId",
|
||||
align: "left",
|
||||
label: "ตำแหน่งทางสายงาน",
|
||||
sortable: true,
|
||||
field: "positionEmployeePositionId",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeOc",
|
||||
align: "left",
|
||||
label: "สังกัด",
|
||||
sortable: true,
|
||||
field: "employeeOc",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeTypeIndividual",
|
||||
align: "left",
|
||||
label: "ประเภทบุคคล",
|
||||
sortable: true,
|
||||
field: "employeeTypeIndividual",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeWage",
|
||||
align: "left",
|
||||
label: "ค่าจ้าง",
|
||||
sortable: true,
|
||||
field: "employeeWage",
|
||||
format: (v) => (v ? Number(v).toLocaleString() : ""),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeMoneyIncrease",
|
||||
align: "left",
|
||||
label: "เงินเพิ่มการครองชึพชั่วคราว",
|
||||
sortable: true,
|
||||
field: "employeeMoneyIncrease",
|
||||
format: (v) => (v ? Number(v).toLocaleString() : ""),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeMoneyAllowance",
|
||||
align: "left",
|
||||
label: "เงินช่วยเหลือการครองชึพชั่วคราว",
|
||||
sortable: true,
|
||||
field: "employeeMoneyAllowance",
|
||||
format: (v) => (v ? Number(v).toLocaleString() : ""),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeMoneyEmployee",
|
||||
align: "left",
|
||||
label: "เงินสมทบประกันสังคม(ลูกจ้าง)",
|
||||
sortable: true,
|
||||
field: "employeeMoneyEmployee",
|
||||
format: (v) => (v ? Number(v).toLocaleString() : ""),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "employeeMoneyEmployer",
|
||||
align: "left",
|
||||
label: "เงินสมทบประกันสังคม(นายจ้าง)",
|
||||
sortable: true,
|
||||
field: "employeeMoneyEmployer",
|
||||
format: (v) => (v ? Number(v).toLocaleString() : ""),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "createdFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "createdFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "createdAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
]);
|
||||
const visibleColumns = ref<String[]>([
|
||||
"positionEmployeeGroupId",
|
||||
"positionEmployeeLineId",
|
||||
"positionEmployeePositionId",
|
||||
"employeeOc",
|
||||
"employeeTypeIndividual",
|
||||
"employeeWage",
|
||||
"employeeMoneyIncrease",
|
||||
"employeeMoneyAllowance",
|
||||
"employeeMoneyEmployee",
|
||||
"employeeMoneyEmployer",
|
||||
"createdFullName",
|
||||
"createdAt",
|
||||
]);
|
||||
|
||||
function onClickHistory() {
|
||||
showLoader();
|
||||
modalHistory.value = true;
|
||||
http
|
||||
.get(config.API.informationHistoryEmployee(profileId.value))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
rows.value = data;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
profileId.value && fetchData();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row q-gutter-sm items-center">
|
||||
<div class="toptitle col text-right q-gutter-x-sm">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="mdi-pencil-outline"
|
||||
color="primary"
|
||||
@click="onClickEdit"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="mdi-history"
|
||||
color="info"
|
||||
@click="onClickHistory"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขข้อมูลลูกจ้างชั่วคราว</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-card bordered class="my-card bg-grey-1 q-pa-md">
|
||||
<div :class="$q.screen.gt.xs ? 'row' : 'column'">
|
||||
<!-- column 1 -->
|
||||
<div class="col-md-7 col-12 row">
|
||||
<div class="col-5 text-grey-6 text-weight-medium">
|
||||
<div class="q-py-xs">กลุ่มงาน</div>
|
||||
<div class="q-py-xs">สายงาน</div>
|
||||
<div class="q-py-xs">ตำแหน่งทางสายงาน</div>
|
||||
<div class="q-py-xs">สังกัด</div>
|
||||
<div class="q-py-xs">ประเภทบุคคล</div>
|
||||
</div>
|
||||
|
||||
<!-- data -->
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.positionEmployeeGroupId }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.positionEmployeeLineId }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.positionEmployeePositionId }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeOc }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeTypeIndividual }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- column 2 -->
|
||||
<div class="col-md-5 col-12 row">
|
||||
<div class="col-5 col text-grey-6 text-weight-medium">
|
||||
<div class="q-py-xs">ค่าจ้าง</div>
|
||||
<div class="q-py-xs">เงินเพิ่มการครองชึพชั่วคราว</div>
|
||||
<div class="q-py-xs">เงินช่วยเหลือการครองชึพชั่วคราว</div>
|
||||
<div class="q-py-xs">เงินสมทบประกันสังคม(ลูกจ้าง)</div>
|
||||
<div class="q-py-xs">เงินสมทบประกันสังคม(นายจ้าง)</div>
|
||||
</div>
|
||||
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeWage }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeMoneyIncrease }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeMoneyAllowance }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeMoneyEmployee }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ dataEmployee.employeeMoneyEmployer }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
|
||||
<!-- Dialog แก้ไขข้อมูลลูกจ้างชั่วคราว -->
|
||||
<q-dialog v-model="modalEdit" persistent full-width>
|
||||
<q-card>
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
tittle="แก้ไขข้อมูลลูกจ้างชั่วคราว"
|
||||
:close="onCloseDialog"
|
||||
/>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.positionEmployeeGroupId"
|
||||
class="inputgreen"
|
||||
label="กลุ่มงาน"
|
||||
:rules="[(val: string) => !!val || `${'กรุณากรอกกลุ่มงาน'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.positionEmployeeLineId"
|
||||
class="inputgreen"
|
||||
label="สายงาน"
|
||||
:rules="[(val: string) => !!val || `${'กรุณากรอกสายงาน'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.positionEmployeePositionId"
|
||||
class="inputgreen"
|
||||
label="ตำแหน่งทางสายงาน"
|
||||
:rules="[(val: string) => !!val || `${'กรุณากรอกตำแหน่งทางสายงาน'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeOc"
|
||||
class="inputgreen"
|
||||
label="สังกัด"
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกสังกัด'}`]" -->
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeTypeIndividual"
|
||||
class="inputgreen"
|
||||
label="ประเภทบุคคล"
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกประเภทบุคคล'}`]" -->
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeWage"
|
||||
class="inputgreen"
|
||||
label="ค่าจ้าง"
|
||||
mask="###,###,###,###"
|
||||
reverse-fill-mask
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกค่าจ้าง'}`]" -->
|
||||
</div>
|
||||
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeMoneyIncrease"
|
||||
class="inputgreen"
|
||||
label="เงินเพิ่มการครองชึพชั่วคราว"
|
||||
mask="###,###,###,###"
|
||||
reverse-fill-mask
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินเพิ่มการครองชึพชั่วคราว'}`]" -->
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeMoneyAllowance"
|
||||
class="inputgreen"
|
||||
label="เงินช่วยเหลือการครองชึพชั่วคราว"
|
||||
mask="###,###,###,###"
|
||||
reverse-fill-mask
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินช่วยเหลือการครองชึพชั่วคราว'}`]" -->
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeMoneyEmployee"
|
||||
class="inputgreen"
|
||||
label="เงินสมทบประกันสังคม(ลูกจ้าง)"
|
||||
mask="###,###,###,###"
|
||||
reverse-fill-mask
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินสมทบประกันสังคม(ลูกจ้าง)'}`]" -->
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.employeeMoneyEmployer"
|
||||
class="inputgreen"
|
||||
label="เงินสมทบประกันสังคม(นายจ้าง)"
|
||||
mask="###,###,###,###"
|
||||
reverse-fill-mask
|
||||
/>
|
||||
<!-- :rules="[(val: string) => !!val || `${'กรุณากรอกเงินสมทบประกันสังคม(นายจ้าง))'}`]" -->
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- Dialog ประวัติการแก้ไขข้อมูลลูกจ้างชั่วคราว -->
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขข้อมูลส่วนตัว"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filter"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filter == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filter = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filter"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filter = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filter"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right"> </q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,514 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type { QTableProps } from "quasar";
|
||||
import type {
|
||||
Employment,
|
||||
EmploymentHistory,
|
||||
} from "@/modules/04_registryPerson/interface/response/Employee";
|
||||
import type { FormEmployment } from "@/modules/04_registryPerson/interface/request/Employee";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const {
|
||||
date2Thai,
|
||||
dialogConfirm,
|
||||
dialogRemove,
|
||||
success,
|
||||
messageError,
|
||||
hideLoader,
|
||||
showLoader,
|
||||
} = useCounterMixin();
|
||||
|
||||
const profileId = ref<string>(route.params.id.toString());
|
||||
|
||||
/** ข้อมูลการจ้าง*/
|
||||
const rows = ref<Employment[]>([]);
|
||||
const filter = ref<string>("");
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่จ้าง",
|
||||
sortable: false,
|
||||
field: "date",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "command",
|
||||
align: "left",
|
||||
label: "คำสั่งจ้าง",
|
||||
sortable: false,
|
||||
field: "command",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "createdFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "createdFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "createdAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
]);
|
||||
const visibleColumns = ref<string[]>([
|
||||
"date",
|
||||
"command",
|
||||
"createdFullName",
|
||||
"createdAt",
|
||||
]);
|
||||
const modalEmployment = ref<boolean>(false);
|
||||
const isEdit = ref<boolean>(false);
|
||||
const employmentId = ref<string>("");
|
||||
const formData = reactive<FormEmployment>({
|
||||
date: null,
|
||||
command: "",
|
||||
});
|
||||
|
||||
/** function fetch ข้อมูลรายการการจ้าง*/
|
||||
function fetchListEmployment() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.employmentEmployee(profileId.value))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
rows.value = data;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function fetch ข้อมูลการจ้าง
|
||||
* @param id รายการการจ้าง
|
||||
*/
|
||||
function fetchDataEmployment(id: string) {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.employmentEmployeeId(id))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
formData.date = data.date;
|
||||
formData.command = data.command;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function เปิด dialog Form ข้อมูลการจ้าง
|
||||
* @param statusEdit สถานะการ สร้าง หรือ แก่ไข
|
||||
* @param id รายการการจ้าง
|
||||
*/
|
||||
function onOpenDialog(statusEdit: boolean = false, id: string = "") {
|
||||
modalEmployment.value = true;
|
||||
if (statusEdit) {
|
||||
isEdit.value = statusEdit;
|
||||
employmentId.value = id;
|
||||
fetchDataEmployment(id);
|
||||
}
|
||||
}
|
||||
|
||||
/** function ปิด dialog Form ข้อมูลการจ้าง*/
|
||||
function onCloseDialog() {
|
||||
modalEmployment.value = false;
|
||||
isEdit.value = false;
|
||||
employmentId.value = "";
|
||||
formData.date = null;
|
||||
formData.command = "";
|
||||
}
|
||||
|
||||
/** function บันทึกข้อมูลการจ้าง*/
|
||||
function onSubmit() {
|
||||
dialogConfirm($q, () => {
|
||||
showLoader();
|
||||
const methods = isEdit.value ? "put" : "post";
|
||||
const id = isEdit.value ? employmentId.value : profileId.value;
|
||||
http[methods](config.API.employmentEmployee(id), formData)
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
fetchListEmployment();
|
||||
onCloseDialog();
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* function ลบข้อมูลรายการจ้าง
|
||||
* @param id รายการจ้าง
|
||||
*/
|
||||
function onDeleteEmployment(id: string) {
|
||||
dialogRemove($q, () => {
|
||||
showLoader();
|
||||
http
|
||||
.delete(config.API.employmentEmployee(id))
|
||||
.then(() => {
|
||||
success($q, "ลบข้อมูลสำเร็จ");
|
||||
fetchListEmployment();
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** ประวัติข้อมูลการจ้าง*/
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const rowsHistory = ref<EmploymentHistory[]>([]);
|
||||
const filterHistory = ref<string>("");
|
||||
|
||||
/**
|
||||
* function เปิด dialog ประวัติการแก้ไขข้อมูลการจ้าง
|
||||
* @param id รายการการจ้าง
|
||||
*/
|
||||
function onClickHistory(id: string) {
|
||||
modalHistory.value = true;
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.employmentHistoryEmployee(id))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
rowsHistory.value = data;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
profileId.value && fetchListEmployment();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center">
|
||||
<div class="q-gutter-sm">
|
||||
<q-btn
|
||||
size="12px"
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-plus"
|
||||
@click="onOpenDialog()"
|
||||
>
|
||||
<q-tooltip>เพิ่มข้อมูลการจ้าง</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
|
||||
<q-space />
|
||||
<div class="q-gutter-sm" style="display: flex">
|
||||
<q-input outlined dense v-model="filter" label="ค้นหา">
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filter == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filter = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filter"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filter = ''"
|
||||
class="cursor-pointer"
|
||||
/> </template
|
||||
></q-input>
|
||||
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns?.slice(0, 2)"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-mt-sm">
|
||||
<d-table
|
||||
flat
|
||||
bordered
|
||||
id="table"
|
||||
ref="table"
|
||||
:columns="columns?.slice(0, 2)"
|
||||
:rows="rows"
|
||||
:filter="filter"
|
||||
row-key="dateEmployment"
|
||||
:paging="true"
|
||||
dense
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th auto-width></q-th>
|
||||
<q-th auto-width></q-th>
|
||||
<q-th auto-width></q-th>
|
||||
<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" class="cursor-pointer" style="height: 40px">
|
||||
<q-td>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-pencil"
|
||||
@click="onOpenDialog(true, props.row.id)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
color="red"
|
||||
icon="mdi-delete"
|
||||
@click="onDeleteEmployment(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ลบข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
</q-td>
|
||||
<q-td>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
@click="onClickHistory(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>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</div>
|
||||
|
||||
<!-- Dialog เพิ่มข้อมูลการจ้าง -->
|
||||
<q-dialog v-model="modalEmployment" persistent>
|
||||
<q-card style="width: 700px; max-width: 80vw">
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
:tittle="isEdit ? 'แก้ข้อมูลการจ้าง' : 'เพิ่มข้อมูลการจ้าง'"
|
||||
:close="onCloseDialog"
|
||||
/>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="formData.date"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
borderless
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
class="inputgreen"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
class="full-width datepicker"
|
||||
:model-value="
|
||||
formData.date != null ? date2Thai(formData.date) : null
|
||||
"
|
||||
label="วันที่จ้าง"
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่จ้าง'}`]"
|
||||
>
|
||||
<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-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
class="inputgreen"
|
||||
outlined
|
||||
v-model="formData.command"
|
||||
label="คำสั่งจ้าง"
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกคำสั่งจ้าง'}`]"
|
||||
lazy-rules
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- Dialog ประวัติการแก้ไขข้อมูลลูกจ้างชั่วคราว -->
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขข้อมูลส่วนตัว"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterHistory"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterHistory == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterHistory"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rowsHistory"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterHistory"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right"> </q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
import DataEmployee from "@/modules/04_registryPerson/components/detail/Employee/01_DataEmployee.vue";
|
||||
import Employment from "@/modules/04_registryPerson/components/detail/Employee/02_Employment.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">ข้อมูลลูกจ้างชั่วคราว</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ข้อมูลลูกจ้างชั่วคราว" />
|
||||
<q-tab name="2" label="ข้อมูลการจ้าง" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<DataEmployee />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<Employment />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,867 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, watch, onMounted } from "vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import type {
|
||||
RequestItemsHistoryObject,
|
||||
FormMain,
|
||||
} from "@/modules/04_registryPerson/interface/index/government";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { QTableProps } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
/** ฟังชั่นกลาง */
|
||||
const route = useRoute();
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
dateToISO,
|
||||
dialogConfirm,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
success,
|
||||
} = mixin;
|
||||
|
||||
const profileId = ref<string>(route.params.id.toString());
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
/** ตัวแปรข้อมูลหลัก */
|
||||
const formMain = reactive<FormMain>({
|
||||
ocId: "", //สังกัด
|
||||
positionId: "", //ตำแหน่ง
|
||||
positionLine: "", //สายงาน
|
||||
positionLevel: "", //ระดับ
|
||||
numberId: "", //ตำแหน่งเลขที่
|
||||
positionExecutive: "", //ตำแหน่งทางการบริหาร
|
||||
positionExecutiveSide: "", //ด้านตำแหน่งทางการบริหาร
|
||||
positionType: "", //ประเภท
|
||||
positionPathSide: "", //ด้าน/สาขา
|
||||
|
||||
containDate: null, //วันที่สั่งบรรจุ
|
||||
workDate: null, //วันที่เริ่มปฏิบัติราชการ
|
||||
reasonSameDate: "",
|
||||
retireDate: null, //วันเกษียณอายุ
|
||||
ageAll: {
|
||||
year: 0,
|
||||
month: 0,
|
||||
day: 0,
|
||||
}, //อายุราชการ
|
||||
absent: 0, //ขาดราชการ
|
||||
age: 0, //อายุราชการเกื้อกูล
|
||||
});
|
||||
|
||||
/** dialog */
|
||||
const modalEdit = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const rowsHistory = ref<RequestItemsHistoryObject[]>([]);
|
||||
|
||||
const filterKeyword = ref<string>("");
|
||||
|
||||
const containDate = ref<Date | null>(null);
|
||||
const workDate = ref<Date | null>(null);
|
||||
const reasonSameDate = ref<string | null>(null);
|
||||
const containDateRef = ref<object | null>(null);
|
||||
const workDateRef = ref<object | null>(null);
|
||||
const reasonSameDateRef = ref<object | null>(null);
|
||||
|
||||
const visibleColumnsHistory = ref<String[]>([
|
||||
"oc",
|
||||
"position",
|
||||
"positionPathSide",
|
||||
"posNo",
|
||||
"positionLine",
|
||||
"positionType",
|
||||
"positionLevel",
|
||||
"positionExecutive",
|
||||
"positionExecutiveSide",
|
||||
"dateAppoint",
|
||||
"dateStart",
|
||||
"retireDate",
|
||||
"govAge",
|
||||
"govAgeAbsent",
|
||||
"govAgePlus",
|
||||
"reasonSameDate",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
const columnsHistory = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "oc",
|
||||
align: "left",
|
||||
label: "สังกัด",
|
||||
sortable: true,
|
||||
field: "oc",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionPathSide",
|
||||
align: "left",
|
||||
label: "ตำแหน่ง",
|
||||
sortable: true,
|
||||
field: "positionPathSide",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "position",
|
||||
align: "left",
|
||||
label: "ด้าน/สาขา",
|
||||
sortable: true,
|
||||
field: "position",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "posNo",
|
||||
align: "left",
|
||||
label: "ตำแหน่งเลขที่",
|
||||
sortable: true,
|
||||
field: "posNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionLine",
|
||||
align: "left",
|
||||
label: "สายงาน",
|
||||
sortable: true,
|
||||
field: "positionLine",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionType",
|
||||
align: "left",
|
||||
label: "ประเภท",
|
||||
sortable: true,
|
||||
field: "positionType",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionLevel",
|
||||
align: "left",
|
||||
label: "ระดับ",
|
||||
sortable: true,
|
||||
field: "positionLevel",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionExecutive",
|
||||
align: "left",
|
||||
label: "ตำแหน่งทางการบริหาร",
|
||||
sortable: true,
|
||||
field: "positionExecutive",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "positionExecutiveSide",
|
||||
align: "left",
|
||||
label: "ด้านทางการบริหาร",
|
||||
sortable: true,
|
||||
field: "positionExecutiveSide",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateAppoint",
|
||||
align: "left",
|
||||
label: "วันที่บรรจุ",
|
||||
sortable: true,
|
||||
field: "dateAppoint",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateStart",
|
||||
align: "left",
|
||||
label: "เริ่มปฎิบัติราชการ",
|
||||
sortable: true,
|
||||
field: "dateStart",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "retireDate",
|
||||
align: "left",
|
||||
label: "วันเกษียณอายุ",
|
||||
sortable: true,
|
||||
field: "retireDate",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "govAge",
|
||||
align: "left",
|
||||
label: "อายุราชการ",
|
||||
sortable: true,
|
||||
field: "govAge",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "govAgeAbsent",
|
||||
align: "left",
|
||||
label: "ขาดราชการ",
|
||||
sortable: true,
|
||||
field: "govAgeAbsent",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "govAgePlus",
|
||||
align: "left",
|
||||
label: "อายุราชการเกื้อกูล",
|
||||
sortable: true,
|
||||
field: "govAgePlus",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reasonSameDate",
|
||||
align: "left",
|
||||
label: "เหตุผลกรณีไม่ตรงวัน",
|
||||
sortable: true,
|
||||
field: "reasonSameDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
/** เปิด dialog */
|
||||
function openDialogEdit() {
|
||||
modalEdit.value = true;
|
||||
containDate.value = formMain.containDate ? formMain.containDate : null;
|
||||
workDate.value = formMain.workDate ? formMain.workDate : null;
|
||||
reasonSameDate.value = formMain.reasonSameDate
|
||||
? formMain.reasonSameDate
|
||||
: null;
|
||||
}
|
||||
|
||||
function openDialogHistory() {
|
||||
modalHistory.value = true;
|
||||
filterKeyword.value = "";
|
||||
getDataHistory();
|
||||
}
|
||||
/** ปิด dialog */
|
||||
function closeDialog() {
|
||||
modalEdit.value = false;
|
||||
containDate.value = null;
|
||||
workDate.value = null;
|
||||
reasonSameDate.value = null;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm($q, () => {
|
||||
showLoader();
|
||||
http
|
||||
.patch(
|
||||
config.API.profileNewGovernmentById(profileId.value, empType.value),
|
||||
{
|
||||
dateAppoint: containDate.value,
|
||||
dateStart: workDate.value,
|
||||
reasonSameDate:
|
||||
dateToISO(containDate.value as Date) ===
|
||||
dateToISO(workDate.value as Date)
|
||||
? ""
|
||||
: reasonSameDate.value,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
getData();
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
closeDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** ดึงข้อมูลราชการ */
|
||||
function getData() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewGovernmentById(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
formMain.ocId = data.org ?? "-"; //สังกัด
|
||||
formMain.positionId = data.position ?? "-"; //ตำแหน่ง
|
||||
formMain.positionLine = data.positionField ?? "-"; //สายงาน
|
||||
formMain.positionLevel = data.posLevel ?? "-"; //ระดับ
|
||||
formMain.numberId = data.posMasterNo ?? "-"; //ตำแหน่งเลขที่
|
||||
formMain.positionType = data.posType ?? "-"; //ประเภท
|
||||
formMain.positionExecutive = data.posExecutive ?? "-"; //ตำแหน่งทางการ บริหาร
|
||||
formMain.positionPathSide = data.positionArea ?? "-"; //ด้านสาขา
|
||||
formMain.positionExecutiveSide = data.positionExecutiveField ?? "-"; //ด้านทางการบริหาร
|
||||
|
||||
formMain.containDate = data.dateAppoint;
|
||||
formMain.workDate = data.dateStart;
|
||||
formMain.reasonSameDate = data.reasonSameDate;
|
||||
formMain.retireDate = data.dateLeave;
|
||||
formMain.dateRetireLaw = data.dateRetireLaw;
|
||||
formMain.ageAll = data.govAge;
|
||||
formMain.absent = data.govAgeAbsent;
|
||||
formMain.age = data.govAgePlus;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/** ดึงข้อมูลประวัติ */
|
||||
function getDataHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewGovernmentHistory(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
rowsHistory.value = [];
|
||||
data.map((e: RequestItemsHistoryObject) => {
|
||||
rowsHistory.value.push({
|
||||
oc: e.oc,
|
||||
position: e.position,
|
||||
positionPathSide: e.positionPathSide,
|
||||
posNo: e.posNo,
|
||||
positionLine: e.positionLine,
|
||||
positionType: e.positionType,
|
||||
positionLevel: e.positionLevel,
|
||||
positionExecutive: e.positionExecutive,
|
||||
positionExecutiveSide: e.positionExecutiveSide,
|
||||
dateAppoint: new Date(e.dateAppoint),
|
||||
dateStart: new Date(e.dateStart),
|
||||
dateRetire: e.dateRetire,
|
||||
dateRetireLaw: e.dateRetireLaw,
|
||||
govAge: e.govAge,
|
||||
govAgeAbsent: e.govAgeAbsent,
|
||||
govAgePlus: e.govAgePlus,
|
||||
reasonSameDate: e.reasonSameDate,
|
||||
createdFullName: e.createdFullName,
|
||||
createdAt: new Date(e.createdAt),
|
||||
lastUpdatedAt: e.lastUpdatedAt,
|
||||
lastUpdateFullName: e.lastUpdateFullName,
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
modalHistory.value = false;
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row">
|
||||
<q-space />
|
||||
<div class="q-gutter-x-sm">
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
@click="openDialogEdit()"
|
||||
><q-tooltip>แก้ไขข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
@click="openDialogHistory()"
|
||||
><q-tooltip>ประวิติข้อมูลราชการ</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-card bordered class="bg-grey-1 q-pa-md q-mt-sm">
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-sm-6 col-md-6 q-gutter-y-sm">
|
||||
<div class="row items-center">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>สังกัด</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">{{ formMain.ocId }}</div>
|
||||
</div>
|
||||
<div class="row items-center">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>{{ empType === "" ? `ตำแหน่งในสายงาน` : `ตำแหน่ง` }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">{{ formMain.positionId }}</div>
|
||||
</div>
|
||||
<div class="row items-center">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>ตำแหน่งเลขที่</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">{{ formMain.numberId }}</div>
|
||||
</div>
|
||||
<div class="row items-center" v-if="empType === ''">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>ตำแหน่งทางการบริหาร</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionExecutive }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center" v-if="empType === ''">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>ด้านทางการบริหาร</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionExecutiveSide }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6 q-gutter-y-sm">
|
||||
<div class="row items-center" v-if="empType === ''">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>สายงาน</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionLine }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>{{ empType === "" ? "ตำแหน่งประเภท" : "กลุ่มงาน" }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionType }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>{{ empType === "" ? "ระดับ" : "ระดับชั้นงาน" }}</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionLevel }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="row items-center" v-if="empType === ''">
|
||||
<div class="col-12 col-sm-12 col-md-5 text-grey-6 text-weight-medium">
|
||||
<div>ด้าน/สาขา</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
{{ formMain.positionPathSide }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator color="grey-4" class="q-my-md" />
|
||||
<div class="row q-col-gutter-md">
|
||||
<div class="col-12 col-sm-6 col-md-6 q-gutter-y-sm">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>วันที่สั่งบรรจุ</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.containDate ? date2Thai(formMain.containDate) : "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>วันที่เริ่มปฏิบัติราชการ</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.workDate !== null
|
||||
? date2Thai(formMain.workDate as Date)
|
||||
: "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-if="dateToISO(formMain.containDate as Date) !== dateToISO(formMain.workDate as Date)"
|
||||
class="col-12 col-sm-6 col-md-6"
|
||||
>
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>เหตุผลที่วันที่ไม่ตรงกัน</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.reasonSameDate !== "" ? formMain.reasonSameDate : "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>วันครบเกษียณอายุ</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.retireDate
|
||||
? date2Thai(formMain.retireDate as Date)
|
||||
: "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-sm-6 col-md-6 q-gutter-y-sm">
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium">อายุราชการ</span>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.ageAll
|
||||
? `${formMain.ageAll.day} วัน ${formMain.ageAll.month} เดือน ${formMain.ageAll.year} ปี`
|
||||
: "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium">ขาดราชการ</span>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{ formMain.absent ? formMain.absent : 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>อายุราชการเกื้อกูล</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{ formMain.age ? formMain.age : 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-sm-6 col-md-6">
|
||||
<div class="row">
|
||||
<div class="col-12 col-sm-12 col-md-5">
|
||||
<span class="text-grey-6 text-weight-medium"
|
||||
>วันที่เกษียณอายุราชการตามกฏหมาย</span
|
||||
>
|
||||
</div>
|
||||
<div class="col-12 col-sm-12 col-md-7">
|
||||
<span>{{
|
||||
formMain.dateRetireLaw
|
||||
? date2Thai(formMain.dateRetireLaw as Date)
|
||||
: "-"
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
|
||||
<!-- dialog edit -->
|
||||
<q-dialog v-model="modalEdit" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit">
|
||||
<DialogHeader tittle="แก้ไขข้อมูลราชการ" :close="closeDialog" />
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-xs-12 col-md-6">
|
||||
<datepicker
|
||||
v-model="containDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="containDateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
hide-bottom-space
|
||||
dense
|
||||
outlined
|
||||
:model-value="containDate !== null
|
||||
? date2Thai(containDate as Date)
|
||||
: null
|
||||
"
|
||||
:rules="[
|
||||
(val) => !!val || 'กรุณาเลือก วัน/เดือน/ปี ที่บรรจุ',
|
||||
]"
|
||||
label="วัน/เดือน/ปี ที่บรรจุ"
|
||||
>
|
||||
<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-md-6">
|
||||
<datepicker
|
||||
v-model="workDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="workDateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
hide-bottom-space
|
||||
dense
|
||||
outlined
|
||||
:model-value="workDate !== null
|
||||
? date2Thai(workDate as Date)
|
||||
: null
|
||||
"
|
||||
:rules="[(val) => !!val || 'กรุณาเลือกเริ่มปฎิบัติราชการ']"
|
||||
label="วัน/เดือน/ปี เริ่มปฎิบัติราชการ"
|
||||
>
|
||||
<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-12"
|
||||
v-if="containDate && workDate ? dateToISO(containDate as Date) !== dateToISO(workDate as Date) : false"
|
||||
>
|
||||
<q-input
|
||||
ref="reasonSameDateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
label="เหตุผลกรณีไม่ตรงกัน"
|
||||
type="textarea"
|
||||
outlined
|
||||
dense
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || 'กรุณากรอก เหตุผลกรณีไม่ตรงกัน']"
|
||||
v-model="reasonSameDate"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<!-- dialog History -->
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขข้อมูลราชการ"
|
||||
:close="() => (modalHistory = !modalHistory)"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row q-pb-sm q-gutter-x-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
class="col-2"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumnsHistory"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columnsHistory"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
:columns="columnsHistory"
|
||||
:rows="rowsHistory"
|
||||
flat
|
||||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
class="custom-header-table"
|
||||
:filter="filterKeyword"
|
||||
:visible-columns="visibleColumnsHistory"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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-th auto-width></q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,743 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import type { QTableProps } from "quasar";
|
||||
import type {
|
||||
RequestItemsObject,
|
||||
FormFilter,
|
||||
DataOption,
|
||||
DisciplineOps,
|
||||
} from "@/modules/04_registryPerson/interface/index/discipline";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar } from "quasar";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import DialogHistory from "@/modules/04_registryPerson/components/detail/GovernmentInformation/02_DisciplineHistory.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
dialogConfirm,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
success,
|
||||
|
||||
dialogRemove,
|
||||
} = mixin;
|
||||
const disciplineData = reactive<RequestItemsObject>({
|
||||
date: null,
|
||||
level: "",
|
||||
detail: "",
|
||||
unStigma: "",
|
||||
refCommandNo: "",
|
||||
profileId: profileId.value,
|
||||
refCommandDate: null,
|
||||
});
|
||||
const rows = ref<RequestItemsObject[]>([]);
|
||||
const mode = ref<string>("table");
|
||||
const filterKeyword = ref<string>("");
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"level",
|
||||
"detail",
|
||||
"unStigma",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
"date",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "level",
|
||||
align: "left",
|
||||
label: "ระดับการลงโทษทางวินัย",
|
||||
sortable: true,
|
||||
field: "level",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "unStigma",
|
||||
align: "left",
|
||||
label: "ประเภทคำสั่ง",
|
||||
sortable: true,
|
||||
field: "unStigma",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const dateRef = ref<object | null>(null);
|
||||
const detailRef = ref<object | null>(null);
|
||||
const refCommandNoRef = ref<object | null>(null);
|
||||
|
||||
/** dialog */
|
||||
const edit = ref<boolean>(false);
|
||||
const modal = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
const id = ref<string>("");
|
||||
|
||||
const Ops = ref<any>({
|
||||
levelOptions: [
|
||||
{ id: "0", name: "ไม่ร้ายแรง", disable: true },
|
||||
{ id: "ภาคทัณฑ์", name: "ภาคทัณฑ์", disable: false },
|
||||
{
|
||||
id: "ตัดเงินเดือน",
|
||||
name: "ตัดเงินเดือน",
|
||||
disable: false,
|
||||
},
|
||||
{
|
||||
id: "ลดขั้นเงินเดือน",
|
||||
name: "ลดขั้นเงินเดือน",
|
||||
disable: false,
|
||||
},
|
||||
{ id: "4", name: "ร้ายแรง", disable: true },
|
||||
{ id: "ปลดออก", name: "ปลดออก", disable: false },
|
||||
{ id: "ไล่ออก", name: "ไล่ออก", disable: false },
|
||||
{ id: "อื่นๆ", name: "อื่นๆ", disable: false },
|
||||
],
|
||||
});
|
||||
const OpsFilter = ref<any>({
|
||||
levelOptions: [
|
||||
{ id: "0", name: "ไม่ร้ายแรง", disable: true },
|
||||
{ id: "ภาคทัณฑ์", name: "ภาคทัณฑ์", disable: false },
|
||||
{
|
||||
id: "ตัดเงินเดือน",
|
||||
name: "ตัดเงินเดือน",
|
||||
disable: false,
|
||||
},
|
||||
{
|
||||
id: "ลดขั้นเงินเดือน",
|
||||
name: "ลดขั้นเงินเดือน",
|
||||
disable: false,
|
||||
},
|
||||
{ id: "4", name: "ร้ายแรง", disable: true },
|
||||
{ id: "ปลดออก", name: "ปลดออก", disable: false },
|
||||
{ id: "ไล่ออก", name: "ไล่ออก", disable: false },
|
||||
{ id: "อื่นๆ", name: "อื่นๆ", disable: false },
|
||||
],
|
||||
});
|
||||
|
||||
function filterSelector(val: string, update: Function, refData: string) {
|
||||
switch (refData) {
|
||||
case "levelOptions":
|
||||
update(() => {
|
||||
Ops.value.levelOptions = OpsFilter.value.levelOptions.filter(
|
||||
(v: DataOption) => v.name.indexOf(val) > -1
|
||||
);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** ปิด dialog */
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
edit.value = false;
|
||||
disciplineData.date = null;
|
||||
disciplineData.detail = "";
|
||||
disciplineData.level = "";
|
||||
disciplineData.unStigma = "";
|
||||
disciplineData.refCommandNo = "";
|
||||
disciplineData.refCommandDate = null;
|
||||
}
|
||||
|
||||
function openDialogAdd() {
|
||||
modal.value = true;
|
||||
}
|
||||
|
||||
async function fetchData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewDisciplineByProfileId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function addData() {
|
||||
const body = {
|
||||
date: disciplineData.date,
|
||||
level: disciplineData.level,
|
||||
detail: disciplineData.detail,
|
||||
unStigma: disciplineData.unStigma,
|
||||
refCommandNo: disciplineData.refCommandNo,
|
||||
profileId: empType.value === "" ? disciplineData.profileId : undefined,
|
||||
profileEmployeeId:
|
||||
empType.value !== "" ? disciplineData.profileId : undefined,
|
||||
refCommandDate: disciplineData.refCommandDate,
|
||||
};
|
||||
await http
|
||||
.post(config.API.profileNewDiscipline(empType.value), body)
|
||||
.then(() => {
|
||||
fetchData(profileId.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function editData(idData: string) {
|
||||
await http
|
||||
.patch(
|
||||
config.API.profileNewDisciplineByDisciplineId(idData, empType.value),
|
||||
{
|
||||
...disciplineData,
|
||||
profileId: undefined,
|
||||
}
|
||||
)
|
||||
.then(() => {
|
||||
fetchData(profileId.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
// function deleteData(idData: string) {
|
||||
// dialogRemove($q, () =>
|
||||
// http
|
||||
// .delete(config.API.profileNewDisciplineByDisciplineId(idData))
|
||||
// .then(() => {
|
||||
// fetchData(profileId.value);
|
||||
// success($q, "ลบข้อมูลสำเร็จ");
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// messageError($q, err);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// hideLoader();
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
/**
|
||||
* กดเลือกข้อมูลที่จะแก้ไข
|
||||
* @param props ค่า props ใน row ที่เลือก
|
||||
*/
|
||||
function openDialogEdit(props: RequestItemsObject) {
|
||||
modal.value = true;
|
||||
edit.value = true;
|
||||
id.value = props.id ? props.id : "";
|
||||
disciplineData.date = props.date;
|
||||
disciplineData.detail = props.detail;
|
||||
disciplineData.level = props.level;
|
||||
disciplineData.unStigma = props.unStigma;
|
||||
disciplineData.refCommandNo = props.refCommandNo;
|
||||
disciplineData.refCommandDate = props.refCommandDate;
|
||||
}
|
||||
|
||||
function openDialogHistory(idOrder: string) {
|
||||
modalHistory.value = true;
|
||||
id.value = idOrder;
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
edit.value ? editData(id.value) : addData();
|
||||
closeDialog();
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData(profileId.value);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn dense color="primary" icon="add" flat round @click="openDialogAdd()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="mode == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
:card-container-class="mode === 'card' ? 'q-col-gutter-md' : ''"
|
||||
:grid="mode === 'card'"
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:filter="filterKeyword"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
>
|
||||
<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">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
icon="mdi-pencil-outline"
|
||||
clickable
|
||||
@click="openDialogEdit(props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขวินัย</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- <q-btn
|
||||
color="red"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-delete"
|
||||
clickable
|
||||
@click.stop="deleteData(props.row.id)"
|
||||
v-close-popup
|
||||
>
|
||||
<q-tooltip>ลบข้อมูล</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1
|
||||
}}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-card flat bordered class="q-pa-none">
|
||||
<div class="row bg-grey-3">
|
||||
<q-space />
|
||||
<div class="q-gutter-x-sm">
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
flat
|
||||
round
|
||||
@click="openDialogEdit(props.row)"
|
||||
><q-tooltip>แก้ไข</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
flat
|
||||
round
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
><q-tooltip>ประวิติแก้ไขวินัย</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-none">
|
||||
<div class="row q-pa-sm">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
ระดับการลงโทษทางวินัย
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.level !== "" ? props.row.level : "-" }}
|
||||
</div>
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
วัน/เดือน/ปี
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.date ? date2Thai(props.row.date) : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">ล้างมลทิน</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.unStigma !== "" ? props.row.unStigma : "-" }}
|
||||
</div>
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
เลขที่คำสั่ง
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{
|
||||
props.row.refCommandNo !== "" ? props.row.refCommandNo : "-"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
เอกสารอ้างอิง (ลงวันที่)
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{
|
||||
props.row.refCommandDate
|
||||
? date2Thai(props.row.refCommandDate)
|
||||
: "-"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">รายละเอียด</div>
|
||||
<div class="col-9">
|
||||
{{ props.row.detail !== "" ? props.row.detail : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<!-- dialog add edit -->
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit()">
|
||||
<DialogHeader
|
||||
:tittle="edit ? 'แก้ไขข้อมูลวินัย' : 'เพิ่มข้อมูลวินัย'"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="disciplineData.date"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
:model-value="date2Thai(disciplineData.date)"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วัน/เดือน/ปี'}`"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
ref="detailRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="disciplineData.detail"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'รายละเอียด'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<selector
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="disciplineData.level"
|
||||
:label="`${'ระดับการลงโทษทางวินัย'}`"
|
||||
emit-value
|
||||
map-options
|
||||
option-label="name"
|
||||
:options="Ops.levelOptions"
|
||||
option-value="id"
|
||||
use-input
|
||||
clearable
|
||||
hide-bottom-space
|
||||
input-debounce="0"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'levelOptions'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
v-model="disciplineData.unStigma"
|
||||
hide-bottom-space
|
||||
:label="`${'ประเภทคำสั่ง'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
ref="refCommandNoRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="disciplineData.refCommandNo"
|
||||
hide-bottom-space
|
||||
:label="`${'เลขที่คำสั่ง'}`"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอกเลขที่คำสั่ง'}`]"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="mdi-file" class="cursor-pointer" />
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="disciplineData.refCommandDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
clearable
|
||||
dense
|
||||
:model-value="date2Thai(disciplineData.refCommandDate)"
|
||||
hide-bottom-space
|
||||
:label="`${'เอกสารอ้างอิง (ลงวันที่)'}`"
|
||||
@clear="disciplineData.refCommandDate = null"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<DialogHistory v-model:modal="modalHistory" v-model:id="id" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type {
|
||||
RequestItemsObject,
|
||||
FormFilter,
|
||||
} from "@/modules/04_registryPerson/interface/index/discipline";
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const id = defineModel<string>("id", { required: true });
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const filterKeyword = ref<string>("");
|
||||
const rows = ref<RequestItemsObject[]>([]); //select data history
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const visibleColumns = ref<String[]>([
|
||||
"level",
|
||||
"detail",
|
||||
"unStigma",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
"date",
|
||||
"createdFullName",
|
||||
"createdAt",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "level",
|
||||
align: "left",
|
||||
label: "ระดับการลงโทษทางวินัย",
|
||||
sortable: true,
|
||||
field: "level",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "unStigma",
|
||||
align: "left",
|
||||
label: "ล้างมลทิน",
|
||||
sortable: true,
|
||||
field: "unStigma",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
format: (v) => date2Thai(v),
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
function getHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(
|
||||
config.API.profileNewDisciplineHisByDisciplineId(id.value, empType.value)
|
||||
)
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
rows.value = [];
|
||||
data.map((e: RequestItemsObject) => {
|
||||
rows.value.push({
|
||||
...e,
|
||||
id: e.id,
|
||||
level: e.level,
|
||||
detail: e.detail,
|
||||
unStigma: e.unStigma,
|
||||
refCommandNo: e.refCommandNo,
|
||||
refCommandDate:
|
||||
e.refCommandDate == null ? null : new Date(e.refCommandDate),
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
watch(modal, (status) => {
|
||||
if (status == true) {
|
||||
getHistory();
|
||||
filterKeyword.value = "";
|
||||
} else {
|
||||
filterKeyword.value = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader tittle="ประวัติแก้ไขวินัย" :close="() => (modal = false)" />
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
v-model:pagination="historyPagination"
|
||||
:filter="filterKeyword"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize +
|
||||
props.rowIndex +
|
||||
1
|
||||
}}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,815 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import type {
|
||||
DetailData,
|
||||
FormFilter,
|
||||
DataOptionLeave,
|
||||
DataOption,
|
||||
ResponseTotalObject,
|
||||
MyObjectRef,
|
||||
} from "@/modules/04_registryPerson/interface/index/leave";
|
||||
|
||||
import DialogHistory from "@/modules/04_registryPerson/components/detail/GovernmentInformation/03_LeaveHistory.vue";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
const rowsTotal = ref<ResponseTotalObject[]>([]);
|
||||
const id = ref<string>("");
|
||||
const route = useRoute();
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
dialogConfirm,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
success,
|
||||
date2Thai,
|
||||
dateToISO,
|
||||
} = mixin;
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const mode = ref<string>("table");
|
||||
const filterKeyword = ref<string>("");
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const rows = ref<DetailData[]>([]);
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
const modal = ref<boolean>(false);
|
||||
const edit = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
const reason = ref<string>(""); //เหตุผล
|
||||
const numLeave = ref<number>(1);
|
||||
const dateRange = ref<[Date, Date]>([new Date(), new Date()]);
|
||||
const numUsedLeave = ref<number>(0);
|
||||
const typeLeave = ref<any>();
|
||||
const typeLeaveOption = ref<DataOptionLeave[]>([]);
|
||||
const typeLeaveOptionFilter = ref<DataOptionLeave[]>([]);
|
||||
|
||||
const statLeave = ref<string>("");
|
||||
const statLeaveOption = ref<DataOption[]>([
|
||||
{ id: "approve", name: "ผ่านการอนุมัติ" },
|
||||
{ id: "reject", name: "ไม่ผ่านการอนุมัติ" },
|
||||
{ id: "cancel", name: "ยกเลิก" },
|
||||
{ id: "waitting", name: "รออนุมัติ" },
|
||||
]);
|
||||
const statLeaveOptionFilter = ref<DataOption[]>([
|
||||
{ id: "approve", name: "ผ่านการอนุมัติ" },
|
||||
{ id: "reject", name: "ไม่ผ่านการอนุมัติ" },
|
||||
{ id: "cancel", name: "ยกเลิก" },
|
||||
{ id: "waitting", name: "รออนุมัติ" },
|
||||
]);
|
||||
|
||||
const statusLeave = (val: string) => {
|
||||
switch (val) {
|
||||
case "waitting":
|
||||
return "รออนุมัติ";
|
||||
case "reject":
|
||||
return "ไม่ผ่านการอนุมัติ";
|
||||
case "approve":
|
||||
return "ผ่านการอนุมัติ";
|
||||
case "cancel":
|
||||
return "ยกเลิก";
|
||||
default:
|
||||
return "-";
|
||||
}
|
||||
};
|
||||
|
||||
const clickEditRowType = () => {
|
||||
const filter = typeLeaveOptionFilter.value.filter(
|
||||
(v: DataOptionLeave) => v.id == typeLeave.value
|
||||
);
|
||||
if (filter.length > 0) {
|
||||
numUsedLeave.value = filter[0].totalLeave;
|
||||
}
|
||||
};
|
||||
|
||||
const typeLeaveRef = ref<object | null>(null);
|
||||
const dateRangeRef = ref<object | null>(null);
|
||||
const numLeaveRef = ref<object | null>(null);
|
||||
const statLeaveRef = ref<object | null>(null);
|
||||
const reasonRef = ref<object | null>(null);
|
||||
const objectRef: MyObjectRef = {
|
||||
typeLeave: typeLeaveRef,
|
||||
dateRange: dateRangeRef,
|
||||
numLeave: numLeaveRef,
|
||||
statLeave: statLeaveRef,
|
||||
reason: reasonRef,
|
||||
};
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"no",
|
||||
"typeLeave",
|
||||
"dateLeave",
|
||||
"numLeave",
|
||||
"status",
|
||||
"reason",
|
||||
]);
|
||||
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
align: "left",
|
||||
label: "ลำดับ",
|
||||
sortable: false,
|
||||
field: "no",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "typeLeave",
|
||||
align: "left",
|
||||
label: "ประเภทการลา",
|
||||
sortable: true,
|
||||
field: "typeLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateLeave",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี ที่ลา",
|
||||
sortable: true,
|
||||
field: "dateLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "numLeave",
|
||||
align: "left",
|
||||
label: "จำนวนวันลา",
|
||||
sortable: true,
|
||||
field: "numLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
align: "left",
|
||||
label: "สถานะ",
|
||||
sortable: true,
|
||||
field: "status",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reason",
|
||||
align: "left",
|
||||
label: "เหตุผล",
|
||||
sortable: true,
|
||||
field: "reason",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
function openDialogAdd() {
|
||||
modal.value = true;
|
||||
edit.value = false;
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewLeaveType())
|
||||
.then((res) => {
|
||||
const dataOp = res.data.result.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
code: item.code,
|
||||
}));
|
||||
|
||||
typeLeaveOption.value = dataOp;
|
||||
typeLeaveOptionFilter.value = dataOp;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||
*/
|
||||
function clickTotal() {
|
||||
rowsTotal.value = [];
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewLeaveType())
|
||||
.then((res) => {
|
||||
const dataOp = res.data.result.map((item: DataOption) => ({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
}));
|
||||
|
||||
typeLeaveOption.value = dataOp;
|
||||
typeLeaveOptionFilter.value = dataOp;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function openDialogEdit(props: DetailData) {
|
||||
edit.value = true;
|
||||
modal.value = true;
|
||||
id.value = props.id;
|
||||
typeLeave.value = {
|
||||
id: props.typeLeaveId,
|
||||
name: props.typeLeave,
|
||||
code: props.code,
|
||||
};
|
||||
statLeave.value = props.status;
|
||||
reason.value = props.reason;
|
||||
dateRange.value = [
|
||||
new Date(props.dateStartLeave as Date),
|
||||
new Date(props.dateEndLeave as Date),
|
||||
];
|
||||
numLeave.value = props.numLeave;
|
||||
clickTotal();
|
||||
if (rowsTotal.value.length > 0) {
|
||||
let data: DataOptionLeave[] = [];
|
||||
rowsTotal.value.map((e: ResponseTotalObject) => {
|
||||
data.push({
|
||||
id: e.typeLeaveId,
|
||||
name: e.typeLeave,
|
||||
totalLeave: e.totalLeave,
|
||||
});
|
||||
});
|
||||
typeLeaveOption.value = data;
|
||||
typeLeaveOptionFilter.value = data;
|
||||
}
|
||||
}
|
||||
|
||||
/** ปิด dialog */
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
edit.value = false;
|
||||
|
||||
id.value = "";
|
||||
typeLeave.value = "";
|
||||
statLeave.value = "";
|
||||
reason.value = "";
|
||||
dateRange.value = [new Date(), new Date()];
|
||||
numLeave.value = 1;
|
||||
numUsedLeave.value = 0;
|
||||
}
|
||||
|
||||
function filterSelector(val: any, update: Function, filtername: string) {
|
||||
switch (filtername) {
|
||||
case "typeLeaveOption":
|
||||
update(() => {
|
||||
typeLeaveOption.value = typeLeaveOptionFilter.value.filter(
|
||||
(v: DataOptionLeave) =>
|
||||
v.name.toLowerCase().indexOf(val.toLowerCase()) > -1
|
||||
);
|
||||
});
|
||||
break;
|
||||
case "statLeaveOption":
|
||||
update(() => {
|
||||
statLeaveOption.value = statLeaveOptionFilter.value.filter(
|
||||
(v: DataOption) =>
|
||||
v.name.toLowerCase().indexOf(val.toLowerCase()) > -1
|
||||
);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง
|
||||
* @param val ช่วงวันที่
|
||||
*/
|
||||
function dateThaiRange(val: [Date, Date]) {
|
||||
if (val === null) {
|
||||
} else if (date2Thai(val[0]) === date2Thai(val[1])) {
|
||||
return `${date2Thai(val[0])}`;
|
||||
} else {
|
||||
return `${date2Thai(val[0])} - ${date2Thai(val[1])} `;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||
*/
|
||||
function openDialogHistory(idOrder: string) {
|
||||
modalHistory.value = true;
|
||||
id.value = idOrder;
|
||||
}
|
||||
|
||||
/** validate check*/
|
||||
function validateForm() {
|
||||
const hasError = [];
|
||||
for (const key in objectRef) {
|
||||
if (Object.prototype.hasOwnProperty.call(objectRef, key)) {
|
||||
const property = objectRef[key];
|
||||
if (property.value && typeof property.value.validate === "function") {
|
||||
const isValid = property.value.validate();
|
||||
hasError.push(isValid);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasError.every((result) => result === true)) {
|
||||
dialogConfirm($q, async () => {
|
||||
if (edit.value == false) {
|
||||
saveData();
|
||||
} else {
|
||||
editData();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* บันทึกเพิ่มข้อมูล
|
||||
*/
|
||||
function saveData() {
|
||||
showLoader();
|
||||
|
||||
http
|
||||
.post(config.API.profileNewLeave(empType.value), {
|
||||
leaveTypeId: typeLeave.value.id,
|
||||
dateLeaveStart: dateToISO(dateRange.value[0]),
|
||||
dateLeaveEnd: dateToISO(dateRange.value[1]),
|
||||
leaveDays: numLeave.value,
|
||||
leaveCount: 0,
|
||||
totalLeave: 0,
|
||||
status: statLeave.value,
|
||||
reason: reason.value,
|
||||
profileId: empType.value === "" ? profileId.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? profileId.value : undefined,
|
||||
})
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
closeDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
getData();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* บันทึกแก้ไขข้อมูล
|
||||
*/
|
||||
const editData = async () => {
|
||||
showLoader();
|
||||
http
|
||||
.patch(config.API.profileNewLeaveById(id.value, empType.value), {
|
||||
leaveTypeId: typeLeave.value.id,
|
||||
dateLeaveStart: dateToISO(dateRange.value[0]),
|
||||
dateLeaveEnd: dateToISO(dateRange.value[1]),
|
||||
leaveDays: numLeave.value,
|
||||
leaveCount: 0,
|
||||
totalLeave: 0,
|
||||
status: statLeave.value,
|
||||
reason: reason.value,
|
||||
})
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
closeDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
getData();
|
||||
});
|
||||
};
|
||||
|
||||
function getData() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewLeaveById(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
console.log(res.data.result);
|
||||
const data = res.data.result;
|
||||
rows.value = data.map((item: any) => ({
|
||||
id: item.id,
|
||||
typeLeave: item.leaveType.name,
|
||||
code: item.leaveType.refCommandDate,
|
||||
dateStartLeave: item.dateLeaveStart,
|
||||
dateEndLeave: item.dateLeaveEnd,
|
||||
numLeave: item.leaveDays,
|
||||
status: item.status,
|
||||
reason: item.reason,
|
||||
typeLeaveId: item.leaveTypeId,
|
||||
}));
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn dense color="primary" icon="add" flat round @click="openDialogAdd()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="mode == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:card-container-class="mode === 'card' ? 'q-col-gutter-md' : ''"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:grid="mode === 'card'"
|
||||
:paging="true"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
>
|
||||
>
|
||||
<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">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
icon="mdi-pencil-outline"
|
||||
clickable
|
||||
@click="openDialogEdit(props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขการลา</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="col.name == 'dateLeave'">
|
||||
{{
|
||||
dateThaiRange([props.row.dateStartLeave, props.row.dateEndLeave])
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="col.name == 'status'">
|
||||
{{ statusLeave(col.value) }}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-6">
|
||||
<q-card flat bordered class="q-pa-none">
|
||||
<div class="row bg-grey-3">
|
||||
<q-space />
|
||||
<div class="q-gutter-x-sm">
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
flat
|
||||
round
|
||||
@click="openDialogEdit(props.row)"
|
||||
><q-tooltip>แก้ไขข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
flat
|
||||
round
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
><q-tooltip>ประวิติแก้ไขการลา</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-none">
|
||||
<div class="row q-pa-sm">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
ประเภทการลา
|
||||
</div>
|
||||
<div class="col-9">
|
||||
{{ props.row.typeLeave !== "" ? props.row.typeLeave : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
วัน/เดือน/ปี ที่ลา
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{
|
||||
props.row.dateStartLeave
|
||||
? date2Thai(props.row.dateStartLeave)
|
||||
: "-"
|
||||
}}
|
||||
</div>
|
||||
<div class="col-3 text-grey-6 text-weight-medium">จำนวนวันลา</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.numLeave ? props.row.numLeave : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">สถานะ</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.status ? statusLeave(props.row.status) : "-" }}
|
||||
</div>
|
||||
<div class="col-3 text-grey-6 text-weight-medium">เหตุผล</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.reason !== "" ? props.row.reason : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<!-- dialog add edit -->
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<form @submit.prevent="validateForm">
|
||||
<DialogHeader
|
||||
:tittle="edit ? 'แก้ไขข้อมูลการลา' : 'เพิ่มข้อมูลการลา'"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
ref="typeLeaveRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="typeLeave"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือกประเภทการลา'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'ประเภทการลา'}`"
|
||||
@update:modelValue="clickEditRowType"
|
||||
map-options
|
||||
option-label="name"
|
||||
:options="typeLeaveOption"
|
||||
option-value="id"
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'typeLeaveOption'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
:readonly="!typeLeave"
|
||||
menu-class-name="modalfix"
|
||||
v-model="dateRange"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
range
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
:readonly="!typeLeave"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
ref="dateRangeRef"
|
||||
:model-value="dateThaiRange(dateRange)"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือกวัน เดือน ปีที่ลา'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วัน เดือน ปีที่ลา'}`"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
ref="numLeaveRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="numLeave"
|
||||
type="number"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอกจำนวนวันที่ลา'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'จำนวนวันที่ลา'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
ref="statLeaveRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="statLeave"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือกสถานะการลา'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'สถานะการลา'}`"
|
||||
emit-value
|
||||
map-options
|
||||
option-label="name"
|
||||
:options="statLeaveOption"
|
||||
option-value="id"
|
||||
use-input
|
||||
input-debounce="0"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'statLeaveOption'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-12">
|
||||
<q-input
|
||||
ref="reasonRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="reason"
|
||||
type="textarea"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอกเหตุผล'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'เหตุผล'}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<DialogHistory v-model:modal="modalHistory" v-model:id="id" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,319 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type {
|
||||
DetailData,
|
||||
FormFilter,
|
||||
} from "@/modules/04_registryPerson/interface/index/leave";
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const id = defineModel<string>("id", { required: true });
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
|
||||
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const filterKeyword = ref<string>("");
|
||||
const rows = ref<DetailData[]>([]); //select data history
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const visibleColumns = ref<String[]>([
|
||||
"no",
|
||||
"typeLeave",
|
||||
"dateLeave",
|
||||
"numLeave",
|
||||
"sumLeave",
|
||||
"totalLeave",
|
||||
"status",
|
||||
"reason",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "no",
|
||||
align: "left",
|
||||
label: "ลำดับ",
|
||||
sortable: false,
|
||||
field: "no",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "typeLeave",
|
||||
align: "left",
|
||||
label: "ประเภทการลา",
|
||||
sortable: true,
|
||||
field: "typeLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateLeave",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี ที่ลา",
|
||||
sortable: true,
|
||||
field: "dateLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "numLeave",
|
||||
align: "left",
|
||||
label: "จำนวนวันลา",
|
||||
sortable: true,
|
||||
field: "numLeave",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "status",
|
||||
align: "left",
|
||||
label: "สถานะ",
|
||||
sortable: true,
|
||||
field: "status",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reason",
|
||||
align: "left",
|
||||
label: "เหตุผล",
|
||||
sortable: true,
|
||||
field: "reason",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
function getHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewLeaveHistory(id.value, empType.value))
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
rows.value = [];
|
||||
data.map((e: any) => {
|
||||
rows.value.push({
|
||||
...e,
|
||||
id: e.id,
|
||||
typeLeave: e.leaveType.name,
|
||||
code: e.leaveType.refCommandDate,
|
||||
dateStartLeave: e.dateLeaveStart,
|
||||
dateEndLeave: e.dateLeaveEnd,
|
||||
numLeave: e.leaveDays,
|
||||
status: e.status,
|
||||
reason: e.reason,
|
||||
typeLeaveId:
|
||||
e.typeLeaveId !== "00000000-0000-0000-0000-000000000000"
|
||||
? e.typeLeaveId
|
||||
: "",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
// messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* แปลงช่วงวันที่ถ้า2ค่าเป็นวันเดียวกันจะโชววันเดียวแต่ถ้าไม่เท่ากันจะแสดงเป็นช่วง
|
||||
* @param val ช่วงวันที่
|
||||
*/
|
||||
function dateThaiRange(val: [Date, Date]) {
|
||||
if (val === null) {
|
||||
} else if (date2Thai(val[0]) === date2Thai(val[1])) {
|
||||
return `${date2Thai(val[0])}`;
|
||||
} else {
|
||||
return `${date2Thai(val[0])} - ${date2Thai(val[1])} `;
|
||||
}
|
||||
}
|
||||
|
||||
function statusLeave(val: string) {
|
||||
switch (val) {
|
||||
case "waitting":
|
||||
return "รออนุมัติ";
|
||||
case "reject":
|
||||
return "ไม่ผ่านการอนุมัติ";
|
||||
case "approve":
|
||||
return "ผ่านการอนุมัติ";
|
||||
case "cancel":
|
||||
return "ยกเลิก";
|
||||
default:
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
|
||||
watch(modal, (status) => {
|
||||
if (status == true) {
|
||||
getHistory();
|
||||
filterKeyword.value = "";
|
||||
} else {
|
||||
filterKeyword.value = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader tittle="ประวัติแก้ไขการลา" :close="() => (modal = false)" />
|
||||
<q-separator color="grey-4" />
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
v-model:pagination="historyPagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize +
|
||||
props.rowIndex +
|
||||
1
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="col.name == 'dateLeave'">
|
||||
{{
|
||||
dateThaiRange([
|
||||
props.row.dateStartLeave,
|
||||
props.row.dateEndLeave,
|
||||
])
|
||||
}}
|
||||
</div>
|
||||
<div v-else-if="col.name == 'status'">
|
||||
{{ statusLeave(col.value) }}
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,723 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import type {
|
||||
FormFilter,
|
||||
RequestItemsObject,
|
||||
} from "@/modules/04_registryPerson/interface/index/performSpecialWork";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import DialogHistory from "@/modules/04_registryPerson/components/detail/GovernmentInformation/04_PerformSpecialWorkHistory.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
dialogConfirm,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
success,
|
||||
dialogRemove,
|
||||
} = mixin;
|
||||
|
||||
const modal = ref<boolean>(false);
|
||||
const edit = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
const id = ref<string>("");
|
||||
|
||||
const dateStartRef = ref<object | null>(null);
|
||||
const dateEndRef = ref<object | null>(null);
|
||||
const detailRef = ref<object | null>(null);
|
||||
const referenceRef = ref<object | null>(null);
|
||||
|
||||
const dutyData = reactive<RequestItemsObject>({
|
||||
profileId: profileId.value,
|
||||
dateStart: new Date(),
|
||||
dateEnd: null,
|
||||
detail: "",
|
||||
reference: "",
|
||||
refCommandNo: "",
|
||||
refCommandDate: null,
|
||||
});
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const rows = ref<RequestItemsObject[]>([]);
|
||||
const filterKeyword = ref<string>("");
|
||||
const mode = ref<string>("table");
|
||||
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"dateStart",
|
||||
"dateEnd",
|
||||
"detail",
|
||||
"reference",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "dateStart",
|
||||
align: "left",
|
||||
label: "เริ่มต้น",
|
||||
sortable: true,
|
||||
field: "dateStart",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateEnd",
|
||||
align: "left",
|
||||
label: "สิ้นสุด",
|
||||
sortable: true,
|
||||
field: "dateEnd",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
/** เปิด dialog */
|
||||
function openDialogAdd() {
|
||||
modal.value = true;
|
||||
}
|
||||
|
||||
/** กดแก้ไข */
|
||||
function openDialogEdit(props: RequestItemsObject) {
|
||||
modal.value = true;
|
||||
edit.value = true;
|
||||
id.value = props.id ? props.id : "";
|
||||
dutyData.dateStart = props.dateStart;
|
||||
dutyData.dateEnd = props.dateEnd;
|
||||
dutyData.detail = props.detail;
|
||||
dutyData.reference = props.reference;
|
||||
dutyData.refCommandNo = props.refCommandNo;
|
||||
dutyData.refCommandDate = props.refCommandDate;
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังชั้นดูข้อมูลประวัติแก้ไขข้อมูลที่เลือก
|
||||
* @param row ข้อมูล row ที่ดูประวัติการแก้ไข
|
||||
*/
|
||||
function openDialogHistory(idOrder: string) {
|
||||
modalHistory.value = true;
|
||||
id.value = idOrder;
|
||||
}
|
||||
|
||||
/** ปิด dialog */
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
edit.value = false;
|
||||
|
||||
dutyData.dateStart = new Date();
|
||||
dutyData.dateEnd = null;
|
||||
dutyData.detail = "";
|
||||
dutyData.reference = "";
|
||||
dutyData.refCommandNo = "";
|
||||
dutyData.refCommandDate = null;
|
||||
}
|
||||
|
||||
/** fetch ข้อมูล */
|
||||
async function fetchData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewDutyByProfileId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/** เพิ่มข้อมูล */
|
||||
|
||||
async function addData() {
|
||||
const body = {
|
||||
profileId: empType.value === "" ? profileId.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? profileId.value : undefined,
|
||||
dateStart: dutyData.dateStart,
|
||||
dateEnd: dutyData.dateEnd,
|
||||
detail: dutyData.detail,
|
||||
reference: dutyData.reference,
|
||||
refCommandNo: dutyData.refCommandNo,
|
||||
refCommandDate: dutyData.refCommandDate,
|
||||
};
|
||||
await http
|
||||
.post(config.API.profileNewDuty(empType.value), body)
|
||||
.then(() => {
|
||||
fetchData(profileId.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/** แก้ไขข้อมูล */
|
||||
|
||||
async function editData(idData: string) {
|
||||
await http
|
||||
.patch(config.API.profileNewDutyByDutyId(idData, empType.value), {
|
||||
...dutyData,
|
||||
profileId: undefined,
|
||||
})
|
||||
.then(() => {
|
||||
fetchData(profileId.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/** ลบข้อมูล */
|
||||
|
||||
// function deleteData(idData: string) {
|
||||
// dialogRemove($q, () =>
|
||||
// http
|
||||
// .delete(config.API.profileNewDutyByDutyId(idData))
|
||||
// .then(() => {
|
||||
// fetchData(profileId.value);
|
||||
// success($q, "ลบข้อมูลสำเร็จ");
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// messageError($q, err);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// hideLoader();
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
/** กด Submit */
|
||||
|
||||
async function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
edit.value ? editData(id.value) : addData();
|
||||
closeDialog();
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData(profileId.value);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn dense color="primary" icon="add" flat round @click="openDialogAdd()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="mode == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:card-container-class="mode === 'card' ? 'q-col-gutter-md' : ''"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:grid="mode === 'card'"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
v-model:pagination="pagination"
|
||||
>
|
||||
>
|
||||
<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">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
icon="mdi-pencil-outline"
|
||||
clickable
|
||||
@click="openDialogEdit(props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขปฏิบัติราชการพิเศษ</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- <q-btn
|
||||
color="red"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-delete"
|
||||
clickable
|
||||
@click.stop="deleteData(props.row.id)"
|
||||
v-close-popup
|
||||
>
|
||||
<q-tooltip>ลบข้อมูล</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize + props.rowIndex + 1
|
||||
}}
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-card flat bordered class="q-pa-none">
|
||||
<div class="row bg-grey-3">
|
||||
<q-space />
|
||||
<div class="q-gutter-x-sm">
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
flat
|
||||
round
|
||||
@click="openDialogEdit(props.row)"
|
||||
><q-tooltip>แก้ไขข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
flat
|
||||
round
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
><q-tooltip>ประวัติแก้ไขปฏิบัติราชการพิเศษ</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-none">
|
||||
<div class="row q-pa-sm">
|
||||
<div class="col text-grey-6 text-weight-medium">เริ่มต้น</div>
|
||||
<div class="col">
|
||||
{{ props.row.dateStart ? date2Thai(props.row.dateStart) : "-" }}
|
||||
</div>
|
||||
<div class="col text-grey-6 text-weight-medium">สิ้นสุด</div>
|
||||
<div class="col">
|
||||
{{ props.row.dateEnd ? date2Thai(props.row.dateEnd) : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
เอกสารอ้างอิง
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{ props.row.reference ? props.row.reference : "-" }}
|
||||
</div>
|
||||
<div class="col text-grey-6 text-weight-medium">เลขที่คำสั่ง</div>
|
||||
<div class="col">
|
||||
{{ props.row.refCommandNo ? props.row.refCommandNo : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">
|
||||
เอกสารอ้างอิง (ลงวันที่)
|
||||
</div>
|
||||
<div class="col-3">
|
||||
{{
|
||||
props.row.refCommandDate
|
||||
? date2Thai(props.row.refCommandDate)
|
||||
: "-"
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<div class="row q-pa-sm bg-grey-2">
|
||||
<div class="col-3 text-grey-6 text-weight-medium">รายละเอียด</div>
|
||||
<div class="col-9">
|
||||
{{ props.row.detail ? props.row.detail : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit()">
|
||||
<DialogHeader
|
||||
:tittle="
|
||||
edit
|
||||
? 'แก้ไขข้อมูลปฏิบัติราชการพิเศษ'
|
||||
: 'เพิ่มข้อมูลปฏิบัติราชการพิเศษ'
|
||||
"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="dutyData.dateStart"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateStartRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
:model-value="date2Thai(dutyData.dateStart)"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่เริ่มต้น'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วันที่เริ่มต้น'}`"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="dutyData.dateEnd"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
:min-date="dutyData.dateStart"
|
||||
:readonly="!dutyData.dateStart"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateEndRef"
|
||||
:readonly="!dutyData.dateStart"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
dense
|
||||
outlined
|
||||
:model-value="date2Thai(dutyData.dateEnd)"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่สิ้นสุด'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วันที่สิ้นสุด'}`"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
ref="referenceRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
autogrow
|
||||
v-model="dutyData.reference"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกเอกสารอ้างอิง'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'เอกสารอ้างอิง'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
ref="detailRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
autogrow
|
||||
v-model="dutyData.detail"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'รายละเอียด'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
v-model="dutyData.refCommandNo"
|
||||
:label="`${'เลขที่คำสั่ง'}`"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="mdi-file" class="cursor-pointer" />
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="dutyData.refCommandDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
:borderless="!edit"
|
||||
:model-value="
|
||||
dutyData.refCommandDate == null ? null : date2Thai(dutyData.refCommandDate as Date)
|
||||
"
|
||||
hide-bottom-space
|
||||
:label="`${'เอกสารอ้างอิง (ลงวันที่)'}`"
|
||||
clearable
|
||||
@clear="dutyData.refCommandDate = null"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
<template
|
||||
v-if="dutyData.refCommandDate && edit"
|
||||
v-slot:append
|
||||
>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<DialogHistory v-model:modal="modalHistory" v-model:id="id" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type {
|
||||
FormFilter,
|
||||
ResponseObject,
|
||||
} from "@/modules/04_registryPerson/interface/index/performSpecialWork";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const id = defineModel<string>("id", { required: true });
|
||||
|
||||
const route = useRoute();
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
|
||||
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const filterKeyword = ref<string>("");
|
||||
const rows = ref<ResponseObject[]>([]); //select data history
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const visibleColumns = ref<String[]>([
|
||||
"dateStart",
|
||||
"dateEnd",
|
||||
"detail",
|
||||
"reference",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "dateStart",
|
||||
align: "left",
|
||||
label: "เริ่มต้น",
|
||||
sortable: true,
|
||||
field: "dateStart",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "dateEnd",
|
||||
align: "left",
|
||||
label: "สิ้นสุด",
|
||||
sortable: true,
|
||||
field: "dateEnd",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
function getHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewDutyHisByDutyId(id.value, empType.value))
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
rows.value = [];
|
||||
data.map((e: ResponseObject) => {
|
||||
rows.value.push({
|
||||
id: e.id,
|
||||
dateStart: new Date(e.dateStart),
|
||||
dateEnd: new Date(e.dateEnd),
|
||||
detail: e.detail,
|
||||
reference: e.reference,
|
||||
refCommandNo: e.refCommandNo,
|
||||
refCommandDate:
|
||||
e.refCommandDate == null ? null : new Date(e.refCommandDate),
|
||||
createdFullName: e.createdFullName,
|
||||
createdAt: new Date(e.createdAt),
|
||||
lastUpdateFullName: e.lastUpdateFullName,
|
||||
lastUpdatedAt: e.lastUpdatedAt,
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
watch(modal, (status) => {
|
||||
if (status == true) {
|
||||
getHistory();
|
||||
filterKeyword.value = "";
|
||||
} else {
|
||||
filterKeyword.value = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขปฏิบัติราชการพิเศษ"
|
||||
:close="() => (modal = false)"
|
||||
/>
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
v-model:pagination="historyPagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div v-if="col.name === 'no'">
|
||||
{{
|
||||
(formFilter.page - 1) * formFilter.pageSize +
|
||||
props.rowIndex +
|
||||
1
|
||||
}}
|
||||
</div>
|
||||
<div v-else class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
/** importComponents*/
|
||||
import Info from "@/modules/04_registryPerson/components/detail/GovernmentInformation/01_Info.vue";
|
||||
import Discipline from "@/modules/04_registryPerson/components/detail/GovernmentInformation/02_Discipline.vue";
|
||||
import Leave from "@/modules/04_registryPerson/components/detail/GovernmentInformation/03_Leave.vue";
|
||||
import PerformSpecialWork from "@/modules/04_registryPerson/components/detail/GovernmentInformation/04_PerformSpecialWork.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">ข้อมูลราชการ</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ข้อมูลราชการ" />
|
||||
<q-tab name="2" label="วินัย" />
|
||||
<q-tab name="3" label="การลา" />
|
||||
<q-tab name="4" label="ปฏิบัติราชการพิเศษ" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<Info />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<Discipline />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="3">
|
||||
<Leave />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="4">
|
||||
<PerformSpecialWork />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,482 @@
|
|||
<script setup lang="ts">
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import { ref, onMounted, reactive } from "vue";
|
||||
import type {
|
||||
RowList,
|
||||
FormFilter,
|
||||
MyObjectRef,
|
||||
} from "@/modules/04_registryPerson/interface/index/other";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import DialogHistory from "@/modules/04_registryPerson/components/detail/Other/01_OtherInformationHistory.vue";
|
||||
const route = useRoute();
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
date2Thai,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
success,
|
||||
messageError,
|
||||
dialogRemove,
|
||||
dialogConfirm,
|
||||
} = mixin;
|
||||
|
||||
const id = ref<string>("");
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const mode = ref<string>("table");
|
||||
const filterKeyword = ref<string>("");
|
||||
const rows = ref<RowList[]>([]);
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
|
||||
/** modal */
|
||||
const modal = ref<boolean>(false);
|
||||
const edit = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
const date = ref<Date | null>(null);
|
||||
const detail = ref<string>();
|
||||
|
||||
const dateRef = ref<object | null>(null);
|
||||
const detailRef = ref<object | null>(null);
|
||||
const objectRef: MyObjectRef = {
|
||||
date: dateRef,
|
||||
detail: detailRef,
|
||||
};
|
||||
|
||||
const visibleColumns = ref<String[]>(["date", "detail"]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width: 50px;",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
/** เปิด dialog */
|
||||
function openDialogAdd() {
|
||||
modal.value = true;
|
||||
}
|
||||
|
||||
/** dialog แก้ไข
|
||||
* @param props ข้อมูล row ของรายการ
|
||||
*/
|
||||
function openDialogEdit(props: RowList) {
|
||||
modal.value = true;
|
||||
edit.value = true;
|
||||
|
||||
id.value = props.id;
|
||||
date.value = props.date;
|
||||
detail.value = props.detail;
|
||||
}
|
||||
/** dialog ประติ
|
||||
* @param id id รายการ
|
||||
*/
|
||||
function openDialogHistory(idOrder: string) {
|
||||
id.value = idOrder;
|
||||
modalHistory.value = true;
|
||||
}
|
||||
|
||||
/** ปิด dialog */
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
edit.value = false;
|
||||
date.value = null;
|
||||
detail.value = "";
|
||||
}
|
||||
|
||||
/** validate check*/
|
||||
function validateForm() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
if (edit.value) {
|
||||
editData();
|
||||
} else {
|
||||
saveData();
|
||||
}
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* บันทึกเพิ่มข้อมูล
|
||||
*/
|
||||
async function saveData() {
|
||||
showLoader();
|
||||
await http
|
||||
.post(config.API.profileNewOther(empType.value), {
|
||||
profileId: empType.value === "" ? profileId.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? profileId.value : undefined,
|
||||
date: date.value,
|
||||
detail: detail.value,
|
||||
})
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
getData();
|
||||
closeDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* บันทึกแก้ไขข้อมูล
|
||||
*/
|
||||
async function editData() {
|
||||
showLoader();
|
||||
await http
|
||||
.patch(config.API.profileNewOtherById(id.value, empType.value), {
|
||||
date: date.value,
|
||||
detail: detail.value,
|
||||
})
|
||||
.then((res) => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
getData();
|
||||
closeDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewOtherByProfileId(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn dense color="primary" icon="add" flat round @click="openDialogAdd()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="mode == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
:rows="rows"
|
||||
:columns="columns"
|
||||
dense
|
||||
bordered
|
||||
v-model:pagination="pagination"
|
||||
flat
|
||||
:card-container-class="mode === 'card' ? 'q-col-gutter-md' : ''"
|
||||
:grid="mode === 'card'"
|
||||
:paging="true"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
>
|
||||
<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">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="openDialogEdit(props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขอื่นๆ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-card flat bordered>
|
||||
<div class="row bg-grey-3">
|
||||
<q-space />
|
||||
<div class="q-gutter-x-sm">
|
||||
<q-btn
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
flat
|
||||
round
|
||||
@click="openDialogEdit(props.row)"
|
||||
><q-tooltip>แก้ไข</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
flat
|
||||
round
|
||||
@click="openDialogHistory(props.row.id)"
|
||||
><q-tooltip>ประวิติแก้ไขอื่นๆ</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<q-separator />
|
||||
<q-card-section class="q-pa-none">
|
||||
<q-item
|
||||
v-for="(col, index) in props.cols.filter(
|
||||
(col) => col.name !== 'desc'
|
||||
)"
|
||||
:key="col.name"
|
||||
:class="index % 2 !== 0 ? 'bg-grey-1' : ''"
|
||||
>
|
||||
<q-item-section class="text-grey-6">
|
||||
<q-item-label>{{ col.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section class="text-dark">
|
||||
<q-item-label>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<!-- dialog add edit -->
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 70%">
|
||||
<q-form greedy @submit.prevent @validation-success="validateForm">
|
||||
<DialogHeader
|
||||
:tittle="edit ? 'แก้ไขข้อมูลอื่นๆ' : 'เพิ่มข้อมูลอื่นๆ'"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-xs-6 col-sm-3 col-md-3">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="date"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
:model-value="date2Thai(date)"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือกวันที่'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วันที่'}`"
|
||||
>
|
||||
<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-6 col-sm-9 col-md-9">
|
||||
<q-input
|
||||
ref="detailRef"
|
||||
class="full-width inputgreen cursor-pointer"
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
v-model="detail"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'รายละเอียด'}`"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
dense
|
||||
unelevated
|
||||
label="บันทึก"
|
||||
id="onSubmit"
|
||||
type="submit"
|
||||
color="public"
|
||||
class="q-px-md"
|
||||
>
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<DialogHistory v-model:modal="modalHistory" v-model:id="id" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, reactive } from "vue";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar, type QTableProps } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import type { RowList } from "@/modules/04_registryPerson/interface/index/other";
|
||||
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type {
|
||||
RequestItemsObject,
|
||||
FormFilter,
|
||||
} from "@/modules/04_registryPerson/interface/index/discipline";
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const id = defineModel<string>("id", { required: true });
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const filterKeyword = ref<string>("");
|
||||
const rows = ref<RowList[]>([]); //select data history
|
||||
const formFilter = reactive<FormFilter>({
|
||||
page: 1,
|
||||
pageSize: 12,
|
||||
keyword: "",
|
||||
type: "",
|
||||
posType: "",
|
||||
posLevel: "",
|
||||
retireYear: "",
|
||||
rangeYear: { min: 0, max: 60 },
|
||||
isShowRetire: false,
|
||||
isProbation: false,
|
||||
});
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const visibleColumns = ref<String[]>([
|
||||
"date",
|
||||
"detail",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วันที่",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px; width: 50px;",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
function getHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewOtherHisById(id.value, empType.value))
|
||||
.then((res) => {
|
||||
let data = res.data.result;
|
||||
rows.value = [];
|
||||
data.map((e: RowList) => {
|
||||
rows.value.push({
|
||||
id: e.id,
|
||||
date: e.date,
|
||||
detail: e.detail,
|
||||
lastUpdateFullName: e.lastUpdateFullName,
|
||||
lastUpdatedAt: new Date(e.lastUpdatedAt),
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
watch(modal, (status) => {
|
||||
if (status == true) {
|
||||
getHistory();
|
||||
filterKeyword.value = "";
|
||||
} else {
|
||||
filterKeyword.value = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader tittle="ประวัติแก้ไขอื่นๆ" :close="() => (modal = false)" />
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterKeyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterKeyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterKeyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterKeyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:filter="filterKeyword"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,258 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import axios from "axios";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { ArrayFileList } from "@/modules/04_registryPerson/interface/index/document";
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const {
|
||||
success,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
dialogConfirm,
|
||||
dialogRemove,
|
||||
} = mixin;
|
||||
|
||||
const documentFile = ref<any>(null);
|
||||
const fileList = ref<ArrayFileList[]>([]);
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
|
||||
async function getData() {
|
||||
showLoader();
|
||||
await http
|
||||
.get(
|
||||
config.API.file("ระบบทะเบียนประวัติ", "เอกสารหลักฐาน", profileId.value)
|
||||
)
|
||||
.then((res) => {
|
||||
fileList.value = res.data;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ฟังก์ชั่นสำหรับอัพโหลดไฟล์เอกสารหลักฐาน
|
||||
*/
|
||||
async function uploadFileDoc(uploadUrl: string, file: any) {
|
||||
const Data = new FormData();
|
||||
Data.append("file", documentFile.value);
|
||||
showLoader();
|
||||
await axios
|
||||
.put(uploadUrl, file, {
|
||||
headers: {
|
||||
"Content-Type": file.type,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
success($q, "อัปโหลดไฟล์สำเร็จ");
|
||||
getData();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
documentFile.value = null;
|
||||
});
|
||||
}
|
||||
|
||||
async function clickUpload(file: any) {
|
||||
const fileName = { fileName: file.name };
|
||||
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
const selectedFile = file;
|
||||
const formdata = new FormData();
|
||||
formdata.append("file", selectedFile);
|
||||
await http
|
||||
.post(
|
||||
config.API.file(
|
||||
"ระบบทะเบียนประวัติ",
|
||||
"เอกสารหลักฐาน",
|
||||
profileId.value
|
||||
),
|
||||
{
|
||||
replace: false,
|
||||
fileList: fileName,
|
||||
}
|
||||
)
|
||||
.then(async (res) => {
|
||||
const foundKey: string | undefined = Object.keys(res.data).find(
|
||||
(key) =>
|
||||
res.data[key]?.fileName !== undefined &&
|
||||
res.data[key]?.fileName !== ""
|
||||
);
|
||||
foundKey &&
|
||||
uploadFileDoc(res.data[foundKey]?.uploadUrl, documentFile.value);
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
});
|
||||
},
|
||||
"ยืนยันการอัปโหลดไฟล์",
|
||||
"ต้องการยืนยันการอัปโหลดไฟล์นี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* ดาวน์โหลดลิงค์ไฟล์
|
||||
* @param fileName file name
|
||||
*/
|
||||
function downloadFile(fileName: string) {
|
||||
showLoader();
|
||||
http
|
||||
.get(
|
||||
config.API.fileByFile(
|
||||
"ระบบทะเบียนประวัติ",
|
||||
"เอกสารหลักฐาน",
|
||||
profileId.value,
|
||||
fileName
|
||||
)
|
||||
)
|
||||
.then((res) => {
|
||||
const data = res.data.downloadUrl;
|
||||
window.open(data, "_blank");
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(async () => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* ลบไฟล์
|
||||
* @param fileName file name
|
||||
*/
|
||||
function deleteFile(fileName: string) {
|
||||
dialogRemove($q, async () => {
|
||||
showLoader();
|
||||
http
|
||||
.delete(
|
||||
config.API.fileByFile(
|
||||
"ระบบทะเบียนประวัติ",
|
||||
"เอกสารหลักฐาน",
|
||||
profileId.value,
|
||||
fileName
|
||||
)
|
||||
)
|
||||
.then((res) => {
|
||||
success($q, `ลบไฟล์สำเร็จ`);
|
||||
setTimeout(() => {
|
||||
getData();
|
||||
hideLoader();
|
||||
}, 1000);
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-card bordered class="row col-12" style="border: 1px solid #d6dee1">
|
||||
<div class="col-12 text-weight-medium bg-grey-1 q-py-sm q-px-md">
|
||||
อัปโหลดไฟล์เอกสารหลักฐาน
|
||||
</div>
|
||||
<div class="col-12"><q-separator /></div>
|
||||
<div class="row col-12 q-col-gutter-y-sm q-pa-sm">
|
||||
<div class="col-12 row">
|
||||
<q-file
|
||||
for="inputFiles"
|
||||
class="col-12"
|
||||
outlined
|
||||
dense
|
||||
v-model="documentFile"
|
||||
label="ไฟล์เอกสารหลักฐาน"
|
||||
hide-bottom-space
|
||||
accept=".pdf,.xlsx,.docx,.png,.jpg"
|
||||
clearable
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon name="attach_file" color="primary" />
|
||||
</template>
|
||||
<template v-slot:after>
|
||||
<q-btn
|
||||
size="14px"
|
||||
v-if="documentFile"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
color="add"
|
||||
icon="mdi-upload"
|
||||
@click="clickUpload(documentFile)"
|
||||
><q-tooltip>อัปโหลดไฟล์</q-tooltip></q-btn
|
||||
>
|
||||
</template>
|
||||
</q-file>
|
||||
|
||||
<!-- <div class="col-1 self-center" v-if="formData.documentFile"></div> -->
|
||||
</div>
|
||||
|
||||
<div v-if="fileList.length > 0" class="col-xs-12 row">
|
||||
<q-list class="full-width rounded-borders" bordered separator>
|
||||
<q-item
|
||||
clickable
|
||||
v-ripple
|
||||
v-for="data in fileList"
|
||||
:key="data.id"
|
||||
class="items-center"
|
||||
>
|
||||
<q-item-section>{{ data.fileName }}</q-item-section>
|
||||
<q-space />
|
||||
<div>
|
||||
<q-btn
|
||||
size="12px"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
color="blue"
|
||||
icon="mdi-download"
|
||||
@click="downloadFile(data.fileName)"
|
||||
><q-tooltip>ดาวน์โหลดไฟล์</q-tooltip></q-btn
|
||||
>
|
||||
<q-btn
|
||||
size="12px"
|
||||
flat
|
||||
round
|
||||
dense
|
||||
color="red"
|
||||
class="q-ml-sm"
|
||||
icon="mdi-delete-outline"
|
||||
@click="deleteFile(data.fileName)"
|
||||
><q-tooltip>ลบไฟล์</q-tooltip></q-btn
|
||||
>
|
||||
</div>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</div>
|
||||
|
||||
<div class="col-12" v-else>
|
||||
<q-card class="q-pa-md" bordered> ไม่มีรายการเอกสาร </q-card>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
/** importComponents*/
|
||||
import OtherInformation from "@/modules/04_registryPerson/components/detail/Other/01_OtherInformation.vue";
|
||||
import Documentipline from "@/modules/04_registryPerson/components/detail/Other/02_Document.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">เอกสารหลักฐานและอื่นๆ</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ข้อมูลอื่นๆ" />
|
||||
<q-tab name="2" label="เอกสารหลักฐาน" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<OtherInformation />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<Documentipline />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,899 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, watch, ref, reactive } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { QTableColumn, QForm } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useProfileDataStore } from "@/modules/04_registryPerson/stores/profile";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import type { RequestObject } from "@/modules/04_registryPerson/interface/request/Profile";
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/Profile";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const mixin = useCounterMixin();
|
||||
const store = useProfileDataStore();
|
||||
const {
|
||||
success,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
date2Thai,
|
||||
messageError,
|
||||
dialogConfirm,
|
||||
dialogMessageNotify,
|
||||
} = mixin;
|
||||
const { calculateAge, fetchPerson, filterSelector } = store;
|
||||
const props = defineProps({
|
||||
fetchDataPersonal: { type: Function, require: true },
|
||||
});
|
||||
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const modal = ref<boolean>(false);
|
||||
const informaData = ref<ResponseObject>();
|
||||
const rowsHistory = ref<ResponseObject[]>([]);
|
||||
const filterHistory = ref<string>("");
|
||||
const modalHistory = ref<boolean>(false);
|
||||
|
||||
const id = ref<string>("");
|
||||
const age = ref<string | null>("");
|
||||
const formData = reactive<RequestObject>(store.defaultProfile);
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const dataLabel = {
|
||||
citizenId: "เลขประจำตัวประชาชน",
|
||||
name: "ชื่อ - สกุล",
|
||||
birthDate: "วัน/เดือน/ปีเกิด",
|
||||
age: "อายุ",
|
||||
gender: "เพศ",
|
||||
relationship: "สถานภาพ",
|
||||
nationality: "สัญชาติ",
|
||||
ethnicity: "เชื้อชาติ",
|
||||
religion: "ศาสนา",
|
||||
bloodGroup: "หมู่เลือด",
|
||||
phone: "เบอร์โทร",
|
||||
|
||||
prefix: "คำนำหน้าชื่อ",
|
||||
rank: "ยศ",
|
||||
firstName: "ชื่อ",
|
||||
lastName: "นามสกุล",
|
||||
};
|
||||
|
||||
const columnsHistory = ref<QTableColumn[]>([
|
||||
{
|
||||
name: "citizenId",
|
||||
align: "left",
|
||||
label: "เลขประจำตัวประชาชน",
|
||||
sortable: true,
|
||||
field: "citizenId",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "prefix",
|
||||
align: "left",
|
||||
label: "คำนำหน้าชื่อ",
|
||||
sortable: true,
|
||||
field: "prefix",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "rank",
|
||||
align: "left",
|
||||
label: "ยศ",
|
||||
sortable: true,
|
||||
field: "rank",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "firstName",
|
||||
align: "left",
|
||||
label: "ชื่อ",
|
||||
sortable: true,
|
||||
field: "firstName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastName",
|
||||
align: "left",
|
||||
label: "นามสกุล",
|
||||
sortable: true,
|
||||
field: "lastName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "birthDate",
|
||||
align: "left",
|
||||
label: "วัน/เดือน/ปี เกิด",
|
||||
sortable: true,
|
||||
field: "birthDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => {
|
||||
return v ? date2Thai(v) : "";
|
||||
},
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "gender",
|
||||
align: "left",
|
||||
label: "เพศ",
|
||||
sortable: true,
|
||||
field: "gender",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "relationship",
|
||||
align: "left",
|
||||
label: "สถานภาพ",
|
||||
sortable: true,
|
||||
field: "relationship",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "bloodGroup",
|
||||
align: "left",
|
||||
label: "หมู่เลือด",
|
||||
sortable: true,
|
||||
field: "bloodGroup",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "nationality",
|
||||
align: "left",
|
||||
label: "สัญชาติ",
|
||||
sortable: true,
|
||||
field: "nationality",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "ethnicity",
|
||||
align: "left",
|
||||
label: "เชื้อชาติ",
|
||||
sortable: true,
|
||||
field: "ethnicity",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "religion",
|
||||
align: "left",
|
||||
label: "ศาสนา",
|
||||
sortable: true,
|
||||
field: "religion",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "phone",
|
||||
align: "left",
|
||||
label: "เบอร์โทร",
|
||||
sortable: true,
|
||||
field: "phone",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "createdFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "createdFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "createdAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const visibleColumnsHistory = ref<String[]>([
|
||||
"citizenId",
|
||||
"prefix",
|
||||
"rank",
|
||||
"firstName",
|
||||
"lastName",
|
||||
"birthDate",
|
||||
"gender",
|
||||
"relationship",
|
||||
"bloodGroup",
|
||||
"nationality",
|
||||
"ethnicity",
|
||||
"religion",
|
||||
"phone",
|
||||
"createdFullName",
|
||||
"createdAt",
|
||||
]);
|
||||
|
||||
async function getData() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.registryNewByProfileId(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
informaData.value = res.data.result;
|
||||
id.value = res.data.result.id;
|
||||
|
||||
if (res.data.result.birthDate) {
|
||||
console.log("birthDate===>", res.data.result.birthDate);
|
||||
|
||||
age.value = calculateAge(res.data.result.birthDate);
|
||||
console.log("age===>", age.value);
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
const calculateMaxDate = () => {
|
||||
const today = new Date();
|
||||
today.setFullYear(today.getFullYear() - 18);
|
||||
return today;
|
||||
};
|
||||
|
||||
async function editData() {
|
||||
showLoader();
|
||||
await http
|
||||
.put(config.API.profileNewProfileById(id.value, empType.value), {
|
||||
...formData,
|
||||
employeeClass: route.name === "registry-employeeId" ? "TEMP" : undefined,
|
||||
})
|
||||
.then(() => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
getData(), (modal.value = false);
|
||||
props.fetchDataPersonal?.();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function onClickOpenDialog() {
|
||||
if (!informaData.value) return;
|
||||
modal.value = true;
|
||||
console.log("onClickOpenDialog birthDate===>", informaData.value.birthDate);
|
||||
|
||||
id.value = informaData.value.id;
|
||||
age.value = calculateAge(informaData.value.birthDate);
|
||||
formData.citizenId = informaData.value.citizenId;
|
||||
formData.prefix = informaData.value.prefix;
|
||||
formData.rank = informaData.value.rank;
|
||||
formData.firstName = informaData.value.firstName;
|
||||
formData.lastName = informaData.value.lastName;
|
||||
formData.birthDate = informaData.value.birthDate;
|
||||
formData.gender = informaData.value.gender;
|
||||
formData.relationship = informaData.value.relationship;
|
||||
formData.nationality = informaData.value.nationality;
|
||||
formData.ethnicity = informaData.value.ethnicity;
|
||||
formData.religion = informaData.value.religion;
|
||||
formData.bloodGroup = informaData.value.bloodGroup;
|
||||
formData.phone = informaData.value.phone;
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
editData();
|
||||
modal.value = false;
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
async function clickHistory() {
|
||||
modalHistory.value = true;
|
||||
await http
|
||||
.get(config.API.profileNewProfileHisById(id.value, empType.value))
|
||||
.then((res) => {
|
||||
rowsHistory.value = res.data.result;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function changeCardID(citizenId: string | number | null) {
|
||||
if (citizenId != null && typeof citizenId == "string") {
|
||||
if (citizenId.length == 13 && citizenId) {
|
||||
http
|
||||
.put(config.API.profileNewCitizenId(citizenId), {
|
||||
citizenId: citizenId,
|
||||
})
|
||||
.then(() => {})
|
||||
.catch((err) => {
|
||||
if (err.response.data.status === 500) {
|
||||
dialogMessageNotify($q, err.response.data.message);
|
||||
} else {
|
||||
messageError($q, err);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => formData.birthDate,
|
||||
(v) => {
|
||||
console.log("v===>", v);
|
||||
|
||||
if (v) {
|
||||
age.value = calculateAge(v);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await getData();
|
||||
|
||||
if (store.Ops && store.Ops.prefixOps && store.Ops.prefixOps.length === 0) {
|
||||
fetchPerson();
|
||||
}
|
||||
|
||||
// store.Ops.prefixOps.length === 0 ||
|
||||
// store.Ops.genderOps.length === 0 ||
|
||||
// store.Ops.bloodOps.length === 0 ||
|
||||
// store.Ops.statusOps.length === 0 ||
|
||||
// store.Ops.religionOps.length === 0
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row q-gutter-sm items-center">
|
||||
<div class="toptitle col text-right q-gutter-x-sm">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="mdi-pencil-outline"
|
||||
color="primary"
|
||||
@click="onClickOpenDialog"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
icon="mdi-history"
|
||||
color="info"
|
||||
@click="clickHistory"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขข้อมูลส่วนตัว</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-card bordered class="my-card bg-grey-1 q-pa-md">
|
||||
<div v-if="informaData" :class="$q.screen.gt.xs ? 'row' : 'column'">
|
||||
<!-- column 1 -->
|
||||
<div class="col-md-7 col-12 row">
|
||||
<div class="col-5 text-grey-6 text-weight-medium">
|
||||
<div
|
||||
v-for="label in Object.keys(dataLabel).slice(0, 6)"
|
||||
class="q-py-xs"
|
||||
>
|
||||
{{ dataLabel[label as keyof typeof dataLabel] }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- data -->
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.citizenId }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{
|
||||
`${
|
||||
informaData.rank ? informaData.rank : informaData.prefix ?? ""
|
||||
} ${informaData.firstName} ${informaData.lastName}`
|
||||
}}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.birthDate ? date2Thai(informaData.birthDate) : "" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ age ? age : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.gender ? informaData.gender : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.relationship ? informaData.relationship : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- column 2 -->
|
||||
<div class="col-md-5 col-12 row">
|
||||
<div class="col-5 col text-grey-6 text-weight-medium">
|
||||
<div
|
||||
v-for="label in Object.keys(dataLabel).slice(6, 11)"
|
||||
class="q-py-xs"
|
||||
>
|
||||
{{ dataLabel[label as keyof typeof dataLabel] }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- data -->
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.nationality ? informaData.nationality : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.ethnicity ? informaData.ethnicity : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.religion ? informaData.religion : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.bloodGroup ? informaData.bloodGroup : "-" }}
|
||||
</div>
|
||||
<div class="q-py-xs">
|
||||
{{ informaData.phone ? informaData.phone : "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card>
|
||||
|
||||
<!-- Edit Dialog -->
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
tittle="แก้ไขประวัติส่วนตัว"
|
||||
:close="() => (modal = false)"
|
||||
/>
|
||||
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
maxlength="13"
|
||||
mask="#############"
|
||||
v-model="formData.citizenId"
|
||||
class="inputgreen"
|
||||
:label="dataLabel.citizenId"
|
||||
:rules="[
|
||||
(val: string) => !!val || `${'กรุณากรอก เลขประจำตัวประชาชน'}`,
|
||||
(val: string) =>
|
||||
val.length >= 13 ||
|
||||
`${'กรุณากรอกเลขประจำตัวประชาชนให้ครบ'}`,
|
||||
]"
|
||||
@update:model-value="changeCardID"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
input-debounce="0"
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
v-model="formData.prefix"
|
||||
class="inputgreen"
|
||||
:options="store.Ops.prefixOps"
|
||||
:label="dataLabel.prefix"
|
||||
:rules="[(val: string) => !!val || `${'กรุณาเลือก คำนำหน้าชื่อ'}`]"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'prefixOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
clearable
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
input-debounce="0"
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
v-model="formData.rank"
|
||||
class="inputgreen"
|
||||
:options="store.Ops.rankOps"
|
||||
:label="dataLabel.rank"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'rankOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.firstName"
|
||||
class="inputgreen"
|
||||
:label="dataLabel.firstName"
|
||||
:rules="[(val: string) => !!val || `${'กรุณากรอก ชื่อ'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.lastName"
|
||||
class="inputgreen"
|
||||
:label="dataLabel.lastName"
|
||||
:rules="[(val: string) => !!val || `${'กรุณากรอก นามสกุล'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
autoApply
|
||||
:max-date="calculateMaxDate()"
|
||||
borderless
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
menu-class-name="modalfix"
|
||||
v-model="formData.birthDate"
|
||||
:locale="'th'"
|
||||
>
|
||||
<template #year="{ year }">
|
||||
{{ year + 543 }}
|
||||
</template>
|
||||
<template #year-overlay-value="{ value }">
|
||||
{{ parseInt(value + 543) }}
|
||||
</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
for="inputDatereceive"
|
||||
ref="dateReceivedRef"
|
||||
outlined
|
||||
dense
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
:model-value="
|
||||
formData.birthDate ? date2Thai(formData.birthDate) : null
|
||||
"
|
||||
:label="dataLabel.birthDate"
|
||||
:rules="[
|
||||
(val) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`,
|
||||
]"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon
|
||||
name="event"
|
||||
class="cursor-pointer"
|
||||
color="primary"
|
||||
>
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
</template>
|
||||
</datepicker>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
readonly
|
||||
v-model="age"
|
||||
:label="dataLabel.age"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
clearable
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
input-debounce="0"
|
||||
option-label="name"
|
||||
option-value="name"
|
||||
v-model="formData.gender"
|
||||
class="inputgreen"
|
||||
:options="store.Ops.genderOps"
|
||||
:label="dataLabel.gender"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'genderOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
clearable
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="name"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.relationship"
|
||||
:options="store.Ops.statusOps"
|
||||
:label="dataLabel.relationship"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'statusOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="formData.nationality"
|
||||
:label="dataLabel.nationality"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
class="inputgreen"
|
||||
v-model="formData.ethnicity"
|
||||
:label="dataLabel.ethnicity"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
clearable
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="name"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
v-model="formData.religion"
|
||||
class="inputgreen"
|
||||
:options="store.Ops.religionOps"
|
||||
:label="dataLabel.religion"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'religionOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
clearable
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="name"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
v-model="formData.bloodGroup"
|
||||
class="inputgreen"
|
||||
:options="store.Ops.bloodOps"
|
||||
:label="dataLabel.bloodGroup"
|
||||
@filter="(inputValue: any,
|
||||
doneFn: Function) => filterSelector(inputValue, doneFn, 'bloodOps'
|
||||
)"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
mask="##########"
|
||||
class="inputgreen"
|
||||
v-model="formData.phone"
|
||||
:label="dataLabel.phone"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn
|
||||
label="บันทึก"
|
||||
id="onSubmit"
|
||||
type="submit"
|
||||
color="public"
|
||||
class="q-px-md"
|
||||
>
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขข้อมูลส่วนตัว"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterHistory"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterHistory == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterHistory"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumnsHistory"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columnsHistory"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columnsHistory"
|
||||
:rows="rowsHistory"
|
||||
class="custom-header-table"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumnsHistory"
|
||||
:filter="filterHistory"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right"> </q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.modalfix {
|
||||
position: fixed !important;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,934 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, ref, reactive, watch } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
import { useQuasar } from "quasar";
|
||||
import type { QTableProps } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useAddressDataStore } from "@/modules/04_registryPerson/stores/Address";
|
||||
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/Address";
|
||||
import type { RequestObject } from "@/modules/04_registryPerson/interface/request/Address";
|
||||
|
||||
const $q = useQuasar();
|
||||
const store = useAddressDataStore();
|
||||
const mixin = useCounterMixin();
|
||||
const route = useRoute();
|
||||
const {
|
||||
fetchProvince,
|
||||
fetchDistrict,
|
||||
fetchSubDistrict,
|
||||
findData,
|
||||
filterSelector,
|
||||
} = store;
|
||||
const {
|
||||
date2Thai,
|
||||
success,
|
||||
messageError,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
dialogConfirm,
|
||||
} = mixin;
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const currentPage = ref<number>(1);
|
||||
const maxPage = ref<number>(1);
|
||||
const modal = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const rowsHistory = ref<ResponseObject[]>([]);
|
||||
const filterHistory = ref<string>("");
|
||||
|
||||
const id = ref<string>("");
|
||||
const rawSameAddress = ref<string>("0");
|
||||
const sameAddress = ref<string>("0");
|
||||
const addressData = reactive<ResponseObject>(store.defaultAddress);
|
||||
const formData = reactive<RequestObject>(store.defaultAddressForm);
|
||||
|
||||
const adsName = reactive({
|
||||
regisP: "",
|
||||
regisD: "",
|
||||
regisSD: "",
|
||||
|
||||
currentP: "",
|
||||
currentD: "",
|
||||
currentSD: "",
|
||||
});
|
||||
|
||||
const dataLabel = {
|
||||
registrationAddress: "ที่อยู่ตามทะเบียนบ้าน",
|
||||
registrationProvince: "จังหวัด",
|
||||
registrationDistrict: "เขต/อำเภอ",
|
||||
registrationSubDistrict: "แขวง / ตำบล",
|
||||
registrationZipCode: "รหัสไปรษณีย์",
|
||||
|
||||
currentAddress: "ที่อยู่ปัจจุบัน",
|
||||
currentProvince: "จังหวัด",
|
||||
currentDistrict: "เขต/อำเภอ",
|
||||
currentSubDistrict: "แขวง / ตำบล",
|
||||
currentZipCode: "รหัสไปรษณีย์",
|
||||
|
||||
registrationSame: "ที่อยู่ปัจจุบันตรงกับที่อยู่ตามทะเบียนบ้าน",
|
||||
};
|
||||
|
||||
const visibleColumnsHistory = ref<String[]>([
|
||||
"currentAddress",
|
||||
"currentDistrict",
|
||||
"currentSubDistrict",
|
||||
"currentZipCode",
|
||||
"registrationAddress",
|
||||
"registrationDistrict",
|
||||
"registrationProvince",
|
||||
"registrationSame",
|
||||
"registrationSubDistrict",
|
||||
"registrationZipCode",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
const columnsHistory = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "registrationAddress",
|
||||
align: "left",
|
||||
label: "ที่อยู่ตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: "registrationAddress",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "registrationProvince",
|
||||
align: "left",
|
||||
label: "จังหวัดตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: "registrationProvince",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "registrationDistrict",
|
||||
align: "left",
|
||||
label: "เขต/อำเภอตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: "registrationDistrict",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "registrationSubDistrict",
|
||||
align: "left",
|
||||
label: "แขวง/ตำบลตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: "registrationSubDistrict",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "registrationZipCode",
|
||||
align: "left",
|
||||
label: "รหัสไปรษณีย์ตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: "registrationZipCode",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "registrationSame",
|
||||
align: "left",
|
||||
label: "ที่อยู่ปัจจุบันตรงกับที่อยู่ตามทะเบียนบ้าน",
|
||||
sortable: true,
|
||||
field: (v) =>
|
||||
v.registrationAddress === v.currentAddress &&
|
||||
v.registrationZipCode === v.currentZipCode
|
||||
? "ใช่"
|
||||
: "ไม่",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "currentAddress",
|
||||
align: "left",
|
||||
label: "ที่อยู่ปัจจุบัน",
|
||||
sortable: true,
|
||||
field: "currentAddress",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "currentProvince",
|
||||
align: "left",
|
||||
label: "จังหวัดปัจจุบัน",
|
||||
sortable: true,
|
||||
field: "currentProvince",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "currentDistrict",
|
||||
align: "left",
|
||||
label: "เขต/อำเภอปัจจุบัน",
|
||||
sortable: true,
|
||||
field: "currentDistrict",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "currentSubDistrict",
|
||||
align: "left",
|
||||
label: "แขวง/ตำบลปัจจุบัน",
|
||||
sortable: true,
|
||||
field: "currentSubDistrict",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => (v ? v.name : "-"),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "currentZipCode",
|
||||
align: "left",
|
||||
label: "รหัสไปรษณีย์ปัจจุบัน",
|
||||
sortable: true,
|
||||
field: "currentZipCode",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
async function getData() {
|
||||
showLoader();
|
||||
await http
|
||||
.get(
|
||||
config.API.profileNewAddressByProfileId(profileId.value, empType.value)
|
||||
)
|
||||
.then((res) => {
|
||||
Object.assign(addressData, res.data.result);
|
||||
|
||||
if (addressData) {
|
||||
id.value = addressData.id;
|
||||
addressData.currentAddress === addressData.registrationAddress &&
|
||||
addressData.currentZipCode === addressData.registrationZipCode &&
|
||||
addressData.currentAddress &&
|
||||
addressData.registrationAddress &&
|
||||
addressData.currentZipCode &&
|
||||
addressData.registrationZipCode
|
||||
? (rawSameAddress.value = "1")
|
||||
: (rawSameAddress.value = "0");
|
||||
}
|
||||
sameAddress.value = rawSameAddress.value;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function selectProvince(e: string | null, name: string) {
|
||||
if (!e) return;
|
||||
if (name == "1") {
|
||||
formData.registrationDistrictId = "";
|
||||
formData.registrationSubDistrictId = "";
|
||||
formData.registrationZipCode = "";
|
||||
} else {
|
||||
formData.currentDistrictId = "";
|
||||
formData.currentSubDistrictId = "";
|
||||
formData.currentZipCode = "";
|
||||
}
|
||||
await fetchDistrict(e, name);
|
||||
}
|
||||
|
||||
async function selectDistrict(e: string | null, name: string) {
|
||||
if (!e) return;
|
||||
if (name == "1") {
|
||||
formData.registrationSubDistrictId = "";
|
||||
formData.registrationZipCode = "";
|
||||
} else {
|
||||
formData.currentSubDistrictId = "";
|
||||
formData.currentZipCode = "";
|
||||
}
|
||||
await fetchSubDistrict(e, name);
|
||||
}
|
||||
|
||||
function selectSubDistrict(e: string | null, name: string) {
|
||||
if (!e) return;
|
||||
if (name == "1") {
|
||||
const findcode = store.Ops.subdistrictOps.filter((r) => r.id == e);
|
||||
const namecode = findcode.length > 0 ? findcode[0].zipCode : "";
|
||||
formData.registrationZipCode = namecode;
|
||||
} else {
|
||||
const findcode = store.Ops.subdistrictCOps.filter((r) => r.id == e);
|
||||
const namecode = findcode.length > 0 ? findcode[0].zipCode : "";
|
||||
formData.currentZipCode = namecode;
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchAll() {
|
||||
await getData();
|
||||
if (!store.profileIdBefore) {
|
||||
store.profileIdBefore = profileId.value;
|
||||
}
|
||||
if (
|
||||
store.Ops.provinceOps.length === 0 ||
|
||||
store.Ops.districtOps.length === 0 ||
|
||||
store.Ops.districtCOps.length === 0 ||
|
||||
store.Ops.subdistrictOps.length === 0 ||
|
||||
store.Ops.subdistrictCOps.length === 0 ||
|
||||
store.profileIdBefore !== profileId.value
|
||||
) {
|
||||
await fetchProvince();
|
||||
await fetchDistrict(addressData.registrationProvinceId, "1");
|
||||
await fetchDistrict(addressData.currentProvinceId, "2");
|
||||
await fetchSubDistrict(addressData.registrationDistrictId, "1");
|
||||
await fetchSubDistrict(addressData.currentDistrictId, "2");
|
||||
store.profileIdBefore = profileId.value;
|
||||
}
|
||||
|
||||
adsName.regisP = findData(
|
||||
store.Ops.provinceOps,
|
||||
addressData.registrationProvinceId
|
||||
).name;
|
||||
adsName.regisD = findData(
|
||||
store.Ops.districtOps,
|
||||
addressData.registrationDistrictId
|
||||
).name;
|
||||
adsName.regisSD = findData(
|
||||
store.Ops.subdistrictOps,
|
||||
addressData.registrationSubDistrictId
|
||||
).name;
|
||||
|
||||
adsName.currentP = findData(
|
||||
store.Ops.provinceOps,
|
||||
addressData.currentProvinceId
|
||||
).name;
|
||||
adsName.currentD = findData(
|
||||
store.Ops.districtCOps,
|
||||
addressData.currentDistrictId
|
||||
).name;
|
||||
adsName.currentSD = findData(
|
||||
store.Ops.subdistrictCOps,
|
||||
addressData.currentSubDistrictId
|
||||
).name;
|
||||
}
|
||||
|
||||
async function editData() {
|
||||
showLoader();
|
||||
await http
|
||||
.patch(config.API.profileNewAddressById(id.value, empType.value), {
|
||||
...formData,
|
||||
id: undefined,
|
||||
})
|
||||
.then((res) => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
fetchAll();
|
||||
modal.value = false;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function clickClose() {
|
||||
Object.assign(formData, store.defaultAddressForm);
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
async function onClickOpenDialog() {
|
||||
if (!addressData) return;
|
||||
await Object.assign(formData, addressData);
|
||||
const checkDistrict = await store.Ops.districtOps.some(
|
||||
(e: any) => e.id === addressData.registrationDistrictId
|
||||
);
|
||||
const checkSubDistrict = await store.Ops.subdistrictOps.some(
|
||||
(e: any) => e.id === addressData.registrationSubDistrictId
|
||||
);
|
||||
const checkDistrictC = await store.Ops.districtCOps.some(
|
||||
(e: any) => e.id === addressData.currentDistrictId
|
||||
);
|
||||
const checkSubDistrictC = await store.Ops.subdistrictCOps.some(
|
||||
(e: any) => e.id === addressData.currentSubDistrictId
|
||||
);
|
||||
|
||||
modal.value = true;
|
||||
sameAddress.value = rawSameAddress.value;
|
||||
|
||||
if (!checkDistrict || !checkSubDistrict) {
|
||||
await fetchDistrict(addressData.registrationProvinceId, "1");
|
||||
await fetchSubDistrict(addressData.registrationDistrictId, "1");
|
||||
}
|
||||
if (!checkDistrictC || !checkSubDistrictC) {
|
||||
await fetchDistrict(addressData.currentProvinceId, "2");
|
||||
await fetchSubDistrict(addressData.currentDistrictId, "2");
|
||||
}
|
||||
}
|
||||
|
||||
async function clickHistory() {
|
||||
modalHistory.value = true;
|
||||
await http
|
||||
.get(config.API.profileNewAddressHisById(id.value, empType.value))
|
||||
.then((res) => {
|
||||
rowsHistory.value = res.data.result;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
if (sameAddress.value === "1") {
|
||||
formData.currentAddress = formData.registrationAddress;
|
||||
formData.currentProvinceId = formData.registrationProvinceId;
|
||||
formData.currentDistrictId = formData.registrationDistrictId;
|
||||
formData.currentSubDistrictId = formData.registrationSubDistrictId;
|
||||
formData.currentZipCode = formData.registrationZipCode;
|
||||
store.Ops.districtCOps = store.Ops.districtOps;
|
||||
store.Ops.subdistrictCOps = store.Ops.subdistrictOps;
|
||||
}
|
||||
editData();
|
||||
modal.value = false;
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
function sameAddressToggle(v: string) {
|
||||
if (v === "0") {
|
||||
formData.currentAddress = "";
|
||||
formData.currentProvinceId = "";
|
||||
formData.currentDistrictId = "";
|
||||
formData.currentSubDistrictId = "";
|
||||
formData.currentZipCode = "";
|
||||
store.Ops.districtCOps = [];
|
||||
store.Ops.subdistrictCOps = [];
|
||||
}
|
||||
}
|
||||
|
||||
watch(
|
||||
() => sameAddress.value,
|
||||
(v) => {
|
||||
sameAddressToggle(v);
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchAll();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row q-gutter-sm items-center">
|
||||
<div class="toptitle col text-right q-gutter-x-sm">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
dense
|
||||
icon="mdi-pencil-outline"
|
||||
color="primary"
|
||||
@click="onClickOpenDialog"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
dense
|
||||
flat
|
||||
round
|
||||
icon="mdi-history"
|
||||
color="info"
|
||||
@click="clickHistory"
|
||||
>
|
||||
<q-tooltip>ประวัติข้อมูลที่อยู่</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-12">
|
||||
<q-card bordered class="bg-grey-1 q-ma-sm">
|
||||
<q-card-section>
|
||||
<div class="text-bold">ที่อยู่ตามทะเบียนบ้าน</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div :class="$q.screen.gt.xs ? '' : 'column'">
|
||||
<!-- column 1 -->
|
||||
<div class="col-md-6 col-12 row">
|
||||
<div class="col-5 text-grey-6 text-weight-medium">ที่อยู่</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ addressData.registrationAddress || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">แขวง/ตำบล</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.regisSD || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">เขต/อำเภอ</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.regisD || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">จังหวัด</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.regisP || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">
|
||||
รหัสไปรษณีย์
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ addressData.registrationZipCode || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
<div class="col-md-6 col-12">
|
||||
<q-card bordered class="bg-grey-1 q-ma-sm">
|
||||
<q-card-section>
|
||||
<div class="text-bold">ที่อยู่ปัจจุบัน</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div :class="$q.screen.gt.xs ? '' : 'column'">
|
||||
<div class="col-md-6 col-12 row">
|
||||
<div class="col-5 text-grey-6 text-weight-medium">ที่อยู่</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ addressData.currentAddress || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">แขวง/ตำบล</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.currentSD || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">เขต/อำเภอ</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.currentD || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">จังหวัด</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ adsName.currentP || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-5 text-grey-6 text-weight-medium">
|
||||
รหัสไปรษณีย์
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="q-py-xs">
|
||||
{{ addressData.currentZipCode || "-" }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Edit Dialog -->
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card>
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader tittle="แก้ไขข้อมูลที่อยู่" :close="clickClose" />
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="col-12 q-pb-xs">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
type="textarea"
|
||||
class="inputgreen"
|
||||
v-model="formData.registrationAddress"
|
||||
:label="dataLabel.registrationAddress"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ตามทะเบียนบ้าน'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.registrationProvinceId"
|
||||
:options="store.Ops.provinceOps"
|
||||
:label="dataLabel.registrationProvince"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
|
||||
@update:model-value="(value:string) => selectProvince(value, '1')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.registrationDistrictId"
|
||||
:options="store.Ops.districtOps"
|
||||
:label="dataLabel.registrationDistrict"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
|
||||
@update:model-value="(value:string) => selectDistrict(value, '1')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'districtOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.registrationSubDistrictId"
|
||||
:options="store.Ops.subdistrictOps"
|
||||
:label="dataLabel.registrationSubDistrict"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
|
||||
@update:model-value="(value:string) => selectSubDistrict(value, '1')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
readonly
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.registrationZipCode"
|
||||
:label="dataLabel.registrationZipCode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- same address ? -->
|
||||
<div class="col-xs-12 q-gutter-sm items-center flex q-my-sm">
|
||||
<label class="text-medium"
|
||||
>ที่อยู่ปัจจุบันตรงกับที่อยู่ตามทะเบียนบ้าน</label
|
||||
>
|
||||
<q-radio
|
||||
dense
|
||||
val="1"
|
||||
label="ใช่"
|
||||
checked-icon="task_alt"
|
||||
class="inputgreen"
|
||||
v-model="sameAddress"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
/>
|
||||
<q-radio
|
||||
dense
|
||||
val="0"
|
||||
label="ไม่"
|
||||
checked-icon="task_alt"
|
||||
class="inputgreen"
|
||||
v-model="sameAddress"
|
||||
unchecked-icon="panorama_fish_eye"
|
||||
/>
|
||||
</div>
|
||||
<!-- current address -->
|
||||
<div v-if="sameAddress === '0'">
|
||||
<div class="col-12 q-pb-xs">
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
type="textarea"
|
||||
class="inputgreen"
|
||||
v-model="formData.currentAddress"
|
||||
:label="dataLabel.currentAddress"
|
||||
:rules="[(val:string) => !!val || `${'กรุณากรอก ที่อยู่ปัจจุบัน'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.currentProvinceId"
|
||||
:options="store.Ops.provinceOps"
|
||||
:label="dataLabel.currentProvince"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก จังหวัด'}`]"
|
||||
@update:model-value="(value:string) => selectProvince(value, '2')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'provinceOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.currentDistrictId"
|
||||
:options="store.Ops.districtCOps"
|
||||
:label="dataLabel.currentDistrict"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก เขต / อำเภอ'}`]"
|
||||
@update:model-value="(value:string) => selectDistrict(value, '2')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'districtCOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-select
|
||||
dense
|
||||
outlined
|
||||
use-input
|
||||
lazy-rules
|
||||
emit-value
|
||||
map-options
|
||||
hide-bottom-space
|
||||
option-value="id"
|
||||
option-label="name"
|
||||
input-debounce="0"
|
||||
class="inputgreen"
|
||||
v-model="formData.currentSubDistrictId"
|
||||
:options="store.Ops.subdistrictCOps"
|
||||
:label="dataLabel.currentSubDistrict"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือก แขวง / ตำบล'}`]"
|
||||
@update:model-value="(value:string) => selectSubDistrict(value, '2')"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterSelector(inputValue, doneFn,'subdistrictCOps'
|
||||
) "
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
dense
|
||||
readonly
|
||||
outlined
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
v-model="formData.currentZipCode"
|
||||
:label="dataLabel.registrationZipCode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="modalHistory" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
tittle="ประวัติแก้ไขข้อมูลที่อยู่"
|
||||
:close="() => (modalHistory = false)"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section style="max-height: 50vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="filterHistory"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="filterHistory == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="filterHistory"
|
||||
name="cancel"
|
||||
@click.stop.prevent="filterHistory = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-model="visibleColumnsHistory"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columnsHistory"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columnsHistory"
|
||||
:rows="rowsHistory"
|
||||
:paging="true"
|
||||
:rows-per-page-options="[10, 25, 50, 100]"
|
||||
:visible-columns="visibleColumnsHistory"
|
||||
:filter="filterHistory"
|
||||
>
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,670 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { QForm, useQuasar } from "quasar";
|
||||
import dialogHeader from "@/components/DialogHeader.vue";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import type { RequestItemsObject } from "@/modules/04_registryPerson/interface/request/SpecialSkill";
|
||||
import type { ResponseObject } from "@/modules/04_registryPerson/interface/response/SpecialSkill";
|
||||
import type { QTableProps } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
const mixin = useCounterMixin();
|
||||
const $q = useQuasar();
|
||||
const mode = ref<string>("table");
|
||||
const {
|
||||
dialogRemove,
|
||||
dialogConfirm,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
success,
|
||||
date2Thai,
|
||||
} = mixin;
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "field",
|
||||
align: "left",
|
||||
label: "ด้าน",
|
||||
sortable: true,
|
||||
field: "field",
|
||||
headerStyle: "font-size: 14px; width: 50px;",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "remark",
|
||||
align: "left",
|
||||
label: "หมายเหตุ",
|
||||
sortable: true,
|
||||
field: "remark",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const historyColumns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "field",
|
||||
align: "left",
|
||||
label: "ด้าน",
|
||||
sortable: true,
|
||||
field: "field",
|
||||
headerStyle: "font-size: 14px; width: 50px;",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "remark",
|
||||
align: "left",
|
||||
label: "หมายเหตุ",
|
||||
sortable: true,
|
||||
field: "remark",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
format: (v) => date2Thai(v),
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
|
||||
const historyDialog = ref<boolean>(false);
|
||||
const dialog = ref<boolean>(false);
|
||||
const dialogStatus = ref<string>("create");
|
||||
const rows = ref<ResponseObject[]>([]);
|
||||
const historyRows = ref<ResponseObject[]>([]);
|
||||
const route = useRoute();
|
||||
const id = ref<string>(route.params.id.toString());
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
const editId = ref<string>("");
|
||||
const keyword = ref<string>("");
|
||||
const historyKeyword = ref<string>("");
|
||||
|
||||
const specialSkill = reactive<RequestItemsObject>({
|
||||
field: "",
|
||||
detail: "",
|
||||
remark: "",
|
||||
reference: "",
|
||||
profileId: id.value,
|
||||
dateStart: null,
|
||||
dateEnd: null,
|
||||
});
|
||||
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const historyPagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const visibleColumns = ref<string[]>([
|
||||
"field",
|
||||
"detail",
|
||||
"remark",
|
||||
"reference",
|
||||
]);
|
||||
|
||||
const historyVisibleColumns = ref<string[]>([
|
||||
"field",
|
||||
"detail",
|
||||
"remark",
|
||||
"reference",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
function closeDialog() {
|
||||
dialog.value = false;
|
||||
}
|
||||
|
||||
function closeHistoryDialog() {
|
||||
historyDialog.value = false;
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
dialogConfirm(
|
||||
$q,
|
||||
async () => {
|
||||
dialogStatus.value === "create" ? addData() : editData(editId.value);
|
||||
closeDialog();
|
||||
},
|
||||
"ยืนยันการบันทึกข้อมูล",
|
||||
"ต้องการยืนยันการบันทึกข้อมูลนี้หรือไม่ ?"
|
||||
);
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
specialSkill.detail = "";
|
||||
specialSkill.field = "";
|
||||
specialSkill.reference = "";
|
||||
specialSkill.remark = "";
|
||||
}
|
||||
|
||||
function editForm(row: any) {
|
||||
dialogStatus.value = "edit";
|
||||
editId.value = row.id;
|
||||
specialSkill.detail = row.detail;
|
||||
specialSkill.field = row.field;
|
||||
specialSkill.reference = row.reference;
|
||||
specialSkill.remark = row.remark;
|
||||
dialog.value = true;
|
||||
}
|
||||
|
||||
async function fetchData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewAbilityByProfileId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function fetchHistoryData(id: string) {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewAbilityHisByAbilityId(id, empType.value))
|
||||
.then(async (res) => {
|
||||
historyRows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function addData() {
|
||||
await http
|
||||
.post(config.API.profileNewAbility(empType.value), {
|
||||
...specialSkill,
|
||||
dateStart: null,
|
||||
dateEnd: null,
|
||||
profileId: empType.value === "" ? id.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? id.value : undefined,
|
||||
})
|
||||
.then(() => {
|
||||
fetchData(id.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function editData(idData: string) {
|
||||
await http
|
||||
.patch(config.API.profileNewAbilityByAbilityId(idData, empType.value), {
|
||||
...specialSkill,
|
||||
dateStart: null,
|
||||
dateEnd: null,
|
||||
profileId: undefined,
|
||||
})
|
||||
.then(() => {
|
||||
fetchData(id.value);
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function deleteData(idData: string) {
|
||||
dialogRemove($q, () =>
|
||||
http
|
||||
.delete(config.API.profileNewAbilityByAbilityId(idData, empType.value))
|
||||
.then(() => {
|
||||
fetchData(id.value);
|
||||
success($q, "ลบข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
await fetchData(id.value);
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
dense
|
||||
icon="add"
|
||||
@click="() => ((dialogStatus = 'create'), clearForm(), (dialog = true))"
|
||||
>
|
||||
<q-tooltip>เพิ่มข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-space />
|
||||
<q-input dense outlined v-model="keyword" label="ค้นหา">
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
v-if="mode === 'table'"
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="mode"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: mode === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
:grid="mode === 'card'"
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:filter="keyword"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
<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" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
color="primary"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
icon="mdi-pencil-outline"
|
||||
clickable
|
||||
@click="
|
||||
() => {
|
||||
editForm(props.row);
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click="
|
||||
fetchHistoryData(props.row.id);
|
||||
historyDialog = true;
|
||||
"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขความสามารถพิเศษ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>{{ col.value ? col.value : "-" }}</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div
|
||||
class="q-pa-xs col-xs-12 col-sm-6 col-md-6 col-lg-6 grid-style-transition"
|
||||
>
|
||||
<q-card bordered>
|
||||
<q-card-actions align="right" class="bg-grey-3">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
size="14px"
|
||||
@click="
|
||||
() => {
|
||||
editForm(props.row);
|
||||
}
|
||||
"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
class="no-shadow toggle-borderd"
|
||||
round
|
||||
size="14px"
|
||||
color="info"
|
||||
icon="mdi-history"
|
||||
@click="
|
||||
fetchHistoryData(props.row.id);
|
||||
historyDialog = true;
|
||||
"
|
||||
>
|
||||
<q-tooltip>ประวัติแก้ไขความสามารถพิเศษ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<q-separator />
|
||||
<div class="row">
|
||||
<div class="col q-pa-sm label-color">ด้าน</div>
|
||||
<div class="col q-pa-sm">{{ props.cols[0].value }}</div>
|
||||
<div class="col q-pa-sm label-color">รายละเอียด</div>
|
||||
<div class="col q-pa-sm">{{ props.cols[1].value }}</div>
|
||||
</div>
|
||||
<div :class="`row bg-color`">
|
||||
<div class="col q-pa-sm label-color">หมายเหตุ</div>
|
||||
<div class="col q-pa-sm">{{ props.cols[2].value }}</div>
|
||||
<div class="col q-pa-sm label-color">เอกสารอ้างอิง</div>
|
||||
<div class="col q-pa-sm">{{ props.cols[3].value }}</div>
|
||||
</div>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="dialog" class="dialog" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit()">
|
||||
<dialog-header
|
||||
:tittle="
|
||||
dialogStatus == 'edit'
|
||||
? 'แก้ไขข้อมูลความสามารถพิเศษ'
|
||||
: 'เพิ่มข้อมูลความสามารถพิเศษ'
|
||||
"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-x-xs q-col-gutter-y-xs">
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
class="inputgreen"
|
||||
dense
|
||||
bg-color="white"
|
||||
v-model="specialSkill.field"
|
||||
label="ด้าน"
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกด้านความสามารถพิเศษ'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
class="inputgreen"
|
||||
bg-color="white"
|
||||
v-model="specialSkill.detail"
|
||||
label="รายละเอียด"
|
||||
hide-bottom-space
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-12">
|
||||
<q-input
|
||||
class="inputgreen"
|
||||
outlined
|
||||
dense
|
||||
bg-color="white"
|
||||
v-model="specialSkill.remark"
|
||||
label="หมายเหตุ"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-12">
|
||||
<q-input
|
||||
class="inputgreen"
|
||||
outlined
|
||||
dense
|
||||
bg-color="white"
|
||||
v-model="specialSkill.reference"
|
||||
label="เอกสารอ้างอิง"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<q-dialog v-model="historyDialog" class="dialog" persistent>
|
||||
<q-layout
|
||||
view="lHh lpr lFf"
|
||||
container
|
||||
style="height: 500px; min-width: 80%"
|
||||
class="bg-white"
|
||||
>
|
||||
<q-header>
|
||||
<q-toolbar>
|
||||
<dialog-header
|
||||
tittle="ประวัติแก้ไขความสามารถพิเศษ"
|
||||
:close="closeHistoryDialog"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<q-separator color="grey-4" />
|
||||
</q-header>
|
||||
|
||||
<q-page-container>
|
||||
<q-page class="q-pa-md">
|
||||
<q-toolbar style="padding: 0px" class="text-primary q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
bg-color="white"
|
||||
v-model="historyKeyword"
|
||||
label="ค้นหา"
|
||||
class="q-mr-sm"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-select
|
||||
v-model="historyVisibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
bg-color="white"
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="historyColumns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</q-toolbar>
|
||||
<d-table
|
||||
ref="table"
|
||||
:columns="historyColumns"
|
||||
:rows="historyRows"
|
||||
row-key="name"
|
||||
flat
|
||||
bordered
|
||||
:paging="true"
|
||||
dense
|
||||
:filter="historyKeyword"
|
||||
v-model:pagination="historyPagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
class="custom-header-table"
|
||||
:visible-columns="historyVisibleColumns"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<q-th v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<span class="text-weight-medium">{{ col.label }}</span>
|
||||
</q-th>
|
||||
<q-th auto-width />
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:body="props" v-if="mode === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>{{ col.value ? col.value : "-" }}</div>
|
||||
</q-td>
|
||||
<q-td auto-width> </q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-page>
|
||||
</q-page-container>
|
||||
</q-layout>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.label-color {
|
||||
color: #747474cc;
|
||||
}
|
||||
|
||||
.bg-color {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
/** importComponents*/
|
||||
import Profile from "@/modules/04_registryPerson/components/detail/PersonalInformation/01_Profile.vue";
|
||||
import NameChangeHistory from "@/modules/04_registryPerson/components/detail/PersonalInformation/02_NameChangeHistory.vue";
|
||||
import Address from "@/modules/04_registryPerson/components/detail/PersonalInformation/03_Address.vue";
|
||||
import Family from "@/modules/04_registryPerson/components/detail/PersonalInformation/04_Family.vue";
|
||||
import Education from "@/modules/04_registryPerson/components/detail/PersonalInformation/05_Education.vue";
|
||||
import SpecialSkill from "@/modules/04_registryPerson/components/detail/PersonalInformation/06_SpecialSkill.vue";
|
||||
|
||||
import FamilyNew from "@/modules/04_registryPerson/components/detail/PersonalInformation/04_FamilyNew.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
const props = defineProps({
|
||||
fetchDataPersonal: { type: Function, require: true },
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">ข้อมูลส่วนตัว</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-card>
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ประวัติส่วนตัว" />
|
||||
<q-tab name="2" label="ประวัติการเปลี่ยนชื่อ-นามสกุล" />
|
||||
<q-tab name="3" label="ข้อมูลที่อยู่" />
|
||||
<q-tab name="4" label="ข้อมูลครอบครัว" />
|
||||
<q-tab name="5" label="ประวัติการศึกษา" />
|
||||
<q-tab name="6" label="ความสามารถพิเศษ" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<Profile :fetchDataPersonal="props.fetchDataPersonal" />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<NameChangeHistory :fetchDataPersonal="props.fetchDataPersonal" />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="3">
|
||||
<Address />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="4">
|
||||
<FamilyNew />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="5">
|
||||
<Education />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="6">
|
||||
<SpecialSkill />
|
||||
</q-tab-panel>
|
||||
<!-- <q-tab-panel name="7">
|
||||
<FamilyNew />
|
||||
</q-tab-panel> -->
|
||||
</q-tab-panels>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,348 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import type { QTableProps } from "quasar";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const {
|
||||
date2Thai,
|
||||
dialogConfirm,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
success,
|
||||
} = useCounterMixin();
|
||||
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const salaryId = defineModel<string>("salaryId", { required: true });
|
||||
|
||||
const baseColumns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
{
|
||||
name: "amount",
|
||||
align: "left",
|
||||
label: empType.value === "-employee" ? "ค่าตอบแทนรายเดือน" : "เงินเดือน",
|
||||
sortable: true,
|
||||
field: "amount",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => Number(v).toLocaleString(),
|
||||
},
|
||||
{
|
||||
name: "positionSalaryAmount",
|
||||
align: "left",
|
||||
label: "เงินประจำตำแหน่ง",
|
||||
sortable: true,
|
||||
field: "positionSalaryAmount",
|
||||
headerStyle: "font-size: 14px",
|
||||
format: (v) => Number(v).toLocaleString(),
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "mouthSalaryAmount",
|
||||
align: "left",
|
||||
label: "เงินค่าตอบแทนรายเดือน",
|
||||
sortable: true,
|
||||
field: "mouthSalaryAmount",
|
||||
headerStyle: "font-size: 14px",
|
||||
format: (v) => Number(v).toLocaleString(),
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "oc",
|
||||
align: "left",
|
||||
label: "สังกัด",
|
||||
sortable: true,
|
||||
field: "oc",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "position",
|
||||
align: "left",
|
||||
label: "ตำแหน่ง",
|
||||
sortable: true,
|
||||
field: "position",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "posNo",
|
||||
align: "left",
|
||||
label: "ตำแหน่งเลขที่",
|
||||
sortable: true,
|
||||
field: "posNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionLine",
|
||||
align: "left",
|
||||
label: "สายงาน",
|
||||
sortable: true,
|
||||
field: "positionLine",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionPathSide",
|
||||
align: "left",
|
||||
label: "ด้าน/สาขา",
|
||||
sortable: true,
|
||||
field: "positionPathSide",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionType",
|
||||
align: "left",
|
||||
label: "ตำแหน่งประเภท",
|
||||
sortable: true,
|
||||
field: "positionType",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionLevel",
|
||||
align: "left",
|
||||
label: "ระดับ",
|
||||
sortable: true,
|
||||
field: "positionLevel",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionExecutive",
|
||||
align: "left",
|
||||
label: "ตำแหน่งทางการบริหาร",
|
||||
sortable: true,
|
||||
field: "positionExecutive",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "positionExecutiveSide",
|
||||
align: "left",
|
||||
label: "ด้านทางการบริหาร",
|
||||
sortable: true,
|
||||
field: "positionExecutiveSide",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "salaryClass",
|
||||
align: "left",
|
||||
label: "ตำแหน่ง (รายละเอียด)",
|
||||
sortable: true,
|
||||
field: "salaryClass",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "templateDoc",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "templateDoc",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
},
|
||||
]);
|
||||
const visibleColumns = ref<string[]>([
|
||||
"date",
|
||||
"amount",
|
||||
"positionSalaryAmount",
|
||||
"mouthSalaryAmount",
|
||||
"oc",
|
||||
"position",
|
||||
"posNo",
|
||||
"positionLine",
|
||||
"positionPathSide",
|
||||
"positionType",
|
||||
"positionLevel",
|
||||
"positionExecutive",
|
||||
"positionExecutiveSide",
|
||||
"salaryClass",
|
||||
"templateDoc",
|
||||
"refCommandNo",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
|
||||
const columns = computed(() => {
|
||||
if (empType.value === "-employee") {
|
||||
if (baseColumns.value) {
|
||||
return baseColumns.value.filter(
|
||||
(column) =>
|
||||
column.name !== "positionSalaryAmount" &&
|
||||
column.name !== "mouthSalaryAmount"
|
||||
);
|
||||
}
|
||||
}
|
||||
return baseColumns.value;
|
||||
});
|
||||
const rows = ref<any[]>([]);
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
const keyword = ref<string>("");
|
||||
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
function fetchListHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileListSalaryHistoryNew(salaryId.value, empType.value))
|
||||
.then((res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => modal.value,
|
||||
() => {
|
||||
modal.value && fetchListHistory();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
:tittle="'ประวัติแก้ไขตำแหน่ง/เงินเดือน'"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
v-model="keyword"
|
||||
label="ค้นหา"
|
||||
class="q-mr-sm"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon v-if="keyword === ''" name="search" />
|
||||
<q-icon
|
||||
v-else
|
||||
name="clear"
|
||||
class="cursor-pointer"
|
||||
@click="keyword = ''"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:filter="keyword"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[10, 20, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols">
|
||||
<div class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,581 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useRoute } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
import DialogHisotory from "@/modules/04_registryPerson/components/detail/Salary/02_NotReceiveSalaryHistory.vue";
|
||||
|
||||
import type { QTableProps } from "quasar";
|
||||
import type { RowList } from "@/modules/04_registryPerson/interface/index/salary";
|
||||
import type { RequestNoPaidObject } from "@/modules/04_registryPerson/interface/request/Salary";
|
||||
|
||||
const $q = useQuasar();
|
||||
const route = useRoute();
|
||||
const {
|
||||
date2Thai,
|
||||
dialogConfirm,
|
||||
showLoader,
|
||||
hideLoader,
|
||||
messageError,
|
||||
success,
|
||||
dialogRemove,
|
||||
} = useCounterMixin();
|
||||
const id = ref<string>("");
|
||||
const profileId = ref<string>(
|
||||
route.params.id ? route.params.id.toString() : ""
|
||||
);
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const modelView = ref<string>("table");
|
||||
const modalDialog = ref<boolean>(false);
|
||||
const modalHistory = ref<boolean>(false);
|
||||
const isStatusEdit = ref<boolean>(false);
|
||||
const rows = ref<RowList[]>([]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
const visibleColumns = ref<string[]>([
|
||||
"date",
|
||||
"detail",
|
||||
"reference",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
]);
|
||||
const formData = reactive<RequestNoPaidObject>({
|
||||
date: null,
|
||||
reference: "",
|
||||
detail: "",
|
||||
refCommandNo: "",
|
||||
refCommandDate: null,
|
||||
});
|
||||
const formFilter = reactive({
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
keyword: "",
|
||||
});
|
||||
const maxPage = ref<number>(1);
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm($q, () => {
|
||||
isStatusEdit.value ? editData() : saveData();
|
||||
onClickCloseDialog();
|
||||
});
|
||||
}
|
||||
|
||||
function onClickOpenDialog(StatusEdit: boolean = false, data: any = []) {
|
||||
isStatusEdit.value = StatusEdit;
|
||||
id.value = StatusEdit ? data.id : "";
|
||||
formData.date = StatusEdit ? data.date : null;
|
||||
formData.reference = StatusEdit ? data.reference : "";
|
||||
formData.detail = StatusEdit ? data.detail : "";
|
||||
formData.refCommandNo = StatusEdit ? data.refCommandNo : "";
|
||||
formData.refCommandDate = StatusEdit ? data.refCommandDate : null;
|
||||
modalDialog.value = true;
|
||||
}
|
||||
|
||||
function onClickCloseDialog() {
|
||||
modalDialog.value = false;
|
||||
isStatusEdit.value = false;
|
||||
}
|
||||
|
||||
async function getData() {
|
||||
showLoader();
|
||||
await http
|
||||
.get(config.API.profileNewNoPaidByProfileId(profileId.value, empType.value))
|
||||
.then((res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function saveData() {
|
||||
showLoader();
|
||||
await http
|
||||
.post(config.API.profileNewNoPaid(empType.value), {
|
||||
...formData,
|
||||
profileId: empType.value === "" ? profileId.value : undefined,
|
||||
profileEmployeeId: empType.value !== "" ? profileId.value : undefined,
|
||||
})
|
||||
.then((res) => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
getData();
|
||||
onClickCloseDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
async function editData() {
|
||||
showLoader();
|
||||
await http
|
||||
.patch(config.API.profileNewNoPaidById(id.value, empType.value), {
|
||||
...formData,
|
||||
profileId: undefined,
|
||||
})
|
||||
.then((res) => {
|
||||
success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
getData();
|
||||
onClickCloseDialog();
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
// async function deleteData(id: string) {
|
||||
// showLoader();
|
||||
// await http
|
||||
// .delete(config.API.profileNewNoPaidById(id))
|
||||
// .then((res) => {
|
||||
// success($q, "ลบข้อมูลสำเร็จ");
|
||||
// getData();
|
||||
// })
|
||||
// .catch((e) => {
|
||||
// messageError($q, e);
|
||||
// })
|
||||
// .finally(() => {
|
||||
// hideLoader();
|
||||
// });
|
||||
// }
|
||||
|
||||
function onClickHistory(rowId: string) {
|
||||
id.value = rowId;
|
||||
modalHistory.value = true;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getData();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-gutter-x-sm q-pb-sm">
|
||||
<q-btn
|
||||
dense
|
||||
color="teal-5"
|
||||
icon="add"
|
||||
flat
|
||||
round
|
||||
@click="onClickOpenDialog()"
|
||||
><q-tooltip>เพิ่มข้อมูล</q-tooltip></q-btn
|
||||
>
|
||||
|
||||
<q-space />
|
||||
<q-input
|
||||
standout
|
||||
dense
|
||||
v-model="formFilter.keyword"
|
||||
ref="filterRef"
|
||||
outlined
|
||||
placeholder="ค้นหา"
|
||||
debounce="300"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon
|
||||
v-if="formFilter.keyword == ''"
|
||||
name="search"
|
||||
@click.stop.prevent="formFilter.keyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
<q-icon
|
||||
v-if="formFilter.keyword"
|
||||
name="cancel"
|
||||
@click.stop.prevent="formFilter.keyword = ''"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-select
|
||||
v-if="modelView == 'table'"
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
<q-btn-toggle
|
||||
v-model="modelView"
|
||||
dense
|
||||
class="no-shadow toggle-borderd"
|
||||
toggle-color="grey-4"
|
||||
:options="[
|
||||
{ value: 'table', slot: 'table' },
|
||||
{ value: 'card', slot: 'card' },
|
||||
]"
|
||||
>
|
||||
<template v-slot:table>
|
||||
<q-icon
|
||||
name="format_list_bulleted"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modelView === 'table' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template v-slot:card>
|
||||
<q-icon
|
||||
name="mdi-view-grid-outline"
|
||||
size="24px"
|
||||
:style="{
|
||||
color: modelView === 'card' ? '#787B7C' : '#C9D3DB',
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
</div>
|
||||
|
||||
<d-table
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
:filter="formFilter.keyword"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
:grid="modelView === 'card'"
|
||||
>
|
||||
<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" v-if="modelView === 'table'">
|
||||
<q-tr :props="props" class="cursor-pointer">
|
||||
<q-td auto-width>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
class="q-mr-xs"
|
||||
size="14px"
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก้ไขข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
color="info"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
icon="mdi-history"
|
||||
@click.stop.prevent="onClickHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติบันทึกวันที่ไม่ได้รับเงินเดือนฯ</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- <q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
size="14px"
|
||||
color="red"
|
||||
icon="mdi-delete"
|
||||
@click="
|
||||
dialogRemove($q, async () => await deleteData(props.row.id))
|
||||
"
|
||||
>
|
||||
<q-tooltip>ลบข้อมูล</q-tooltip>
|
||||
</q-btn> -->
|
||||
</q-td>
|
||||
<q-td v-for="col in props.cols" :key="col.id">
|
||||
<div>{{ col.value ? col.value : "-" }}</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
<template v-slot:item="props" v-else>
|
||||
<div
|
||||
class="q-pa-xs col-xs-12 col-sm-6 col-md-6 col-lg-3 grid-style-transition"
|
||||
>
|
||||
<q-card bordered>
|
||||
<q-card-actions class="bg-grey-3" align="right">
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="primary"
|
||||
icon="mdi-pencil-outline"
|
||||
@click="onClickOpenDialog(true, props.row)"
|
||||
>
|
||||
<q-tooltip>แก่ไขข้อมุล</q-tooltip>
|
||||
</q-btn>
|
||||
<q-btn
|
||||
flat
|
||||
round
|
||||
color="info"
|
||||
icon="history"
|
||||
@click="onClickHistory(props.row.id)"
|
||||
>
|
||||
<q-tooltip>ประวัติบันทึกวันที่ไม่ได้รับเงินเดือนฯ</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
<q-separator />
|
||||
<q-list>
|
||||
<q-item
|
||||
v-for="(col, index) in props.cols.filter(
|
||||
(col) => col.name !== 'desc'
|
||||
)"
|
||||
:key="col.name"
|
||||
:class="index % 2 !== 0 ? 'bg-grey-1' : ''"
|
||||
>
|
||||
<q-item-section class="text-grey-6">
|
||||
<q-item-label>{{ col.label }}</q-item-label>
|
||||
</q-item-section>
|
||||
<q-item-section class="text-dark">
|
||||
<q-item-label>{{ col.value ? col.value : "-" }}</q-item-label>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-card>
|
||||
</div>
|
||||
</template>
|
||||
</d-table>
|
||||
|
||||
<q-dialog v-model="modalDialog" persistent>
|
||||
<q-card>
|
||||
<q-form @submit.prevent greedy @validation-success="onSubmit">
|
||||
<DialogHeader
|
||||
:tittle="
|
||||
isStatusEdit
|
||||
? 'แก้ไขบันทึกวันที่ไม่ได้รับเงินเดือนฯ'
|
||||
: 'เพิ่มบันทึกวันที่ไม่ได้รับเงินเดือนฯ'
|
||||
"
|
||||
:close="onClickCloseDialog"
|
||||
/>
|
||||
<q-separator />
|
||||
|
||||
<q-card-section>
|
||||
<div class="row col-12 q-col-gutter-sm">
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="formData.date"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
ref="dateRef"
|
||||
outlined
|
||||
dense
|
||||
borderless
|
||||
class="inputgreen"
|
||||
:model-value="date2Thai(formData.date)"
|
||||
:rules="[(val) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'วัน/เดือน/ปี'}`"
|
||||
>
|
||||
<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-6 col-md-6">
|
||||
<q-input
|
||||
ref="referenceRef"
|
||||
outlined
|
||||
dense
|
||||
autogrow
|
||||
lazy-rules
|
||||
borderless
|
||||
v-model="formData.reference"
|
||||
class="inputgreen"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกเอกสารอ้างอิง'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'เอกสารอ้างอิง'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<q-input
|
||||
ref="detailRef"
|
||||
outlined
|
||||
dense
|
||||
autogrow
|
||||
lazy-rules
|
||||
borderless
|
||||
v-model="formData.detail"
|
||||
class="inputgreen"
|
||||
:rules="[(val) => !!val || `${'กรุณากรอกรายละเอียด'}`]"
|
||||
hide-bottom-space
|
||||
:label="`${'รายละเอียด'}`"
|
||||
/>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<q-input
|
||||
outlined
|
||||
dense
|
||||
lazy-rules
|
||||
borderless
|
||||
v-model="formData.refCommandNo"
|
||||
class="inputgreen"
|
||||
hide-bottom-space
|
||||
:label="`${'เลขที่คำสั่ง'}`"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="mdi-file" class="cursor-pointer" />
|
||||
</template>
|
||||
</q-input>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6 col-md-6">
|
||||
<datepicker
|
||||
menu-class-name="modalfix"
|
||||
v-model="formData.refCommandDate"
|
||||
:locale="'th'"
|
||||
autoApply
|
||||
:enableTimePicker="false"
|
||||
week-start="0"
|
||||
>
|
||||
<template #year="{ year }">{{ year + 543 }}</template>
|
||||
<template #year-overlay-value="{ value }">{{
|
||||
parseInt(value + 543)
|
||||
}}</template>
|
||||
<template #trigger>
|
||||
<q-input
|
||||
clearable
|
||||
outlined
|
||||
dense
|
||||
borderless
|
||||
class="inputgreen"
|
||||
:model-value="
|
||||
formData.refCommandDate == null ? null : date2Thai(formData.refCommandDate as Date)
|
||||
"
|
||||
hide-bottom-space
|
||||
:label="`${'เอกสารอ้างอิง (ลงวันที่)'}`"
|
||||
@clear="formData.refCommandDate = null"
|
||||
>
|
||||
<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>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right">
|
||||
<q-btn label="บันทึก" id="onSubmit" type="submit" color="public">
|
||||
<q-tooltip>บันทึกข้อมูล</q-tooltip>
|
||||
</q-btn>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
|
||||
<DialogHisotory v-model:modal="modalHistory" v-model:id="id" />
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
import { useRoute } from "vue-router";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type { QTableProps } from "quasar";
|
||||
import type { RowList } from "@/modules/04_registryPerson/interface/index/salary";
|
||||
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
const route = useRoute();
|
||||
const $q = useQuasar();
|
||||
const mixin = useCounterMixin();
|
||||
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
|
||||
|
||||
const empType = ref<string>(
|
||||
route.name === "registryNewByid" ? "" : "-employee"
|
||||
);
|
||||
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const id = defineModel<string>("id", { required: true });
|
||||
const filter = ref<string>("");
|
||||
const rows = ref<RowList[]>([]);
|
||||
const columns = ref<QTableProps["columns"]>([
|
||||
{
|
||||
name: "date",
|
||||
align: "left",
|
||||
label: "วัน เดือน ปี",
|
||||
sortable: true,
|
||||
field: "date",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "reference",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง",
|
||||
sortable: true,
|
||||
field: "reference",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "detail",
|
||||
align: "left",
|
||||
label: "รายละเอียด",
|
||||
sortable: true,
|
||||
field: "detail",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandNo",
|
||||
align: "left",
|
||||
label: "เลขที่คำสั่ง",
|
||||
sortable: true,
|
||||
field: "refCommandNo",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "refCommandDate",
|
||||
align: "left",
|
||||
label: "เอกสารอ้างอิง (ลงวันที่)",
|
||||
sortable: true,
|
||||
field: "refCommandDate",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdateFullName",
|
||||
align: "left",
|
||||
label: "ผู้ดำเนินการ",
|
||||
sortable: true,
|
||||
field: "lastUpdateFullName",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
{
|
||||
name: "lastUpdatedAt",
|
||||
align: "left",
|
||||
label: "วันที่แก้ไข",
|
||||
sortable: true,
|
||||
field: "lastUpdatedAt",
|
||||
headerStyle: "font-size: 14px",
|
||||
style: "font-size: 14px",
|
||||
format: (v) => date2Thai(v),
|
||||
sort: (a: string, b: string) =>
|
||||
a.localeCompare(b, undefined, { numeric: true, sensitivity: "base" }),
|
||||
},
|
||||
]);
|
||||
const visibleColumns = ref<string[]>([
|
||||
"date",
|
||||
"reference",
|
||||
"detail",
|
||||
"refCommandNo",
|
||||
"refCommandDate",
|
||||
"lastUpdateFullName",
|
||||
"lastUpdatedAt",
|
||||
]);
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
});
|
||||
|
||||
function getHistory() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.profileNewNoPaidHisById(id.value, empType.value))
|
||||
.then((res) => {
|
||||
rows.value = res.data.result;
|
||||
})
|
||||
.catch((e) => {
|
||||
messageError($q, e);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
}
|
||||
|
||||
watch(modal, (status) => {
|
||||
if (status == true) {
|
||||
getHistory();
|
||||
filter.value = "";
|
||||
} else {
|
||||
filter.value = "";
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent full-width>
|
||||
<q-card style="min-width: 80%">
|
||||
<DialogHeader
|
||||
:tittle="'ประวัติแก้ไขบันทึกวันที่ไม่ได้รับเงินเดือนฯ'"
|
||||
:close="closeDialog"
|
||||
/>
|
||||
<q-separator color="grey-4" />
|
||||
|
||||
<q-card-section style="max-height: 60vh" class="scroll">
|
||||
<div class="row q-gutter-sm q-mb-sm">
|
||||
<q-space />
|
||||
<q-input
|
||||
dense
|
||||
outlined
|
||||
v-model="filter"
|
||||
label="ค้นหา"
|
||||
class="q-mr-sm"
|
||||
>
|
||||
<template v-slot:append>
|
||||
<q-icon name="search" />
|
||||
</template>
|
||||
</q-input>
|
||||
|
||||
<q-select
|
||||
v-model="visibleColumns"
|
||||
multiple
|
||||
outlined
|
||||
dense
|
||||
options-dense
|
||||
:display-value="$q.lang.table.columns"
|
||||
emit-value
|
||||
map-options
|
||||
:options="columns"
|
||||
option-value="name"
|
||||
options-cover
|
||||
style="min-width: 150px"
|
||||
/>
|
||||
</div>
|
||||
<d-table
|
||||
ref="table"
|
||||
row-key="id"
|
||||
flat
|
||||
bordered
|
||||
dense
|
||||
:filter="filter"
|
||||
:columns="columns"
|
||||
:rows="rows"
|
||||
:paging="true"
|
||||
v-model:pagination="pagination"
|
||||
:rows-per-page-options="[20, 50, 100]"
|
||||
:visible-columns="visibleColumns"
|
||||
>
|
||||
<template v-slot:header="props">
|
||||
<q-tr :props="props">
|
||||
<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" class="cursor-pointer">
|
||||
<q-td v-for="col in props.cols" :key="col.name" :props="props">
|
||||
<div class="table_ellipsis">
|
||||
{{ col.value ? col.value : "-" }}
|
||||
</div>
|
||||
</q-td>
|
||||
</q-tr>
|
||||
</template>
|
||||
</d-table>
|
||||
</q-card-section>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
/** importComponents*/
|
||||
import PositionSalary from "@/modules/04_registryPerson/components/detail/Salary/01_PositionSalary.vue";
|
||||
import NotReceiveSalary from "@/modules/04_registryPerson/components/detail/Salary/02_NotReceiveSalary.vue";
|
||||
|
||||
const tab = ref<string>("1");
|
||||
</script>
|
||||
<template>
|
||||
<div class="row items-center q-my-md">
|
||||
<div class="text-dark row items-center q-px-md">
|
||||
<q-icon name="mdi-account" class="q-mr-md" size="22px" />
|
||||
<div class="text-subtitle1 text-weight-bold">ข้อมูลเงินเดือน/ค่าจ้าง</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<q-separator />
|
||||
<q-tabs
|
||||
v-model="tab"
|
||||
active-color="blue-8"
|
||||
align="left"
|
||||
bordered
|
||||
narrow-indicator
|
||||
indicator-color="transparent"
|
||||
dense
|
||||
class="text-grey q-pl-sm"
|
||||
>
|
||||
<q-tab name="1" label="ตำแหน่ง/เงินเดือน" />
|
||||
<q-tab name="2" label="บันทึกวันที่ไม่ได้รับเงินเดือนฯ" />
|
||||
</q-tabs>
|
||||
<q-separator />
|
||||
|
||||
<q-tab-panels v-model="tab" animated>
|
||||
<q-tab-panel name="1">
|
||||
<PositionSalary />
|
||||
</q-tab-panel>
|
||||
<q-tab-panel name="2">
|
||||
<NotReceiveSalary />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
124
src/modules/04_registryPerson/components/detail/TabMain.vue
Normal file
124
src/modules/04_registryPerson/components/detail/TabMain.vue
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
import { useRoute } from "vue-router";
|
||||
|
||||
import { useRegistryDetailNewDataStore } from "@/modules/04_registryPerson/stores/DetailMain";
|
||||
|
||||
import PersonalInformationMain from "@/modules/04_registryPerson/components/detail/PersonalInformation/Main.vue";
|
||||
import GovernmentInformationMain from "@/modules/04_registryPerson/components/detail/GovernmentInformation/Main.vue";
|
||||
import salaryMain from "@/modules/04_registryPerson/components/detail/Salary/Main.vue";
|
||||
import AchievementMain from "@/modules/04_registryPerson/components/detail/Achievement/Main.vue";
|
||||
import OtherMaim from "@/modules/04_registryPerson/components/detail/Other/Main.vue";
|
||||
import EmployeeMain from "@/modules/04_registryPerson/components/detail/Employee/Main.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const store = useRegistryDetailNewDataStore();
|
||||
const props = defineProps({
|
||||
fetchDataPersonal: { type: Function, require: true },
|
||||
});
|
||||
|
||||
const itemsTab = ref<any>([
|
||||
{
|
||||
name: "1",
|
||||
icon: "mdi-account",
|
||||
label: "ข้อมูลส่วนตัว",
|
||||
},
|
||||
{
|
||||
name: "2",
|
||||
icon: "mdi-account-tie",
|
||||
label:
|
||||
route.name === "registry-employeeId"
|
||||
? "ข้อมูลลูกจ้างชั่วคราว"
|
||||
: "ข้อมูลราชการ",
|
||||
},
|
||||
{
|
||||
name: "3",
|
||||
icon: "mdi-cash",
|
||||
label: "เงินเดือน/ค่าจ้าง",
|
||||
},
|
||||
{
|
||||
name: "4",
|
||||
icon: "mdi-medal",
|
||||
label: "ข้อมูลผลงาน",
|
||||
},
|
||||
{
|
||||
name: "5",
|
||||
icon: "mdi-bookmark",
|
||||
label: "ข้อมูลอื่นๆ",
|
||||
},
|
||||
]);
|
||||
|
||||
const splitterModel = ref<number>(12);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-splitter v-model="splitterModel" disable class="split">
|
||||
<template v-slot:before>
|
||||
<div class="">
|
||||
<!-- bg-tab-regi -->
|
||||
<q-tabs
|
||||
v-model="store.tabMain"
|
||||
vertical
|
||||
class="text-grey-6 text-weight-light"
|
||||
active-class="bg-white text-blue-8 text-weight-bold bg-blue-1"
|
||||
><!-- indicator-color="transparent" -->
|
||||
<q-tab
|
||||
class="q-py-sm"
|
||||
v-for="(tab, index) in itemsTab"
|
||||
:key="index"
|
||||
:name="tab.name"
|
||||
:icon="tab.icon"
|
||||
:label="tab.label"
|
||||
/><!-- hover-tab -->
|
||||
</q-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-slot:after>
|
||||
<q-tab-panels
|
||||
v-model="store.tabMain"
|
||||
animated
|
||||
swipeable
|
||||
vertical
|
||||
transition-prev="jump-up"
|
||||
transition-next="jump-up"
|
||||
class="q-pa-none"
|
||||
><!-- split -->
|
||||
<q-tab-panel
|
||||
v-for="(tab, index) in itemsTab"
|
||||
:key="index"
|
||||
:name="tab.name"
|
||||
class="q-pa-none"
|
||||
>
|
||||
<PersonalInformationMain
|
||||
v-if="store.tabMain === '1'"
|
||||
:fetchDataPersonal="props.fetchDataPersonal"
|
||||
/>
|
||||
<EmployeeMain
|
||||
v-if="store.tabMain === '2' && route.name === 'registry-employeeId'"
|
||||
/>
|
||||
<GovernmentInformationMain v-else-if="store.tabMain === '2'" />
|
||||
|
||||
<salaryMain v-if="store.tabMain === '3'" />
|
||||
<AchievementMain v-if="store.tabMain === '4'" />
|
||||
<OtherMaim v-if="store.tabMain === '5'" />
|
||||
</q-tab-panel>
|
||||
</q-tab-panels>
|
||||
</template>
|
||||
</q-splitter>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hover-tab:hover {
|
||||
background-color: #0793f1;
|
||||
color: white !important;
|
||||
opacity: 1 !important;
|
||||
}
|
||||
.bg-tab-regi {
|
||||
background-color: #273238;
|
||||
}
|
||||
.split {
|
||||
border-radius: 10px !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
<script setup lang="ts">
|
||||
import { reactive, ref, watch } from "vue";
|
||||
import { useQuasar } from "quasar";
|
||||
import http from "@/plugins/http";
|
||||
import config from "@/app.config";
|
||||
|
||||
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
|
||||
|
||||
/**
|
||||
* importComponents
|
||||
*/
|
||||
import DialogHeader from "@/components/DialogHeader.vue";
|
||||
|
||||
/**
|
||||
* importStore
|
||||
*/
|
||||
import { useRequestEditStore } from "@/modules/04_registryPerson/stores/RequestEdit";
|
||||
import { useCounterMixin } from "@/stores/mixin";
|
||||
|
||||
/**
|
||||
* use
|
||||
*/
|
||||
const $q = useQuasar();
|
||||
const store = useRequestEditStore();
|
||||
const { dialogConfirm, showLoader, hideLoader, messageError, success } =
|
||||
useCounterMixin();
|
||||
|
||||
/**
|
||||
* props
|
||||
*/
|
||||
const modal = defineModel<boolean>("modal", { required: true });
|
||||
const requestId = defineModel<string>("requestId", { required: true });
|
||||
const props = defineProps({
|
||||
fetchData: { type: Function, requied: true },
|
||||
});
|
||||
|
||||
const isReadOnly = ref<boolean>(false);
|
||||
const formData = reactive({
|
||||
status: "",
|
||||
remark: "",
|
||||
});
|
||||
const statusOptionMain = ref<DataOption[]>(
|
||||
store.optionStatus.filter((e) => e.id !== "")
|
||||
);
|
||||
const statusOption = ref<DataOption[]>(statusOptionMain.value);
|
||||
|
||||
function onSubmit() {
|
||||
dialogConfirm($q, () => {
|
||||
showLoader();
|
||||
http
|
||||
.patch(config.API.requestEdit + `${requestId.value}`, {
|
||||
status: formData.status,
|
||||
remark: formData.remark,
|
||||
})
|
||||
.then(async () => {
|
||||
await props.fetchData?.();
|
||||
closeDialog();
|
||||
await success($q, "บันทึกข้อมูลสำเร็จ");
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
hideLoader();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function closeDialog() {
|
||||
modal.value = false;
|
||||
formData.status = "";
|
||||
formData.remark = "";
|
||||
}
|
||||
|
||||
function classInput(val: boolean) {
|
||||
return {
|
||||
"full-width cursor-pointer ": val,
|
||||
"full-width cursor-pointer inputgreen": !val,
|
||||
};
|
||||
}
|
||||
|
||||
function filterOption(val: string, update: Function) {
|
||||
update(() => {
|
||||
statusOption.value = statusOptionMain.value.filter(
|
||||
(v: any) => v.name.indexOf(val) > -1
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function fetchDataRequest() {
|
||||
showLoader();
|
||||
http
|
||||
.get(config.API.requestEdit + `${requestId.value}`)
|
||||
.then((res) => {
|
||||
const data = res.data.result;
|
||||
formData.status = data.status;
|
||||
formData.remark = data.remark;
|
||||
if (data.status !== "PENDING") {
|
||||
isReadOnly.value = true;
|
||||
} else {
|
||||
isReadOnly.value = false;
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
messageError($q, err);
|
||||
})
|
||||
.finally(() => {
|
||||
hideLoader();
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => modal.value,
|
||||
() => {
|
||||
modal.value && fetchDataRequest();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<q-dialog v-model="modal" persistent>
|
||||
<q-card style="width: 700px; max-width: 80vw">
|
||||
<q-form greedy @submit.prevent @validation-success="onSubmit">
|
||||
<DialogHeader tittle="แก้ไขสถานะคำร้อง" :close="closeDialog" />
|
||||
<q-separator />
|
||||
|
||||
<q-card-section>
|
||||
<div class="row q-col-gutter-sm">
|
||||
<div class="col-xs-12 col-md-12">
|
||||
<q-select
|
||||
:class="classInput(isReadOnly)"
|
||||
:readonly="isReadOnly"
|
||||
v-model="formData.status"
|
||||
label="สถานะ"
|
||||
dense
|
||||
outlined
|
||||
emit-value
|
||||
map-options
|
||||
:options="statusOption"
|
||||
:rules="[(val:string) => !!val || `${'กรุณาเลือกสถานะ'}`]"
|
||||
lazy-rules
|
||||
hide-bottom-space
|
||||
use-input
|
||||
option-label="name"
|
||||
option-value="id"
|
||||
@filter="(inputValue:string,
|
||||
doneFn:Function) => filterOption(inputValue, doneFn
|
||||
) "
|
||||
>
|
||||
<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-md-12">
|
||||
<q-input
|
||||
:class="classInput(isReadOnly)"
|
||||
:readonly="isReadOnly"
|
||||
v-model="formData.remark"
|
||||
label="หมายเหตุ"
|
||||
dense
|
||||
outlined
|
||||
type="textarea"
|
||||
hide-bottom-space
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-separator />
|
||||
|
||||
<q-card-actions align="right" v-if="!isReadOnly">
|
||||
<q-btn label="บันทึก" color="secondary" type="submit"
|
||||
><q-tooltip>บันทึก</q-tooltip></q-btn
|
||||
>
|
||||
</q-card-actions>
|
||||
</q-form>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue