ระบบการพัฒนา => รายการโครงการปรับการแสดงผลแบบฟอร์ม

This commit is contained in:
DESKTOP-1R2VSQH\Lenovo ThinkPad E490 2024-08-08 11:53:58 +07:00
parent 41a0d80b64
commit 20e99fe23b
13 changed files with 1791 additions and 1319 deletions

View file

@ -1,5 +1,5 @@
<script setup lang="ts">
import { onMounted, reactive, ref, computed } from "vue";
import { onMounted, reactive, ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
@ -8,6 +8,7 @@ import { useCounterMixin } from "@/stores/mixin";
import type {
DataOptionTechnique,
FormProjectDetail,
DataOption,
} from "@/modules/15_development/interface/index/Main";
import type { DataStrategic } from "@/modules/15_development/interface/response/Main";
@ -16,10 +17,13 @@ import { useDevelopmentDataStore } from "@/modules/15_development/store/developm
import http from "@/plugins/http";
import config from "@/app.config";
const isChangeData = defineModel<boolean>("isChangeData", { required: true });
const props = defineProps({
prevStep: { type: Function, required: true },
nextStep: { type: Function, required: true },
onCheckChangeData: { type: Function, required: true },
});
const step = ref<string>("");
const reasonPlanned70 = ref<string>("");
const reasonPlanned20 = ref<string>("");
@ -52,16 +56,19 @@ const $q = useQuasar();
const store = useDevelopmentDataStore();
const route = useRoute();
const projectId = ref<string>(route.params.id.toLocaleString());
const { showLoader, hideLoader, dialogConfirm, messageError, success } =
const { showLoader, hideLoader, messageError, date2Thai, diffDay } =
useCounterMixin();
const checkRoutePermission = ref<boolean>(
route.name == "developmentDetailPage"
);
const projectTypeOp = ref<String[]>([
"โครงการตามยุทธศาสตร์",
"โครงการตามภารกิจประจำของหน่วยงาน",
"โครงการใหม่",
"โครงการต่อเนื่อง",
const projectTypeOp = ref<any[]>([
{ label: "โครงการตามยุทธศาสตร์", value: "โครงการตามยุทธศาสตร์" },
{
label: "โครงการตามภารกิจประจำของหน่วยงาน",
value: "โครงการตามภารกิจประจำของหน่วยงาน",
},
{ label: "โครงการใหม่", value: "โครงการใหม่" },
{ label: "โครงการต่อเนื่อง", value: "โครงการต่อเนื่อง" },
]);
/** option */
@ -169,6 +176,10 @@ const formData = reactive<FormProjectDetail>({
strategyChildPlannedNode: 0, //node
strategyChildActualId: null, //id
strategyChildActualNode: 0, //node
dateStart: null, //
dateEnd: null, //
totalDate: null, // ()
developmentAddresss: [{ address: "", provinceId: "" }], // ,
});
const nodes = ref<any>([]);
@ -179,6 +190,25 @@ const noData = ref<string>("ไม่มีข้อมูล");
const expanded = ref<Array<string | null>>([]);
const expanded2 = ref<Array<string | null>>([]);
/**
* งขอม งหว
*/
function fetchProvince() {
http
.get(config.API.province)
.then((res) => {
const data = res.data.result;
provinceOp.value = data.map((item: DataOption) => ({
id: item.id,
name: item.name,
}));
provinceOpMain.value = provinceOp.value;
})
.catch((e) => {
messageError($q, e);
});
}
/** ดึงข้อมูลทั้งหมด */
function fetchData() {
showLoader();
@ -186,7 +216,6 @@ function fetchData() {
.get(config.API.developmentMainTab("tab3", projectId.value))
.then((res) => {
const data = res.data.result;
formData.developmentProjectTypes = data.developmentProjectTypes;
formData.projectModal = data.projectModal;
formData.isBackPlanned = data.isBackPlanned;
@ -205,6 +234,13 @@ function fetchData() {
data.developmentProjectTechniqueActuals;
formData.projectModalPlanned = data.projectModalPlanned;
formData.projectModalActual = data.projectModalActual;
// formData.dateStart = data.dateStart;
// formData.dateEnd = data.dateEnd;
// formData.totalDate = data.totalDate;
// formData.developmentAddresss = data.developmentAddresss.map((e: any) => ({
// address: e.address,
// provinceId: e.provinceId,
// }));
const arrayExpanded = [
data.strategyChild1Planned,
@ -250,6 +286,7 @@ function fetchData() {
})
.finally(() => {
hideLoader();
isChangeData.value = false;
});
}
@ -267,39 +304,16 @@ function fetchTree() {
})
.finally(() => {
hideLoader();
isChangeData.value = false;
});
}
/** Main save */
async function onSubmit() {
// dialogConfirm($q, async () => {
function onSubmit() {
showLoader();
await http
http
.put(config.API.developmentMainTab("tab3", projectId.value), {
developmentProjectTypes: formData.developmentProjectTypes,
projectModal: formData.projectModal,
isBackPlanned: formData.isBackPlanned,
isHoldPlanned: formData.isHoldPlanned,
projectDayBackPlanned: formData.isBackPlanned
? formData.projectDayBackPlanned
: null,
projectDayHoldPlanned: formData.projectDayHoldPlanned,
projectNigthHoldPlanned: formData.projectNigthHoldPlanned,
developmentProjectTechniquePlanneds:
formData.developmentProjectTechniquePlanneds,
isBackActual: formData.isBackActual,
isHoldActual: formData.isHoldActual,
projectDayBackActual: formData.projectDayBackActual,
projectDayHoldActual: formData.projectDayHoldActual,
projectNigthHoldActual: formData.projectNigthHoldActual,
developmentProjectTechniqueActuals:
formData.developmentProjectTechniqueActuals,
projectModalActual: formData.projectModalActual,
projectModalPlanned: formData.projectModalPlanned,
strategyChildPlannedId: formData.strategyChildPlannedId,
strategyChildPlannedNode: formData.strategyChildPlannedNode,
strategyChildActualId: formData.strategyChildActualId,
strategyChildActualNode: formData.strategyChildActualNode,
...formData,
reasonPlanned70: reasonPlanned70.value,
reasonPlanned20: reasonPlanned20.value,
reasonPlanned10: reasonPlanned10.value,
@ -307,16 +321,14 @@ async function onSubmit() {
reasonActual20: reasonActual20.value,
reasonActual10: reasonActual10.value,
})
.then(() => {
// success($q, "");
// fetchData();
step.value == "next" ? props.nextStep() : props.prevStep();
})
.then(() => {})
.catch((err) => {
messageError($q, err);
hideLoader();
})
.finally(() => {
isChangeData.value = false;
});
// });
}
/**
@ -333,36 +345,89 @@ function updateSelected(data: DataStrategic, type: string) {
formData.strategyChildActualNode = data.level;
}
}
/** ดึงข้อมูลเมื่อคอมโพเนนต์โหลดเสร็จสมบูรณ์ */
onMounted(() => {
const provinceOp = ref<DataOption[]>([]);
const provinceOpMain = ref<DataOption[]>([]);
/** เพิ่มข้อมูลสถานที่ดำเนินการ */
function onClickAddLocation() {
const data = {
address: "",
provinceId: "",
};
formData.developmentAddresss.push(data);
}
/** ลบข้อมูล */
function onClickDeleteLocation(index: number) {
formData.developmentAddresss.splice(index, 1);
}
/**
* Fuction Filter งหว
* @param val าตวพมพนหา
* @param update กครงทมพ
*/
const filterSelector = (val: string, update: Function) => {
update(() => {
provinceOp.value = provinceOpMain.value.filter(
(v: DataOption) => v.name.indexOf(val) > -1
);
});
};
watch(
() => [formData.dateStart, formData.dateEnd],
() => {
if (formData.dateStart && formData.dateEnd) {
formData.totalDate = diffDay(formData.dateStart, formData.dateEnd);
}
}
);
/**
* function ไปย Tab อไป
*/
function onNextTab() {
step.value == "next" ? props.nextStep() : props.prevStep();
}
/**
* งขอมลเมอคอมโพเนนตโหลดเสรจสมบรณ
*/
onMounted(async () => {
fetchProvince();
fetchData();
fetchTree();
});
/**
* เรยก function ไปใชหนาหล
*/
defineExpose({
onSubmit,
});
</script>
<template>
<q-form greedy @submit.prevent @validation-success="onSubmit">
<q-form greedy @submit.prevent @validation-success="onNextTab">
<div class="row q-pa-sm">
<div class="col-12">
<q-select
:readonly="checkRoutePermission"
dense
outlined
v-model="formData.developmentProjectTypes"
<div class="col-12 text-bold">ประเภทโครงการ</div>
<q-option-group
:disable="checkRoutePermission"
:options="projectTypeOp"
label="ประเภทโครงการ"
option-label="name"
option-value="id"
emit-value
map-options
multiple
class="inputgreen"
type="checkbox"
v-model="formData.developmentProjectTypes"
color="primary"
keep-color
@update:model-value="props.onCheckChangeData()"
/>
</div>
<!-- ความสอดคลองหรอเชอมโยงกบยทธศาสตร/แผน -->
<q-card bordered class="col-12 q-my-sm">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-3 q-py-xs q-px-md"
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
ความสอดคลองหรอเชอมโยงกบยทธศาสตร/แผน
</div>
@ -373,7 +438,7 @@ onMounted(() => {
<div class="col-6">
<q-card bordered class="col-12">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-3 q-py-xs q-px-md"
>
ทธศาสตร/แผน
</div>
@ -413,7 +478,10 @@ onMounted(() => {
<template v-slot:default-header="prop">
<q-item
clickable
@click.stop="updateSelected(prop.node, '1')"
@click.stop="
updateSelected(prop.node, '1'),
props.onCheckChangeData()
"
:active="
formData.strategyChildPlannedId == prop.node.id
"
@ -434,7 +502,7 @@ onMounted(() => {
<div class="col-6">
<q-card bordered class="col-12">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-3 q-py-xs q-px-md"
>
ทธศาสตร/แผน
</div>
@ -473,7 +541,10 @@ onMounted(() => {
<template v-slot:default-header="prop">
<q-item
clickable
@click.stop="updateSelected(prop.node, '2')"
@click.stop="
updateSelected(prop.node, '2'),
props.onCheckChangeData()
"
:active="formData.strategyChildActualId == prop.node.id"
active-class="my-list-link text-primary text-weight-medium"
class="row col-12 items-center text-dark q-py-xs q-pl-sm rounded-borders my-list"
@ -493,9 +564,201 @@ onMounted(() => {
</q-card-section>
</q-card>
<!-- เวลาและสถานทดำเนนการ -->
<q-card bordered class="col-12 q-my-sm">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-3 q-py-xs q-px-md"
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
เวลาและสถานทดำเนนการ
</div>
<q-separator />
<q-card-section>
<div class="row col-12 q-col-gutter-sm">
<div class="col-12 text-bold">ระยะเวลาดำเนนการ</div>
<div class="row col-12 q-col-gutter-sm">
<div class="col-12 col-sm-6 col-md-3">
<datepicker
menu-class-name="modalfix"
v-model="formData.dateStart"
:locale="'th'"
autoApply
:readonly="checkRoutePermission"
:enableTimePicker="false"
week-start="0"
:max-date="formData.dateEnd"
@update:model-value="props.onCheckChangeData()"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
class="inputgreen"
dense
:readonly="checkRoutePermission"
outlined
:model-value="
formData.dateStart
? date2Thai(formData.dateStart)
: null
"
: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 col-sm-6 col-md-3">
<datepicker
menu-class-name="modalfix"
v-model="formData.dateEnd"
:locale="'th'"
:readonly="checkRoutePermission"
autoApply
:enableTimePicker="false"
week-start="0"
:min-date="formData.dateStart"
@update:model-value="props.onCheckChangeData()"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
dense
:readonly="checkRoutePermission"
outlined
class="inputgreen"
:model-value="
formData.dateEnd ? date2Thai(formData.dateEnd) : null
"
: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 col-sm-6 col-md-3">
<q-input
dense
:readonly="checkRoutePermission"
outlined
class="inputgreen"
label="รวมระยะเวลา (วัน)"
v-model="formData.totalDate"
mask="#"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
<div class="col-12 q-mt-md">
<span class="text-bold">สถานทดำเนนการ</span>
<q-btn
v-if="!checkRoutePermission"
dense
flat
round
color="primary"
icon="add"
@click="onClickAddLocation"
>
<q-tooltip>เพมสถานทดำเนนการ</q-tooltip>
</q-btn>
</div>
<div
class="col-12"
v-for="(item, index) in formData.developmentAddresss"
>
<div class="row q-col-gutter-sm">
<div class="col-8">
<q-input
:readonly="checkRoutePermission"
outlined
dense
class="inputgreen"
v-model="formData.developmentAddresss[index].address"
label="ชื่อสถานที่"
@update:model-value="props.onCheckChangeData()"
/>
</div>
<div class="col-3">
<q-select
:readonly="checkRoutePermission"
outlined
dense
v-model="formData.developmentAddresss[index].provinceId"
label="จังหวัด"
:options="provinceOp"
option-label="name"
option-value="id"
emit-value
map-options
class="inputgreen"
use-input
@update:model-value="props.onCheckChangeData()"
@filter="
(inputValue:string, doneFn:Function) =>
filterSelector(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-1 text-center">
<q-btn
v-if="index !== 0 && !checkRoutePermission"
dense
flat
round
color="red"
icon="delete"
@click="
onClickDeleteLocation(index), props.onCheckChangeData()
"
>
<q-tooltip>ลบ</q-tooltip></q-btn
>
</div>
</div>
</div>
</div>
</q-card-section>
</q-card>
<!-- ปแบบโครงการ -->
<q-card bordered class="col-12 q-my-sm">
<div
class="col-xs-12 col-sm-12 text-weight-medium bg-grey-1 q-py-xs q-px-md"
>
ปแบบโครงการ
</div>
@ -517,6 +780,7 @@ onMounted(() => {
value="GO_BLACK"
label="ไป-กลับ"
v-model="formData.isBackPlanned"
@update:model-value="props.onCheckChangeData()"
></q-checkbox>
</div>
<div class="col-12 col-md-4">
@ -531,6 +795,7 @@ onMounted(() => {
mask="#"
reverse-fill-mask
class="inputgreen"
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
@ -546,6 +811,7 @@ onMounted(() => {
value="HOLD"
label="พักค้าง"
v-model="formData.isHoldPlanned"
@update:model-value="props.onCheckChangeData()"
></q-checkbox>
</div>
<div class="col-12 col-md-4">
@ -560,6 +826,7 @@ onMounted(() => {
mask="#"
reverse-fill-mask
class="inputgreen"
@update:model-value="props.onCheckChangeData()"
/>
</div>
<div class="col-12 col-md-4">
@ -574,6 +841,7 @@ onMounted(() => {
mask="#"
class="inputgreen"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
@ -599,11 +867,13 @@ onMounted(() => {
v-model="formData.developmentProjectTechniquePlanneds"
:options="projectTechniquesOp1"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox11">
<div class="offset-4 col-8 q-mt-sm relative-position">
<div class="other_custom_input">
<q-input
@update:model-value="props.onCheckChangeData()"
v-model="reasonPlanned70"
dense
:readonly="
@ -633,6 +903,7 @@ onMounted(() => {
v-model="formData.developmentProjectTechniquePlanneds"
:options="projectTechniquesOp2"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox12">
<div class="offset-4 col-8 q-mt-sm relative-position">
@ -647,6 +918,7 @@ onMounted(() => {
outlined
class="inputgreen"
label="กรุณาระบุ"
@update:model-value="props.onCheckChangeData()"
></q-input>
</div>
</div>
@ -667,6 +939,7 @@ onMounted(() => {
v-model="formData.developmentProjectTechniquePlanneds"
:options="projectTechniquesOp3"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox13">
<div class="offset-4 col-8 q-mt-sm relative-position">
@ -681,6 +954,7 @@ onMounted(() => {
outlined
class="inputgreen"
label="กรุณาระบุ"
@update:model-value="props.onCheckChangeData()"
></q-input>
</div>
</div>
@ -700,6 +974,7 @@ onMounted(() => {
mask="#"
reverse-fill-mask
class="inputgreen"
@update:model-value="props.onCheckChangeData()"
/>
</div>
@ -855,6 +1130,7 @@ onMounted(() => {
outlined
class="inputgreen"
label="กรุณาระบุ"
@update:model-value="props.onCheckChangeData()"
></q-input>
</div>
</div>
@ -872,6 +1148,7 @@ onMounted(() => {
label="จำนวน (รุ่น)"
mask="#"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
@ -908,20 +1185,6 @@ onMounted(() => {
>
</q-btn>
</div>
<!-- <q-separator v-if="!checkRoutePermission" />
<div class="text-right q-pa-sm" v-if="!checkRoutePermission">
<q-btn
unelevated
label="บันทึก"
id="onSubmit"
type="submit"
color="public"
class="q-px-md"
>
<q-tooltip>นทกขอม</q-tooltip>
</q-btn>
</div> -->
</q-form>
</template>