Merge branch 'develop' into nice_dev

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2023-08-16 14:35:25 +07:00
commit 7b6c390193
23 changed files with 1612 additions and 473 deletions

View file

@ -0,0 +1,11 @@
/**
* API Structure + Org Chart
*/
import env from "../index";
const message = `${env.API_DASHBOARD_URI}/message`;
export default {
msgNotificate: `${message}/my-notifications`,
msgInbox: `${message}/my-inboxes`,
};

View file

@ -29,6 +29,7 @@ const config = ref<any>({
// API_PROBATION_URI: "https://ehr.joolsoft.com/v1",
API_PROBATION_URI: "https://bmaehr.joolsoft.com/nodeapi/v1",
// API_PROBATION_URI: "http://192.168.1.151:7776/v1",
API_DASHBOARD_URI: "http://192.168.1.9:6026/api/v1",
},
test: {
API_URI: "http://localhost:5010/api/v1",
@ -73,7 +74,13 @@ const API_RETIREMENT_URI = ref<string>(
config.value[env.value].API_RETIREMENT_URI
);
const API_URI_ORG_TREE = ref<string>(config.value[env.value].API_URI_ORG_TREE);
const API_PROBATION_URI = ref<string>(config.value[env.value].API_PROBATION_URI);
const API_PROBATION_URI = ref<string>(
config.value[env.value].API_PROBATION_URI
);
const API_DASHBOARD_URI = ref<string>(
config.value[env.value].API_DASHBOARD_URI
);
export default {
env: env.value,
@ -87,6 +94,7 @@ export default {
API_PLACEMENT_URI: API_PLACEMENT_URI.value,
API_URI_ORG_TREE: API_URI_ORG_TREE.value,
MEET_URI: MEET_URI.value,
API_RETIREMENT_URI:API_RETIREMENT_URI.value,
API_PROBATION_URI: API_PROBATION_URI.value
API_RETIREMENT_URI: API_RETIREMENT_URI.value,
API_PROBATION_URI: API_PROBATION_URI.value,
API_DASHBOARD_URI: API_DASHBOARD_URI.value,
};

View file

@ -37,6 +37,9 @@ import retirement from "./api/06_retirement/api.retirement";
/** API ระบบงานเครื่องราชอิสริยาภรณ์ List */
import insignia from "./api/07_insignia/api.insignia";
/** API dashboard */
import message from "./api/00_dashboard/api.message";
// environment variables
export const compettitivePanel = import.meta.env.VITE_COMPETITIVE_EXAM_PANEL;
export const qualifyDisableExamPanel = import.meta.env
@ -74,6 +77,9 @@ const API = {
...probation,
...retirement,
...insignia,
//dashboard
...message,
};
export default {

View file

@ -28,10 +28,10 @@ interface menuType {
}
interface notiType {
id: number;
id: string;
sender: string;
body: string;
timereceive: string;
timereceive: Date;
}
interface optionType {
@ -337,7 +337,7 @@ const menuList = readonly<any[]>([
role: "insignia",
children: [
{
label: "รายการเสนอขอ",
label: "รอบการเสนอขอ",
path: "insigniaProposals",
role: "insignia",
},
@ -370,7 +370,7 @@ const menuList = readonly<any[]>([
role: "coin",
children: [
{
label: "รายการเสนอขอ",
label: "รอบการเสนอขอ",
path: "coinProposals",
role: "coin",
},

View file

@ -0,0 +1,27 @@
interface ResponseInbox {
body: string;
createdAt: Date;
createdFullName: string;
createdUserId: string;
id: string;
isOpen: boolean;
lastUpdateFullName: string;
lastUpdateUserId: string;
lastUpdatedAt: Date;
openDate: Date | null;
payload: string;
receiveDate: Date;
receiverUserId: string;
subject: string;
}
interface DataInbox {
no: string;
sender: string;
subject: string;
timereceive: Date;
body: string;
ratingModel: number;
}
export type { ResponseInbox, DataInbox };

View file

@ -65,14 +65,525 @@
</div>
</div>
</q-card>
<q-card bordered class="row col-12 text-dark q-mt-sm">
<div class="bg-grey-1 q-pa-sm col-12 row items-center text-primary">
<div class="q-pl-sm text-weight-bold text-dark">
แกไขขอมลเพอลงบญชแนบทาย
</div>
<q-space />
<div class="q-gutter-sm" v-if="!edit">
<q-btn
outline
color="primary"
dense
icon-right="mdi-file-edit-outline"
class="q-px-sm"
label="แก้ไข"
style="width: 80px"
@click="edit = !edit"
/>
</div>
<div class="q-gutter-sm" v-else>
<q-btn
outline
color="public"
dense
class="q-px-sm"
label="บันทึก"
style="width: 80px"
@click="conditionSave"
/>
<q-btn
outline
color="red"
dense
class="q-px-sm"
label="ยกเลิก"
style="width: 80px"
@click="cancel"
/>
</div>
</div>
<div class="col-12"><q-separator /></div>
<q-form ref="myForm">
<div class="row col-12 q-pa-md">
<div class="col-12 row bg-white">
<div class="col-xs-12 row items-center q-col-gutter-md">
<div class="col-xs-12">
<div class="text-weight-bold text-grey">อมลสวนต</div>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
v-model="informaData.cardid"
dense
@update:model-value="changeCardID"
lazy-rules
:rules="[
(val:string) => !!val || `${'กรุณากรอก เลขบัตรประจำตัวประชาชน'}`,
(val:string) =>
val.length >= 13 ||
`${'กรุณากรอกเลขบัตรประจำตัวประชาชนให้ครบ'}`,
]"
:readonly="!edit"
:borderless="!edit"
label="เลขบัตรประจำตัวประชาชน"
maxlength="13"
mask="#############"
/>
<!-- :rules="[(val:any) =>val.length != 13 ||`${'กรุณากรอกเลขบัตรประจำตัวประชาชนให้ครบ'}`,]" -->
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:rules="[(val:string) => !!val || `${'กรุณาเลือก คำนำหน้าชื่อ'}`]"
:outlined="edit"
dense
lazy-rules
v-model="informaData.prefixId"
emit-value
map-options
option-label="name"
:options="Ops.prefixOps"
option-value="id"
:label="`${'คำนำหน้าชื่อ'}`"
use-input
input-debounce="0"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'prefixOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="informaData.firstname"
:rules="[(val:string) => !!val || `${'กรุณากรอก ชื่อ'}`]"
:label="`${'ชื่อ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3 col-md-3">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="informaData.lastname"
:rules="[(val:string) => !!val || `${'กรุณากรอก นามสกุล'}`]"
:label="`${'นามสกุล'}`"
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<datepicker
v-model="informaData.birthDate"
:locale="'th'"
autoApply
:enableTimePicker="false"
week-start="0"
:max-date="new Date()"
:disabled="!edit"
@update:model-value="handleDate"
>
<template #year="{ year }">
{{ year + 543 }}
</template>
<template #year-overlay-value="{ value }">
{{ parseInt(value + 543) }}
</template>
<template #trigger>
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
:model-value="
informaData.birthDate == null
? null
: date2Thai(informaData.birthDate)
"
:rules="[(val:string) => !!val || `${'กรุณาเลือก วัน/เดือน/ปี เกิด'}`]"
:label="`${'วัน/เดือน/ปี เกิด'}`"
>
<template v-slot:prepend>
<q-icon
name="event"
class="cursor-pointer"
:style="
edit
? 'color: var(--q-primary)'
: 'color: var(--q-grey)'
"
>
</q-icon>
</template>
</q-input>
</template>
</datepicker>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<q-input
:class="getClass(false)"
hide-bottom-space
dense
lazy-rules
readonly
borderless
:style="!edit ? '' : 'padding:0 12px;'"
:model-value="informaData.age"
:label="`${'อายุ'}`"
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:outlined="edit"
dense
lazy-rules
v-model="informaData.genderId"
emit-value
map-options
option-label="name"
:options="Ops.genderOps"
option-value="id"
:label="`${'เพศ'}`"
use-input
input-debounce="0"
:rules="[(val:string) => !!val || `${'กรุณาเลือก เพศ'}`]"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'genderOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:outlined="edit"
dense
lazy-rules
v-model="informaData.statusId"
emit-value
map-options
option-label="name"
:options="Ops.statusOps"
option-value="id"
:label="`${'สถานภาพ'}`"
use-input
input-debounce="0"
:rules="[(val:string) => !!val || `${'กรุณาเลือก สถานภาพ'}`]"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'statusOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="informaData.nationality"
:label="`${'สัญชาติ'}`"
:rules="[(val:string) => !!val || `${'กรุณากรอก สัญชาติ'}`]"
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<q-input
:class="getClass(edit)"
hide-bottom-space
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="informaData.ethnicity"
:label="`${'เชื้อชาติ'}`"
:rules="[(val:string) => !!val || `${'กรุณากรอก เชื้อชาติ'}`]"
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:outlined="edit"
dense
lazy-rules
v-model="informaData.religionId"
emit-value
map-options
option-label="name"
:options="Ops.religionOps"
option-value="id"
:label="`${'ศาสนา'}`"
use-input
input-debounce="0"
:rules="[(val:string) => !!val || `${'กรุณาเลือก ศาสนา'}`]"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'religionOps'
) "
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:outlined="edit"
dense
lazy-rules
v-model="informaData.bloodId"
emit-value
map-options
option-label="name"
:options="Ops.bloodOps"
option-value="id"
:label="`${'หมู่เลือด'}`"
use-input
input-debounce="0"
:rules="[(val:string) => !!val || `${'กรุณาเลือก หมู่เลือด'}`]"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'bloodOps'
) "
clearable
/>
</div>
<div class="col-xs-6 col-sm-2 col-md-2">
<q-input
hide-bottom-space
:outlined="edit"
dense
lazy-rules
type="tel"
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
v-model="informaData.tel"
:label="`${'เบอร์โทร'}`"
mask="##########"
:rules="[(val:string) => !!val || `${'กรุณากรอก เบอร์โทร'}`]"
/>
</div>
<div
class="col-xs-6 col-sm-3 col-md-3"
v-if="informaData.profileType == 'employee'"
>
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:rules="[(val:string) => !!val || `${'กรุณาเลือก ประเภทการจ้าง'}`]"
:outlined="edit"
dense
lazy-rules
v-model="informaData.employeeType"
emit-value
map-options
option-label="name"
:options="Ops.employeeTypeOps"
option-value="id"
:label="`${'ประเภทการจ้าง'}`"
use-input
input-debounce="0"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'employeeTypeOps'
) "
/>
</div>
<div
class="col-xs-6 col-sm-3 col-md-3"
v-if="informaData.profileType == 'employee'"
>
<selector
:hide-dropdown-icon="!edit"
hide-bottom-space
:class="getClass(edit)"
:readonly="!edit"
:borderless="!edit"
:rules="[(val:string) => !!val || `${'กรุณาเลือก ประเภทลูกจ้าง'}`]"
:outlined="edit"
dense
lazy-rules
v-model="informaData.employeeClass"
emit-value
map-options
option-label="name"
:options="Ops.employeeClassOps"
option-value="id"
:label="`${'ประเภทลูกจ้าง'}`"
use-input
input-debounce="0"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'employeeClassOps'
) "
/>
</div>
<div class="col-xs-12">
<div class="text-weight-bold text-grey">
ตำแหนงและหนวยงานเด
</div>
</div>
<div class="col-xs-12">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="educationOld"
:rules="[(val) => !!val || `${'กรุณากรอกวุฒิ/สาขา'}`]"
hide-bottom-space
:label="`${'วุฒิ/สาขา'}`"
type="textarea"
autogrow
/>
</div>
<div class="col-xs-12">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="organizationPositionOld"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่ง/สังกัด'}`]"
hide-bottom-space
:label="`${'ตำแหน่ง/สังกัด'}`"
type="textarea"
/>
</div>
<div class="col-xs-6 col-sm-3">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="positionTypeOld"
:rules="[(val) => !!val || `${'กรุณากรอกตำแหน่งประเภท'}`]"
hide-bottom-space
:label="`${'ตำแหน่งประเภท'}`"
/>
</div>
<div class="col-xs-6 col-sm-3">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="positionLevelOld"
:rules="[(val) => !!val || `${'กรุณากรอกระดับ'}`]"
hide-bottom-space
:label="`${'ระดับ'}`"
/>
</div>
<div class="col-xs-6 col-sm-3">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="posNo"
:rules="[(val) => !!val || `${'กรุณากรอกเลขที่'}`]"
hide-bottom-space
:label="`${'เลขที่'}`"
/>
</div>
<div class="col-xs-6 col-sm-3">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="salary"
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
hide-bottom-space
:label="`${'เงินเดือน'}`"
type="number"
/>
</div>
<div class="col-xs-12">
<q-input
:class="getClass(edit)"
:outlined="edit"
dense
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="reason"
:rules="[(val) => !!val || `${'กรุณากรอกหมายเหตุ '}`]"
hide-bottom-space
:label="`${'หมายเหตุ '}`"
type="textarea"
/>
</div>
</div>
</div>
</div>
</q-form>
</q-card>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { useQuasar } from "quasar";
import { useRoute, useRouter } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { useProfileDataStore } from "@/modules/08_registryEmployee/store";
import type { QTableProps, QForm } from "quasar";
import type { ResponseTitle } from "@/modules/05_placement/interface/response/Receive";
import type { InformationOps } from "@/modules/04_registry/interface/index/Main";
import type {
Information,
DataOption,
} from "@/modules/04_registry/components/profileType";
import { defaultInformation } from "@/modules/04_registry/components/profileType";
import http from "@/plugins/http";
import config from "@/app.config";
@ -90,8 +601,12 @@ const {
showLoader,
hideLoader,
success,
dateToISO,
} = mixin;
const profileStore = useProfileDataStore();
const { changeRetireText } = profileStore;
const title = ref<ResponseTitle>({
fullname: "",
organizationPositionOld: "",
@ -99,21 +614,227 @@ const title = ref<ResponseTitle>({
positionTypeOld: "",
});
const myForm = ref<QForm | null>(null);
const edit = ref<boolean>(false);
const educationOld = ref<string>("");
const organizationPositionOld = ref<string>("");
const positionTypeOld = ref<string>("");
const positionLevelOld = ref<string>("");
const posNo = ref<string>("");
const salary = ref<number>(0);
const organization = ref<string>("");
const date = ref<Date | null>(null);
const reason = ref<string>("");
const informaData = ref<Information>(defaultInformation);
const dateBefore = ref<Date>(new Date());
const defaultCitizenData = ref<string>("");
const Ops = ref<InformationOps>({
prefixOps: [],
prefixOldOps: [],
genderOps: [],
bloodOps: [],
statusOps: [],
religionOps: [],
employeeClassOps: [
{ id: "perm", name: "ลูกจ้างประจำ" },
{ id: "temp", name: "ลูกจ้างชั่วคราว" },
],
employeeTypeOps: [
{ id: "gov", name: "งบประมาณเงินอุดหนุนรัฐบาล" },
{ id: "bkk", name: "งบประมาณกรุงเทพมหานคร" },
],
});
const OpsFilter = ref<InformationOps>({
prefixOps: [],
prefixOldOps: [],
genderOps: [],
bloodOps: [],
statusOps: [],
religionOps: [],
employeeClassOps: [
{ id: "perm", name: "ลูกจ้างประจำ" },
{ id: "temp", name: "ลูกจ้างชั่วคราว" },
],
employeeTypeOps: [
{ id: "gov", name: "งบประมาณเงินอุดหนุนรัฐบาล" },
{ id: "bkk", name: "งบประมาณกรุงเทพมหานคร" },
],
});
onMounted(async () => {
await fetchPerson();
await getData();
});
const fetchPerson = async () => {
showLoader();
await http
.get(config.API.person)
.then((res) => {
const data = res.data.result;
let optionbloodGroups: DataOption[] = [];
data.bloodGroups.map((r: any) => {
optionbloodGroups.push({
id: r.id.toString(),
name: r.name.toString(),
});
});
Ops.value.bloodOps = optionbloodGroups;
OpsFilter.value.bloodOps = optionbloodGroups;
let optiongenders: DataOption[] = [];
data.genders.map((r: any) => {
optiongenders.push({
id: r.id.toString(),
name: r.name.toString(),
});
});
Ops.value.genderOps = optiongenders;
OpsFilter.value.genderOps = optiongenders;
let optionprefixs: DataOption[] = [];
data.prefixs.map((r: any) => {
optionprefixs.push({
id: r.id.toString(),
name: r.name.toString(),
});
});
Ops.value.prefixOps = optionprefixs;
OpsFilter.value.prefixOps = optionprefixs;
let optionrelationships: DataOption[] = [];
data.relationships.map((r: any) => {
optionrelationships.push({
id: r.id.toString(),
name: r.name.toString(),
});
});
Ops.value.statusOps = optionrelationships;
OpsFilter.value.statusOps = optionrelationships;
let optionreligions: DataOption[] = [];
data.religions.map((r: any) => {
optionreligions.push({
id: r.id.toString(),
name: r.name.toString(),
});
});
Ops.value.religionOps = optionreligions;
OpsFilter.value.religionOps = optionreligions;
})
.catch((e: any) => {})
.finally(() => {
// hideLoader();
});
};
const getData = async () => {
showLoader();
await http
.get(config.API.receiveDataId(paramsId.toString()))
.then((res: any) => {
.then(async (res: any) => {
const data = res.data.result;
title.value.fullname = `${data.firstname ?? "-"} ${data.lastname ?? "-"}`;
title.value.organizationPositionOld = data.organizationPositionOld ?? "-";
title.value.positionLevelOld = data.positionLevelOld ?? "-";
title.value.positionTypeOld = data.positionTypeOld ?? "-";
defaultCitizenData.value = data.citizenId == null ? "" : data.citizenId;
informaData.value = {
cardid: data.citizenId ?? "",
age: "",
prefix: "",
prefixId:
(data.prefixId == "00000000-0000-0000-0000-000000000000"
? null
: data.prefixId) ?? "",
firstname: data.firstname ?? "",
lastname: data.lastname ?? "",
birthDate:
data.dateOfBirth !== null ? new Date(data.dateOfBirth) : null,
genderId:
(data.gender == "00000000-0000-0000-0000-000000000000"
? null
: data.gender) ?? "",
bloodId:
(data.bloodGroup == "00000000-0000-0000-0000-000000000000"
? null
: data.bloodGroup) ?? "",
nationality: data.nationality ?? "",
ethnicity: data.race ?? "",
statusId:
(data.relationship == "00000000-0000-0000-0000-000000000000"
? null
: data.relationship) ?? "",
religionId:
(data.religion == "00000000-0000-0000-0000-000000000000"
? null
: data.religion) ?? "",
tel: data.telephoneNumber ?? "",
employeeType: "",
employeeClass: "",
profileType: "",
};
educationOld.value = data.educationOld ?? "";
organizationPositionOld.value = data.organizationPositionOld ?? "";
positionTypeOld.value = data.positionTypeOld ?? "";
positionLevelOld.value = data.positionLevelOld ?? "";
posNo.value = data.positionNumberOld ?? "";
salary.value = data.amountOld ?? 0;
reason.value = data.reason ?? "";
await calRetire(new Date(dateToISO(new Date(data.dateOfBirth))));
dateBefore.value = new Date(data.dateOfBirth);
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
hideLoader();
});
};
const cancel = async () => {
edit.value = !edit.value;
if (myForm.value !== null) {
await getData();
myForm.value.reset();
}
};
const changeCardID = async (value: string | number | null) => {
if (value != null && typeof value == "string") {
if (value.length == 13 && value != defaultCitizenData.value) {
await checkCitizen(value);
// informaData.value.cardid = defaultCitizenData.value;
}
}
};
const checkCitizen = async (id: string) => {
console.log("String");
showLoader();
await http
.get(config.API.profileCitizenId(id))
.then((res) => {
const data = res.data.result.citizen;
if (!data) {
dialogMessage(
$q,
"ข้อความแจ้งเตือน",
"เลขบัตรประจำตัวประชาชนนี้มีการใช้งานแล้ว",
"warning",
undefined,
"orange",
undefined,
undefined,
true
);
informaData.value.cardid = defaultCitizenData.value;
}
})
.catch((e) => {
messageError($q, e);
@ -122,6 +843,164 @@ const getData = async () => {
hideLoader();
});
};
const filterSelector = (val: any, update: Function, refData: string) => {
switch (refData) {
case "prefixOps":
update(() => {
Ops.value.prefixOps = OpsFilter.value.prefixOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "genderOps":
update(() => {
Ops.value.genderOps = OpsFilter.value.genderOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "bloodOps":
update(() => {
Ops.value.bloodOps = OpsFilter.value.bloodOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "statusOps":
update(() => {
Ops.value.statusOps = OpsFilter.value.statusOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "religionOps":
update(() => {
Ops.value.religionOps = OpsFilter.value.religionOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "employeeClassOps":
update(() => {
Ops.value.employeeClassOps = OpsFilter.value.employeeClassOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
case "employeeTypeOps":
update(() => {
Ops.value.employeeTypeOps = OpsFilter.value.employeeTypeOps.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
break;
default:
break;
}
};
const handleDate = async (modelData: Date) => {
informaData.value.birthDate = modelData;
await calRetire(modelData);
};
const calRetire = async (birth: Date) => {
const body = {
birthDate: dateToISO(birth),
};
// if (dateToISO(dateBefore.value) != dateToISO(birth)) {
showLoader();
await http
.post(config.API.profileCalRetire, body)
.then((res: any) => {
const data = res.data.result;
informaData.value.age = data.age;
changeRetireText(data.retireDate);
dateBefore.value = birth;
})
.catch((e: any) => {
messageError($q, e);
const retire = new Date(`${birth.getFullYear() + 60}-09-30`);
informaData.value.birthDate = dateBefore.value;
changeRetireText(date2Thai(retire));
})
.finally(() => {
hideLoader();
});
// }
};
const conditionSave = async () => {
if (myForm.value !== null) {
myForm.value.validate().then((success) => {
if (success) {
dialogMessage(
$q,
"ต้องการแก้ไขข้อมูลหรือไม่?",
"แก้ไขข้อมูลเพื่อลงบัญชีแนบท้าย",
"mdi-help-circle-outline",
"ตกลง",
"public",
async () => await saveData(),
undefined
);
}
});
}
};
const saveData = async () => {
const body = {
citizenId: informaData.value.cardid,
prefixId: informaData.value.prefixId,
firstname: informaData.value.firstname,
lastname: informaData.value.lastname,
dateOfBirth:
informaData.value.birthDate !== null
? dateToISO(informaData.value.birthDate)
: null,
genderId: informaData.value.genderId,
nationality: informaData.value.nationality,
race: informaData.value.ethnicity,
religionId: informaData.value.religionId,
bloodGroupId: informaData.value.bloodId,
relationshipId: informaData.value.statusId,
telephoneNumber: informaData.value.tel,
reason: reason.value,
educationOld: educationOld.value,
organizationPositionOld: organizationPositionOld.value,
positionTypeOld: positionTypeOld.value,
positionLevelOld: positionLevelOld.value,
positionNumberOld: posNo.value,
amount: 0,
amountOld: salary.value,
};
showLoader();
await http
.put(config.API.receiveDataId(route.params.id.toString()), body)
.then((res: any) => {
// const data = res.data.result;
// console.log(data);
success($q, "แก้ไขข้อมูลเพื่อลงบัญชีแนบท้ายสำเร็จ");
edit.value = false;
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
await getData();
hideLoader();
});
};
const getClass = (val: boolean) => {
return {
"full-width inputgreen cursor-pointer": val,
"full-width cursor-pointer": !val,
};
};
</script>
<style lang="scss" scope>
.q-img {

View file

@ -1,39 +1,40 @@
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import type { QTableProps } from "quasar";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useRouter } from "vue-router";
import DialogFooter from "@/modules/05_placement/components/Receive/DialogFooter.vue";
import DialogHeader from "@/modules/05_placement/components/Receive/DialogHeader.vue";
import DialogOrgTree from "@/modules/05_placement/components/Receive/receiveModal.vue";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
const mixin = useCounterMixin(); //
const { showLoader, hideLoader, dateText, success, messageError, date2Thai } =
mixin;
const selected = ref([]);
const checkSelected = computed(() => {
if (selected.value.length === 0) {
return true;
}
});
const add = () => {
router.push(`/receive/add`);
};
const clickClose = () => {
modal.value = false;
};
import type { QTableProps } from "quasar";
import type {
ResponseData,
ResponseRow,
} from "@/modules/05_placement/interface/response/Receive";
const $q = useQuasar();
const router = useRouter();
const mixin = useCounterMixin(); //
const {
showLoader,
hideLoader,
dialogMessage,
success,
messageError,
date2Thai,
} = mixin;
const selected = ref<ResponseRow[]>([]);
const modal = ref<boolean>(false);
const popup = () => {
modal.value = true;
};
const router = useRouter();
const modalTree = ref<boolean>(false);
const personal = ref<any[]>([]);
@ -56,57 +57,10 @@ const visibleColumns2 = ref<string[]>([
const filterKeyword = ref<string>("");
const filterKeyword2 = ref<string>("");
const filterRef = ref<any>(null);
const resetFilter = () => {
filterKeyword.value = "";
filterKeyword2.value = "";
filterRef.value.focus();
};
onMounted(() => {
fecthlistRecevice();
});
const listRecevice = ref<any>([]);
const fecthlistRecevice = async () => {
showLoader();
await http
.get(config.API.receiveData())
.then((res) => {
let response = res.data.result;
listRecevice.value = response;
// console.log(response);
rows.value = response.map((e: any) => ({
personalId: e.id,
citizenId: e.citizenId,
fullname: e.firstname + " " + e.lastname,
organizationName:
e.organizationName +
" " +
e.organizationShortName +
" " +
e.positionNumber +
" " +
e.positionPath,
orgName: e.organizationName,
organizationShortName: e.organizationShortName,
positionNumber: e.positionNumber,
positionPath: e.positionPath,
birthday: date2Thai(e.dateOfBirth),
}));
// console.log(rows.value);
rows2.value = rows.value.filter((e: any) => e.orgName !== null);
})
.catch((e) => {
console.log(typeof e);
})
.finally(() => {
hideLoader();
});
};
// const nextPage = (id:string) => {
// router.push("/retirement/resign/"+id);
// };
const rows = ref<any>([
const listRecevice = ref<any[]>([]);
const filters = ref<ResponseRow[]>([]);
const rows = ref<ResponseRow[]>([
// {
// personalId: "08db721d-add6-47b0-8a13-5f45d106e8d1",
// citizenId: "1234444332222",
@ -119,18 +73,18 @@ const rows = ref<any>([
// birthday: dateText(new Date("1989-09-03")),
// },
]);
const rows2 = ref<any>([
{
personalId: "08db721d-add6-47b0-8a13-5f45d106e8d1",
citizenId: "1234444332222",
fullname: "นางสาวอย พชช",
organizationName: "นักจัดการงานทั่วไป",
orgName: "กลุ่มงานช่วยนักบริหาร",
organizationShortName: "สกจ.",
positionNumber: "กก. 1",
positionPath: "นักจัดการงานทั่วไป",
birthday: dateText(new Date("1989-09-03")),
},
const rows2 = ref<ResponseRow[]>([
// {
// personalId: "08db721d-add6-47b0-8a13-5f45d106e8d1",
// citizenId: "1234444332222",
// fullname: " ",
// organizationName: "",
// orgName: "",
// organizationShortName: ".",
// positionNumber: ". 1",
// positionPath: "",
// birthday: dateText(new Date("1989-09-03")),
// },
]);
const columns = ref<QTableProps["columns"]>([
{
@ -231,6 +185,77 @@ const columns2 = ref<QTableProps["columns"]>([
},
]);
onMounted(() => {
fecthlistRecevice();
});
const fecthlistRecevice = async () => {
showLoader();
await http
.get(config.API.receiveData())
.then((res: any) => {
const response = res.data.result;
listRecevice.value = response;
// console.log(response);
let list: ResponseRow[] = [];
response.map((e: ResponseData) => {
list.push({
personalId: e.id ?? "",
citizenId: e.citizenId ?? "-",
fullname: e.firstname + " " + e.lastname,
organizationName:
e.organizationName +
" " +
e.organizationShortName +
" " +
e.positionNumber +
" " +
e.positionPath,
orgName: e.organizationName,
organizationShortName: e.organizationShortName,
positionNumber: e.positionNumber,
positionPath: e.positionPath,
birthday: e.dateOfBirth == null ? "-" : date2Thai(e.dateOfBirth),
status: e.status,
});
});
rows.value = list;
filters.value = list;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
const resetFilter = () => {
filterKeyword.value = "";
filterKeyword2.value = "";
filterRef.value.focus();
};
const checkSelected = computed(() => {
if (selected.value.length === 0) {
return true;
}
});
const row = filters.value.filter(
(r: ResponseRow) =>
r.status == "WAITTING" || r.status == "PENDING" || r.status == "APPROVE"
);
rows2.value = row;
const add = () => {
router.push(`/receive/add`);
};
const clickClose = () => {
modal.value = false;
};
const openModalTree = (id: string) => {
personalId.value = id;
console.log(personalId.value);
@ -240,31 +265,33 @@ const openModalTree = (id: string) => {
};
const openDelete = (id: string) => {
console.log(id);
dialogMessage(
$q,
"ลบข้อมูล",
"ต้องการทำการลบข้อมูลนี้ใช่หรือไม่",
"delete",
undefined,
"red",
async () => await fetchDataDelete(id),
undefined,
false
);
};
$q.dialog({
title: `ลบข้อมูล`,
message: `ต้องการทำการลบข้อมูลนี้ใช่หรือไม่?`,
cancel: "ยกเลิก",
ok: "ยืนยัน",
persistent: true,
})
.onOk(async () => {
showLoader();
await http
.delete(config.API.receiveDataId(id))
.then((res) => {
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
fecthlistRecevice();
hideLoader();
});
const fetchDataDelete = async (id: string) => {
showLoader();
await http
.delete(config.API.receiveDataId(id))
.then((res) => {
success($q, "ลบข้อมูลสำเร็จ");
})
.onCancel(() => {});
.catch((e) => {
messageError($q, e);
})
.finally(() => {
fecthlistRecevice();
hideLoader();
});
};
const closeModalTree = async () => {
@ -277,6 +304,30 @@ const nextPage = (row: any) => {
path: `/receive/${row.personalId}`,
});
};
const saveOrder = async () => {
const id = selected.value.map((r: any) => r.personalId);
const body = {
id,
};
showLoader();
await http
.post(config.API.receiveReport, body)
.then((res: any) => {
// const data = res.data.result;
// console.log(data);
success($q, "ส่งไปออกคำสั่งรับโอนสำเร็จ");
clickClose();
})
.catch((e) => {
messageError($q, e);
})
.finally(async () => {
await fecthlistRecevice();
hideLoader();
});
};
</script>
<template>
<div class="toptitle text-dark col-12 row items-center">รายการรบโอน</div>
@ -626,7 +677,7 @@ const nextPage = (row: any) => {
<q-card-actions align="right" class="bg-white text-teal">
<q-btn
label="ส่งไปออกคำสั่ง"
@click=""
@click="saveOrder"
:disable="checkSelected"
color="public"
/>

View file

@ -166,7 +166,7 @@ const columns = ref<QTableProps["columns"]>([
{
name: "organization",
align: "left",
label: "หน่วยงานที่ขอโอนไป",
label: "หน่วยงานที่ขอย้ายไป",
sortable: true,
field: "organization",
headerStyle: "font-size: 14px",
@ -240,7 +240,7 @@ const columns2 = ref<QTableProps["columns"]>([
{
name: "organization",
align: "left",
label: "หน่วยงานที่ขอโอนไป",
label: "หน่วยงานที่ขอย้ายไป",
sortable: true,
field: "organization",
headerStyle: "font-size: 14px",

View file

@ -50,8 +50,8 @@ const organization = ref<string>("");
const reason = ref<string>("");
const status = ref<string>("");
const date = ref<Date | null>(null);
const salary = ref<string>("");
const salaryNew = ref<string>("");
const amount = ref<number>();
const amountOld = ref<number>();
const positionTypeOld = ref<string>("");
const positionLevelOld = ref<string>("");
const dateOfBirth = ref<Date>()
@ -131,7 +131,8 @@ const getData = async () => {
reason.value = data.reason;
status.value = data.status;
date.value = data.date;
salary.value = data.salary;
amount.value = data.amount;
amountOld.value = data.amountOld;
positionTypeOld.value = data.positionTypeOld;
positionLevelOld.value = data.positionLevelOld;
positionNumberOld.value = data.positionNumberOld;
@ -178,6 +179,10 @@ const conditionSave = async () => {
});
}
};
const cancelBtn = () => {
edit.value=!edit
getData()
}
const saveData = async () => {
const body = {
educationOld: educationOld.value,
@ -190,7 +195,8 @@ const saveData = async () => {
positionTypeOld: positionTypeOld.value,
positionLevelOld: positionLevelOld.value,
positionNumberOld: positionNumberOld.value,
amountOld: salary.value,
amount: amount.value,
amountOld: amountOld.value,
dateOfBirth:dateOfBirth.value ,
genderId:genderId.value ,
nationality:nationality.value ,
@ -348,7 +354,7 @@ onMounted(async () => {
class="q-px-sm"
label="ยกเลิก"
style="width: 80px"
@click="edit = !edit"
@click="cancelBtn"
/>
</div>
</div>
@ -454,7 +460,7 @@ onMounted(async () => {
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="salary"
v-model="amountOld"
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
hide-bottom-space
:label="`${'เงินเดือน'}`"
@ -492,7 +498,7 @@ onMounted(async () => {
lazy-rules
:readonly="!edit"
:borderless="!edit"
v-model="salaryNew"
v-model="amount"
:rules="[(val) => !!val || `${'กรุณากรอกเงินเดือน'}`]"
hide-bottom-space
:label="`${'เงินเดือน'}`"

View file

@ -95,7 +95,7 @@
class="q-px-sm"
label="ยกเลิก"
style="width: 80px"
@click="edit = !edit"
@click="cancelBtn"
/>
</div>
</div>
@ -429,6 +429,10 @@
});
}
};
const cancelBtn = () => {
edit.value=!edit
getData()
}
const saveData = async () => {
const body = {
organization: organization.value,

View file

@ -497,7 +497,7 @@ const getData = async () => {
positionTypeOld.value = data.positionTypeOld ?? "";
positionLevelOld.value = data.positionLevelOld ?? "";
posNo.value = data.posNo ?? "";
salary.value = data.salary ?? "";
salary.value = data.salary ?? 0;
organization.value = data.organization ?? "";
date.value = data.date !== null ? new Date(data.date) : null;
reason.value = data.reason ?? "";

View file

@ -95,7 +95,7 @@
class="q-px-sm"
label="ยกเลิก"
style="width: 80px"
@click="edit = !edit"
@click="cancelBtn"
/>
</div>
</div>
@ -429,6 +429,10 @@ const conditionSave = async () => {
});
}
};
const cancelBtn = () => {
edit.value=!edit
getData()
}
const saveData = async () => {
const body = {
organization: organization.value,

View file

@ -364,7 +364,8 @@ const postData = async () => {
<div class="col-12 row q-mt-xs">
<div class="col-12 text-top2 row items-center">
ความเหนของผอำนาจสงบรรจตามมาตรา 52
คณะกรรมการ
<!-- ความเหนของผอำนาจสงบรรจตามมาตรา 52 -->
</div>
<div class="col-12 row q-col-gutter-md">
<q-select
@ -422,7 +423,8 @@ const postData = async () => {
<div class="col-12 row q-mt-xs">
<div class="col-12 text-top2 row items-center">
อำนาจสงบรรจตามมาตรา 52
คณะกรรมการ
<!-- อำนาจสงบรรจตามมาตรา 52 -->
</div>
<div class="col-12 row q-col-gutter-md">
<q-select

View file

@ -40,7 +40,8 @@ const props = defineProps({
});
onMounted(async () => {
console.log(props.tab);
console.log("tab===>",props.tab)
await fecthFormdata(assignId.value);
if (props.tab !== undefined) {
round.value = props.tab.charAt(4);

View file

@ -3,9 +3,22 @@ import { ref, watch, onMounted } from "vue";
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const assignId = ref<string>(route.params.form.toString());
const personalId = ref<string>(route.params.personalId.toString());
const tabHead = ref<string>("save1");
const props = defineProps({
loop: {
type: Number,
},
addData: {
type: Function,
default() {
return "Default function";
},
},
changeTab: {
type: Function,
default() {
@ -14,31 +27,19 @@ const props = defineProps({
},
activeTab: String,
});
onMounted(() => {
console.log(props);
});
watch(tabHead, () => {
console.log(props);
props.changeTab(tabHead.value);
});
const nextPage = () => {
if (props.activeTab) {
router.push(
"/probation/detail/add/08db721d-ade4-480e-8d84-0853946a0ea5/f4ce5428-98b6-4425-88fe-24c29db9f885"
);
}
// const url =
// "/probation/detail/add/08db721d-ade4-480e-8d84-0853946a0ea5/f4ce5428-98b6-4425-88fe-24c29db9f885";
// window.open(url, "_blank");
props.addData();
};
</script>
<template>
<q-header class="bg-grey-1">
<div class="bg-grey-1">
|{{tabHead}}|
<div class="col-12 row q-gutter-x-md items-center">
<q-tabs
dense
@ -47,42 +48,15 @@ const nextPage = () => {
indicator-color="grey-1"
class="text-grey-7"
>
<q-tab name="save1" label="ครั้งที่ 1" />
<q-btn
size="12px"
flat
dense
icon="mdi-download"
:disable="tabHead !== 'save1'"
:color="tabHead !== 'save1' ? 'grey' : 'add'"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
<q-menu>
<q-list style="min-width: 150px">
<q-item clickable v-close-popup>
<q-item-section avatar
><q-icon color="red" name="mdi-file-pdf"
/></q-item-section>
<q-item-section>ไฟล .PDF</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section avatar
><q-icon color="blue" name="mdi-file-word"
/></q-item-section>
<q-item-section>ไฟล .docx</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
<q-tab name="save2" label="ครั้งที่ 2" />
<q-tab v-for="i in loop" :name="`save${i}`" :label="`ครั้งที่ ${i}`">
<q-btn
size="12px"
flat
dense
icon="mdi-download"
:disable="tabHead !== 'save2'"
:color="tabHead !== 'save2' ? 'grey' : 'add'"
:disable="tabHead !== 'save'+i"
:color="tabHead !== 'save'+i ? 'grey' : 'add'"
>
<q-tooltip>ดาวนโหลด</q-tooltip>
<q-menu>
@ -102,6 +76,8 @@ const nextPage = () => {
</q-list>
</q-menu>
</q-btn>
</q-tab>
<!-- <q-tab name="save3" label="ครั้งที่ 3" />
<q-btn size="12px" flat dense icon="mdi-download" :disable="tab !== 'save3'"
:color="tab !== 'save3' ? 'grey' : 'add'">

View file

@ -1,16 +1,25 @@
<script setup lang="ts">
import { ref, defineAsyncComponent, watch, onMounted } from "vue";
import { ref, defineAsyncComponent, watch, onMounted, onUpdated } from "vue";
import { useCounterMixin } from "@/stores/mixin";
import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import { useRoute, useRouter } from "vue-router";
const Header = defineAsyncComponent(
() =>import("@/modules/05_placement/components/probation/FormEvaluation/Header.vue")
);
const FormSaveResult = defineAsyncComponent(
() => import( "@/modules/05_placement/components/probation/FormEvaluation/FormSaveResult.vue")
);
import http from "@/plugins/http";
import config from "@/app.config";
const router = useRouter();
const route = useRoute();
const $q = useQuasar();
const mixin = useCounterMixin();
const { showLoader, hideLoader, messageError, success } = mixin;
const assignId = ref<string>(route.params.form.toString());
const personalId = ref<string>(route.params.personalId.toString());
const evaluate = ref<any>([]);
const tabHead = ref<string>("save1");
@ -18,98 +27,60 @@ const tabs = ref<any>([]);
const tab = ref<string>("save1");
const activeTab = ref<string>("tab2");
const props = defineProps({
activeTab: String,
onMounted(async () => {
await fecthAssign(assignId.value);
tab.value ='save1'
});
onMounted(() => {
console.log(props.activeTab);
// fecthAssign(assignId.value);
});
watch(props, () => {
console.log(props);
});
// const fecthAssign = async (id: string) => {
// showLoader();
// await http
// .get(config.API.formevaluate(id))
// .then((res: any) => {
// evaluate.value = res.data.data.evaluate;
// tabs.value = evaluate.value;
// console.log(tabs.value);
// })
// .catch((e: any) => {
// console.log(e);
// messageError($q, e);
// })
// .finally(() => {
// hideLoader();
// });
// };
const fecthAssign = async (id: string) => {
showLoader();
await http
.get(config.API.formevaluate(id))
.then((res: any) => {
evaluate.value = res.data.data.evaluate;
tabs.value = evaluate.value;
// console.log(tabs.value);
})
.catch((e: any) => {
console.log(e);
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
const changeTab = (tabVal: string) => {
console.log(tabVal);
console.log("tabVal===>",tabVal);
tab.value = tabVal;
};
const nextPage = () => {
const newTabLabel = tabs.value.length + 1;
tabs.value.push({ no: newTabLabel });
const addData = () => {
router.push(
`/probation/detail/add/${personalId.value}/${assignId.value}`
);
};
const Header = defineAsyncComponent(
() =>
import(
"@/modules/05_placement/components/probation/FormEvaluation/Header.vue"
)
);
const FormSaveResult = defineAsyncComponent(
() =>
import(
"@/modules/05_placement/components/probation/FormEvaluation/FormSaveResult.vue"
)
);
</script>
<template>
<Header :change-tab="changeTab" :activeTab="activeTab" />
<Header :change-tab="changeTab" :activeTab="activeTab" :add-data="addData" :loop="tabs.length"/>
<!-- <q-header class="bg-grey-1">
<div class="bg-grey-1">
<div class="col-12 row q-gutter-xs-md items-center">
<q-tabs
dense
v-model="tabHead"
active-class="text-primary text-weight-medium"
indicator-color="grey-1"
class="text-grey-7"
>
<q-tab
v-for="tabData in tabs"
:key="tabData.no"
:name="tabData.no"
:label="'ครั้งที่' + tabData.no"
@click="changeTab('save' + tabData.no)"
>
<q-btn
size="12px"
flat
dense
icon="mdi-download"
:disable="tabHead !== tabData.no"
:color="tabHead !== tabData.no ? 'grey' : 'add'"
>
<q-tabs dense v-model="tabHead" active-class="text-primary text-weight-medium" indicator-color="grey-1"
class="text-grey-7">
<q-tab v-for="tabData in tabs" :key="tabData.no" :name="tabData.no" :label="'ครั้งที่' + tabData.no"
@click="changeTab('save' + tabData.no)">
<q-btn size="12px" flat dense icon="mdi-download" :disable="tabHead !== tabData.no"
:color="tabHead !== tabData.no ? 'grey' : 'add'">
<q-tooltip>ดาวนโหลด</q-tooltip>
<q-menu>
<q-list style="min-width: 150px">
<q-item clickable v-close-popup>
<q-item-section avatar
><q-icon color="red" name="mdi-file-pdf"
/></q-item-section>
<q-item-section avatar><q-icon color="red" name="mdi-file-pdf" /></q-item-section>
<q-item-section>ไฟล .PDF</q-item-section>
</q-item>
<q-item clickable v-close-popup>
<q-item-section avatar
><q-icon color="blue" name="mdi-file-word"
/></q-item-section>
<q-item-section avatar><q-icon color="blue" name="mdi-file-word" /></q-item-section>
<q-item-section>ไฟล .docx</q-item-section>
</q-item>
</q-list>
@ -126,19 +97,15 @@ const FormSaveResult = defineAsyncComponent(
<q-separator />
</div>
</q-header> -->
<!-- <q-page-container>
<q-page-container>
<q-tab-panels v-model="tab" animated>
<q-tab-panel
v-for="tabName in tabs"
:key="tabName"
:name="'save' + tabName.no"
>
<q-tab-panel v-for="tabName in tabs" :key="tabName" :name="'save' + tabName.no">
<FormSaveResult :tab="tab" />
</q-tab-panel>
</q-tab-panels>
</q-page-container> -->
</q-page-container>
<q-page-container>
<!-- <q-page-container>
<q-tab-panels v-model="tab" animated>
<q-tab-panel name="save1">
<FormSaveResult :tab="tab" />
@ -148,5 +115,5 @@ const FormSaveResult = defineAsyncComponent(
<FormSaveResult :tab="tab" />
</q-tab-panel>
</q-tab-panels>
</q-page-container>
</q-page-container> -->
</template>

View file

@ -1,5 +1,3 @@
import { type } from "os";
interface ResponseTitle {
fullname: string;
organizationPositionOld: string;
@ -7,4 +5,53 @@ interface ResponseTitle {
positionTypeOld: string;
}
export type { ResponseTitle };
interface ResponseRow {
personalId: string;
citizenId: string;
fullname: string;
organizationName: string;
orgName: string;
organizationShortName: string;
positionNumber: string;
positionPath: string;
birthday: string | null;
status: string;
}
interface ResponseData {
citizenId: string;
createdAt: Date;
dateOfBirth: Date;
educationOld: string;
firstname: string;
gender: string;
id: string;
isActive: boolean;
lastname: string;
organizationName: string;
organizationPositionId: string;
organizationPositionOld: string;
organizationShortName: string;
posNoId: string;
positionId: string;
positionLevel: string;
positionLevelId: string;
positionLevelOld: string;
positionLine: string;
positionLineId: string;
positionNumber: string;
positionNumberOld: string;
positionPath: string;
positionPathSide: string;
positionPathSideId: string;
positionType: string;
positionTypeId: string;
positionTypeOld: string;
prefix: string;
reason: string;
recruitDate: Date;
salary: number;
status: string;
}
export type { ResponseTitle, ResponseData, ResponseRow };

View file

@ -24,12 +24,16 @@
<div class="col-xs-12 col-sm-12 row">
<q-separator />
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<q-input
<q-select
class="col-10"
dense
outlined
v-model="roundInsig"
:options="options"
option-value="value"
option-label="label"
label="รอบการเสนอขอพระราชทานเครื่องราชฯ"
@update:model-value="updateDateRange"
/>
<datepicker
menu-class-name="modalfix"
@ -210,9 +214,12 @@ const dateEnd = ref<Date>(new Date());
const yearly = ref<number>(new Date().getFullYear());
const files = ref<any>();
const fileDocDataUpload = ref<File[]>([]);
const roundInsig = ref<string>("");
const roundInsig = ref<any>();
const datelast = ref<number>(1);
const options = ref([
{label:"ครั้งที่ 1",value:1},
{label:"ครั้งที่ 2",value:2}
])
onMounted(async () => {
await fetchData();
});
@ -312,6 +319,18 @@ const checkSave = async () => {
// };
// return valueData;
// };
const updateDateRange = () => {
// console.log("test")
if (roundInsig.value.value == 1) {
dateStart.value = new Date(new Date().getFullYear(), 9, 1);
dateEnd.value = new Date(new Date().getFullYear() + 1, 3, 29);
console.log(1)
} else if (roundInsig.value.value == 2) {
dateStart.value = new Date(new Date().getFullYear(), 3, 29);
dateEnd.value = new Date(new Date().getFullYear() + 1, 6, 28);
console.log(2)
}
};
const addData = async () => {
const formData = new FormData();

View file

@ -1,183 +1,3 @@
<template>
<div class="toptitle text-dark col-12 row items-center">
รายการรอบการเสนอขอพระราชทานเครองราชอสรยาภรณ
</div>
<q-card flat bordered class="col-12 q-mt-sm q-pa-md">
<div class="row q-col-gutter-sm">
<div class="row col-12 q-col-gutter-sm">
<div>
<q-btn
@click="clickAdd()"
size="12px"
flat
round
color="add"
icon="mdi-plus"
>
<q-tooltip>เพมรายการรอบการเสนอขอ</q-tooltip>
</q-btn>
</div>
<q-space />
<q-input
class="col-xs-12 col-sm-3 col-md-2"
standout
dense
v-model="filterKeyword"
ref="filterRef"
outlined
debounce="300"
placeholder="ค้นหา"
>
<template v-slot:append>
<q-icon v-if="filterKeyword == ''" name="search" />
<q-icon
v-if="filterKeyword !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</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"
class="col-xs-12 col-sm-3 col-md-2"
/>
</div>
<div class="col-12">
<q-table
ref="table"
:columns="columns"
:rows="rows"
:filter="filterKeyword"
row-key="Order"
flat
bordered
:paging="true"
dense
class="custom-header-table"
v-bind="attrs"
:visible-columns="visibleColumns"
:pagination-label="paginationLabel"
v-model:pagination="pagination"
>
<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-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td key="round" :props="props" @click="clickEdit(props.row)">
{{ props.row.round }}
</q-td>
<q-td key="year" :props="props" @click="clickEdit(props.row)">
{{ props.row.year }}
</q-td>
<q-td
key="startDate"
:props="props"
@click="clickEdit(props.row)"
>
{{ props.row.startDate }}
</q-td>
<q-td key="endDate" :props="props" @click="clickEdit(props.row)">
{{ props.row.endDate }}
</q-td>
<q-td key="status" :props="props" @click="clickEdit(props.row)">
<q-icon
v-if="props.row.status == true"
name="mdi-close"
color="grey-5"
class="text-h5"
@click="clickEdit(props.row)"
/>
<q-icon
v-else
name="mdi-check"
color="positive"
class="text-h5"
@click="clickEdit(props.row)"
/>
</q-td>
<q-td key="statusRoyal" :props="props">
<q-icon
v-if="props.row.statusRoyal == 'ยังไม่ได้เสนอ'"
name="mdi-timer-sand"
color="orange"
class="text-h5"
@click="clickEdit(props.row)"
/>
<q-icon
v-else
name="mdi-check"
color="positive"
class="text-h5"
@click="clickEdit(props.row)"
/>
</q-td>
<q-td auto-width>
<q-btn
dense
size="12px"
flat
round
color="light-blue-8"
@click.stop.prevent="clickProposals(props.row.file)"
icon="mdi-file-download"
>
<q-tooltip>ดาวนโหลดเอกสารประกอบ </q-tooltip>
</q-btn>
</q-td>
<q-td auto-width>
<q-btn
dense
size="12px"
flat
round
color="red"
@click="clickDelete(props.row.id)"
icon="mdi-delete"
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</q-table>
</div>
</div>
</q-card>
</template>
<script setup lang="ts">
import { ref, useAttrs, onMounted } from "vue";
import type { QTableProps } from "quasar";
@ -216,7 +36,7 @@ const visibleColumns = ref<string[]>([
"year",
"startDate",
"endDate",
"status",
// "status",
"statusRoyal",
]); //
@ -436,6 +256,187 @@ const paginationLabel = (start: string, end: string, total: string) => {
else return start + "-" + end + " ใน " + total;
};
</script>
<template>
<div class="toptitle text-dark col-12 row items-center">
รายการรอบการเสนอขอพระราชทานเครองราชอสรยาภรณ
</div>
<q-card flat bordered class="col-12 q-mt-sm q-pa-md">
<div class="row q-col-gutter-sm">
<div class="row col-12 q-col-gutter-sm">
<div>
<q-btn
@click="clickAdd()"
size="12px"
flat
round
color="add"
icon="mdi-plus"
>
<q-tooltip>เพมรายการรอบการเสนอขอ</q-tooltip>
</q-btn>
</div>
<q-space />
<q-input
class="col-xs-12 col-sm-3 col-md-2"
standout
dense
v-model="filterKeyword"
ref="filterRef"
outlined
debounce="300"
placeholder="ค้นหา"
>
<template v-slot:append>
<q-icon v-if="filterKeyword == ''" name="search" />
<q-icon
v-if="filterKeyword !== ''"
name="clear"
class="cursor-pointer"
@click="resetFilter"
/>
</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"
class="col-xs-12 col-sm-3 col-md-2"
/>
</div>
<div class="col-12">
<q-table
ref="table"
:columns="columns"
:rows="rows"
:filter="filterKeyword"
row-key="Order"
flat
bordered
:paging="true"
dense
class="custom-header-table"
v-bind="attrs"
:visible-columns="visibleColumns"
:pagination-label="paginationLabel"
v-model:pagination="pagination"
>
<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-th auto-width />
</q-tr>
</template>
<template v-slot:body="props">
<q-tr :props="props" class="cursor-pointer">
<q-td key="round" :props="props" @click="clickEdit(props.row)">
{{ props.row.round }}
</q-td>
<q-td key="year" :props="props" @click="clickEdit(props.row)">
{{ props.row.year }}
</q-td>
<q-td
key="startDate"
:props="props"
@click="clickEdit(props.row)"
>
{{ props.row.startDate }}
</q-td>
<q-td key="endDate" :props="props" @click="clickEdit(props.row)">
{{ props.row.endDate }}
</q-td>
<q-td key="status" :props="props" @click="clickEdit(props.row)">
<q-icon
v-if="props.row.status == true"
name="mdi-close"
color="grey-5"
class="text-h5"
@click="clickEdit(props.row)"
/>
<q-icon
v-else
name="mdi-check"
color="positive"
class="text-h5"
@click="clickEdit(props.row)"
/>
</q-td>
<q-td key="statusRoyal" :props="props">
<q-icon
v-if="props.row.statusRoyal == 'ยังไม่ได้เสนอ'"
name="mdi-timer-sand"
color="orange"
class="text-h5"
@click="clickEdit(props.row)"
/>
<q-icon
v-else
name="mdi-check"
color="positive"
class="text-h5"
@click="clickEdit(props.row)"
/>
</q-td>
<q-td auto-width>
<q-btn
dense
size="12px"
flat
round
color="light-blue-8"
@click.stop.prevent="clickProposals(props.row.file)"
icon="mdi-file-download"
>
<q-tooltip>ดาวนโหลดเอกสารประกอบ </q-tooltip>
</q-btn>
</q-td>
<q-td auto-width>
<q-btn
dense
size="12px"
flat
round
color="red"
@click="clickDelete(props.row.id)"
icon="mdi-delete"
>
<q-tooltip>ลบขอม</q-tooltip>
</q-btn>
</q-td>
</q-tr>
</template>
<template v-slot:pagination="scope">
<q-pagination
v-model="pagination.page"
active-color="primary"
color="dark"
:max="scope.pagesNumber"
:max-pages="5"
size="sm"
boundary-links
direction-links
></q-pagination>
</template>
</q-table>
</div>
</div>
</q-card>
</template>
<style lang="scss" scope>
.filter-card {

View file

@ -24,12 +24,16 @@
<div class="col-xs-12 col-sm-12 row">
<q-separator />
<div class="col-12 row q-pa-sm q-col-gutter-sm">
<q-input
<q-select
class="col-10"
dense
outlined
v-model="roundCoin"
label="รอบการเสนอขอพระราชทานเหรียญจักรพรรดิมาลา"
:options="options"
option-value="value"
option-label="label"
@update:model-value="updateDateRange"
/>
<datepicker
menu-class-name="modalfix"
@ -210,9 +214,12 @@ const dateEnd = ref<Date>(new Date());
const yearly = ref<number>(new Date().getFullYear());
const files = ref<any>();
const fileDocDataUpload = ref<File[]>([]);
const roundCoin = ref<string>("");
const roundCoin = ref<any>("");
const datelast = ref<number>(1);
const options = ref([
{label:"ครั้งที่ 1",value:1},
{label:"ครั้งที่ 2",value:2}
])
onMounted(async () => {
await fetchData();
});
@ -336,7 +343,18 @@ const checkSave = async () => {
// };
// return valueData;
// };
const updateDateRange = () => {
// console.log("test")
if (roundCoin.value.value == 1) {
dateStart.value = new Date(new Date().getFullYear(), 9, 1);
dateEnd.value = new Date(new Date().getFullYear() + 1, 3, 29);
console.log(1)
} else if (roundCoin.value.value == 2) {
dateStart.value = new Date(new Date().getFullYear(), 3, 29);
dateEnd.value = new Date(new Date().getFullYear() + 1, 6, 28);
console.log(2)
}
};
const addData = async () => {
const formData = new FormData();
formData.append("name", roundCoin.value);

View file

@ -216,7 +216,7 @@ const visibleColumns = ref<string[]>([
"year",
"startDate",
"endDate",
"status",
// "status",
"statusRoyal",
]); //

View file

@ -1,34 +1,57 @@
<script setup lang="ts">
import { ref } from "vue";
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import type {
ResponseInbox,
DataInbox,
} from "@/interface/response/dashboard/dashboard";
const $q = useQuasar();
const mixin = useCounterMixin(); //
const {
showLoader,
hideLoader,
dialogMessage,
success,
messageError,
date2Thai,
} = mixin;
const iteminbox = ref<any>([]);
const splitterModel = ref<number>(30);
const link = ref<number>(1);
const inboxList = ref<any>([
const link = ref<string>("0");
const inboxList = ref<DataInbox[]>([
{
no: 1,
no: "1",
sender: "เจ้าหน้าที่ทะเบียนประวัติ",
subject: "ขอแก้ไขข้อมูลทะเบียนประวัติ",
timereceive: "13/12/2565",
timereceive: new Date(),
body: "ขอแก้ไขข้อมูลทะเบียนประวัติ เรื่อง ชื่อ-นามสกุล",
ratingModel: 0,
},
{
no: 2,
no: "2",
sender: "เจ้าหน้าที่ทะเบียนประวัติ",
subject: "ขอแก้ไขข้อมูลทะเบียนประวัติ",
timereceive: "13/12/2565",
timereceive: new Date(),
body: "ขอแก้ไขข้อมูลทะเบียนประวัติ เรื่อง ชื่อ-นามสกุล",
ratingModel: 1,
ratingModel: 0,
},
]);
const data = ref<any>([
{
no: 1,
sender: "เจ้าหน้าที่ทะเบียนประวัติ",
subject: "ขอแก้ไขข้อมูลทะเบียนประวัติ",
timereceive: "13/12/2565",
body: "ขอแก้ไขข้อมูลทะเบียนประวัติ เรื่อง ชื่อ-นามสกุล",
},
const data = ref<DataInbox[]>([
// {
// no: "1",
// sender: "",
// subject: "",
// timereceive: new Date(),
// body: " -",
// ratingModel: 0,
// },
]);
const btnReply = ref<boolean>(true);
const listpayload = ref<any>([]);
@ -51,6 +74,46 @@ const barStyle = ref<any>({
width: "9px",
opacity: 0.2,
});
onMounted(async () => {
await getData();
});
const getData = async () => {
showLoader();
await http
.get(config.API.msgInbox)
.then((res: any) => {
const response = res.data.result;
// console.log(response);
let list: DataInbox[] = [];
response.map((e: ResponseInbox) => {
list.push({
no: e.id ?? "",
sender:
e.createdFullName == "" || e.createdFullName == null
? "เจ้าหน้าที่"
: e.createdFullName,
subject: e.subject ?? "",
timereceive: new Date(e.createdAt),
body: e.body ?? "",
ratingModel: 0,
});
});
inboxList.value = list;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
const selectInbox = (id: string) => {
link.value = id;
data.value = inboxList.value.filter((r) => r.no == id);
};
</script>
<!-- page:หนาแรก -->
@ -88,10 +151,11 @@ const barStyle = ref<any>({
class="mytry"
:active="link === contact.no"
active-class="my-menu-link"
@click="selectInbox(contact.no)"
>
<q-item-section>
<q-item-label caption class="text-weight-light">{{
contact.timereceive
date2Thai(contact.timereceive)
}}</q-item-label>
<q-item-label class="text-weight-medium">{{
contact.sender
@ -174,7 +238,9 @@ const barStyle = ref<any>({
</q-item-section>
<q-item-section side top>
<q-item-label caption>{{ d.timereceive }}</q-item-label>
<q-item-label caption>{{
date2Thai(d.timereceive)
}}</q-item-label>
<div class="text-grey-8 q-gutter-xs q-pt-sm">
<q-btn
flat

View file

@ -5,6 +5,11 @@ import { useRoute, useRouter } from "vue-router";
import { useDataStore } from "@/stores/data";
import { storeToRefs } from "pinia";
import { scroll, useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import type {
ScrollType,
notiType,
@ -21,6 +26,15 @@ const store = useDataStore();
const route = useRoute();
const router = useRouter();
const link = ref<string>("");
const mixin = useCounterMixin(); //
const {
showLoader,
hideLoader,
dialogMessage,
success,
messageError,
date2Thai,
} = mixin;
const $q = useQuasar();
const { tabData, loader } = storeToRefs(store);
@ -38,10 +52,10 @@ const text = ref<string>("");
const notiList = ref<notiType[]>([
{
id: 1,
id: "1",
sender: "ท",
body: "ขอแก้ไขข้อมูลทะเบียนประวัติ",
timereceive: "13/12/2565",
timereceive: new Date(),
},
]);
const options = ref<optionType[]>([
@ -64,6 +78,36 @@ const options = ref<optionType[]>([
color: "indigo",
},
]);
const getDataNotification = async () => {
showLoader();
await http
.get(config.API.msgNotificate)
.then((res: any) => {
const response = res.data.result;
// console.log("response", response);
let list: notiType[] = [];
response.map((e: any) => {
list.push({
id: e.id,
sender:
e.createdFullName == "" || e.createdFullName == null
? "เจ้าหน้าที่"[0]
: e.createdFullName[0],
body: e.body ?? "",
timereceive: new Date(e.createdAt),
});
});
notiList.value = list;
})
.catch((e) => {
messageError($q, e);
})
.finally(() => {
hideLoader();
});
};
/**
* ใหแสดง แทปดานขวา เมอเขาหน รายละเอยดทะเบยนประว
*/
@ -166,7 +210,8 @@ const activeBtn = () => {
* เรมเขามา state rightActive เป state โชว มขวา
* งจ boolean งตอง set
*/
onMounted(() => {
onMounted(async () => {
await getDataNotification();
myEventHandler(null, false);
window.addEventListener("resize", (e: any) => {
myEventHandler(e, true);
@ -221,7 +266,8 @@ const myEventHandler = (e: any, setSCroll: boolean) => {
*/
const activeMenu = (path: string) => {
if (path == "dashboard" && route.fullPath == "/") return true;
if (path == "registry" && route.fullPath == "/registry-employee") return false;
if (path == "registry" && route.fullPath == "/registry-employee")
return false;
if (path == "registry" && route.fullPath == "/") return false;
// if (path != "registry" && path == "registryEmployee" && route.fullPath == "/registryEmployee") return true;
const bool = route.fullPath.includes(`/${path}`);
@ -427,7 +473,7 @@ if (keycloak.tokenParsed != null) {
n.body
}}</q-item-label>
<q-item-label caption class="row items-center text-grey-7">{{
n.timereceive
date2Thai(n.timereceive)
}}</q-item-label>
</q-item-section>
<q-btn