fix:registry

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2025-12-16 14:09:16 +07:00
parent 18101353a1
commit 4c569a1d3f
10 changed files with 502 additions and 127 deletions

View file

@ -62,10 +62,10 @@ const formData = reactive<FormDataSalary>({
positionPathSide: "", ///
positionExecutive: "", //
positionExecutiveField: "", //
amount: null, //
amountSpecial: null, //
positionSalaryAmount: null, //
mouthSalaryAmount: null, //
amount: undefined, //
amountSpecial: undefined, //
positionSalaryAmount: undefined, //
mouthSalaryAmount: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -91,10 +91,10 @@ const formReadonly = reactive<FormDataSalary>({
positionPathSide: "", ///
positionExecutive: "", //
positionExecutiveField: "", //
amount: null, //
amountSpecial: null, //
positionSalaryAmount: null, //
mouthSalaryAmount: null, //
amount: undefined, //
amountSpecial: undefined, //
positionSalaryAmount: undefined, //
mouthSalaryAmount: undefined, //
orgRoot: "", //
orgChild1: "", // 1
orgChild2: "", // 2
@ -377,10 +377,10 @@ function onClickCloseDialog() {
formData.positionPathSide = "";
formData.positionExecutive = "";
formData.positionExecutiveField = "";
formData.amount = null;
formData.amountSpecial = null;
formData.positionSalaryAmount = null;
formData.mouthSalaryAmount = null;
formData.amount = undefined;
formData.amountSpecial = undefined;
formData.positionSalaryAmount = undefined;
formData.mouthSalaryAmount = undefined;
formData.orgRoot = "";
formData.orgChild1 = "";
formData.orgChild2 = "";
@ -405,9 +405,9 @@ function onClickCloseDialog() {
formReadonly.positionPathSide = "";
formReadonly.positionExecutive = "";
formReadonly.positionExecutiveField = "";
formReadonly.amount = null;
formReadonly.positionSalaryAmount = null;
formReadonly.mouthSalaryAmount = null;
formReadonly.amount = undefined;
formReadonly.positionSalaryAmount = undefined;
formReadonly.mouthSalaryAmount = undefined;
formReadonly.orgRoot = "";
formReadonly.orgChild1 = "";
formReadonly.orgChild2 = "";

View file

@ -5,6 +5,8 @@ import { useEditPosDataStore } from "@/modules/04_registryPerson/stores/Edit";
import type { DataOption } from "@/modules/04_registryPerson/interface/index/Main";
import type { FormDataSalary } from "@/modules/04_registryPerson/interface/request/Edit";
import CurruncyInput from "@/components/CurruncyInput.vue";
const { date2Thai } = useCounterMixin();
const store = useEditPosDataStore();
@ -597,7 +599,7 @@ function classInput(val: boolean) {
<div class="col-12">
<div class="row q-col-gutter-sm">
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
ref="salaryRef"
@ -605,15 +607,20 @@ function classInput(val: boolean) {
outlined
v-model="formData.amount"
label="เงินเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
ref="amountSpecialRef"
@ -621,39 +628,54 @@ function classInput(val: boolean) {
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
dense
outlined
v-model="formData.positionSalaryAmount"
label="เงินประจำตำแหน่ง"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
lazy-rules
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินประจำตำแหน่งต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
<div class="col-xs-6 col-sm-6 col-md-4">
<q-input
<CurruncyInput
:class="classInput(isReadonly)"
:readonly="isReadonly"
dense
outlined
v-model="formData.mouthSalaryAmount"
label="เงินค่าตอบแทนรายเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนรายเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
</div>
</div>

View file

@ -20,6 +20,7 @@ import type {
import DialogForm from "@/modules/04_registryPerson/views/edit/components/DialogForm.vue";
import DialogSort from "@/modules/04_registryPerson/views/edit/components/DialogSort.vue";
import CurruncyInput from "@/components/CurruncyInput.vue";
const $q = useQuasar();
const route = useRoute();
@ -47,6 +48,10 @@ const statusCheckEdit = defineModel<string>("statusCheckEdit", {
required: true,
});
const amountRef = ref<any>(null);
const amountSpecialRef = ref<any>(null);
const currencyPopupRef = ref<any>(null);
//Table
const isLoad = ref<boolean>(true);
const rowIndex = ref<number>(0);
@ -341,7 +346,6 @@ function onEditData(index: number) {
rowIndex.value = index;
modal.value = true;
isAddPosition.value = index === -1; // index -1
console.log(`isAddPosition: ${isAddPosition.value}`);
}
/**
@ -559,6 +563,14 @@ function onShow(data: DataPosition, colName: string) {
* @param close
*/
async function onSave(val: any, id: string, close?: () => void) {
// validation amountRef validate method
if (amountRef.value && typeof amountRef.value.validate === "function") {
const isValid = amountRef.value.validate();
if (isValid === false) {
return; // validation
}
}
if (isUpdateData.value) {
showLoader();
const isCol = (key: string) => colNameMain.value === key;
@ -746,6 +758,97 @@ function onUpdateData() {
isUpdateData.value = true;
}
/**
* งกนตรวจสอบ validation และบนทกขอมลสำหรบทกประเภท
*/
async function validateAndSave(
val: any,
id: string,
close?: () => void,
fieldType: "amount" | "currency" | "normal" = "normal"
) {
let isValid = true;
// validation amount fields
if (fieldType === "amount") {
// Validate
if (formData.amount !== null && formData.amount !== undefined) {
const amountNum =
typeof formData.amount === "number"
? formData.amount
: Number(String(formData.amount).replace(/,/g, ""));
if (amountNum > 10000000) {
isValid = false;
}
}
// Validate
if (
isValid &&
formData.amountSpecial !== null &&
formData.amountSpecial !== undefined
) {
const amountSpecialNum =
typeof formData.amountSpecial === "number"
? formData.amountSpecial
: Number(String(formData.amountSpecial).replace(/,/g, ""));
if (amountSpecialNum > 10000000) {
isValid = false;
}
}
// Force validate refs
if (
isValid &&
amountRef.value &&
typeof amountRef.value.validate === "function"
) {
const amountValid = amountRef.value.validate();
isValid = isValid && amountValid !== false;
}
if (
isValid &&
amountSpecialRef.value &&
typeof amountSpecialRef.value.validate === "function"
) {
const amountSpecialValid = amountSpecialRef.value.validate();
isValid = isValid && amountSpecialValid !== false;
}
}
// validation currency fields
else if (fieldType === "currency") {
// Validate
if (val !== null && val !== undefined) {
const numVal =
typeof val === "number" ? val : Number(String(val).replace(/,/g, ""));
if (numVal > 10000000) {
isValid = false;
}
}
// Force validate ref
if (
isValid &&
currencyPopupRef.value &&
typeof currencyPopupRef.value.validate === "function"
) {
const currencyValid = currencyPopupRef.value.validate();
isValid = isValid && currencyValid !== false;
}
}
// validation
if (isValid) {
await onSave(val, id, close);
return true;
} else {
// validation (rules error message )
return false;
}
}
onMounted(async () => {
await Promise.all([fetchData(), fetchType()]);
});
@ -946,7 +1049,11 @@ onMounted(async () => {
label-set="บันทึก"
label-cancel="ยกเลิก"
@before-show="onShow(props.row, col.name)"
:persistent="col.name === 'commandNo'"
:persistent="
col.name === 'commandNo' || col.name === 'amount'
"
:buttons="false"
@save="null"
>
<div class="q-mb-xs">
{{ `แก้ไข${col.label}` }}
@ -999,27 +1106,65 @@ onMounted(async () => {
</div>
<div class="q-gutter-sm" v-if="col.name === 'amount'">
<q-input
<CurruncyInput
ref="amountRef"
:edit="true"
dense
outlined
v-model="formData.amount"
label="เงินเดือน"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินเดือนต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
<q-input
<CurruncyInput
ref="amountSpecialRef"
:edit="true"
dense
outlined
v-model="formData.amountSpecial"
label="เงินค่าตอบแทนพิเศษ"
mask="###,###,###,###"
reverse-fill-mask
hide-bottom-space
lazy-rules
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || 'เงินค่าตอบแทนพิเศษต้องไม่เกิน 10,000,000 บาท';
}
]"
/>
<!-- Custom buttons สำหร amount -->
<div class="row justify-around q-pt-sm">
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'amount'
)
"
/>
</div>
</div>
<div class="q-gutter-sm" v-else-if="col.name === 'posNo'">
@ -1165,7 +1310,11 @@ onMounted(async () => {
</q-select>
</div>
<div class="row justify-around q-pt-sm">
<!-- Default buttons สำหร fields นๆ (ไมใช amount และ positionLevel) -->
<div
v-if="col.name !== 'amount' && col.name !== 'positionLevel'"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
@ -1177,7 +1326,40 @@ onMounted(async () => {
flat
color="primary"
label="บันทึก"
@click="onSave(formData, props.row.id, scope.cancel)"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
<!-- Custom buttons สำหร positionLevel -->
<div
v-if="col.name === 'positionLevel'"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
@ -1205,6 +1387,8 @@ onMounted(async () => {
label-set="บันทึก"
label-cancel="ยกเลิก"
@before-show="onShow(props.row, col.name)"
:buttons="false"
@save="null"
>
<div class="q-mb-xs">
{{ `แก้ไข${col.label}` }}
@ -1276,7 +1460,14 @@ onMounted(async () => {
flat
color="primary"
label="บันทึก"
@click="onSave(formData, props.row.id, scope.cancel)"
@click="
validateAndSave(
formData,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
@ -1293,13 +1484,37 @@ onMounted(async () => {
v-slot="scope"
:persistent="
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign'
col.name === 'commandDateSign' ||
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
"
v-model="props.row[col.name]"
buttons
:buttons="
col.name !== 'mouthSalaryAmount' &&
col.name !== 'positionSalaryAmount' &&
col.name !== 'commandDateAffect' &&
col.name !== 'commandDateSign' &&
col.name !== 'positionName' &&
col.name !== 'positionExecutive' &&
col.name !== 'positionExecutiveField' &&
col.name !== 'remark' &&
col.name !== 'positionType'
"
label-set="บันทึก"
label-cancel="ยกเลิก"
@save="onSave"
@save="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount' ||
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign' ||
col.name === 'positionName' ||
col.name === 'positionExecutive' ||
col.name === 'positionExecutiveField' ||
col.name === 'remark' ||
col.name === 'positionType'
? null
: onSave
"
@before-show="onShow(props.row, col.name)"
>
<div class="q-mb-xs">
@ -1360,19 +1575,26 @@ onMounted(async () => {
@update:model-value="onUpdateData"
/>
<q-input
<CurruncyInput
v-else-if="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
"
:ref="`currencyRef_${col.name}`"
:edit="true"
dense
outlined
v-model="scope.value"
mask="###,###,###,###"
reverse-fill-mask
lazy-rules
hide-bottom-space
@update:model-value="onUpdateData"
:rules="[
(val:number) => {
if (!val) return true;
const numVal = typeof val === 'number' ? val : Number(String(val).replace(/,/g, ''));
return numVal <= 10000000 || `${col.label}ต้องไม่เกิน 10,000,000 บาท`;
}
]"
/>
<q-select
@ -1409,6 +1631,77 @@ onMounted(async () => {
</q-item>
</template>
</q-select>
<!-- Custom buttons สำหร persistent fields -->
<div
v-if="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount' ||
col.name === 'commandDateAffect' ||
col.name === 'commandDateSign'
"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
col.name === 'mouthSalaryAmount' ||
col.name === 'positionSalaryAmount'
? validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'currency'
)
: validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
<!-- Default buttons สำหร fields นๆ ไมใช persistent -->
<div
v-else-if="
col.name === 'positionName' ||
col.name === 'positionExecutive' ||
col.name === 'positionExecutiveField' ||
col.name === 'remark' ||
col.name === 'positionType'
"
class="row justify-around q-pt-sm"
>
<q-btn
flat
color="primary"
label="ยกเลิก"
@click="scope.cancel"
/>
<q-btn
flat
color="primary"
label="บันทึก"
@click="
validateAndSave(
scope.value,
props.row.id,
scope.cancel,
'normal'
)
"
/>
</div>
</q-popup-edit>
</div>
</q-td>