hrms-mgt/src/modules/15_development/components/Risk.vue

528 lines
16 KiB
Vue

<script setup lang="ts">
import { onMounted, reactive, ref } from "vue";
import { useQuasar } from "quasar";
import { useRoute } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
/**
* importType
*/
import type { QTableProps } from "quasar";
import type { FormRisk } from "@/modules/15_development/interface/request/Main";
import type { ResRisk } from "@/modules/15_development/interface/response/Main";
/**
* importComponents
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importstore
*/
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
const $q = useQuasar();
const route = useRoute();
const {
showLoader,
hideLoader,
messageError,
dialogConfirm,
success,
dialogRemove,
} = useCounterMixin();
/**
* props
*/
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 projectId = ref<string>(route.params.id.toLocaleString());
const checkRoutePermission = ref<boolean>(
route.name == "developmentDetailPage"
);
const step = ref<string>("");
/**
* ข้อมูล Table
*/
const rows = ref<ResRisk[]>([]);
const columns = ref<QTableProps["columns"]>([
{
name: "issues",
align: "left",
label: "ประเด็นความเสี่ยง",
sortable: false,
field: "issues",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "chance",
align: "left",
label: "โอกาสที่จะเกิด",
sortable: false,
field: "chance",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "effects",
align: "left",
label: "ผลกระทบจากการเกิด",
field: "effects",
sortable: false,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "riskLevel",
align: "left",
label: "ระดับความเสี่ยง",
sortable: false,
field: "riskLevel",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
{
name: "riskManagement",
align: "left",
label: "แนวทางการบริหารความเสี่ยง",
sortable: false,
field: "riskManagement",
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
]);
/************ ความเสี่ยงของโครงการ ***************/
const modalRisk = ref<boolean>(false);
const riskId = ref<string>("");
const isEdit = ref<boolean>(false);
const formDataRisk = reactive<FormRisk>({
issues: "", //ประเด็นความเสี่ยง
chance: null, //โอกาสที่จะเกิด
effects: null, //ผลกระทบจากการเกิด
riskLevel: "", //ระดับความเสี่ยง
riskManagement: "", //เเนวทางการบริหารความเสี่ยง
});
const expect = ref<string>(""); //ประโยชน์ที่คาดว่าจะได้รับ
/**
* ดึงข้อมูล ความเสี่ยงประโยชน์ที่คาดว่าจะได้รับ
*/
function fetchData() {
http
.get(config.API.developmentMainTab("tab8", projectId.value))
.then((res) => {
const data = res.data.result;
rows.value = data.developmentRisks;
expect.value = data.expect;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isChangeData.value = false;
});
}
/**
* ระดับความเสี่ยงของโครงการ option
*/
function calRiskLevel() {
if (formDataRisk.chance && formDataRisk.effects) {
const riskLevel =
Number(formDataRisk.chance) * Number(formDataRisk.effects);
formDataRisk.riskLevel =
riskLevel == 1
? "น้อยมาก"
: riskLevel == 2
? "น้อย"
: riskLevel == 3 || riskLevel == 4 || riskLevel == 6
? "ปานกลาง"
: riskLevel == 5 || riskLevel == 8 || riskLevel == 9 || riskLevel == 10
? "สูง"
: riskLevel == 12 ||
riskLevel == 15 ||
riskLevel == 16 ||
riskLevel == 20 ||
riskLevel == 25
? "สูงมาก"
: "";
}
}
/**
* บันทึกข้อมูลประโยชน์ที่คาดว่าจะได้รับ
*/
function onSubmit() {
showLoader();
http
.put(config.API.developmentMainTab("tab8", projectId.value), {
expect: expect.value,
})
.then(() => {})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
isChangeData.value = false;
});
}
/**
* เพิ่มความเสี่ยงของโครงการ
* @param status เพิ่ม,แก่ไข
* @param data ข้อมูลความเสี่ยงของโครงการ
*/
function onClickAddRisk(status: boolean = false, data: ResRisk | null = null) {
modalRisk.value = true;
isEdit.value = status;
if (data) {
riskId.value = data.id;
formDataRisk.issues = data.issues; //ประเด็นความเสี่ยง
formDataRisk.chance = data.chance; //โอกาสที่จะเกิด
formDataRisk.effects = data.effects; //ผลกระทบจากการเกิด
formDataRisk.riskLevel = data.riskLevel; //ระดับความเสี่ยง
formDataRisk.riskManagement = data.riskManagement; //เเนวทางการบริหารความเสี่ยง
}
}
/**
* ปืด popup ข้อมูลความเสี่ยงของโครงการ
*/
function onCloseDialog() {
modalRisk.value = false;
formDataRisk.issues = "";
formDataRisk.chance = null;
formDataRisk.effects = null;
formDataRisk.riskLevel = "";
formDataRisk.riskManagement = "";
}
/**
* ยืนยันการบันทึกข้อมูลความเสี่ยงของโครงการ
*/
function onSubmitRisk() {
const id = isEdit.value ? riskId.value : projectId.value;
const path = isEdit.value ? "tab8_1_edit" : "tab8_1_add";
dialogConfirm($q, () => {
showLoader();
http
.put(config.API.developmentMainTab(path, id), formDataRisk)
.then(() => {
fetchData();
onCloseDialog();
success($q, "เพิ่มข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
hideLoader();
});
});
}
/**
* ยืนยันการลบข้อมูลความเสี่ยงของโครงการ
* @param id ความเสี่ยงของโครงการ
*/
function onDeleteRisk(id: string) {
dialogRemove($q, () => {
showLoader();
http
.delete(config.API.developmentMainTab("tab8_1", id))
.then(() => {
fetchData();
success($q, "ลบข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
hideLoader();
});
});
}
/**
* function ไปยัง Tab ค่อไป
*/
function onNextTab() {
step.value == "next" ? props.nextStep() : props.prevStep();
}
/**
* ดึงข้อมูลเมื่อคอมโพเนนต์โหลดเสร็จสมบูรณ์
*/
onMounted(() => {
fetchData();
});
/**
* เรียก function ไปใช่หน้าหลัก
*/
defineExpose({
onSubmit,
});
</script>
<template>
<q-form greedy @submit.prevent @validation-success="onNextTab">
<div class="q-pa-sm">
<!-- ความเสยงของโครงการ -->
<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"
>
ความเสยงของโครงการ
<q-btn
flat
round
color="primary"
icon="add"
@click="onClickAddRisk()"
>
<q-tooltip>เพมขมม</q-tooltip>
</q-btn>
</div>
<q-separator />
<q-card-section>
<div class="row col-12 q-col-gutter-sm">
<div class="col-12">
<d-table
ref="table"
:columns="columns"
:rows="rows"
:paging="true"
row-key="id"
flat
bordered
dense
:rows-per-page-options="[10, 25, 50, 100]"
>
<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">
<q-tr :props="props">
<q-td>
<q-btn
v-if="!checkRoutePermission"
dense
flat
round
color="edit"
icon="edit"
@click="onClickAddRisk(true, props.row)"
>
<q-tooltip>แกไขขอม</q-tooltip>
</q-btn>
<q-btn
v-if="!checkRoutePermission"
dense
flat
round
color="red"
icon="delete"
@click="onDeleteRisk(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>
</div>
</q-card-section>
</q-card>
<!-- ประโยชนคาดวาจะได -->
<q-card bordered class="col-12 q-my-sm q-mt-md">
<div
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">
<q-input
outlined
:readonly="checkRoutePermission"
dense
class="inputgreen"
v-model="expect"
label="ประโยชน์ที่คาดว่าจะได้รับ"
type="textarea"
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
</q-card-section>
</q-card>
</div>
<q-separator />
<div class="text-center q-pa-sm" v-if="!checkRoutePermission">
<q-btn
rounded
label="ก่อนหน้า"
icon="mdi-chevron-left"
id="onSubmit"
type="submit"
color="public"
class="q-mr-xs"
style="width: 120px"
@click="step = 'prev'"
>
</q-btn>
<q-btn
rounded
label="ถัดไป"
icon-right="mdi-chevron-right"
id="onSubmit"
type="submit"
color="public"
class="q-ml-xs"
style="width: 120px"
@click="step = 'next'"
>
</q-btn>
</div>
</q-form>
<q-dialog v-model="modalRisk" persistent>
<q-card style="width: 700px; max-width: 80vw">
<q-form greedy @submit.prevent @validation-success="onSubmitRisk">
<DialogHeader
:tittle="
isEdit ? 'แก้ไขความเสี่ยงของโครงการ' : 'เพิ่มความเสี่ยงของโครงการ'
"
:close="onCloseDialog"
/>
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-12">
<q-input
outlined
:readonly="checkRoutePermission"
dense
class="inputgreen"
v-model="formDataRisk.issues"
label="ประเด็นความเสี่ยง"
type="textarea"
hide-bottom-space
lazy-rules
:rules="[
(val:string) =>
!!val || `${'กรุณากรอกประเด็นความเสี่ยง'}`,
]"
/>
</div>
<div class="col-3">
<q-select
outlined
dense
class="inputgreen"
:readonly="checkRoutePermission"
v-model="formDataRisk.chance"
label="โอกาสที่จะเกิด"
:options="[1, 2, 3, 4]"
@update:model-value="calRiskLevel"
lazy-rules
hide-bottom-space
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกโอกาสที่จะเกิด'}`,
]"
></q-select>
</div>
<div class="col-3">
<q-select
:readonly="checkRoutePermission"
outlined
dense
class="inputgreen"
v-model="formDataRisk.effects"
hide-bottom-space
label="ผลกระทบจากการเกิด"
:options="[1, 2, 3, 4]"
@update:model-value="calRiskLevel"
lazy-rules
:rules="[
(val:string) =>
!!val || `${'กรุณาเลือกผลกระทบจากการเกิด'}`,
]"
>
</q-select>
</div>
<div class="col-6">
<q-input
readonly
outlined
dense
class="formDataRisk"
v-model="formDataRisk.riskLevel"
label="ระดับความเสี่ยง"
/>
</div>
<div class="col-12">
<q-input
outlined
:readonly="checkRoutePermission"
dense
class="inputgreen"
v-model="formDataRisk.riskManagement"
label="เเนวทางการบริหารความเสี่ยง"
type="textarea"
/>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right" class="bg-white text-teal">
<q-btn label="บันทึก" type="submit" color="public"> </q-btn>
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<style scoped></style>