Merge branch 'develop' into devTee

This commit is contained in:
STW_TTTY\stwtt 2024-09-12 11:38:57 +07:00
commit 1766039004
33 changed files with 1020 additions and 1143 deletions

View file

@ -0,0 +1,7 @@
import env from "../index";
const command = `${env.API_URI}/order`;
export default {
commandType: `${command}/order-type`,
};

View file

@ -67,6 +67,9 @@ import KPI from "./api/14_KPI/api.KPI";
/** API เงินเดือน/ค่าจ้าง*/
import development from "./api/15_development/api.development";
/** ออกคำสั่งใหม่ */
import command from "./api/18_command/api.command";
import file from "./api/file/api.file";
// environment variables
@ -133,6 +136,9 @@ const API = {
...KPI,
...development,
/** ออกคำสั่งใหม่ */
...command,
/*file*/
...file,
};

View file

@ -1,9 +1,10 @@
<script setup lang="ts">
import { ref, reactive, watch, defineProps } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
/**
* importType
@ -12,9 +13,12 @@ import type {
DataOption,
FormPositionSelect,
} from "@/modules/02_organization/interface/index/Main";
import type {
DataPosType,
DataLevel,
} from "@/modules/02_organization/interface/response/Main";
import type {
OptionType,
OptionLevel,
OptionExecutive,
} from "@/modules/02_organization/interface/response/organizational";
@ -33,9 +37,8 @@ const { dialogConfirm, showLoader, hideLoader, messageError, success } = mixin;
/**
* props
*/
const modal = defineModel<boolean>("modalAdd", { required: true });
const isEditCheck = defineModel<boolean>("isEdit", { required: true });
const modal = defineModel<boolean>("modalAdd", { required: true }); // , popup
const isEditCheck = defineModel<boolean>("isEdit", { required: true }); //
const props = defineProps({
emitSearch: Function,
getData: Function,
@ -43,20 +46,20 @@ const props = defineProps({
levelOp: Object,
});
const dataLevel = ref<any>();
const posExecutive = ref<string>("");
const isSpecial = ref<boolean>(false);
const shape = ref<string>("false");
const isReadonly = ref<boolean>(false); //
const dataLevel = ref<DataPosType[]>([]); //
const posExecutive = ref<string>(""); //
const isSpecial = ref<boolean>(false); //
const shape = ref<string>("false"); //
const isDisValidate = ref<boolean>(false);
const typeOpsMain = ref<DataOption[]>([]);
const levelOpsMain = ref<DataOption[]>([]);
const executiveOpsMain = ref<DataOption[]>([]);
const executiveOps = ref<DataOption[]>([]);
const typeOps = ref<DataOption[]>([]);
const levelOps = ref<DataOption[]>([]);
const typeOpsMain = ref<DataOption[]>([]); //
const levelOpsMain = ref<DataOption[]>([]); //
const executiveOpsMain = ref<DataOption[]>([]); //
const typeOps = ref<DataOption[]>([]); //
const levelOps = ref<DataOption[]>([]); //
const executiveOps = ref<DataOption[]>([]); //
const shapeOp = ref<DataOption[]>([
{
id: "false",
@ -67,6 +70,8 @@ const shapeOp = ref<DataOption[]>([
name: "เพิ่มใหม่",
},
]);
//
const formPositionSelect = reactive<FormPositionSelect>({
positionId: "",
positionName: "",
@ -92,7 +97,7 @@ function validateFormPositionEdit() {
}
/**
* นทกการแกไข
* นทกการแกไขตำแหน
*/
function saveSelectEdit() {
dialogConfirm(
@ -150,7 +155,7 @@ function saveSelectEdit() {
);
}
/**
* งช นท
* งชนทการเพมขอมลตำแหน
*/
function onSubmitSelectEdit() {
dialogConfirm(
@ -212,11 +217,13 @@ function onSubmitSelectEdit() {
}
/**
* งช เครยลฟอร
* งชนเคลยรฟอรมขอม
*
* กำหนดคาฟอรมขอมลเปนค Default
*/
async function clearFormPositionSelect() {
isEditCheck.value = false;
isDisValidate.value = await true;
isDisValidate.value = true;
formPositionSelect.positionId = "";
formPositionSelect.positionName = "";
formPositionSelect.positionField = "";
@ -227,10 +234,76 @@ async function clearFormPositionSelect() {
formPositionSelect.positionArea = "";
isSpecial.value = false;
setTimeout(async () => {
isDisValidate.value = await false;
isDisValidate.value = false;
}, 1000);
}
/**
* งกเรยกขอมลรายการประเภทตำแหน
*/
async function fetchType() {
await http
.get(config.API.orgPosType)
.then(async (res) => {
dataLevel.value = await res.data.result;
typeOpsMain.value = res.data.result.map((e: OptionType) => ({
id: e.id,
name: e.posTypeName,
}));
typeOps.value = typeOpsMain.value;
})
.catch((err) => {
messageError($q, err);
});
}
/**
* งกนกำหนดตวเลอกประเภทตำแหนงตาม id ประเภทตำแหน
* @param val id ประเภทตำแหน
*/
async function updateSelectType(val: string) {
//
const listLevel = dataLevel.value.find((e: DataPosType) => e.id === val);
levelOpsMain.value =
listLevel?.posLevels.map((e: DataLevel) => ({
id: e.id,
name: e.posLevelName ? e.posLevelName.toString() : "",
})) || [];
levelOps.value = levelOpsMain.value;
formPositionSelect.positionLevel = "";
}
/**
* งกเรยกขอมลรายการตำแหนงทางการบรหาร
*/
async function fetchExecutive() {
await http
.get(config.API.orgPosExecutive)
.then(async (res) => {
executiveOpsMain.value = await res.data.result.map(
(e: OptionExecutive) => ({
id: e.id,
name: e.posExecutiveName,
})
);
executiveOps.value = executiveOpsMain.value;
})
.catch((err) => {
messageError($q, err);
});
}
/**
* งกนป Popup
*
* และเรยก clearFormPositionSelect() เพอกำหนดฟอรมขอมลเป Default
*/
function close() {
modal.value = false;
clearFormPositionSelect();
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
@ -243,57 +316,11 @@ function inputEdit(val: boolean) {
}
/**
* function เลอกประเภทตำแหน
* @param val id ประเภทตำแหน
* การเปลยนแปลงของ modal.value
*
* าเป true ทำการเรยกขอมลรายการประเภทตำแหน และ อมลรายการตำแหนงทางการบรหาร
* และถาม props.data จะกำหนด formPositionSelect เปนตาม props.data
*/
function updateSelectType(val: string) {
//
const listLevel = dataLevel.value.find((e: any) => e.id === val);
levelOpsMain.value = listLevel.posLevels.map((e: OptionLevel) => ({
id: e.id,
name: e.posLevelName,
}));
levelOps.value = levelOpsMain.value;
formPositionSelect.positionLevel = "";
}
function close() {
modal.value = false;
clearFormPositionSelect();
}
async function fetchType() {
http
.get(config.API.orgPosType)
.then((res) => {
dataLevel.value = res.data.result;
typeOpsMain.value = res.data.result.map((e: OptionType) => ({
id: e.id,
name: e.posTypeName,
}));
typeOps.value = typeOpsMain.value;
})
.catch((err) => {
messageError($q, err);
});
}
/** function เรียกรายการตำแหน่งทางการบริหาร */
function fetchExecutive() {
http
.get(config.API.orgPosExecutive)
.then((res) => {
executiveOpsMain.value = res.data.result.map((e: OptionExecutive) => ({
id: e.id,
name: e.posExecutiveName,
}));
executiveOps.value = executiveOpsMain.value;
})
.catch((err) => {
messageError($q, err);
});
}
watch(
() => modal.value,
async () => {
@ -303,8 +330,7 @@ watch(
hideLoader();
if (props.data) {
const dataList = props.data;
updateSelectType(dataList.posTypeId);
await updateSelectType(dataList.posTypeId);
formPositionSelect.positionId = dataList.id;
formPositionSelect.positionName = dataList.positionName;
formPositionSelect.positionField = dataList.positionField;

View file

@ -1,20 +1,30 @@
<script setup lang="ts">
import { ref, reactive, watch, computed } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
import type {
FormDataAgency,
FormAgencyRef,
DataOption,
} from "@/modules/02_organization/interface/index/Main";
import DialogHeader from "@/components/DialogHeader.vue";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
const $q = useQuasar();
const store = useOrganizational();
const mixin = useCounterMixin();
const { dialogConfirm, showLoader, hideLoader, messageError, success } = mixin;
/**
* props
*/
const level = defineModel<number>("orgLevel", { required: true });
const actionType = defineModel<string>("actionType", { required: true });
const props = defineProps({
@ -46,11 +56,7 @@ const props = defineProps({
},
});
const $q = useQuasar();
const store = useOrganizational();
const mixin = useCounterMixin();
const { dialogConfirm, showLoader, hideLoader, messageError, success } = mixin;
//
const orgLevelOptionMain = ref<DataOption[]>([
{ name: "ระดับสำนัก", id: "DEPARTMENT" },
{
@ -60,18 +66,10 @@ const orgLevelOptionMain = ref<DataOption[]>([
{ name: "ระดับส่วน/กลุ่มภารกิจ", id: "DIVISION" },
{ name: "ระดับฝ่าย/กลุ่มงาน", id: "SECTION" },
]);
const orgLevelOption = ref<DataOption[]>([]); //
const orgLevelSubOptionMain = ref<DataOption[]>([]); //
const orgLevelSubOptionMain = ref<DataOption[]>([]);
const orgLevelOption = ref<DataOption[]>([]);
const orgNameRef = ref<Object | null>(null);
const orgShortNameRef = ref<Object | null>(null);
const orgCodeRef = ref<Object | null>(null);
const orgLevelRef = ref<Object | null>(null);
const orgLevelSubRef = ref<Object | null>(null);
//
const formData = reactive<FormDataAgency>({
orgName: "",
orgShortName: "",
@ -84,35 +82,11 @@ const formData = reactive<FormDataAgency>({
responsibility: "",
});
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const objectComplaintsRef: FormAgencyRef = {
orgName: orgNameRef,
orgShortName: orgShortNameRef,
orgCode: orgCodeRef,
orgLevel: orgLevelRef,
orgLevelSub: orgLevelSubRef,
};
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function validateForm() {
const hasError = [];
for (const key in objectComplaintsRef) {
if (Object.prototype.hasOwnProperty.call(objectComplaintsRef, key)) {
const property = objectComplaintsRef[key];
if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate();
hasError.push(isValid);
}
}
}
if (hasError.every((result) => result === true)) {
onSubmit();
} else {
}
}
/** ฟังชั่น บันทึก */
/**
* งกนบนทกขอมลสวนราชการ
*
* actionType.value === "ADD" จะบนทกการเพมขอมลสวนราชการ ไม จะบนทกการแกไขขอมลสวนราชการ
**/
function onSubmit() {
dialogConfirm($q, async () => {
showLoader();
@ -156,7 +130,7 @@ function onSubmit() {
.then(async () => {
await props.fetchDataTree(store.draftId);
await success($q, "บันทึกข้อมูลสำเร็จ");
await closeClear();
closeClear();
})
.catch((err) => {
messageError($q, err);
@ -189,7 +163,7 @@ function onSubmit() {
false
);
await success($q, "บันทึกข้อมูลสำเร็จ");
await closeClear();
closeClear();
})
.catch((err) => {
messageError($q, err);
@ -202,7 +176,7 @@ function onSubmit() {
}
/**
* function เช formdata กลบไปคาวาง และป popup
* งกนเช formdata กลบไปคาวาง และป popup
*/
function closeClear() {
formData.orgName = "";
@ -217,73 +191,11 @@ function closeClear() {
}
/**
* callback function ทำงานเมอมการเป popup
*/
watch(
() => props.modal,
() => {
if (props.modal === true) {
if (actionType.value === "ADD") {
if (props.dataNode) {
formData.orgCode =
props?.dataNode?.orgLevel !== 0
? props?.dataNode.orgTreeCode
: undefined;
formData.orgShortName =
props?.dataNode?.orgLevel !== 0
? props?.dataNode.orgTreeShortName
: undefined;
}
if (level.value === 0) {
formData.orgLevel = "DEPARTMENT";
orgLevelOption.value = orgLevelOptionMain.value;
} else {
orgLevelOption.value = orgLevelOptionMain.value.slice(1, 4);
formData.orgLevel = "";
}
formData.orgLevel == "DEPARTMENT" ? selectOrgLevele("DEPARTMENT") : "";
} else {
if (props.dataNode) {
formData.orgName = props.dataNode.orgTreeName;
formData.orgShortName = props.dataNode.orgTreeShortName;
formData.orgCode = props.dataNode.orgTreeCode;
formData.orgPhoneEx = props.dataNode.orgTreePhoneEx;
formData.orgPhoneIn = props.dataNode.orgTreePhoneIn;
formData.orgFax = props.dataNode.orgTreeFax;
formData.orgLevel = props.dataNode.orgTreeRank;
formData.orgLevelSub = props.dataNode.orgTreeRankSub;
formData.responsibility = props.dataNode.responsibility;
orgLevelOption.value =
props.dataNode.orgTreeRank === "DEPARTMENT"
? orgLevelOptionMain.value
: orgLevelOptionMain.value.slice(1, 4);
selectOrgLevele(formData.orgLevel, false);
}
}
}
}
);
/**
* title ของ popup
*/
const tittleName = computed(() => {
let name = "";
if (actionType.value === "ADD") {
name = level.value === 0 ? "เพิ่มหน่วยงาน" : "เพิ่มส่วนราชการ";
} else {
name = level.value === 0 ? "แก้ไขหน่วยงาน" : "แก้ไขส่วนราชการ";
}
return name;
});
/**
* function เลอกระดบของสวนราชการ
* @param val
* งกนเลอกระดบของสวนราชการ
* @param val ระดบของสวนราชการ
* @param status
*
* กำหนดตวเลอกของระดบของสวนราชการ( )ตามประเภทระดบของสวนราชการ
*/
function selectOrgLevele(val: string, status: boolean = true) {
formData.orgLevelSub = status ? "" : formData.orgLevelSub;
@ -338,13 +250,77 @@ function selectOrgLevele(val: string, status: boolean = true) {
break;
}
}
/**
* กำหนด Title ของ popup จะถกตงตามประเภทการดำเนนการและระดบทกำหนด
*/
const tittleName = computed(() => {
let name = "";
if (actionType.value === "ADD") {
name = level.value === 0 ? "เพิ่มหน่วยงาน" : "เพิ่มส่วนราชการ";
} else {
name = level.value === 0 ? "แก้ไขหน่วยงาน" : "แก้ไขส่วนราชการ";
}
return name;
});
/**
* callback function ทำงานเม props.modal เป true
*/
watch(
() => props.modal,
() => {
if (props.modal === true) {
if (actionType.value === "ADD") {
if (props.dataNode) {
formData.orgCode =
props?.dataNode?.orgLevel !== 0
? props?.dataNode.orgTreeCode
: undefined;
formData.orgShortName =
props?.dataNode?.orgLevel !== 0
? props?.dataNode.orgTreeShortName
: undefined;
}
if (level.value === 0) {
formData.orgLevel = "DEPARTMENT";
orgLevelOption.value = orgLevelOptionMain.value;
} else {
orgLevelOption.value = orgLevelOptionMain.value.slice(1, 4);
formData.orgLevel = "";
}
formData.orgLevel == "DEPARTMENT" ? selectOrgLevele("DEPARTMENT") : "";
} else {
if (props.dataNode) {
formData.orgName = props.dataNode.orgTreeName;
formData.orgShortName = props.dataNode.orgTreeShortName;
formData.orgCode = props.dataNode.orgTreeCode;
formData.orgPhoneEx = props.dataNode.orgTreePhoneEx;
formData.orgPhoneIn = props.dataNode.orgTreePhoneIn;
formData.orgFax = props.dataNode.orgTreeFax;
formData.orgLevel = props.dataNode.orgTreeRank;
formData.orgLevelSub = props.dataNode.orgTreeRankSub;
formData.responsibility = props.dataNode.responsibility;
orgLevelOption.value =
props.dataNode.orgTreeRank === "DEPARTMENT"
? orgLevelOptionMain.value
: orgLevelOptionMain.value.slice(1, 4);
selectOrgLevele(formData.orgLevel, false);
}
}
}
}
);
</script>
<template>
<template>
<q-dialog v-model="props.modal" persistent>
<q-card style="min-width: 60vw">
<form @submit.prevent="validateForm">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader :tittle="tittleName" :close="closeClear" />
<q-separator />
<q-card-section>
@ -517,7 +493,7 @@ function selectOrgLevele(val: string, status: boolean = true) {
<q-tooltip>นทกขอม</q-tooltip></q-btn
>
</q-card-actions>
</form>
</q-form>
</q-card>
</q-dialog>
</template>

View file

@ -1,13 +1,28 @@
<script setup lang="ts">
import { ref, watch, computed } from "vue";
import { useQuasar } from "quasar";
import { useCounterMixin } from "@/stores/mixin";
import DialogHeader from "@/components/DialogHeader.vue";
import type { FormDateTimeRef } from "@/modules/02_organization/interface/index/Main";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import DialogHeader from "@/components/DialogHeader.vue";
const $q = useQuasar();
const store = useOrganizational();
const {
dialogConfirm,
date2Thai,
showLoader,
hideLoader,
messageError,
success,
} = useCounterMixin();
/**
* porps
*/
const props = defineProps({
modal: Boolean,
close: Function,
@ -18,51 +33,20 @@ const props = defineProps({
},
});
const store = useOrganizational();
const $q = useQuasar();
const mixin = useCounterMixin();
const {
dialogConfirm,
date2Thai,
showLoader,
hideLoader,
messageError,
success,
} = mixin;
const dateTime = ref<Date | null>(null); //
/**
* กำหนดวนทเผยแพรไมใหอยกวาวนปจจ
*/
const minDate = computed(() => {
const date = new Date();
date.setDate(date.getDate() + 1);
return date;
});
const dateTimeRef = ref<Object | null>(null);
const dateTime = ref<Date | null>();
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const objectRef: FormDateTimeRef = {
dateTime: dateTimeRef,
};
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function validateForm() {
const hasError = [];
for (const key in objectRef) {
if (Object.prototype.hasOwnProperty.call(objectRef, key)) {
const property = objectRef[key];
if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate();
hasError.push(isValid);
}
}
}
if (hasError.every((result) => result === true)) {
onSubmit();
} else {
}
}
/** ฟังชั่น บันทึก */
/**
* งกนบนทกการตงเวลาเผยแพร
*/
function onSubmit() {
dialogConfirm($q, () => {
showLoader();
@ -72,8 +56,8 @@ function onSubmit() {
})
.then(async () => {
await props.fetchActive();
await props.close?.();
await success($q, "บันทึกข้อมูลสำเร็จ");
props.close?.();
})
.catch((e) => {
messageError($q, e);
@ -84,6 +68,9 @@ function onSubmit() {
});
}
/**
* งกนยนยนการเผยแพรโครงาสราง
*/
function onClickPublish() {
dialogConfirm(
$q,
@ -106,20 +93,25 @@ function onClickPublish() {
"ต้องการยืนยันการเผยเเพร่ข้อมูลนี้ใช่หรือไม่?"
);
}
/**
* การเปลยนแปลงของ props.modal
*/
watch(
() => props.modal,
() => {
if (props.modal === true) {
if (props.modal) {
dateTime.value = store.orgPublishDate ? store.orgPublishDate : null;
}
}
);
</script>
<template>
<template>
<q-dialog v-model="props.modal" persistent>
<q-card style="min-width: 18vw">
<form @submit.prevent="validateForm">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader :tittle="`ตั้งเวลาเผยแพร่`" :close="props.close" />
<q-separator />
@ -179,7 +171,7 @@ watch(
<q-space />
<q-btn type="submit" :label="`บันทึก`" color="public" />
</q-card-actions>
</form>
</q-form>
</q-card>
</q-dialog>
</template>

View file

@ -1,8 +1,10 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
/**
* importType
@ -10,16 +12,11 @@ import config from "@/app.config";
import type { QTableProps } from "quasar";
import type {
FormDataPosition,
FormPositionRef,
DataOption,
FormPositionSelect,
RowDetailPositions,
ListMenu,
} from "@/modules/02_organization/interface/index/Main";
import type {
OptionType,
OptionExecutive,
} from "@/modules/02_organization/interface/response/organizational";
import type { FilterMaster } from "@/modules/02_organization/interface/request/organizational";
/**
@ -28,11 +25,6 @@ import type { FilterMaster } from "@/modules/02_organization/interface/request/o
import DialogHeader from "@/components/DialogHeader.vue";
import DialogAddPosition from "@/modules/02_organization/components/DialogAddPosition.vue"; //
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
@ -51,7 +43,7 @@ const {
/**
* props
*/
const reqMaster = defineModel<FilterMaster>("reqMaster", { required: true });
const reqMaster = defineModel<FilterMaster>("reqMaster", { required: true }); // qurey
const props = defineProps({
modal: Boolean,
close: Function,
@ -64,14 +56,15 @@ const props = defineProps({
shortName: { type: String, required: true },
});
const isEdit = ref<boolean>(false);
const modalAdd = ref<boolean>(false);
const isReadonly = ref<boolean>(false); //
const isDisValidate = ref<boolean>(false);
const isPosition = ref<boolean>(false);
const dataCopy = ref<any>();
const search = ref<string>("");
const type = ref<string>("positionName");
const isEdit = ref<boolean>(false); //
const modalAdd = ref<boolean>(false); //
const isPosition = ref<boolean>(false); //
const dataCopy = ref<RowDetailPositions>(); //
const search = ref<string>(""); //
const type = ref<string>("positionName"); //
//
const optionFilter = ref<DataOption[]>([
{ id: "positionName", name: "ตำแหน่งในสายงาน" },
{ id: "positionField", name: "สายงาน" },
@ -81,37 +74,8 @@ const optionFilter = ref<DataOption[]>([
{ id: "positionExecutiveField", name: "ด้านทางการบริหาร" },
{ id: "positionArea", name: "ด้าน/สาขา" },
]);
const typeOpsMain = ref<DataOption[]>([]);
const executiveOpsMain = ref<DataOption[]>([]);
const executiveOps = ref<DataOption[]>([]);
const typeOps = ref<DataOption[]>([]);
const listMenu = ref<ListMenu[]>([
{
label: "คัดลอก",
icon: "mdi-content-copy",
type: "copy",
color: "blue-6",
},
{
label: "แก้ไข",
icon: "mdi-pencil",
type: "edit",
color: "edit",
},
{
label: "ลบ",
icon: "delete",
type: "remove",
color: "red",
},
]);
const rows = ref<RowDetailPositions[]>([]);
const rowsPositionSelect = ref<RowDetailPositions[]>([]);
const prefixNoRef = ref<Object | null>(null);
const positionNoRef = ref<Object | null>(null);
//
const formData = reactive<FormDataPosition>({
shortName: props.shortName,
prefixNo: "",
@ -122,6 +86,7 @@ const formData = reactive<FormDataPosition>({
isOfficer: false,
});
//
const formPositionSelect = reactive<FormPositionSelect>({
positionId: "",
positionName: "",
@ -132,12 +97,10 @@ const formPositionSelect = reactive<FormPositionSelect>({
positionExecutiveField: "",
positionArea: "",
});
/** maping ref เข้าตัวแปรเพื่อเตรียมตรวจสอบ */
const objectPositionRef: FormPositionRef = {
prefixNo: prefixNoRef,
positionNo: positionNoRef,
};
//Table
const rows = ref<RowDetailPositions[]>([]); //
const rowsPositionSelect = ref<RowDetailPositions[]>([]); //
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -222,6 +185,27 @@ const visibleColumns = ref<string[]>([
"positionExecutiveField",
"positionArea",
]);
//
const listMenu = ref<ListMenu[]>([
{
label: "คัดลอก",
icon: "mdi-content-copy",
type: "copy",
color: "blue-6",
},
{
label: "แก้ไข",
icon: "mdi-pencil",
type: "edit",
color: "edit",
},
{
label: "ลบ",
icon: "delete",
type: "remove",
color: "red",
},
]);
/**
* function fetch อมลอตรากำล
@ -249,219 +233,132 @@ async function fetchPosition(id: string) {
});
}
const dataLevel = ref<any>();
/** function เรียกรายการประเภทตำแหน่ง */
async function fetchType() {
// showLoader();
await http
.get(config.API.orgPosType)
.then((res) => {
dataLevel.value = res.data.result;
typeOpsMain.value = res.data.result.map((e: OptionType) => ({
id: e.id,
name: e.posTypeName,
}));
typeOps.value = typeOpsMain.value;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
// hideLoader();
});
}
/** function เรียกรายการตำแหน่งทางการบริหาร */
async function fetchExecutive() {
// showLoader();
await http
.get(config.API.orgPosExecutive)
.then((res) => {
executiveOpsMain.value = res.data.result.map((e: OptionExecutive) => ({
id: e.id,
name: e.posExecutiveName,
}));
executiveOps.value = executiveOpsMain.value;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
// hideLoader();
});
}
/** ฟังก์ชั่นตรวจสอบความถูกต้องของข้อมูลในฟอร์ม */
function validateForm() {
const hasError = [];
for (const key in objectPositionRef) {
if (Object.prototype.hasOwnProperty.call(objectPositionRef, key)) {
const property = objectPositionRef[key];
if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate();
hasError.push(isValid);
}
}
}
if (hasError.every((result) => result === true)) {
if (rows.value.length == 0) {
dialogMessageNotify($q, "กรุณาเลือกตำแหน่งอย่างน้อย 1 ตำแหน่ง");
} else {
onSubmit();
}
}
}
/** ฟังชั่น บันทึก */
/**
* งกนยนยนการบนทกขอมลอตรากำล
*
* props.actionType เป "ADD" หร "COPY" จะเพมรายการตำแหน ไมจะเปนการแกไขขอม
*
*/
function onSubmit() {
dialogConfirm($q, async () => {
const positionsData = rows.value.map((e: any) => ({
posDictName: e.positionName, // ()
posDictField: e.positionField, //
posTypeId: e.posTypeId, //*
posLevelId: e.posLevelId, //*
posExecutiveId: e.posExecutiveId ? e.posExecutiveId : "", //
posDictExecutiveField: e.positionExecutiveField, //
posDictArea: e.positionArea, ///
isSpecial: e.isSpecial,
positionIsSelected: e.positionIsSelected,
}));
const body = {
posMasterNoPrefix: formData.prefixNo, //*Prefix Optional (/)
posMasterNo: Number(formData.positionNo), //*
posMasterNoSuffix: formData.suffixNo, //Suffix .
reason: formData.reason, //Suffix .
isDirector: formData.isDirector,
isOfficer: formData.isOfficer ? formData.isOfficer : false,
orgRootId: props.orgLevel === 0 ? props.treeId : null, //Id
orgChild1Id: props.orgLevel === 1 ? props.treeId : null,
orgChild2Id: props.orgLevel === 2 ? props.treeId : null,
orgChild3Id: props.orgLevel === 3 ? props.treeId : null,
orgChild4Id: props.orgLevel === 4 ? props.treeId : null,
positions: positionsData,
};
//
if (rows.value.length == 0) {
dialogMessageNotify($q, "กรุณาเลือกตำแหน่งอย่างน้อย 1 ตำแหน่ง");
} else {
// dialog
dialogConfirm($q, async () => {
const positionsData = rows.value.map((e: RowDetailPositions) => ({
posDictName: e.positionName, // ()
posDictField: e.positionField, //
posTypeId: e.posTypeId, //*
posLevelId: e.posLevelId, //*
posExecutiveId: e.posExecutiveId ? e.posExecutiveId : "", //
posDictExecutiveField: e.positionExecutiveField, //
posDictArea: e.positionArea, ///
isSpecial: e.isSpecial,
positionIsSelected: e.positionIsSelected,
}));
const body = {
posMasterNoPrefix: formData.prefixNo, //*Prefix Optional (/)
posMasterNo: Number(formData.positionNo), //*
posMasterNoSuffix: formData.suffixNo, //Suffix .
reason: formData.reason, //Suffix .
isDirector: formData.isDirector,
isOfficer: formData.isOfficer ? formData.isOfficer : false,
orgRootId: props.orgLevel === 0 ? props.treeId : null, //Id
orgChild1Id: props.orgLevel === 1 ? props.treeId : null,
orgChild2Id: props.orgLevel === 2 ? props.treeId : null,
orgChild3Id: props.orgLevel === 3 ? props.treeId : null,
orgChild4Id: props.orgLevel === 4 ? props.treeId : null,
positions: positionsData,
};
showLoader();
props.actionType === "ADD" || props.actionType === "COPY"
? await http
.post(config.API.orgPosMaster, body)
.then(async () => {
await props.fetchDataTable?.(
reqMaster.value.id,
reqMaster.value.type,
false
);
await props.getSummary?.();
await close();
await success($q, "เพิ่มข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
})
: props.rowId &&
(await http
.put(config.API.orgPosMasterById(props.rowId), body)
.then(async () => {
await props.fetchDataTable?.(
reqMaster.value.id,
reqMaster.value.type,
false
);
await close();
await success($q, "แก้ไขข้อมูลสำเร็จ");
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
}));
});
}
/** input ค้นหา */
const searchRef = ref<any>(null);
async function searchInput() {
searchRef.value.validate();
if (!searchRef.value.hasError) {
showLoader();
await http
.get(
config.API.orgPosPosition +
`?keyword=${search.value}&type=${type.value}`
)
.then((res) => {
rowsPositionSelect.value = res.data.result;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
showLoader();
props.actionType === "ADD" || props.actionType === "COPY"
? await http
.post(config.API.orgPosMaster, body)
.then(async () => {
await props.fetchDataTable?.(
reqMaster.value.id,
reqMaster.value.type,
false
);
await props.getSummary?.();
await success($q, "เพิ่มข้อมูลสำเร็จ");
close();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
})
: props.rowId &&
(await http
.put(config.API.orgPosMasterById(props.rowId), body)
.then(async () => {
await props.fetchDataTable?.(
reqMaster.value.id,
reqMaster.value.type,
false
);
await success($q, "แก้ไขข้อมูลสำเร็จ");
close();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
}));
});
}
}
/**
* ดลอกขอม
* @param data อมลตำแหน
* งกนตนหาตำแหนงทองการเพ
*/
async function searchInput() {
showLoader();
await http
.get(
config.API.orgPosPosition + `?keyword=${search.value}&type=${type.value}`
)
.then((res) => {
rowsPositionSelect.value = res.data.result;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
/**
* งกนคดลอกขอมลตำแหน
* @param data อมลตำแหนงทองการคดลอก
*/
function copyDetiail(data: RowDetailPositions) {
modalAdd.value = true;
dataCopy.value = data;
}
/**
* แกไขขอม
* @param data อมลตำแหน
* งกแกไขขอมตำแหน
* @param data อมลตำแหนองการแกไข
*/
function editDetiail(data: RowDetailPositions) {
isEdit.value = true;
modalAdd.value = true;
dataCopy.value = data;
console.log(isEdit.value);
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
* งกนเพมขอมลรายการอตรากำล
* @param data อมลตำแหนงทองการเพ
*/
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
watch(
() => props.modal,
async () => {
if (props.modal === true) {
props.actionType === "ADD" && showLoader();
await Promise.all([fetchType(), fetchExecutive()]);
props.actionType === "ADD" && hideLoader();
if (props.actionType === "ADD") {
rowsPositionSelect.value = [];
search.value = "";
rows.value = [];
clearFormPositionSelect();
formData.prefixNo = "";
formData.positionNo = "";
formData.suffixNo = "";
formData.reason = "";
} else {
props.rowId && fetchPosition(props.rowId);
}
}
}
);
async function addPosition(data: RowDetailPositions) {
const isIdExist = await rows.value.some(
(item: any) =>
const isIdExist = rows.value.some(
(item: RowDetailPositions) =>
item.posExecutiveId == data.posExecutiveId &&
item.positionField == data.positionField &&
item.posLevelId == data.posLevelId &&
@ -478,18 +375,20 @@ async function addPosition(data: RowDetailPositions) {
}
/**
* function ลบอมลอตรากำล
* @param id อมลอตรากำล
* งกนลบรายการอมลอตรากำล
* @param id รายการอมลอตรากำลองการลบ
*/
function deleteData(id: string) {
const dataRow = rows.value;
const updatedRows = dataRow.filter((item: any) => item.id !== id);
const updatedRows = dataRow.filter(
(item: RowDetailPositions) => item.id !== id
);
rows.value = updatedRows;
}
/**
* function ลบตำแหน
* @param id ตำแหน
* งกนลบขอมลรายการตำแหน
* @param id อมลรายการตำแหนงทองการลบ
*/
function deletePos(id: string) {
dialogRemove($q, () => {
@ -510,10 +409,9 @@ function deletePos(id: string) {
}
/**
* function เคลยร formData
* งกนกำหนดตวแปรทงหมดใหเปนค Default
*/
async function clearFormPositionSelect() {
isDisValidate.value = await true;
formPositionSelect.positionId = "";
formPositionSelect.positionName = "";
formPositionSelect.positionField = "";
@ -522,27 +420,64 @@ async function clearFormPositionSelect() {
formPositionSelect.positionExecutive = "";
formPositionSelect.positionExecutiveField = "";
formPositionSelect.positionArea = "";
setTimeout(async () => {
isDisValidate.value = await false;
}, 1000);
}
/**
* function popup
*/
function close() {
clearFormPositionSelect();
props.close?.();
search.value = "";
rows.value = [];
formData.prefixNo = "";
formData.positionNo = "";
formData.suffixNo = "";
formData.reason = "";
formData.isDirector = false;
rowsPositionSelect.value = [];
isPosition.value = false;
}
async function emitSearch(keyword: string, typeSelect: string) {
search.value = await keyword;
type.value = await typeSelect;
/**
* งก popup
*
* และกำหนดตวแปรทงหมดใหเปนค Default
*/
function close() {
props.close?.();
clearFormPositionSelect();
}
/**
* งกนคนหาขอมลตำแหน
* @param keyword คำคนหา
* @param typeSelect ปรเภทการคนหา
*/
async function emitSearch(keyword: string, typeSelect: string) {
search.value = keyword;
type.value = typeSelect;
await searchInput();
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
*/
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
/**
* การเปลยยนแปลง props.modal
*
* เม props.modal เป true
*/
watch(
() => props.modal,
async () => {
if (props.modal === true) {
if (props.actionType !== "ADD" && props.rowId) {
fetchPosition(props.rowId);
}
}
}
);
</script>
<template>
@ -555,7 +490,7 @@ async function emitSearch(keyword: string, typeSelect: string) {
:close="close"
/>
<q-separator />
<form @submit.prevent="validateForm">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<q-card-section class="q-pa-sm fixed-height">
<div class="row q-col-gutter-sm">
<div class="col-12">
@ -754,7 +689,7 @@ async function emitSearch(keyword: string, typeSelect: string) {
flat
round
color="teal"
@click="() => ((modalAdd = true), (dataCopy = null))"
@click="() => ((modalAdd = true), (dataCopy = undefined))"
><q-tooltip>สรางตำแหน</q-tooltip></q-btn
>
</div>
@ -777,16 +712,15 @@ async function emitSearch(keyword: string, typeSelect: string) {
<div class="col-12 col-sm-6 col-md-6">
<q-input
ref="searchRef"
:class="inputEdit(isReadonly)"
v-model="search"
outlined
clearable
@clear="search = ''"
dense
lazy-rules
label="คำค้น"
hide-bottom-space
:rules="[(val) => !!val || `กรุณากรอกคำค้น`]"
@keydown.enter.prevent="searchInput()"
/>
</div>
@ -929,7 +863,7 @@ async function emitSearch(keyword: string, typeSelect: string) {
><q-tooltip>นท</q-tooltip></q-btn
>
</q-card-actions>
</form>
</q-form>
</q-card>
</q-dialog>

View file

@ -1,8 +1,10 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
/**
* importType
@ -15,11 +17,6 @@ import type { HistoryPostType } from "@/modules/02_organization/interface/index/
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
@ -37,14 +34,14 @@ const orgId = defineModel<string>("orgId", { required: true });
/**
* อม Table
*/
const rows = ref<HistoryPostType[]>([]);
const rows = ref<HistoryPostType[]>([]); //
const columns = ref<QTableProps["columns"]>([
{
name: "no",
align: "left",
label: "ลำดับ",
sortable: false,
field: "no",
field: (row) => rows.value.indexOf(row) + 1,
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
@ -72,7 +69,7 @@ const columns = ref<QTableProps["columns"]>([
align: "left",
label: "วันที่แก้ไข",
sortable: true,
field: "lastUpdatedAt",
field: (v) => date2Thai(v),
headerStyle: "font-size: 14px",
style: "font-size: 14px",
},
@ -85,26 +82,18 @@ const visibleColumns = ref<string[]>([
]);
/**
* function เรยกขอม ประวหนวยงาน,ประววนราชการ
* function เรยกขอมประวหนวยงาน,ประววนราชการ
*/
function postData() {
async function fetchHistory() {
showLoader();
http
await http
.post(config.API.organizationHistoryPostNew, {
id: orgId.value,
type: type.value,
})
.then((res) => {
const dataList = res.data.result;
const dataMap = dataList.map((item: HistoryPostType) => ({
id: item.id ? item.id : "-",
name: item.name ? item.name : "-",
lastUpdatedAt: item.lastUpdatedAt
? date2Thai(item.lastUpdatedAt as Date, false, true)
: "-",
orgRevisionName: item.orgRevisionName ? item.orgRevisionName : "-",
}));
rows.value = dataMap;
.then(async (res) => {
const data = await res.data.result;
rows.value = data;
})
.catch((e) => {
messageError($q, e);
@ -115,13 +104,13 @@ function postData() {
}
/**
* callback function เม modal = true เรยกขอม ประวหนวยงาน,ประววนราชการ
* การเปลยนแปลง modal เมอเป true จะเรยกขอมประวหนวยงาน,ประววนราชการ
*/
watch(
() => modal.value,
() => {
if (modal.value == true) {
postData();
fetchHistory();
}
}
);
@ -177,43 +166,8 @@ watch(
:key="col.name"
:props="props"
>
<div v-if="col.name == 'no'">
{{ props.rowIndex + 1 }}
</div>
<div v-else-if="col.name == 'orgRevisionIsCurrent'">
<q-icon
:name="
props.row.orgRevisionIsCurrent == true
? 'mdi-check'
: ''
"
:color="
props.row.orgRevisionIsCurrent == true
? 'positive'
: ''
"
class="text-h5"
/>
</div>
<div v-else-if="col.name == 'orgRevisionIsDraft'">
<q-icon
:name="
props.row.orgRevisionIsDraft == true
? 'mdi-check'
: ''
"
:color="
props.row.orgRevisionIsDraft == true
? 'positive'
: ''
"
class="text-h5"
/>
</div>
<div v-else>
{{ col.value }}
<div>
{{ col.value ?? "-" }}
</div>
</q-td>
</q-tr>

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* import Type
@ -15,16 +18,10 @@ import type { HistoryPos } from "@/modules/02_organization/interface/response/or
*/
import Header from "@/components/DialogHeader.vue";
/**
* import Store
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/** Use*/
const $q = useQuasar();
const store = useOrganizational();
const { showLoader, hideLoader, messageError, date2Thai } = useCounterMixin();
const $q = useQuasar();
/**
* props
@ -39,7 +36,7 @@ const props = defineProps({
/**
* อม Table
*/
const rows = ref<HistoryPos[]>([]);
const rows = ref<HistoryPos[]>([]); //
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -156,7 +153,7 @@ function fetchHistoryPos(id: string) {
http
.get(config.API.orgPosHistory(id))
.then((res) => {
const data: HistoryPos[] = res.data.result;
const data = res.data.result;
rows.value = data;
})
.catch((err) => {
@ -168,7 +165,7 @@ function fetchHistoryPos(id: string) {
}
/**
* callback function ทำงานเม modal === true
* การเปลยนแปลง modal เมอเป true จะเรยกเรยกขอมลประวตำแหน
*/
watch(
() => modal.value,

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, computed, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* importType
@ -24,12 +27,6 @@ import type { DataTree } from "@/modules/02_organization/interface/index/organiz
*/
import HeaderDialog from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/
@ -72,19 +69,24 @@ const props = defineProps({
},
});
const title = ref<string>("ย้ายตำแหน่งจากหน่วยงาน/ส่วนราชการปัจจุบัน");
const filterTree = ref<string>("");
const filterRef = ref();
const selectedTree = ref<string>("");
const levelTree = ref<number>(0);
const filterTable = ref<string>("");
const selectedFilter = ref<PosMaster2[]>([]);
const title = ref<string>("ย้ายตำแหน่งจากหน่วยงาน/ส่วนราชการปัจจุบัน"); //title Dialog
const filterTree = ref<string>(""); ///
const filterRef = ref(); //
const selectedTree = ref<string>(""); //
const levelTree = ref<number>(0); //
const filterTable = ref<string>(""); //
const selectedFilter = ref<PosMaster2[]>([]); //
const pagination = ref({
page: reqMaster.value.page,
rowsPerPage: reqMaster.value.pageSize,
});
/**
* ดปมยายตำแหน
*
* เมอไมไดเลอกตำแหนงทองการยายและหนวยงานทองการยายปมยายตำแหนงจะป
*/
const isDisable = computed(() => {
if (selectedTree.value === "" && selectedFilter.value.length === 0) {
return true;
@ -146,6 +148,18 @@ function onClickMovePos() {
}
}
/**
* function updatePagination
* @param newPagination อม Pagination ใหม
*/
function updatePagination(newPagination: NewPagination) {
reqMaster.value.pageSize = newPagination.rowsPerPage;
reqMaster.value.page = 1;
}
/**
* การเปลยนแปลง modal เมอเป true
*/
watch(
() => modal.value,
() => {
@ -164,15 +178,6 @@ watch(
}
}
);
/**
* function updatePagination
* @param newPagination อม Pagination ใหม
*/
function updatePagination(newPagination: NewPagination) {
reqMaster.value.pageSize = newPagination.rowsPerPage;
reqMaster.value.page = 1;
}
</script>
<template>

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* importType
@ -17,12 +20,6 @@ import type {
/** importComponents*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/
@ -45,6 +42,7 @@ const props = defineProps({
},
});
//
const typeOp = ref<DataOption[]>([
{
id: "NEW",
@ -64,10 +62,7 @@ const typeOp = ref<DataOption[]>([
},
]);
const orgRevisionNameRef = ref<Object | null>(null);
const typeRef = ref<Object | null>(null);
const orgRevisionIdRef = ref<Object | null>(null);
//
const formData = reactive<FormDataNewStructure>({
orgRevisionId: "",
orgRevisionName: "",
@ -75,42 +70,14 @@ const formData = reactive<FormDataNewStructure>({
});
/**
* maping ref เขาตวแปรเพอเตรยมตรวจสอบ
*/
const objectRef: FormNewStructureRef = {
orgRevisionName: orgRevisionNameRef,
type: typeRef,
orgRevisionId: orgRevisionIdRef,
};
/**
* งกนตรวจสอบความถกตองของขอมลในฟอร
*/
function validateForm() {
const hasError = [];
for (const key in objectRef) {
if (Object.prototype.hasOwnProperty.call(objectRef, key)) {
const property = objectRef[key];
if (property.value && typeof property.value.validate === "function") {
const isValid = property.value.validate();
hasError.push(isValid);
}
}
}
if (hasError.every((result) => result === true)) {
onSubmit();
}
}
/**
* งช นท
* งกนยนยนการบนทกการกสรางโครงสราง
*/
function onSubmit() {
dialogConfirm(
$q,
() => {
async () => {
showLoader();
http
await http
.post(config.API.createOrganization, formData)
.then(async (res) => {
await props.fetchActive();
@ -119,14 +86,13 @@ function onSubmit() {
store.draftId = res.data.result.id;
store.statusView = "list";
success($q, "บันทึกข้อมูลสำเร็จ");
close();
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
modal.value = false;
hideLoader();
close();
});
},
"ยืนยันการเพิ่มโครงสร้าง",
@ -137,7 +103,7 @@ function onSubmit() {
}
/**
* popup
* popup และกำหนดฟอรมเพมโครงสรางเป Default
*/
function close() {
modal.value = false;
@ -147,7 +113,7 @@ function close() {
}
/**
* เรยกขอม
* งกเรยกขอมประวโครงสราง
*/
function fetchOrgRevision() {
showLoader();
@ -159,7 +125,7 @@ function fetchOrgRevision() {
);
if (data) {
const currentStr = await data.find(
(x: any) => x.orgRevisionIsCurrent === true
(x: HistoryType) => x.orgRevisionIsCurrent === true
);
formData.orgRevisionId = currentStr ? currentStr.orgRevisionId : null;
}
@ -172,6 +138,11 @@ function fetchOrgRevision() {
});
}
/**
* การเปลยนแปลง modal เมอเป true
*
* type ไมเปนการสรางใหมใหเรยกขอมลประวโครงสราง
*/
watch(
() => modal.value,
() => {
@ -184,7 +155,7 @@ watch(
<template>
<q-dialog v-model="modal" persistent>
<q-card style="min-width: 50vw">
<form @submit.prevent="validateForm">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader :tittle="`เพิ่มโครงสร้าง`" :close="close" />
<q-separator />
@ -227,7 +198,7 @@ watch(
<q-card-actions align="right" class="bg-white text-teal">
<q-btn type="submit" :label="`บันทึก`" color="public" />
</q-card-actions>
</form>
</q-form>
</q-card>
</q-dialog>
</template>

View file

@ -2,6 +2,8 @@
import { reactive, watch } from "vue";
import { useQuasar } from "quasar";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* import type
*/
@ -12,11 +14,6 @@ import type { FormDetailPosition } from "@/modules/02_organization/interface/ind
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* importType
@ -29,12 +32,6 @@ import type {
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* import*Store
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/
@ -70,13 +67,13 @@ const props = defineProps({
});
const isReadonly = ref<boolean>(false); //
const typeOpsMain = ref<DataOption[]>([]);
const levelOpsMain = ref<DataOption[]>([]);
const typeOps = ref<DataOption[]>([]);
const levelOps = ref<DataOption[]>([]);
const dataLevel = ref<TypePos[]>([]);
const selected = ref<Position[]>([]);
const isSit = ref<boolean>(false);
const typeOpsMain = ref<DataOption[]>([]); //
const levelOpsMain = ref<DataOption[]>([]); //
const typeOps = ref<DataOption[]>([]); //
const levelOps = ref<DataOption[]>([]); //
const dataLevel = ref<TypePos[]>([]); //
const selected = ref<Position[]>([]); //
const isSit = ref<boolean>(false); //
const formData = reactive<FormPositionFilter>({
positionNo: "", //*
@ -230,13 +227,6 @@ const columnsResult = ref<QTableProps["columns"]>([
},
]);
/**
* function closePopup
*/
function close() {
modal.value = false;
}
/**
* function เรยกขอมลประเภทตำแหน
*/
@ -260,17 +250,6 @@ function fetchType() {
});
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
*/
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
/**
* function เรยกขแมลระดบตำแหน
*/
@ -317,7 +296,7 @@ function onSubmit() {
await props.fetchDataTable?.(store.treeId, store.level, false);
await props.getSummary();
success($q, "บันทึกข้อมูลสำเร็จ");
modal.value = false;
close();
})
.catch((err) => {
messageError($q, err);
@ -381,7 +360,7 @@ function updatePagination(newPagination: NewPagination) {
}
/**
* function เคลยรForm
* function เคลยรวแปรเปนค Default
*/
function clearForm() {
formData.positionType = "";
@ -396,13 +375,39 @@ function clearForm() {
}
/**
* function เคลยรตำแหน
* function เคลยรประเภทตำแหนงและระดตำแหน
*/
function clearPosition() {
formData.positionType = "";
formData.positionLevel = "";
}
/**
* function popup
*/
function close() {
modal.value = false;
clearForm();
}
/**
* งค css ออกไปตามเงอนไข
* @param val true/false
*/
function inputEdit(val: boolean) {
return {
"full-width cursor-pointer inputgreen ": val,
"full-width cursor-pointer inputgreen": !val,
};
}
/**
* callback function ทำงานการคนหาขอมลคนครองเมอมการ update Pagination
*/
watch([() => page.value, () => pageSize.value], () => {
searchData();
});
/**
* callback function ทำงานเมอเป popup
*/
@ -410,7 +415,6 @@ watch(
() => modal.value,
async () => {
if (modal.value == true) {
await clearForm();
await fetchType();
if (props.dataDetailPos) {
@ -440,13 +444,6 @@ watch(
}
}
);
/**
* callback function ทำงานการคนหาขอมลคนครองเมอมการ update Pagination
*/
watch([() => page.value, () => pageSize.value], () => {
searchData();
});
</script>
<template>

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* importType
@ -15,12 +18,6 @@ import type { DataSortAgency } from "@/modules/02_organization/interface/index/o
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, watch, defineProps } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* importType
@ -15,12 +18,6 @@ import type { DataSortPos } from "@/modules/02_organization/interface/index/orga
*/
import DialogHeader from "@/components/DialogHeader.vue";
/**
* importStore
*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/**
* use
*/

View file

@ -1,18 +1,18 @@
<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { reactive, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import DialogHeader from "@/components/DialogHeader.vue";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import DialogHeader from "@/components/DialogHeader.vue";
const $q = useQuasar();
const mixin = useCounterMixin();
const store = useOrganizational();
const { showLoader, hideLoader, messageError, date2Thai } = mixin;
const { showLoader, hideLoader, messageError } = mixin;
const modal = defineModel<boolean>("structureDetail", { required: true });
const treeId = defineModel<string>("treeId", { required: true });
@ -30,12 +30,17 @@ const formData = reactive<any>({
orgShortName: "",
});
/**
* function งขอมลรายละเอยดโหนดขอโครงสรางตาม ID โหนดโครงสราง
* @param id id โหนดโครงสราง
* @param type ระดบโหนดของโครงอสราง
*/
async function fetchDetailTree(id: string, type: string) {
showLoader();
await http
.get(config.API.orgLevelByid(type.toLocaleLowerCase(), id))
.then((res) => {
const data = res.data.result;
.then(async (res) => {
const data = await res.data.result;
const range = data[`org${type}Rank`];
formData.orgName = data.orgRootName ? data.orgRootName : "-";
formData.agencyName = data.orgName ? data.orgName : "-";
@ -60,10 +65,19 @@ async function fetchDetailTree(id: string, type: string) {
});
}
/**
* function popup
*/
function close() {
modal.value = false;
}
/**
* การเปลยนแปลงของ modal
*
* เม modal เป true จะสงระดบของโหนดไปเช
* และจะดงขอมลรายละเอยดโหนดขอโครงสรางตาม ID และ ระด โหนดโครงสราง
*/
watch(
() => modal.value,
async () => {

View file

@ -3,6 +3,8 @@ import { ref, watch, reactive } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/** importType*/
import type { QTableProps } from "quasar";
@ -20,10 +22,6 @@ import type {
/** importComponents*/
import Header from "@/components/DialogHeader.vue";
/** importStore*/
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
/** use*/
const $q = useQuasar();
const store = useOrganizational();
@ -49,7 +47,9 @@ const selectedTree = ref<string>("");
const filterRef = ref();
const levelTree = ref<number>(0);
/** function เรียกข้อมูล Tree แบบ ปัจจุบัน*/
/**
* function เรยกขอม Tree แบบ จจ
*/
async function fetchTree() {
showLoader();
const id: string = store.activeId ? store.activeId?.toString() : "";
@ -66,23 +66,28 @@ async function fetchTree() {
});
}
/** resetFilterTree*/
/**
* resetFilterTree
*/
function resetFilter() {
filterTree.value = "";
filterRef.value.focus();
}
/** function เลือกหน่วยงาน*/
/**
* function เลอกหนวยงาน
*
* และโหลดชอมลตำแหน
*/
async function updateSelected(data: DataTree) {
levelTree.value = data.orgLevel;
selectedTree.value = data.orgTreeId;
reqMaster.id = await data.orgTreeId;
reqMaster.type = await data.orgLevel;
reqMaster.id = data.orgTreeId;
reqMaster.type = data.orgLevel;
await fetchTable();
}
/*************************** TABLE ***********************************/
/** columns*/
const columns = ref<QTableProps["columns"]>([
{
name: "no",
@ -103,7 +108,7 @@ const columns = ref<QTableProps["columns"]>([
style: "font-size: 14px",
},
]);
const rows = ref<PosMaster[]>([]);
const rows = ref<PosMaster[]>([]); //
const reqMaster = reactive<FilterMaster>({
id: "",
type: 0,
@ -116,7 +121,9 @@ const reqMaster = reactive<FilterMaster>({
const totalRow = ref<number>(0);
const selectedPos = ref<PosMaster[]>([]);
/** function เรียกข้อมูล Table Position*/
/**
* function เรยกขอมลรายการตำแหน
*/
async function fetchTable() {
selectedPos.value = [];
await http
@ -149,13 +156,17 @@ function updatePagination(newPagination: NewPagination) {
reqMaster.page = 1;
}
/** funcion ค้นหาข้อมูลใน Table*/
/**
* funcion นหาขอมลใน Table
*/
async function filterKeyword() {
reqMaster.page = 1;
fetchTable();
}
/** function ยืนยันกาสืบทอดตำแหน่ง */
/**
* function นยนกาสบทอดตำแหน
*/
function onClickConfirm() {
if (selectedPos.value.length === 0) {
dialogMessageNotify($q, "กรุณาเลือกตำแหน่งสืบทอด");
@ -187,20 +198,9 @@ function onClickConfirm() {
}
}
/** callblck function ทำการ fetch ข้อมูล tree เมื่อเปิด popup*/
watch(
() => modal.value,
async () => {
modal.value ? await fetchTree() : clearForm();
}
);
/** callblck function ทำการ fetch ข้อมูล Table เมื่อมีการเปลี่ยนหน้า*/
watch([() => reqMaster.page, () => reqMaster.pageSize], async () => {
await fetchTable();
});
/** function clear ข้อมูล*/
/**
* function clear อม
*/
function clearForm() {
nodeTree.value = [];
rows.value = [];
@ -212,6 +212,23 @@ function clearForm() {
reqMaster.pageSize = 10;
reqMaster.keyword = "";
}
/**
* callblck function ทำการ fetch อม tree เมอเป popup*
*/
watch(
() => modal.value,
async () => {
modal.value ? await fetchTree() : clearForm();
}
);
/**
* callblck function ทำการ fetch อม Table เมอมการเปลยนหน
*/
watch([() => reqMaster.page, () => reqMaster.pageSize], async () => {
await fetchTable();
});
</script>
<template>

View file

@ -1,46 +1,45 @@
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { useQuasar } from "quasar";
import { StructChart } from "structure-chart";
import "structure-chart/structure-chart.css";
import http from "@/plugins/http";
import config from "@/app.config";
import { StructChart } from "structure-chart";
import "structure-chart/structure-chart.css";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
const $q = useQuasar();
const mixin = useCounterMixin();
const store = useOrganizational();
const { showLoader, hideLoader, messageError } = mixin;
const $q = useQuasar(); // show dialog
// import chartData from '@/assets/structChartData'
// const dataSource = ref(chartData)
const dataSource = ref(); // Chart
const rootOrgID = ref(); // org id root
const dataSourceLock = ref(); // Chart home
const chartRef = ref(); // chart
const savePNG = () => {
chartRef.value.savePNG();
};
const savePDF = () => {
chartRef.value.savePDF();
};
const loader = ref<boolean>(false); // Loader
onMounted(async () => {
const id =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: store.historyId;
/**
* function ดาวนโหลดไฟลโครงสราง PNG
*/
function savePNG() {
chartRef.value.savePNG();
}
id && (await fetchStructChart(id, "0"));
});
/**
* function ดาวนโหลดไฟลโครงสราง PDF
*/
function savePDF() {
chartRef.value.savePDF();
}
/**
* function งขอมลโครงสราง
* @param id id โครงสราง
* @param type
* @param status
*/
async function fetchStructChart(
id: string,
type: string,
@ -49,9 +48,9 @@ async function fetchStructChart(
showLoader();
await http
.get(config.API.orgStructChart(id, type))
.then((res) => {
.then(async (res) => {
if (res.data.result.length > 0) {
const data = res.data.result[0];
const data = await res.data.result[0];
const struct = [];
struct.push({ ...data, officer: [], heads: [] });
dataSource.value = struct[0];
@ -72,14 +71,14 @@ async function fetchStructChart(
* เมอมการคลกท Chart ใหาน ID ของหนวยงานทกคล แลวดงขอม Chart ของหนวยงานน จาก API
* @param data
*/
const refreshChart = async (data: any, type: number) => {
async function refreshChart(data: any, type: number) {
if (data.value === undefined) {
fetchStructChart(data, type.toString());
rootOrgID.value = data;
} else {
searchAndReplace(dataSource.value, data.value);
}
};
}
function searchAndReplace(data: any, id: string) {
if (data.deptID === id) {
@ -100,7 +99,7 @@ function searchAndReplace(data: any, id: string) {
* @param id OrgID ของหนวยงานทองการหา
* @param chart Array ของ Object ของหนวยงานยอยใน Tree
*/
const chartTraverse = (id: any, chart: any): any => {
function chartTraverse(id: any, chart: any): any {
let _returnPath = [];
for (const child of chart) {
if (child.deptID === id) {
@ -128,7 +127,7 @@ const chartTraverse = (id: any, chart: any): any => {
}
}
}
};
}
const findPath = (id: any) => {
let _path = [];
@ -149,13 +148,13 @@ const theBreadcrumb = ref();
/**
* สราง Path Breadcrumbs
*/
const breadcrumbsGen = () => {
function breadcrumbsGen() {
if (rootOrgID.value !== 0) {
theBreadcrumb.value = [];
const newPath = findPath(rootOrgID.value);
theBreadcrumb.value = newPath;
}
};
}
watch(
() => store.typeOrganizational,
@ -178,6 +177,17 @@ watch(
store.historyId && (await fetchStructChart(store.historyId, "0", true));
}
);
onMounted(async () => {
const id =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: store.historyId;
id && (await fetchStructChart(id, "0"));
});
</script>
<template>

View file

@ -1,12 +1,12 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { OrgChart } from "bma-org-chart";
import "bma-org-chart/org-chart.css";
import http from "@/plugins/http";
import config from "@/app.config";
import { OrgChart } from "bma-org-chart";
import "bma-org-chart/org-chart.css";
import { useCounterMixin } from "@/stores/mixin";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import avatar from "@/assets/avatar_user.jpg";
@ -26,10 +26,10 @@ const chartRef = ref(); // อ้างอิงไปที่ตัว chart
/**
* fetch อม Chart โครงสราง
*/
function fetchOrgChart() {
async function fetchOrgChart() {
showLoader();
let urlRequest = config.API.orgChart(rootOrgID.value);
http
await http
.get(urlRequest)
.then(async (response) => {
if (response.data.result.length > 0) {

View file

@ -23,14 +23,8 @@ import { useCounterMixin } from "@/stores/mixin";
/** use*/
const $q = useQuasar();
const store = useOrganizational();
const {
dialogRemove,
showLoader,
hideLoader,
messageError,
success,
date2Thai,
} = useCounterMixin();
const { dialogRemove, showLoader, hideLoader, messageError, success } =
useCounterMixin();
/** props*/
const nodeTEST = defineModel<OrgTree[]>("nodeTree", { default: [] });
@ -298,8 +292,8 @@ async function onClickEdit(node: OrgTree) {
* @param id ID โครงสราง
* @param rootId RootID
*/
function onClickDel(type: number, id: string, rootId: string) {
const level = store.checkLevel(type);
async function onClickDel(type: number, id: string, rootId: string) {
const level = await store.checkLevel(type);
dialogRemove($q, async () => {
showLoader();
await http

View file

@ -1,22 +1,23 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import config from "@/app.config";
import http from "@/plugins/http";
import genreport from "@/plugins/genreportxlsx";
import { checkPermission } from "@/utils/permissions";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/** importType*/
import type { QTableProps } from "quasar";
import type {
ListMenu,
NewPagination,
DataDocument,
} from "@/modules/02_organization/interface/index/Main";
import type { FilterMaster } from "@/modules/02_organization/interface/request/organizational";
import type {
PosMaster2,
OrgTree,
} from "@/modules/02_organization/interface/response/organizational";
import type { PosMaster2 } from "@/modules/02_organization/interface/response/organizational";
import type { DataPosition } from "@/modules/02_organization/interface/index/organizational";
/** importComponents*/
@ -29,8 +30,6 @@ import DialogSelectPerson from "@/modules/02_organization/components/DialogSelec
import DialogSuccession from "@/modules/02_organization/components/DialogSuccession.vue"; //
/** importStore*/
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const store = useOrganizational();
@ -64,9 +63,9 @@ const props = defineProps({
},
});
const modalSelectPerson = ref<boolean>(false);
const rowId = ref<string>("");
const actionType = ref<string>("");
const modalSelectPerson = ref<boolean>(false); //
const rowId = ref<string>(""); //id
const actionType = ref<string>(""); //
/** ListMenu Table*/
const listMenu = ref<ListMenu[]>([
{
@ -106,7 +105,7 @@ const listMenu = ref<ListMenu[]>([
color: "deep-purple",
},
]);
const document = ref<any>([
const document = ref<DataDocument[]>([
{
name: "บัญชี 1",
val: "report1",
@ -254,7 +253,7 @@ const columnsExpand = ref<QTableProps["columns"]>([
},
]);
const dialogPosition = ref<boolean>(false);
const dialogPosition = ref<boolean>(false); //
/**
* function openPopup เพมอตรากำล
* @param type ประเภท
@ -266,14 +265,19 @@ function onClickPosition(type: string, id: string) {
dialogPosition.value = !dialogPosition.value;
}
/**
* function เป popup เพมแกไข ตรากำล
* @param type ประเภทการกระทำ
* @param id id องการกระทำ
*/
function onClickCopyPosition(type: string, id: string) {
rowId.value = id ? id : "";
actionType.value = type;
dialogPosition.value = !dialogPosition.value;
}
const dialogDetail = ref<boolean>(false);
const dataDetailPos = ref<DataPosition[]>([]);
const dialogDetail = ref<boolean>(false); //
const dataDetailPos = ref<DataPosition[]>([]); //
/**
* function รายละเอยดประวตำแหน
* @param data อม ประวตำแหน
@ -351,13 +355,19 @@ function updatePagination(newPagination: NewPagination) {
reqMaster.value.page = 1;
}
/** function openPopup เลือกตนครอง*/
/**
* function เป pop เลอกตนครอง
* @param data อมลตำแหนงทองการเพมคนครอง
*/
function openSelectPerson(data: DataPosition[]) {
modalSelectPerson.value = true;
dataDetailPos.value = data;
}
/** ลบคนครอง */
/**
* function นยนการลบขอมลคนครอง
* @param id รายการทองการลบ
*/
function removePerson(id: string) {
dialogRemove(
$q,
@ -389,13 +399,17 @@ function removePerson(id: string) {
}
const modalDialogSuccession = ref<boolean>(false);
/** function openPopup สืบทอดตำแหน่ง*/
/**
* function openPopup บทอดตำแหน
*/
function onClickInherit(id: string) {
modalDialogSuccession.value = !modalDialogSuccession.value;
rowId.value = id;
}
/** ดึงข้อมูลสถิติจำนวนด้านบน*/
/**
* งขอมลสถจำนวนดานบน
*/
function getSummary() {
showLoader();
http
@ -428,7 +442,9 @@ function getSummary() {
});
}
/** function DownloadReport*/
/**
* function DownloadReport
*/
async function onClickDownloadReport(val: string, name: string) {
showLoader();
await http

View file

@ -1,8 +1,11 @@
<script setup lang="ts">
import { ref, reactive, onMounted, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/** importType*/
import type {
@ -17,10 +20,6 @@ import type { FilterMaster } from "@/modules/02_organization/interface/request/o
import TreeMain from "@/modules/02_organization/components/TreeMain.vue";
import TreeTable from "@/modules/02_organization/components/TreeTable.vue";
/** importStore*/
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/** use*/
const store = useOrganizational();
const $q = useQuasar();
@ -133,7 +132,9 @@ async function fetchDataTable(id: string, level: number, action: boolean) {
});
}
/** ดึงข้อมูลสถิติจำนวนด้านบน*/
/**
* งขอมลสถจำนวนดานบน
*/
function getSummary() {
http
.post(config.API.orgSummary, {
@ -158,13 +159,20 @@ function getSummary() {
});
}
/** funcion ค้นหาข้อมูลใน Table*/
/**
* funcion นหาขอมลใน Table
*/
async function filterKeyword() {
reqMaster.page = 1;
action1.value === false &&
fetchDataTable(reqMaster.id, reqMaster.type, false);
}
/**
* นหาโครงสรางในขอมลแบบลำดบชนเพอหาทตรงก orgTreeId
* @param data อมลโครงสราง
* @param targetId id ของโครงสรางทองการคนหา
*/
function searchAndReplaceOrgName(data: any, targetId: string) {
for (const child of data) {
if (child.orgTreeId === targetId) {
@ -179,17 +187,6 @@ function searchAndReplaceOrgName(data: any, targetId: string) {
return false; // Not found in this branch
}
/**lifecycle Hook*/
onMounted(async () => {
const id =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: historyId.value;
id && (await fetchDataTree(id));
});
/** callback function ทำงาน ทำการ fetch ข้อมูล Tree เมื่อมีการเลือกประวัติโครงสร้าง*/
watch(
() => count.value,
@ -198,7 +195,9 @@ watch(
}
);
/** callblck function ทำการ fetch ข้อมูล Tree เมื่อมีการเปลี่ยนโครงสร้าง*/
/**
* callblck function ทำการ fetch อม Tree เมอมการเปลยนโครงสราง
*/
watch(
() => store.typeOrganizational,
() => {
@ -210,13 +209,17 @@ watch(
}
);
/** callblck function ทำการ fetch ข้อมูล Table เมื่อมีการเปลี่ยนหน้า*/
/**
* callblck function ทำการ fetch อม Table เมอมการเปลยนหน
*/
watch([() => reqMaster.page, () => reqMaster.pageSize], () => {
action1.value === false &&
fetchDataTable(reqMaster.id, reqMaster.type, false);
});
/** callblck function ทำการ fetch ข้อมูล Table เมื่อแสดงตำแหน่งทั้งหมด*/
/**
* callblck function ทำการ fetch อม Table เมอแสดงตำแหนงทงหมด
*/
watch(
() => reqMaster.isAll,
() => {
@ -235,6 +238,21 @@ watch(
store.draftId && fetchDataTree(store.draftId?.toString());
}
);
/**
* lifecycle Hook ทำเม Components กเรยกใชงาน
*
* และดงชอมลโครงสรางตาม ID ของประเภทโครงสราง จจ,แบบราง
*/
onMounted(async () => {
const id =
store.typeOrganizational === "current"
? store.activeId
: store.typeOrganizational === "draft"
? store.draftId
: historyId.value;
id && (await fetchDataTree(id));
});
</script>
<template>

View file

@ -7,6 +7,11 @@ interface DataOption {
name: string;
}
interface DataDocument {
name: string;
val: string;
}
interface ListMenu {
label: string;
icon: string;
@ -121,6 +126,7 @@ interface RowDetailPositions {
posLevelId: string;
posExecutiveId: string;
isSpecial: boolean;
positionIsSelected: string;
}
interface NewPagination {
@ -147,4 +153,5 @@ export type {
HistoryPostType,
FormPositionSelectRef,
NewPagination,
DataDocument,
};

View file

@ -8,10 +8,10 @@ interface DataPosType {
interface DataLevel {
id: string;
posLevelName: number;
posLevelName: number | string;
posTypeName: string;
posTypeId: string;
posLevelAuthority: string;
}
export type { DataPosType };
export type { DataPosType, DataLevel };

View file

@ -9,17 +9,17 @@ import type {
} from "@/modules/02_organization/interface/response/organizational";
export const useOrganizational = defineStore("organizationalStore", () => {
const typeOrganizational = ref<string>("current");
const statusView = ref<string>("list");
const typeOrganizational = ref<string>("current"); // ประเภทโครงสร้าง
const statusView = ref<string>("list"); // การแสดงผล รายการ,map
const dataActive = ref<DataActive>();
const activeId = ref<string>();
const draftId = ref<string>();
const historyId = ref<string>();
const treeId = ref<string>();
const level = ref<number>();
const isPublic = ref<boolean>(false);
const orgPublishDate = ref<Date | null>(null);
const dataActive = ref<DataActive>(); //ข้อมูลโครงสร้าง
const activeId = ref<string>(); // id โครงสร้างปัจจุบัน
const draftId = ref<string>(); // id แบบร่างโครงสร้าง
const historyId = ref<string>(); // id ประวัติโครงสร้าง
const isPublic = ref<boolean>(false); // การเผยแพร่
const treeId = ref<string>(); // id โหนด
const level = ref<number>(); // ระดับโหนด
const orgPublishDate = ref<Date | null>(null); // วันเผยแพร่
const sumPosition = reactive({
total: 0,
use: 0,
@ -29,6 +29,10 @@ export const useOrganizational = defineStore("organizationalStore", () => {
vacantRoot: 0,
});
/**
*
* @param data
*/
function getSumPosition(data: SumPosition) {
sumPosition.total = data.totalPosition;
sumPosition.totalRoot = data.totalRootPosition ? data.totalRootPosition : 0;
@ -56,14 +60,23 @@ export const useOrganizational = defineStore("organizationalStore", () => {
}
}
function fetchDataActive(data: DataActive) {
/**
*
* @param data
*/
async function fetchDataActive(data: DataActive) {
dataActive.value = data;
activeId.value = data.activeId;
draftId.value = data.draftId;
dataActive.value = data;
isPublic.value = data.isPublic;
orgPublishDate.value = data.orgPublishDate;
}
/**
*
* @param data
* @returns
*/
function fetchPosMaster(data: PosMaster[]) {
const newPosMaster = data.map((e: PosMaster) => ({
...e,
@ -89,7 +102,12 @@ export const useOrganizational = defineStore("organizationalStore", () => {
return newPosMaster;
}
function checkLevel(type: number) {
/**
*
* @param type
* @returns
*/
async function checkLevel(type: number) {
switch (type) {
case 0:
return "Root";
@ -104,6 +122,11 @@ export const useOrganizational = defineStore("organizationalStore", () => {
}
}
/**
*
* @param type
* @returns
*/
function convertType(type: string) {
switch (type) {
case "DEPARTMENT":

View file

@ -1,165 +0,0 @@
<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import { useQuasar } from "quasar";
import http from "@/plugins/http";
import config from "@/app.config";
import type { ListMenu } from "@/modules/02_organization/interface/index/Main";
import type { OrgTree } from "@/modules/02_organization/interface/response/organizational";
/** importStore*/
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
const store = useOrganizational();
const { dialogRemove, showLoader, hideLoader, messageError, success } =
useCounterMixin();
const $q = useQuasar();
const filter = ref<string>("");
const nodes = ref<Array<any>>([]);
const lazy = ref(nodes);
const expanded = ref<Array<any>>([]);
const notFound = ref<string>("ไม่พบข้อมูลที่ค้นหา");
const noData = ref<string>("ไม่มีข้อมูล");
const selected = ref("");
const idVal = ref("");
async function fetchDataTree(id: string) {
showLoader();
await http
.get(config.API.orgByid(id))
.then((res) => {
const data = res.data.result;
nodes.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
const breakLoop = ref<boolean>(false);
const dataObject = ref([]);
async function onSort(orgRootId: string) {
if (orgRootId) {
idVal.value = "children => " + orgRootId;
breakLoop.value = false;
const targetNodeId = orgRootId;
for (let index = 0; index < nodes.value.length; index++) {
const element = nodes.value[index];
searchAndReplace(element, targetNodeId);
if (breakLoop.value) break;
}
} else {
idVal.value = "root";
}
}
function searchAndReplace(treeNode: any, organizationId: string) {
if (treeNode.orgTreeId === organizationId) {
dataObject.value = treeNode.children;
breakLoop.value = true;
} else if (treeNode.children) {
for (const child of treeNode.children) {
searchAndReplace(child, organizationId);
}
}
}
const listAdd = ref<ListMenu[]>([
{
label: "จัดลำดับ",
icon: "filter_list",
type: "SORT",
color: "green-7",
},
]);
onMounted(async () => {
await fetchDataTree("a449eac0-93a5-4ccc-8fbc-2974ca8ee61b");
});
</script>
<template>
<div class="col-12 q-py-md q-px-lg">
<q-tree
class="q-pa-md q-gutter-sm"
dense
default-expand-all
selected-color="primary"
:nodes="lazy"
node-key="orgTreeId"
label-key="orgTreeName"
:filter="filter"
:no-results-label="notFound"
:no-nodes-label="noData"
v-model:expanded="expanded"
v-model:selected="selected"
>
<template v-slot:default-header="prop">
<!-- {{ prop.node.orgTreeName }} -->
<div class="row items-center q-px-xs q-pt-xs q-gutter-sm">
<!--แสดงชอแผนก มพวหนา คลกแลวกาง/ Tree-->
<div>
<div class="text-weight-medium">
{{ prop.node.orgTreeName }}
</div>
<div class="text-weight-light">
{{ prop.node.orgCode == null ? null : prop.node.orgCode }}
{{
prop.node.orgTreeShortName == null
? null
: prop.node.orgTreeShortName
}}
</div>
</div>
</div>
<q-btn
flat
dense
icon="mdi-dots-vertical"
class="q-pa-none q-ml-xs"
color="grey-13"
>
<q-menu>
<q-list
dense
v-for="(item, index) in prop.node.orgLevel === 4
? listAdd.slice(1, 6)
: listAdd"
:key="index"
style="min-width: 100px"
>
<q-item
clickable
v-close-popup
@click="onSort(prop.node.orgRootId)"
>
<q-item-section avatar>
<q-icon :color="item.color" :name="item.icon" />
</q-item-section>
<div>
<q-item-section> {{ item.label }}หนวยงาน </q-item-section>
</div>
</q-item>
</q-list>
</q-menu>
</q-btn>
</template>
</q-tree>
<h5>orgRootId = {{ idVal }}</h5>
<div>
{{ dataObject }}
</div>
</div>
</template>
<style scoped></style>

View file

@ -1,9 +1,12 @@
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { useQuasar } from "quasar";
import { checkPermission } from "@/utils/permissions";
import http from "@/plugins/http";
import config from "@/app.config";
import { checkPermission } from "@/utils/permissions";
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/**
* importType
@ -20,12 +23,6 @@ import StructureOrgMain from "@/modules/02_organization/components/StructureOrgM
import DialogFormNewStructure from "@/modules/02_organization/components/DialogNewStructure.vue";
import DialogDateTime from "@/modules/02_organization/components/DialogFormDateTime.vue";
/**
* importStore
*/
import { useOrganizational } from "@/modules/02_organization/store/organizational";
import { useCounterMixin } from "@/stores/mixin";
/**
* use
*/
@ -46,9 +43,7 @@ const historyId = ref<string>(""); // ID ประวัติโครงสร
const labelHistory = ref<string>("ประวัติโครงสร้าง"); //
const count = ref<number>(0);
/**
* List เพมโครงสราง
*/
//
const itemStructure = ref<DataOption[]>([
{
id: "NEW",
@ -70,15 +65,17 @@ const itemStructure = ref<DataOption[]>([
/**
* function เรยกขอมลโครงสราง แบบปนและ แบบราง
*
* เกบขอมลใน store
*/
function fetchOrganizationActive() {
async function fetchOrganizationActive() {
showLoader();
http
await http
.get(config.API.activeOrganization)
.then((res) => {
const data = res.data.result;
.then(async (res) => {
const data = await res.data.result;
if (data) {
store.fetchDataActive(data);
await store.fetchDataActive(data);
if (data.activeName === null && data.draftName === null) {
isStatusData.value = false;
} else {
@ -100,13 +97,13 @@ function fetchOrganizationActive() {
}
/**
* function เรยกขอมลประวโครงสราง
* function เรยกขอมรายการลประวโครงสราง
*/
function fetchHistory() {
http
async function fetchHistory() {
await http
.get(config.API.organizationHistoryNew)
.then((res) => {
const data = res.data.result;
.then(async (res) => {
const data = await res.data.result;
const filterData = data.filter(
(e: OrgRevision) => !e.orgRevisionIsDraft && !e.orgRevisionIsCurrent
);
@ -150,12 +147,13 @@ function onClickHistory(id: string, name: string) {
}
/**
* lifecycleHook
* lifecycleHook ทำงานเมอมการเรยกใช Components
*
* งขอมลโครงสรางและรายการประวโครงสราง
*/
onMounted(async () => {
store.typeOrganizational = "current";
await fetchOrganizationActive();
await fetchHistory();
await Promise.all([fetchOrganizationActive(), fetchHistory()]);
});
</script>
<template>
@ -370,11 +368,8 @@ onMounted(async () => {
<DialogDateTime
:modal="modalDateTime"
:close="onClickDateTime"
:fetchActive="fetchOrganizationActive"
:fetch-active="fetchOrganizationActive"
/>
<!-- รายละเอยดตำแหน -->
<!-- <DialogPositionDetail v-model:position-detail="modalPositionDetail" /> -->
</template>
<style scoped></style>

View file

@ -148,7 +148,7 @@ async function fetchAssigned() {
async function getCriteria() {
await http
.get(config.API.KpiEvaluationInfo + `/edit`)
.get(config.API.KpiEvaluationInfo + `/criteria`)
.then(async (res) => {
const data = await res.data.result.data;
dataListCriteria.value = data;

View file

@ -998,6 +998,7 @@ defineExpose({
value="GO_BLACK"
label="ไป-กลับ"
v-model="formData.isBackActual"
@update:model-value="props.onCheckChangeData()"
></q-checkbox>
</div>
<div class="col-12 col-md-4">
@ -1010,6 +1011,7 @@ defineExpose({
label="จำนวน (วัน)"
mask="#"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
@ -1023,6 +1025,7 @@ defineExpose({
value="HOLD"
label="พักค้าง"
v-model="formData.isHoldActual"
@update:model-value="props.onCheckChangeData()"
></q-checkbox>
</div>
<div class="col-12 col-md-4">
@ -1035,6 +1038,7 @@ defineExpose({
label="จำนวน (วัน)"
mask="#"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
<div class="col-12 col-md-4">
@ -1047,6 +1051,7 @@ defineExpose({
label="จำนวน (คืน)"
mask="#"
reverse-fill-mask
@update:model-value="props.onCheckChangeData()"
/>
</div>
</div>
@ -1065,6 +1070,7 @@ defineExpose({
v-model="formData.developmentProjectTechniqueActuals"
:options="projectTechniquesOp1"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox21">
<div class="offset-4 col-8 q-mt-sm relative-position">
@ -1094,6 +1100,7 @@ defineExpose({
v-model="formData.developmentProjectTechniqueActuals"
:options="projectTechniquesOp2"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox22">
<div class="offset-4 col-8 q-mt-sm relative-position">
@ -1123,6 +1130,7 @@ defineExpose({
v-model="formData.developmentProjectTechniqueActuals"
:options="projectTechniquesOp3"
type="checkbox"
@update:model-value="props.onCheckChangeData()"
/>
<div class="row" v-if="checkOtherBox23">
<div class="offset-4 col-8 q-mt-sm relative-position">

View file

@ -1,105 +0,0 @@
<script setup lang="ts">
import { ref } from "vue";
import { useQuasar } from "quasar";
import DialogHeader from "@/components/DialogHeader.vue";
import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const { dialogConfirm } = useCounterMixin();
const modal = defineModel<boolean>("modal", { required: true });
const commandNo = ref<string>("");
const commandYear = ref<string>("");
function onSubmit() {
dialogConfirm($q, () => {
console.log(commandNo.value);
console.log(commandYear.value);
onClose();
});
}
function onClose() {
modal.value = false;
commandNo.value = "";
commandYear.value = "";
}
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card style="max-width: 50%">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader :tittle="'ทำสำเนาคำสั่ง'" :close="onClose" />
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-6">
<q-input
class="inputgreen"
outlined
dense
v-model="commandNo"
hide-bottom-space
:label="`${'คำสั่งเลขที่'}`"
:rules="[(val) => !!val || `${'กรุณากรอกคำสั่งเลขที่'}`]"
/>
</div>
<label class="col-1 flex justify-center items-center text-bold"
>/</label
>
<div class="col-5">
<q-input
class="inputgreen"
outlined
dense
v-model="commandYear"
hide-bottom-space
:label="`${'พ.ศ.'}`"
mask="####"
:rules="[(val) => !!val || `${'กรุณากรอก พ.ศ.'}`]"
/>
<!-- <datepicker
v-model="commandYear"
:locale="'th'"
autoApply
year-picker
:enableTimePicker="false"
>
<template #year="{ year }">{{ year + 543 }}</template>
<template #year-overlay-value="{ value }">{{
parseInt(value + 543)
}}</template>
<template #trigger>
<q-input
class="inputgreen"
:model-value="
commandYear !== null ? commandYear + 543 : null
"
:rules="[(val) => !!val || `${'กรุณาเลือก พ.ศ.'}`]"
:label="`${'พ.ศ.'}`"
dense
hide-bottom-space
outlined
>
</q-input>
</template>
</datepicker> -->
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn label="บันทึก" color="public" type="submit" />
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<style scoped></style>

View file

@ -0,0 +1,165 @@
<script setup lang="ts">
import { ref, watch } from "vue";
import { useQuasar } from "quasar";
import { useRouter } from "vue-router";
import http from "@/plugins/http";
import config from "@/app.config";
import type { DataListCommand } from "@/modules/18_command/interface/response/Main";
import DialogHeader from "@/components/DialogHeader.vue";
import { useCounterMixin } from "@/stores/mixin";
const $q = useQuasar();
const router = useRouter();
const { dialogConfirm, showLoader, hideLoader, messageError } =
useCounterMixin();
const modal = defineModel<boolean>("modal", { required: true });
const isCopy = defineModel<boolean>("isCopy", { required: true });
const commandType = ref<string>("");
const commandNo = ref<string>("");
const commandYear = ref<string>("");
const listCommand = ref<DataListCommand[]>([]);
const commandOp = ref<DataListCommand[]>([]);
async function fetchCommandType() {
showLoader();
await http
.get(config.API.commandType)
.then(async (res) => {
const data = await res.data.result;
listCommand.value = data;
commandOp.value = data;
})
.catch((err) => {
messageError($q, err);
})
.finally(() => {
hideLoader();
});
}
function onSubmit() {
dialogConfirm($q, () => {
!isCopy.value && router.push(`/command/edit/1234`);
console.log(commandNo.value);
console.log(commandYear.value);
onClose();
});
}
function filterSelector(val: string, update: Function, refData: string) {
switch (refData) {
case "OrderTypeOption":
update(() => {
commandType.value = val ? "" : commandType.value;
commandOp.value = listCommand.value.filter(
(v: any) => v.name.indexOf(val) > -1
);
});
break;
default:
break;
}
}
function onClose() {
modal.value = false;
commandNo.value = "";
commandYear.value = "";
}
watch(modal, () => {
if (modal.value && !isCopy.value) {
fetchCommandType();
}
});
</script>
<template>
<q-dialog v-model="modal" persistent>
<q-card style="max-width: 35%">
<q-form greedy @submit.prevent @validation-success="onSubmit">
<DialogHeader
:tittle="isCopy ? 'ทำสำเนาคำสั่ง' : 'เพิ่มคำสั่ง'"
:close="onClose"
/>
<q-separator />
<q-card-section>
<div class="row q-col-gutter-sm">
<div class="col-12" v-if="!isCopy">
<q-select
class="inputgreen"
v-model="commandType"
:label="`${'ประเภทคำสั่ง'}`"
dense
emit-value
map-options
option-label="name"
:options="commandOp"
option-value="id"
lazy-rules
use-input
hide-bottom-space
outlined
:rules="[(val) => !!val || `${'กรุณาเลือกประเภทคำสั่ง'}`]"
@filter="(inputValue:any,
doneFn:Function) => filterSelector(inputValue, doneFn,'OrderTypeOption'
) "
>
<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-6">
<q-input
class="inputgreen"
outlined
dense
v-model="commandNo"
hide-bottom-space
:label="`${'คำสั่งเลขที่'}`"
:rules="[(val) => !!val || `${'กรุณากรอกคำสั่งเลขที่'}`]"
lazy-rules
/>
</div>
<label class="col-1 flex justify-center items-center text-bold"
>/</label
>
<div class="col-5">
<q-input
class="inputgreen"
outlined
dense
v-model="commandYear"
hide-bottom-space
:label="`${'พ.ศ.'}`"
mask="####"
:rules="[(val) => !!val || `${'กรุณากรอก พ.ศ.'}`]"
lazy-rules
/>
</div>
</div>
</q-card-section>
<q-separator />
<q-card-actions align="right">
<q-btn label="บันทึก" color="public" type="submit" />
</q-card-actions>
</q-form>
</q-card>
</q-dialog>
</template>
<style scoped></style>

View file

@ -6,7 +6,7 @@ import { useRouter } from "vue-router";
import { useCounterMixin } from "@/stores/mixin";
import { useCommandListStore } from "@/modules/18_command/store/ListStore";
import DialogCopyCommand from "@/modules/18_command/components/Main/DialogCopyCommand.vue";
import DialogFormCommand from "@/modules/18_command/components/Main/DialogFormCommand.vue";
import type { QTableProps } from "quasar";
@ -239,7 +239,7 @@ function onReCommand(id: string) {
</template>
</d-table>
<DialogCopyCommand v-model:modal="modalCopy" />
<DialogFormCommand v-model:modal="modalCopy" :is-copy="true" />
</template>
<style scoped></style>

View file

@ -1 +1,14 @@
export type {};
interface DataListCommand {
category: string;
commandCode: string;
createdAt: string | Date;
createdFullName: string;
createdUserId: string;
id: string;
lastUpdateFullName: string;
lastUpdateUserId: string;
lastUpdatedAt: string | Date;
name: string;
}
export type { DataListCommand };

View file

@ -3,12 +3,14 @@ import { onMounted, ref } from "vue";
import { useCommandListStore } from "@/modules/18_command/store/ListStore";
import DialogFormCommand from "@/modules/18_command/components/Main/DialogFormCommand.vue";
import TableList from "@/modules/18_command/components/Main/TableMain.vue";
const store = useCommandListStore();
const yearly = ref<number>(new Date().getFullYear());
const searchKeyword = ref<string>("");
const modalAdd = ref<boolean>(false);
const tabsManu = ref([
{ label: "แบบร่าง", name: "list_draft" },
@ -86,7 +88,14 @@ onMounted(() => {
</template>
</datepicker>
<q-btn flat round dense icon="add" color="primary" />
<q-btn
flat
round
dense
icon="add"
color="primary"
@click.prevent="modalAdd = true"
/>
<q-space />
<q-input
@ -134,6 +143,8 @@ onMounted(() => {
</q-tab-panels>
</q-card-section>
</q-card>
<DialogFormCommand v-model:modal="modalAdd" :is-copy="false" />
</template>
<style scoped></style>