CviLux_fe/src/views/AssetManagement/components/AssetTable.vue

265 lines
7.1 KiB
Vue

<script setup>
import { getAssetList, getAssetSingle, deleteAssetItem } from "@/apis/asset";
import { onMounted, ref, watch, inject, provide, computed } from "vue";
import useSearchParam from "@/hooks/useSearchParam";
import AssetTableAddModal from "./AssetTableAddModal.vue";
import { getOperationCompanyList } from "@/apis/operation";
import { postMQTTRefresh } from "@/apis/alert";
import dayjs from "dayjs";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const { openToast, cancelToastOpen } = inject("app_toast");
const { companyOptions, departmentList, floors } = inject("asset_modal_options");
const FILE_BASEURL = window.env?.VITE_FILE_API_BASEURL;
const { searchParams, changeParams } = useSearchParam();
const totalCoordinates = ref({});
const tableData = ref([]);
const getAssetData = async () => {
totalCoordinates.value = {}; // 在獲取新數據之前清空 totalCoordinates
const res = await getAssetList(searchParams.value?.subSys_id);
if (res.isSuccess) {
// 將 device_coordinate 推入對應樓層的座標陣列
res.data.forEach((d) => {
const floorGuid = d.floor_guid;
if (!totalCoordinates.value[floorGuid]) {
totalCoordinates.value[floorGuid] = [];
}
totalCoordinates.value[floorGuid].push(d.device_coordinate);
});
tableData.value = res.data.map((d) => ({
...d,
key: d.id,
floor: floors.value.find(({ floor_guid }) => d.floor_guid === floor_guid)
?.full_name,
company: companyOptions.value.find(({ id }) => d.operation_id === id),
department: departmentList.value.find(({ id }) => d.department_id === id)
?.name,
buying_date: d?.buying_date
? dayjs(d?.buying_date).format("YYYY-MM-DD")
: "",
created_at: d?.created_at
? dayjs(d?.created_at).format("YYYY-MM-DD")
: "",
}));
}
};
const refreshMQTT = async () => {
const res = await postMQTTRefresh();
if (res.isSuccess) {
openToast("success", t("msg.mqtt_refresh"));
} else {
openToast("error", res.msg, "#outliers_add_table_item");
}
};
onMounted(async () => {
getAssetData();
});
const columns = computed(() => [
// {
// title: t("assetManagement.device_number"),
// key: "device_number",
// class: "break-all",
// },
{
title: t("assetManagement.device_name"),
key: "full_name",
filter: true,
class: "break-all",
},
{
title: t("assetManagement.asset_number"),
key: "asset_number",
},
{
title: t("assetManagement.floor"),
key: "floor",
filter: true,
sort: true,
},
{
title: t("assetManagement.department"),
key: "department",
filter: true,
},
{
title: t("assetManagement.device_coordinate"),
key: "device_coordinate",
},
{
title: t("assetManagement.brand_and_modal"),
key: "brandAndModal",
},
{
title: t("assetManagement.company_and_contact"),
key: "companyAndContact",
},
{
title: t("assetManagement.buying_date"),
key: "buying_date",
sort: true,
},
// {
// title: t("assetManagement.oriFile"),
// key: "oriFile",
// },
{
title: t("assetManagement.created_at"),
key: "created_at",
sort: true,
},
{
title: t("assetManagement.operation"),
key: "operation",
width: 200,
},
]);
watch(
() => searchParams,
(newValue) => {
if (newValue.value?.subSys_id) {
getAssetData();
} else {
tableData.value = [];
}
},
{
deep: true,
}
);
// modal
const editRecord = ref(null);
const openModal = () => {
asset_add_table_item.showModal();
};
const onCancel = () => {
editRecord.value = null;
asset_add_table_item.close();
};
const edit = async (id) => {
// changeParams({ ...searchParams.value, main_id: record.id });
const res = await getAssetSingle(id);
if (res.isSuccess) {
res.data.oriFile = res.data.oriFile.map((file, index) => ({
...file,
key: index,
src: file.file_url,
name: file.orgName,
ext: file.saveName.split(".")[file.saveName.split(".").length - 1],
}));
res.data.sub_device = res.data.sub_device?.map(
({ device_number, points }) => ({
device_number,
points,
})
);
editRecord.value = res.data;
openModal();
} else {
openToast("error", res.msg);
}
};
const remove = async (id) => {
openToast("warning", t("msg.sure_to_delete"), "body", async () => {
await cancelToastOpen();
const res = await deleteAssetItem(id);
if (res.isSuccess) {
getAssetData();
openToast("success", t("msg.delete_success"));
} else {
openToast("error", res.msg);
}
});
};
provide("asset_table_data", {
totalCoordinates,
});
</script>
<template>
<div class="flex justify-between items-center mt-10">
<div class="flex">
<h3 class="text-xl mr-5">{{ $t("assetManagement.device_list") }}</h3>
<AssetTableAddModal
:openModal="openModal"
:onCancel="onCancel"
:editRecord="editRecord"
:getData="getAssetData"
/>
</div>
<button class="btn btn-sm btn-add" @click.prevent="refreshMQTT">
<font-awesome-icon :icon="['fas', 'cog']" />{{
$t("alert.reorganization")
}}
</button>
</div>
<Table :columns="columns" :dataSource="tableData" class="mt-3">
<template #bodyCell="{ record, column, index }">
<template v-if="column.key === 'companyAndContact'">
{{ record.company?.name }} /
{{ record.company?.contact_person }}
</template>
<template v-else-if="column.key === 'brandAndModal'">
{{ record.brand }} / {{ record.device_model }}
</template>
<template v-else-if="column.key === 'oriFile'">
<span v-if="record.oriFile.length === 0"></span>
<template v-else>
<span class="flex flex-wrap gap-1">
<a
v-for="file in record.oriFile"
:href="`${FILE_BASEURL}/${file?.file_url}`"
target="_blank"
class="mx-1"
>
<img
v-if="
file.saveName
.split('.')
[file.saveName.split('.').length - 1]?.match(
/png|jpg|jpeg|gif|bmp|svg/g
)
"
:src="`${FILE_BASEURL}/${file?.file_url}`"
class="w-14 h-14"
/>
<font-awesome-icon
v-else
class="mx-auto mb-2 text-4xl text-white"
:icon="['fas', 'file-word']"
/>
</a>
</span>
</template>
</template>
<template v-else-if="column.key === 'operation'">
<button
class="btn btn-sm btn-success text-white mr-2"
@click.stop.prevent="() => edit(record.main_id)"
>
{{ $t("button.edit") }}
</button>
<button
class="btn btn-sm btn-error text-white"
@click.stop.prevent="() => remove(record.main_id)"
>
{{ $t("button.delete") }}
</button>
</template>
<template v-else>
{{ record[column.key] }}
</template>
</template>
</Table>
</template>
<style lang="scss" scoped></style>