CviLux_fe/src/views/operation/components/OperationTableModal.vue

627 lines
19 KiB
Vue

<script setup>
import { ref, defineProps, watch, inject } from "vue";
import useSearchParam from "@/hooks/useSearchParam";
import dayjs from "dayjs";
import {
postOperationRecord,
postOperationCompany,
updateOperationCompany,
} from "@/apis/operation";
import * as yup from "yup";
import "yup-phone-lite";
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
import Select from "@/components/customUI/Select.vue";
import SearchSelect from "@/components/customUI/SearchSelect.vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const FILE_BASEURL = import.meta.env.VITE_FILE_API_BASEURL;
const props = defineProps({
editRecord: Object,
});
const { openToast } = inject("app_toast");
const { model_data, updateEditRecord, search } = inject("operation_modal") || {
model_data: [],
updateEditRecord: null,
search: null,
};
const { searchParams } = useSearchParam();
const formState = ref([
{
formId: "",
work_type: "",
work_type_name: "",
fix_do: "",
fix_do_code: "",
fix_firm: "",
status: "",
work_person_id: "",
start_time: "",
finish_time: "",
notice: "",
description: "",
lorf: [],
},
{
formId: "",
work_type: "",
work_type_name: "",
fix_do: "",
fix_do_code: "",
fix_firm: "",
status: "",
work_person_id: "",
start_time: "",
finish_time: "",
notice: "",
description: "",
lorf: [],
},
{
contact_person: "",
email: "",
name: "",
phone: "",
remark: "",
tax_id_number: "",
city: "",
address: "",
},
]);
let companySchema = yup.object({
name: yup.string().required(t("button.required")),
contact_person: yup.string().nullable(true),
email: yup.string().email().nullable(true),
phone: yup.string().nullable(true),
city: yup.string().nullable(true),
address: yup.string().nullable(true),
tax_id_number: yup.string().nullable(true),
remark: yup.string().nullable(true),
});
let maintainSchema = yup.object({
formId: yup.string().required(t("button.required")),
work_type: yup.string().required(t("button.required")),
fix_do: yup.string().required(t("button.required")),
fix_do_code: yup.string().required(t("button.required")),
fix_firm: yup.string().required(t("button.required")),
status: yup.number().required(t("button.required")),
work_person_id: yup.string().required(t("button.required")),
start_time: yup.date().required(t("button.required")),
notice: yup.string().nullable(true),
description: yup.string().nullable(true),
});
const updateFileList = (files) => {
formState.value[searchParams.value?.work_type - 1].lorf = files;
};
const dateItem = ref([
{
key: "start_time",
name: "start_time",
value: dayjs(),
dateFormat: "yyyy-MM-dd",
placeholder: t("button.start_time_placeholder"),
},
]);
const dateItem2 = ref([
{
key: "finish_time",
name: "finish_time",
value: dayjs(),
dateFormat: "yyyy-MM-dd",
placeholder: t("button.finish_time_placeholder"),
},
]);
const form = ref(null);
const {
formErrorMsg: maintainFormErrorMsg,
handleSubmit: handleMaintainSubmit,
handleErrorReset: handleMaintainErrorReset,
} = useFormErrorMessage(maintainSchema);
const saveMaintain = async () => {
// TODO: 新增及編輯表單的作業
const formData = new FormData(form.value);
formData.delete("oriFile");
formState.value[searchParams.value.work_type - 1]?.lorf.forEach(
(file, index) => {
formData.append(`lorf[${index}].id`, file.id ? file.id : "");
formData.append(`lorf[${index}].file`, file.id ? null : file);
formData.append(
`lorf[${index}].save_file_name`,
file.id ? file.save_file_name : ""
);
formData.append(`lorf[${index}].ori_file_name`, file.name);
}
);
formData.append("work_type", searchParams.value.work_type);
formData.append(
"start_time",
dayjs(dateItem.value[0].value).format("YYYY-MM-DD")
);
formData.append(
"finish_time",
dayjs(dateItem2.value[0].value).format("YYYY-MM-DD")
);
props.editRecord.id && formData.append("id", props.editRecord.id);
props.editRecord.id
? formData.append("fix_do_code", props.editRecord.fix_do_code)
: formData.append("fix_do_code", formState.value[searchParams.value.work_type - 1]?.fix_do_code);
const value = await handleMaintainSubmit(
maintainSchema,
formState.value[searchParams.value.work_type - 1]
);
const res = await postOperationRecord(formData);
if (res.isSuccess) {
search?.();
onCancel();
} else {
}
};
const {
formErrorMsg: companyFormErrorMsg,
handleSubmit: handleCompanySubmit,
handleErrorReset: handleCompanyErrorReset,
} = useFormErrorMessage(companySchema);
const saveCompany = async () => {
const value = await handleCompanySubmit(
companySchema,
formState.value[searchParams.value?.work_type - 1]
);
let res;
if (props.editRecord) {
res = await updateOperationCompany(value);
} else {
res = await postOperationCompany(value);
}
if (res.isSuccess) {
search();
onCancel();
} else {
openToast("error", res.msg, "#operation_action_item");
}
};
const onOk = async () => {
if (searchParams.value.work_type < 3) {
saveMaintain();
} else {
saveCompany();
}
};
const reset = () => {
for (let [key, value] of Object.entries(
formState.value[searchParams.value?.work_type - 1]
)) {
if (Array.isArray(value)) {
formState.value[searchParams.value?.work_type - 1][key] = [];
} else {
formState.value[searchParams.value?.work_type - 1][key] = "";
}
}
};
const onCancel = () => {
for (let [key, value] of Object.entries(
formState.value[searchParams.value?.work_type - 1]
)) {
formState.value[searchParams.value?.work_type - 1][key] = "";
}
updateEditRecord?.(null);
reset();
handleMaintainErrorReset();
handleCompanyErrorReset();
operation_action_item.close();
};
watch(
() => props.editRecord,
(newVal) => {
if (newVal) {
for (let [key, value] of Object.entries(newVal)) {
formState.value[searchParams.value?.work_type - 1][key] = value;
if (
Object.hasOwn(
formState.value[searchParams.value?.work_type - 1],
"start_time"
)
) {
dateItem.value[0].value = newVal.start_time;
}
if (
Object.hasOwn(
formState.value[searchParams.value?.work_type - 1],
"finish_time"
)
) {
dateItem2.value[0].value = newVal.finish_time;
}
}
if (
Object.hasOwn(
formState.value[searchParams.value?.work_type - 1],
"work_type"
)
) {
const work_types = [t("operation.maintenance"), t("operation.repair")];
formState.value[searchParams.value?.work_type - 1].work_type =
searchParams.value.work_type;
formState.value[searchParams.value?.work_type - 1].work_type_name =
work_types[searchParams.value.work_type - 1];
}
}
}
);
</script>
<template>
<Modal id="operation_action_item" :onCancel="onCancel" width="710">
<template #modalContent>
<form ref="form" class="mt-5 w-full flex flex-wrap justify-between">
<template v-if="searchParams?.work_type < 3">
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'work_type_name'
)
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="work_type_name"
readonly
>
<template #topLeft>{{ $t("operation.project") }}</template>
</Input>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'formId')
"
class="my-2"
:value="formState[searchParams?.work_type - 1]"
name="formId"
readonly
>
<template #topLeft>{{ $t("operation.form_number") }}</template>
</Input>
<DateGroup
class="my-2"
:items="dateItem"
inputClass="w-full shadow-none"
:required="true"
>
<template #topLeft>{{ $t("operation.start_time") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.start_time }}
</span></template
>
</DateGroup>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'fix_do')
"
class="my-2"
:value="formState[searchParams?.work_type - 1]"
name="fix_do"
:required="true"
>
<template #topLeft>{{ $t("operation.repair_item") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.fix_do }}
</span></template
>
</Input>
<SearchSelect
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'fix_do_code'
)
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
selectClass="border-info focus-within:border-info"
name="fix_do_code"
Attribute="full_name"
:options="model_data.model_devList"
:disabled="props.editRecord?.id !== ''"
>
<template #topLeft>{{ $t("operation.repair_item_code") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.fix_do_code }}
</span></template
>
</SearchSelect>
<Select
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'fix_firm')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
selectClass="border-info focus-within:border-info"
name="fix_firm"
Attribute="name"
:options="model_data.model_companyList"
:required="true"
>
<template #topLeft>{{
$t("operation.responsible_vendor")
}}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.fix_firm }}
</span></template
>
</Select>
<RadioGroup
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'status')
"
class="my-2"
name="status"
:value="formState[searchParams?.work_type - 1]"
:items="[
{
key: 1,
value: 1,
title: $t('operation.completed'),
},
{
key: 0,
value: 0,
title: $t('operation.not_completed'),
},
]"
:required="true"
>
<template #topLeft>{{ $t("operation.status") }}</template>
</RadioGroup>
<DateGroup
class="my-2"
:items="dateItem2"
inputClass="w-full shadow-none"
:required="true"
>
<template #topLeft>{{ $t("operation.finish_time") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.finish_time }}
</span></template
>
</DateGroup>
<Select
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'work_person_id'
)
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
selectClass="border-info focus-within:border-info"
name="work_person_id"
Attribute="full_name"
:options="model_data.model_userList"
:required="true"
>
<template #topLeft>{{ $t("operation.worker_id") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ maintainFormErrorMsg.work_person_id }}
</span></template
>
</Select>
<Textarea
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'notice')
"
:value="formState[searchParams?.work_type - 1]"
name="notice"
class="w-full my-2"
>
<template #topLeft>{{ $t("operation.notice") }}</template>
</Textarea>
<Textarea
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'description'
)
"
:value="formState[searchParams?.work_type - 1]"
name="description"
class="w-full my-2"
>
<template #topLeft>{{ $t("operation.result_description") }}</template>
</Textarea>
<Upload
class="my-2"
name="oriFile"
:fileList="formState[searchParams?.work_type - 1]?.lorf"
:getFileList="updateFileList"
:multiple="true"
:baseUrl="`${FILE_BASEURL}/upload/operation`"
>
<template #topLeft>{{ $t("operation.upload_file") }}</template>
</Upload>
</template>
<template v-else>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'name')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="name"
>
<template #topLeft>{{ $t("operation.name") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.name }}
</span></template
>
</Input>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'contact_person'
)
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="contact_person"
>
<template #topLeft>{{ $t("operation.contact_person") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.contact_person }}
</span></template
></Input
>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'phone')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="phone"
>
<template #topLeft>{{ $t("operation.phone") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.phone }}
</span></template
></Input
>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'email')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="email"
>
<template #topLeft>>{{ $t("operation.email") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.email }}
</span></template
>
</Input>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'city')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2 w-[250px]"
name="city"
>
<template #topLeft>{{ $t("operation.city") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.city }}
</span></template
></Input
>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'address')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2 w-4/5"
name="address"
>
<template #topLeft>{{ $t("operation.address") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.address }}
</span></template
></Input
>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(
formState[searchParams?.work_type - 1],
'tax_id_number'
)
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="tax_id_number"
>
<template #topLeft> {{ $t("operation.tax_id_number") }}</template>
<template #bottomLeft
><span class="text-error text-base">
{{ companyFormErrorMsg.tax_id_number }}
</span></template
></Input
>
<Input
v-if="
searchParams?.work_type &&
Object.hasOwn(formState[searchParams?.work_type - 1], 'remark')
"
:value="formState[searchParams?.work_type - 1]"
class="my-2"
name="remark"
>
<template #topLeft>
{{ $t("operation.remark") }}
</template></Input
>
</template>
</form>
</template>
<template #modalAction>
<button
type="reset"
class="btn btn-outline-success mr-2"
@click.prevent="onCancel"
>
{{ $t("button.cancel") }}
</button>
<button
type="submit"
class="btn btn-outline-success"
@click.stop.prevent="onOk"
>
{{ $t("button.submit") }}
</button>
</template>
</Modal>
</template>
<style lang="scss" scoped></style>