feat: Personnel => Option (type, store)

This commit is contained in:
puriphatt 2024-04-10 17:00:28 +07:00
parent 38089a5312
commit 7d6ae75551
4 changed files with 169 additions and 45 deletions

View file

@ -2,10 +2,11 @@
import { ref, onMounted, watch } from 'vue'; import { ref, onMounted, watch } from 'vue';
import { api } from 'src/boot/axios'; import { api } from 'src/boot/axios';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { dialog } from 'src/stores/utils';
import useUserStore from 'stores/user'; import useUserStore from 'stores/user';
import useBranchStore from 'src/stores/branch'; import useBranchStore from 'src/stores/branch';
import { UserCreate, UserTypeStats } from 'src/stores/user/types'; import { UserCreate, UserTypeStats, UserOption } from 'src/stores/user/types';
import { BranchUserStats } from 'src/stores/branch/types'; import { BranchUserStats } from 'src/stores/branch/types';
// import { dateFormat } from 'src/utils/datetime'; // import { dateFormat } from 'src/utils/datetime';
@ -16,10 +17,9 @@ import SelectorList from 'components/SelectorList.vue';
import BtnAddComponent from 'components/01_branch-management/BtnAddComponent.vue'; import BtnAddComponent from 'components/01_branch-management/BtnAddComponent.vue';
import TooltipComponent from 'components/TooltipComponent.vue'; import TooltipComponent from 'components/TooltipComponent.vue';
import FormDialog from 'src/components/FormDialog.vue'; import FormDialog from 'src/components/FormDialog.vue';
import GlobalDialog from 'components/GlobalDialog.vue';
const branchStore = useBranchStore();
const userStore = useUserStore(); const userStore = useUserStore();
const branchStore = useBranchStore();
const { data: userData } = storeToRefs(userStore); const { data: userData } = storeToRefs(userStore);
const defaultFormData = { const defaultFormData = {
@ -53,26 +53,51 @@ const defaultFormData = {
birthDate: null, birthDate: null,
responsibleArea: '', responsibleArea: '',
}; };
const userId = ref('');
const isEdit = ref(false);
const modal = ref(false); const modal = ref(false);
const status = ref(false); const status = ref(false);
const userId = ref('');
const code = ref('');
const selectorLabel = ref(''); const selectorLabel = ref('');
const hqId = ref(''); const hqId = ref('');
const brId = ref(''); const brId = ref('');
const username = ref(''); const username = ref('');
const formData = ref<UserCreate>(structuredClone(defaultFormData)); const formData = ref<UserCreate>({
provinceId: null,
districtId: null,
subDistrictId: null,
telephoneNo: '',
email: '',
zipCode: '',
gender: '',
addressEN: '',
address: '',
trainingPlace: null,
importNationality: null,
sourceNationality: null,
licenseExpireDate: null,
licenseIssueDate: null,
licenseNo: null,
discountCondition: '',
retireDate: null,
startDate: null,
registrationNo: null,
lastNameEN: '',
lastName: '',
firstNameEN: '',
firstName: '',
userRole: '',
userType: '',
keycloakId: '',
profileImage: null,
birthDate: null,
responsibleArea: '',
});
const userStats = ref<BranchUserStats[]>(); const userStats = ref<BranchUserStats[]>();
const typeStats = ref<UserTypeStats>(); const typeStats = ref<UserTypeStats>();
const age = ref<number>(); const age = ref<number>();
const confirmData = ref({
modal: false,
title: '',
message: '',
icon: '',
action: () => {},
});
const userTypeOpts = [ const userTypeOpts = [
{ label: 'พนักงาน', value: 'USER' }, { label: 'พนักงาน', value: 'USER' },
{ label: 'พนักงานส่งเอกสาร', value: 'MESSENGER' }, { label: 'พนักงานส่งเอกสาร', value: 'MESSENGER' },
@ -83,10 +108,12 @@ const genderOpts = [
{ label: 'ชาย', value: 'male' }, { label: 'ชาย', value: 'male' },
{ label: 'หญิง', value: 'female' }, { label: 'หญิง', value: 'female' },
]; ];
const hqOpts = ref([
{ label: '0000000001', value: '1' }, const userOption = ref<UserOption>({
{ label: '0000000002', value: '2' }, hqOpts: [],
]); brOpts: [],
});
const brOpts = ref([ const brOpts = ref([
{ label: '0000000001-1', value: '1' }, { label: '0000000001-1', value: '1' },
{ label: '0000000001-2', value: '2' }, { label: '0000000001-2', value: '2' },
@ -109,13 +136,91 @@ async function createKeycloak() {
return res.data; return res.data;
} }
// function selectFile() { function selectFile() {
// const fileInput = this.$refs.file; // const fileInput = this.$refs.file;
// fileInput.pickFiles(); // fileInput.pickFiles();
// } }
function openDialog() { async function fetchHqOption() {
if (userOption.value.hqOpts.length === 0) {
const res = await branchStore.fetchList({ pageSize: 999, filter: 'head' });
if (res) {
res.result.map((item) => {
userOption.value.hqOpts.push({
label: item.code,
value: item.id,
});
});
}
}
}
async function fetchBrOption(id: string) {
const res = await branchStore.fetchById(id, {
includeSubBranch: true,
});
if (res) {
res.branch.map((item) => {
userOption.value.brOpts.push({
label: item.code,
value: item.id,
});
});
}
}
async function openDialog(id?: string) {
await fetchHqOption();
modal.value = true; modal.value = true;
if (id && userData.value) {
const foundUser = userData.value.result.find((user) => user.id === id);
if (foundUser) {
formData.value.provinceId = foundUser.provinceId;
formData.value.districtId = foundUser.districtId;
formData.value.subDistrictId = foundUser.subDistrictId;
formData.value.telephoneNo = foundUser.telephoneNo;
formData.value.email = foundUser.email;
formData.value.zipCode = foundUser.zipCode;
formData.value.gender = foundUser.gender;
formData.value.addressEN = foundUser.addressEN;
formData.value.address = foundUser.address;
formData.value.trainingPlace = foundUser.trainingPlace;
formData.value.importNationality = foundUser.importNationality;
formData.value.sourceNationality = foundUser.sourceNationality;
formData.value.licenseExpireDate = foundUser.licenseExpireDate
? new Date(foundUser.licenseExpireDate)
: null;
formData.value.licenseIssueDate = foundUser.licenseIssueDate
? new Date(foundUser.licenseIssueDate)
: null;
formData.value.licenseNo = foundUser.licenseNo;
formData.value.discountCondition = foundUser.discountCondition;
formData.value.retireDate = foundUser.retireDate
? new Date(foundUser.retireDate)
: null;
formData.value.startDate = foundUser.startDate
? new Date(foundUser.startDate)
: null;
formData.value.registrationNo = foundUser.registrationNo;
formData.value.lastNameEN = foundUser.lastNameEN;
formData.value.lastName = foundUser.lastName;
formData.value.firstNameEN = foundUser.firstNameEN;
formData.value.firstName = foundUser.firstName;
formData.value.userRole = foundUser.userRole;
formData.value.userType = foundUser.userType;
formData.value.keycloakId = foundUser.keycloakId;
formData.value.profileImage = new File([], foundUser.profileImageUrl);
formData.value.birthDate = foundUser.birthDate
? new Date(foundUser.birthDate)
: null;
formData.value.responsibleArea = foundUser.responsibleArea;
userId.value = foundUser.id;
hqId.value = foundUser.branch[0].id;
brId.value = foundUser.branch;
code.value = foundUser.code;
isEdit.value = true;
}
}
} }
function onClose() { function onClose() {
@ -125,17 +230,14 @@ function onClose() {
brId.value = ''; brId.value = '';
username.value = ''; username.value = '';
userId.value = ''; userId.value = '';
code.value = '';
mapUserType(selectorLabel.value); mapUserType(selectorLabel.value);
} }
function submitConfirm() { async function onSubmit() {
confirmData.value.modal = true;
}
async function onSubmit(id?: string) {
try { try {
if (id) { if (isEdit.value === true && userId.value) {
await userStore.editById(id, formData.value); await userStore.editById(userId.value, formData.value);
} else { } else {
formData.value.keycloakId = await createKeycloak(); formData.value.keycloakId = await createKeycloak();
await userStore.create(formData.value); await userStore.create(formData.value);
@ -164,7 +266,7 @@ function mapUserType(label: string) {
} }
onMounted(async () => { onMounted(async () => {
await userStore.fetchList(); await userStore.fetchList({ includeBranch: true });
typeStats.value = await userStore.typeStats(); typeStats.value = await userStore.typeStats();
if ((await branchStore.userStats(formData.value.userType)) !== false) { if ((await branchStore.userStats(formData.value.userType)) !== false) {
userStats.value = await branchStore.userStats(formData.value.userType); userStats.value = await branchStore.userStats(formData.value.userType);
@ -180,6 +282,15 @@ watch(
} }
}, },
); );
watch(
() => hqId.value,
async (id) => {
fetchBrOption(id);
brId.value = '';
userOption.value.brOpts = [];
},
);
</script> </script>
<template> <template>
@ -207,7 +318,7 @@ watch(
unelevated unelevated
label="+ เพิ่มบุคลากร" label="+ เพิ่มบุคลากร"
padding="4px 16px" padding="4px 16px"
@click="openDialog" @click="openDialog()"
style="background-color: var(--cyan-6); color: white" style="background-color: var(--cyan-6); color: white"
/> />
</div> </div>
@ -245,6 +356,7 @@ watch(
disabled: v.status === 'INACTIVE', disabled: v.status === 'INACTIVE',
})) || [] })) || []
" "
@updateCard="openDialog"
@deleteCard="onDelete" @deleteCard="onDelete"
/> />
<div <div
@ -284,7 +396,7 @@ watch(
title="เพิ่มบุคลากร" title="เพิ่มบุคลากร"
addressTitle="ที่อยู่พนักงาน" addressTitle="ที่อยู่พนักงาน"
addressENTitle="ที่อยู่พนักงาน ENG" addressENTitle="ที่อยู่พนักงาน ENG"
:submit="() => submitConfirm()" :submit="() => onSubmit()"
:close="() => onClose()" :close="() => onClose()"
> >
<template #top> <template #top>
@ -293,13 +405,14 @@ watch(
outlined outlined
emit-value emit-value
map-options map-options
options-dense
class="col-6" class="col-6"
bg-color="white" bg-color="white"
option-label="label" option-label="label"
option-value="value" option-value="value"
label="รหัสสำนักงานใหญ่" label="รหัสสำนักงานใหญ่"
v-model="hqId" v-model="hqId"
:options="hqOpts" :options="userOption.hqOpts"
:rules="[(val: string) => !!val || 'กรุณาเลือกสำนักงานใหญ่']" :rules="[(val: string) => !!val || 'กรุณาเลือกสำนักงานใหญ่']"
/> />
<q-select <q-select
@ -307,13 +420,14 @@ watch(
outlined outlined
emit-value emit-value
map-options map-options
options-dense
class="col-6" class="col-6"
label="รหัสสาขา" label="รหัสสาขา"
bg-color="white" bg-color="white"
option-label="label" option-label="label"
option-value="value" option-value="value"
v-model="brId" v-model="brId"
:options="brOpts" :options="userOption.brOpts"
:rules="[(val: string) => !!val || 'กรุณาเลือกสาขา']" :rules="[(val: string) => !!val || 'กรุณาเลือกสาขา']"
/> />
<q-select <q-select
@ -321,6 +435,7 @@ watch(
outlined outlined
emit-value emit-value
map-options map-options
options-dense
class="col-3" class="col-3"
bg-color="white" bg-color="white"
option-value="value" option-value="value"
@ -335,6 +450,7 @@ watch(
outlined outlined
emit-value emit-value
map-options map-options
options-dense
class="col-3" class="col-3"
bg-color="white" bg-color="white"
label="สิทธิ์ผู้ใช้งาน" label="สิทธิ์ผู้ใช้งาน"
@ -360,7 +476,7 @@ watch(
class="col-3" class="col-3"
bg-color="white" bg-color="white"
label="รหัสพนักงาน" label="รหัสพนักงาน"
v-model="userId" v-model="code"
/> />
<!-- :rules="[(val: string) => !!val || 'กรุณากรอกรหัสพนักงาน']" <!-- :rules="[(val: string) => !!val || 'กรุณากรอกรหัสพนักงาน']"
--> -->
@ -690,15 +806,6 @@ watch(
</div> </div>
</template> </template>
</FormDialog> </FormDialog>
<GlobalDialog
:v-model="confirmData.modal"
:title="confirmData.title"
:message="confirmData.message"
:icon="confirmData.icon"
:persistent="true"
:action="() => onSubmit()"
/>
</template> </template>
<style> <style>
.bg-white { .bg-white {

View file

@ -27,6 +27,7 @@ export type Branch = {
taxNo: string; taxNo: string;
id: string; id: string;
code: string; code: string;
branch: Branch[];
}; };
export type BranchWithChildren = Branch & { branch: Branch[] }; export type BranchWithChildren = Branch & { branch: Branch[] };

View file

@ -124,6 +124,7 @@ const useUserStore = defineStore('api-user', () => {
pageSize?: number; pageSize?: number;
zipCode?: string; zipCode?: string;
query?: string; query?: string;
includeBranch?: boolean;
}, },
flow?: { flow?: {
sessionId: string; sessionId: string;
@ -139,6 +140,7 @@ const useUserStore = defineStore('api-user', () => {
if (opts?.page && opts.page > 0) params.append('page', `${opts.page}`); if (opts?.page && opts.page > 0) params.append('page', `${opts.page}`);
if (opts?.zipCode) params.append('zipCode', opts.zipCode); if (opts?.zipCode) params.append('zipCode', opts.zipCode);
if (opts?.query) params.append('query', opts.query); if (opts?.query) params.append('query', opts.query);
if (opts?.includeBranch) params.append('includeBranch', 'true');
const query = params.toString(); const query = params.toString();

View file

@ -1,4 +1,5 @@
import { District, Province, SubDistrict } from '../address'; import { District, Province, SubDistrict } from '../address';
import { Branch } from '../branch/types';
import { Status } from '../types'; import { Status } from '../types';
export type User = { export type User = {
@ -39,6 +40,9 @@ export type User = {
id: string; id: string;
profileImageUrl: string; profileImageUrl: string;
code: string; code: string;
birthDate?: Date | null;
responsibleArea: string,
branch: Branch[]
}; };
export type UserCreate = { export type UserCreate = {
@ -57,7 +61,7 @@ export type UserCreate = {
licenseExpireDate?: Date | null; licenseExpireDate?: Date | null;
licenseIssueDate?: Date | null; licenseIssueDate?: Date | null;
licenseNo?: string | null; licenseNo?: string | null;
discountCondition?: string; discountCondition?: string | null;
retireDate?: Date | null; retireDate?: Date | null;
startDate?: Date | null; startDate?: Date | null;
registrationNo?: string | null; registrationNo?: string | null;
@ -92,3 +96,13 @@ export type UserTypeStats = {
DELEGATE: number; DELEGATE: number;
AGENCY: number; AGENCY: number;
} }
export type UserOption = {
hqOpts: Option[]
brOpts: Option[]
}
export type Option = {
label: string;
value: string;
}