生產設定: 匯出excel API串接
調整報表管理日期範圍 修改今日生產目標UI 溫度 - 糖度、冷藏溫度 新增 一小時、四小時、八小時 設定 告警小類篩選
This commit is contained in:
parent
02d819437c
commit
fe1570e63b
@ -5,3 +5,4 @@ export const POST_SETTING_TYPE_API = `/SituationRoom/SetProduct`;
|
|||||||
export const GET_SETTING_INVENTORY_API = `/SituationRoom/GetInventory`;
|
export const GET_SETTING_INVENTORY_API = `/SituationRoom/GetInventory`;
|
||||||
export const POST_SETTING_INVENTORY_API = `/SituationRoom/SaveInventory`;
|
export const POST_SETTING_INVENTORY_API = `/SituationRoom/SaveInventory`;
|
||||||
export const GET_SETTING_INVENTORY_LOG_API = `/SituationRoom/GetInventoryLog`;
|
export const GET_SETTING_INVENTORY_LOG_API = `/SituationRoom/GetInventoryLog`;
|
||||||
|
export const GET_SETTING_INVENTORY_EXPORT_API = `/api/report/Inventory`;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import instance from "@/util/request";
|
import instance, { fileInstance } from "@/util/request";
|
||||||
import apihandler from "@/util/apihandler";
|
import apihandler from "@/util/apihandler";
|
||||||
import {
|
import {
|
||||||
POST_CHANGE_GROUP_VALUE_API,
|
POST_CHANGE_GROUP_VALUE_API,
|
||||||
@ -7,7 +7,9 @@ import {
|
|||||||
GET_SETTING_INVENTORY_API,
|
GET_SETTING_INVENTORY_API,
|
||||||
POST_SETTING_INVENTORY_API,
|
POST_SETTING_INVENTORY_API,
|
||||||
GET_SETTING_INVENTORY_LOG_API,
|
GET_SETTING_INVENTORY_LOG_API,
|
||||||
|
GET_SETTING_INVENTORY_EXPORT_API,
|
||||||
} from "./api";
|
} from "./api";
|
||||||
|
import downloadExcel from "@/util/downloadExcel";
|
||||||
|
|
||||||
export const postChangeGroupValue = async (data) => {
|
export const postChangeGroupValue = async (data) => {
|
||||||
const res = await instance.post(POST_CHANGE_GROUP_VALUE_API, data);
|
const res = await instance.post(POST_CHANGE_GROUP_VALUE_API, data);
|
||||||
@ -72,3 +74,26 @@ export const getSettingInventoryLog = async ({ start_time, end_time }) => {
|
|||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getInventoryExportData = async ({ start_date, end_date }) => {
|
||||||
|
const res = await fileInstance.get(
|
||||||
|
GET_SETTING_INVENTORY_EXPORT_API,
|
||||||
|
{
|
||||||
|
params: {
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
},
|
||||||
|
responseType: "blob",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return apihandler(
|
||||||
|
res.code,
|
||||||
|
res,
|
||||||
|
{
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
},
|
||||||
|
downloadExcel
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@ -12,10 +12,11 @@ import instance, { fileInstance } from "@/util/request";
|
|||||||
import apihandler from "@/util/apihandler";
|
import apihandler from "@/util/apihandler";
|
||||||
import downloadExcel from "@/util/downloadExcel";
|
import downloadExcel from "@/util/downloadExcel";
|
||||||
|
|
||||||
export const getElectricMeterLog = async ({ start_date }) => {
|
export const getElectricMeterLog = async ({ start_date, end_date }) => {
|
||||||
const res = await instance.get(GET_ELECTRIC_METER_API, {
|
const res = await instance.get(GET_ELECTRIC_METER_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -26,10 +27,14 @@ export const getElectricMeterLog = async ({ start_date }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getRefrigerationRoomTemperatureLog = async ({ start_date }) => {
|
export const getRefrigerationRoomTemperatureLog = async ({
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
}) => {
|
||||||
const res = await instance.get(GET_REFRIGERATION_ROOM_TEMPERATURE_API, {
|
const res = await instance.get(GET_REFRIGERATION_ROOM_TEMPERATURE_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
@ -39,10 +44,11 @@ export const getRefrigerationRoomTemperatureLog = async ({ start_date }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSipLog = async ({ start_date }) => {
|
export const getSipLog = async ({ start_date, end_date }) => {
|
||||||
const res = await instance.get(GET_SIP_API, {
|
const res = await instance.get(GET_SIP_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
@ -52,10 +58,11 @@ export const getSipLog = async ({ start_date }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getCipLog = async ({ start_date }) => {
|
export const getCipLog = async ({ start_date, end_date }) => {
|
||||||
const res = await instance.get(GET_CIP_API, {
|
const res = await instance.get(GET_CIP_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
@ -65,10 +72,11 @@ export const getCipLog = async ({ start_date }) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportElectricMeterLog = async ({ start_date }) => {
|
export const exportElectricMeterLog = async ({ start_date, end_date }) => {
|
||||||
const res = await fileInstance.get(EXPORT_ELECTRIC_METER_API, {
|
const res = await fileInstance.get(EXPORT_ELECTRIC_METER_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
});
|
});
|
||||||
@ -84,12 +92,16 @@ export const exportElectricMeterLog = async ({ start_date }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportRefrigerationRoomTemperatureLog = async ({ start_date }) => {
|
export const exportRefrigerationRoomTemperatureLog = async ({
|
||||||
|
start_date,
|
||||||
|
end_date,
|
||||||
|
}) => {
|
||||||
const res = await fileInstance.get(
|
const res = await fileInstance.get(
|
||||||
EXPORT_REFRIGERATION_ROOM_TEMPERATURE_API,
|
EXPORT_REFRIGERATION_ROOM_TEMPERATURE_API,
|
||||||
{
|
{
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
}
|
}
|
||||||
@ -106,10 +118,11 @@ export const exportRefrigerationRoomTemperatureLog = async ({ start_date }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportSipLog = async ({ start_date }) => {
|
export const exportSipLog = async ({ start_date, end_date }) => {
|
||||||
const res = await fileInstance.get(EXPORT_SIP_API, {
|
const res = await fileInstance.get(EXPORT_SIP_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
});
|
});
|
||||||
@ -124,10 +137,11 @@ export const exportSipLog = async ({ start_date }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const exportCipLog = async ({ start_date }) => {
|
export const exportCipLog = async ({ start_date, end_date }) => {
|
||||||
const res = await fileInstance.get(EXPORT_CIP_API, {
|
const res = await fileInstance.get(EXPORT_CIP_API, {
|
||||||
params: {
|
params: {
|
||||||
start_date,
|
start_date,
|
||||||
|
end_date,
|
||||||
},
|
},
|
||||||
responseType: "blob",
|
responseType: "blob",
|
||||||
});
|
});
|
||||||
|
|||||||
@ -68,7 +68,7 @@ watch(searchParams, (newValue) => {
|
|||||||
{{ checkedItem.length === store.subSys.length ? "取消全選" : "全選" }}
|
{{ checkedItem.length === store.subSys.length ? "取消全選" : "全選" }}
|
||||||
</button>
|
</button>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
v-for="sub in store.subSys"
|
v-for="sub in store.subSys.filter(sub => sub.is_alarm === 1)"
|
||||||
:key="sub.key"
|
:key="sub.key"
|
||||||
:title="sub.full_name"
|
:title="sub.full_name"
|
||||||
:value="sub.sub_system_tag"
|
:value="sub.sub_system_tag"
|
||||||
|
|||||||
@ -2,29 +2,33 @@
|
|||||||
import { ref, onMounted, watch } from "vue";
|
import { ref, onMounted, watch } from "vue";
|
||||||
import useSearchParam from "@/hooks/useSearchParam";
|
import useSearchParam from "@/hooks/useSearchParam";
|
||||||
import useActiveBtn from "@/hooks/useActiveBtn";
|
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||||
import { getAlertSubList } from "@/apis/alert";
|
import useBuildingStore from "@/stores/useBuildingStore";
|
||||||
|
|
||||||
const { searchParams, changeParams } = useSearchParam();
|
const { searchParams, changeParams } = useSearchParam();
|
||||||
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||||
|
const store = useBuildingStore();
|
||||||
|
|
||||||
const getSubSystems = async () => {
|
const updateSubSystemsFromStore = () => {
|
||||||
const res = await getAlertSubList();
|
const subSystems = store.subSys
|
||||||
const subSystems = res.data.history_Main_Systems.flatMap((mainSystem) => {
|
.filter(subSystem => subSystem.is_alarm === 1)
|
||||||
return mainSystem.history_Sub_systems.map((subSystem, index) => ({
|
.map(subSystem => ({
|
||||||
title: subSystem.full_name,
|
title: subSystem.full_name,
|
||||||
key: subSystem.sub_system_tag,
|
key: subSystem.sub_system_tag,
|
||||||
active: searchParams.value?.subSys_id
|
active: searchParams.value?.subSys_id
|
||||||
? searchParams.value.subSys_id === subSystem.sub_system_tag
|
? searchParams.value.subSys_id === subSystem.sub_system_tag
|
||||||
: subSystem.sub_system_tag == "DP",
|
: subSystem.sub_system_tag == "DP",
|
||||||
}));
|
}));
|
||||||
});
|
|
||||||
setItems(subSystems);
|
setItems(subSystems);
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getSubSystems();
|
updateSubSystemsFromStore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(() => store.subSys, () => {
|
||||||
|
updateSubSystemsFromStore();
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
watch(selectedBtn,
|
watch(selectedBtn,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
if (newValue) {
|
if (newValue) {
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import DashboardElectricity from "./components/DashboardElectricity.vue";
|
|||||||
import DashboardAlert from "./components/DashboardAlert.vue";
|
import DashboardAlert from "./components/DashboardAlert.vue";
|
||||||
import DashboardForgeOptionButton from "./components/DashboardForgeOptionButton.vue";
|
import DashboardForgeOptionButton from "./components/DashboardForgeOptionButton.vue";
|
||||||
import DashboardForgeOptionCard from "./components/DashboardForgeOptionCard.vue";
|
import DashboardForgeOptionCard from "./components/DashboardForgeOptionCard.vue";
|
||||||
|
import DashboardMoreModal from "./components/DashboardMoreModal.vue";
|
||||||
import {
|
import {
|
||||||
getDashboardInit,
|
getDashboardInit,
|
||||||
getDashboardOptionRealTimeData,
|
getDashboardOptionRealTimeData,
|
||||||
@ -106,6 +107,13 @@ const getCompany = async () => {
|
|||||||
companyOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
|
companyOptions.value = res.data.map((d) => ({ ...d, key: d.id }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const currentIntervalType = ref("");
|
||||||
|
|
||||||
|
const openModal = (type) => {
|
||||||
|
currentIntervalType.value = type;
|
||||||
|
dashboard_more.showModal();
|
||||||
|
};
|
||||||
|
|
||||||
// 開始定時器
|
// 開始定時器
|
||||||
const startInterval = (option) => {
|
const startInterval = (option) => {
|
||||||
// 清除之前的定時器
|
// 清除之前的定時器
|
||||||
@ -155,6 +163,7 @@ onUnmounted(() => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
<DashboardMoreModal :currentIntervalType="currentIntervalType" />
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div class="w-1/4 h-full flex flex-col justify-start border-dashboard z-20">
|
<div class="w-1/4 h-full flex flex-col justify-start border-dashboard z-20">
|
||||||
<div class=""><DashboardProduct /></div>
|
<div class=""><DashboardProduct /></div>
|
||||||
@ -186,9 +195,11 @@ onUnmounted(() => {
|
|||||||
:companyOptions="companyOptions"
|
:companyOptions="companyOptions"
|
||||||
/>
|
/>
|
||||||
<div class="w-1/4 flex flex-col justify-start border-dashboard z-20">
|
<div class="w-1/4 flex flex-col justify-start border-dashboard z-20">
|
||||||
<div class=""><DashboardImmediateTemp /></div>
|
<div class="">
|
||||||
|
<DashboardImmediateTemp @open-modal="openModal" />
|
||||||
|
</div>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<DashboardFrozenTemp />
|
<DashboardFrozenTemp @open-modal="openModal"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-5">
|
<div class="mt-5">
|
||||||
<DashboardElectricity />
|
<DashboardElectricity />
|
||||||
|
|||||||
@ -55,12 +55,11 @@ const defaultChartOption = ref({
|
|||||||
|
|
||||||
const frozen_temp_chart = ref(null);
|
const frozen_temp_chart = ref(null);
|
||||||
|
|
||||||
|
|
||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
|
|
||||||
const getData = async () => {
|
const getData = async (timeInterval) => {
|
||||||
const res = await getDashboardTemp({
|
const res = await getDashboardTemp({
|
||||||
timeInterval: 1, // 時間間隔=>1.4.8
|
timeInterval, // 時間間隔=>1.4.8
|
||||||
tempOption: 2, // 1:即時溫度;2:冷藏溫度
|
tempOption: 2, // 1:即時溫度;2:冷藏溫度
|
||||||
});
|
});
|
||||||
if (res.isSuccess) {
|
if (res.isSuccess) {
|
||||||
@ -68,6 +67,25 @@ const getData = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
searchParams,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (
|
||||||
|
newValue[intervalType] &&
|
||||||
|
newValue[intervalType] !== oldValue[intervalType]
|
||||||
|
) {
|
||||||
|
window.clearInterval(timeoutTimer.value);
|
||||||
|
getData(parseInt(newValue[intervalType]));
|
||||||
|
timeoutTimer.value = setInterval(() => {
|
||||||
|
getData(parseInt(newValue[intervalType]));
|
||||||
|
}, 60000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
watch(data, (newValue) => {
|
watch(data, (newValue) => {
|
||||||
if (newValue?.length > 0) {
|
if (newValue?.length > 0) {
|
||||||
frozen_temp_chart.value.chart.setOption({
|
frozen_temp_chart.value.chart.setOption({
|
||||||
@ -90,19 +108,19 @@ watch(data, (newValue) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let timer = null;
|
const timeoutTimer = ref("");
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getData();
|
getData();
|
||||||
timer = setInterval(() => {
|
timeoutTimer.value = setInterval(() => {
|
||||||
getData();
|
getData();
|
||||||
}, 60 * 1000);
|
}, 60 * 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (timer) {
|
if (timeoutTimer.value) {
|
||||||
clearInterval(timer);
|
clearInterval(timeoutTimer.value);
|
||||||
timer = null;
|
timeoutTimer.value = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -111,6 +129,12 @@ onUnmounted(() => {
|
|||||||
<!-- 冷藏溫度 -->
|
<!-- 冷藏溫度 -->
|
||||||
<div class="flex items-center justify-between mb-3">
|
<div class="flex items-center justify-between mb-3">
|
||||||
<h3 class="text-info font-bold text-xl text-center">冷藏溫度</h3>
|
<h3 class="text-info font-bold text-xl text-center">冷藏溫度</h3>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-info"
|
||||||
|
@click="$emit('open-modal', intervalType)"
|
||||||
|
>
|
||||||
|
時間設定
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<LineChart
|
<LineChart
|
||||||
|
|||||||
@ -80,9 +80,9 @@ onMounted(() => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
const getData = async (typeOption) => {
|
const getData = async (timeInterval, typeOption) => {
|
||||||
const res = await getDashboardTemp({
|
const res = await getDashboardTemp({
|
||||||
timeInterval: 1, // 時間間隔=>1.4.8
|
timeInterval, // 時間間隔=>1.4.8
|
||||||
tempOption: 1,
|
tempOption: 1,
|
||||||
typeOption, // 1:二重釜-溫度;2:調理鍋-溫度;3:二重釜-糖度
|
typeOption, // 1:二重釜-溫度;2:調理鍋-溫度;3:二重釜-糖度
|
||||||
});
|
});
|
||||||
@ -91,16 +91,35 @@ const getData = async (typeOption) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let timer = null;
|
const timeoutTimer = ref("");
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
selectedBtn,
|
selectedBtn,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
window.clearInterval(timer);
|
window.clearInterval(timeoutTimer.value);
|
||||||
getData(newValue.key);
|
getData(parseInt(searchParams.value[intervalType] || 1), newValue.key);
|
||||||
timer = setInterval(() => {
|
timeoutTimer.value = setInterval(() => {
|
||||||
getData(newValue.key);
|
getData(parseInt(searchParams.value[intervalType] || 1), newValue.key);
|
||||||
}, 60 * 1000);
|
}, 60000);
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
searchParams,
|
||||||
|
(newValue, oldValue) => {
|
||||||
|
if (
|
||||||
|
newValue[intervalType] &&
|
||||||
|
newValue[intervalType] !== oldValue[intervalType]
|
||||||
|
) {
|
||||||
|
window.clearInterval(timeoutTimer.value);
|
||||||
|
getData(parseInt(newValue[intervalType]), selectedBtn.value.key);
|
||||||
|
timeoutTimer.value = setInterval(() => {
|
||||||
|
getData(parseInt(newValue[intervalType]), selectedBtn.value.key);
|
||||||
|
}, 60000);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: true,
|
deep: true,
|
||||||
@ -110,34 +129,39 @@ watch(
|
|||||||
watch(data, (newValue) => {
|
watch(data, (newValue) => {
|
||||||
// clearChart(other_real_temp_chart.value.chart);
|
// clearChart(other_real_temp_chart.value.chart);
|
||||||
if (newValue?.length > 0) {
|
if (newValue?.length > 0) {
|
||||||
other_real_temp_chart.value.chart.setOption({
|
other_real_temp_chart.value.chart.setOption(
|
||||||
...defaultChartOption.value,
|
{
|
||||||
legend: {
|
...defaultChartOption.value,
|
||||||
data: newValue.map(({ full_name }) => full_name),
|
legend: {
|
||||||
...defaultChartOption.value.legend,
|
data: newValue.map(({ full_name }) => full_name),
|
||||||
},
|
...defaultChartOption.value.legend,
|
||||||
xAxis: {
|
|
||||||
...defaultChartOption.value.xAxis,
|
|
||||||
data: newValue[0]?.data.map(({ time }) => dayjs(time).format("HH:mm")),
|
|
||||||
},
|
|
||||||
series: newValue.map(({ full_name, data: seriesData }, index) => ({
|
|
||||||
name: full_name,
|
|
||||||
type: "line",
|
|
||||||
data: seriesData.map(({ value }) => value),
|
|
||||||
showSymbol: false,
|
|
||||||
itemStyle: {
|
|
||||||
color: SECOND_CHART_COLOR[index],
|
|
||||||
},
|
},
|
||||||
})),
|
xAxis: {
|
||||||
}, { notMerge: true });
|
...defaultChartOption.value.xAxis,
|
||||||
|
data: newValue[0]?.data.map(({ time }) =>
|
||||||
|
dayjs(time).format("HH:mm")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
series: newValue.map(({ full_name, data: seriesData }, index) => ({
|
||||||
|
name: full_name,
|
||||||
|
type: "line",
|
||||||
|
data: seriesData.map(({ value }) => value),
|
||||||
|
showSymbol: false,
|
||||||
|
itemStyle: {
|
||||||
|
color: SECOND_CHART_COLOR[index],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
{ notMerge: true }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
// other_real_temp_chart.value.chart.hideLoading();
|
// other_real_temp_chart.value.chart.hideLoading();
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
if (timer) {
|
if (timeoutTimer.value) {
|
||||||
clearInterval(timer);
|
clearInterval(timeoutTimer.value);
|
||||||
timer = null;
|
timeoutTimer.value = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
@ -145,6 +169,12 @@ onUnmounted(() => {
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex items-center justify-between mb-3">
|
<div class="flex items-center justify-between mb-3">
|
||||||
<h3 class="text-info font-bold text-xl text-center">溫度-糖度</h3>
|
<h3 class="text-info font-bold text-xl text-center">溫度-糖度</h3>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-info"
|
||||||
|
@click="$emit('open-modal', intervalType)"
|
||||||
|
>
|
||||||
|
時間設定
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<ButtonConnectedGroup
|
<ButtonConnectedGroup
|
||||||
|
|||||||
122
src/views/dashboard/components/DashboardMoreModal.vue
Normal file
122
src/views/dashboard/components/DashboardMoreModal.vue
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
<script setup>
|
||||||
|
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||||
|
import { onMounted, watch } from "vue";
|
||||||
|
import useSearchParams from "@/hooks/useSearchParam";
|
||||||
|
const { changeParams, searchParams } = useSearchParams();
|
||||||
|
|
||||||
|
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
currentIntervalType: {
|
||||||
|
type: String,
|
||||||
|
default: "interval_hour",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setItems([
|
||||||
|
{
|
||||||
|
title: "1小時",
|
||||||
|
key: "1hour",
|
||||||
|
active:
|
||||||
|
!searchParams.value?.[props.currentIntervalType] ||
|
||||||
|
searchParams.value?.[props.currentIntervalType] === 1,
|
||||||
|
timeInterval: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "4小時",
|
||||||
|
key: "4hour",
|
||||||
|
active: searchParams.value?.[props.currentIntervalType] === 4,
|
||||||
|
timeInterval: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "8小時",
|
||||||
|
key: "8hour",
|
||||||
|
active: searchParams.value?.[props.currentIntervalType] === 8,
|
||||||
|
timeInterval: 8,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.currentIntervalType,
|
||||||
|
(newValue) => {
|
||||||
|
console.log(
|
||||||
|
"currentIntervalType",
|
||||||
|
newValue,
|
||||||
|
searchParams.value,
|
||||||
|
searchParams.value?.[newValue]
|
||||||
|
);
|
||||||
|
setItems([
|
||||||
|
{
|
||||||
|
title: "1小時",
|
||||||
|
key: "1hour",
|
||||||
|
active:
|
||||||
|
!searchParams.value?.[newValue] ||
|
||||||
|
parseInt(searchParams.value?.[newValue]) === 1,
|
||||||
|
timeInterval: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "4小時",
|
||||||
|
key: "4hour",
|
||||||
|
active: parseInt(searchParams.value?.[newValue]) === 4,
|
||||||
|
timeInterval: 4,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "8小時",
|
||||||
|
key: "8hour",
|
||||||
|
active: parseInt(searchParams.value?.[newValue]) === 8,
|
||||||
|
timeInterval: 8,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
dashboard_more.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
const onOk = async () => {
|
||||||
|
console.log(searchParams.value);
|
||||||
|
changeParams({
|
||||||
|
...searchParams.value,
|
||||||
|
[props.currentIntervalType]: selectedBtn.value.timeInterval,
|
||||||
|
});
|
||||||
|
onCancel();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Modal id="dashboard_more" title="顯示設定" :onCancel="onCancel" width="500">
|
||||||
|
<template #modalContent>
|
||||||
|
<ButtonGroup
|
||||||
|
:items="items"
|
||||||
|
:withLine="true"
|
||||||
|
class="mt-8 mb-6"
|
||||||
|
:onclick="
|
||||||
|
(e, item) => {
|
||||||
|
changeActiveBtn(item);
|
||||||
|
}
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #modalAction>
|
||||||
|
<button
|
||||||
|
type="reset"
|
||||||
|
class="btn btn-outline-success mr-2"
|
||||||
|
@click.prevent="onCancel"
|
||||||
|
>
|
||||||
|
取消
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
@click.stop.prevent="onOk"
|
||||||
|
>
|
||||||
|
確定
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -48,7 +48,7 @@ onMounted(() => {
|
|||||||
setItems([
|
setItems([
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
title: "配方",
|
title: "調理",
|
||||||
key: 1,
|
key: 1,
|
||||||
active: true,
|
active: true,
|
||||||
},
|
},
|
||||||
@ -107,7 +107,7 @@ onUnmounted(() => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th>品名</th>
|
<th>品名</th>
|
||||||
<th>狀態</th>
|
<th>狀態</th>
|
||||||
<th>生產進度</th>
|
<!-- <th>生產進度</th> -->
|
||||||
<th v-if="selectedBtn?.key === 1">功能</th>
|
<th v-if="selectedBtn?.key === 1">功能</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -131,7 +131,7 @@ onUnmounted(() => {
|
|||||||
<tr v-for="item in production_data" :key="item.name">
|
<tr v-for="item in production_data" :key="item.name">
|
||||||
<td>{{ item.name }}</td>
|
<td>{{ item.name }}</td>
|
||||||
<td>{{ item.status }}</td>
|
<td>{{ item.status }}</td>
|
||||||
<td>{{ item.progress }}</td>
|
<!-- <td>{{ item.progress }}</td> -->
|
||||||
<td v-if="item.details && item.details.length">
|
<td v-if="item.details && item.details.length">
|
||||||
<button
|
<button
|
||||||
class="btn btn-xs btn-outline-info"
|
class="btn btn-xs btn-outline-info"
|
||||||
|
|||||||
@ -9,6 +9,7 @@ const tabs = [
|
|||||||
{ label: "品檢" },
|
{ label: "品檢" },
|
||||||
{ label: "流量計" },
|
{ label: "流量計" },
|
||||||
{ label: "SIP" },
|
{ label: "SIP" },
|
||||||
|
{ label: "AI" },
|
||||||
];
|
];
|
||||||
const activeTab = ref(tabs[0].label);
|
const activeTab = ref(tabs[0].label);
|
||||||
</script>
|
</script>
|
||||||
@ -86,9 +87,9 @@ const activeTab = ref(tabs[0].label);
|
|||||||
<th>風味</th>
|
<th>風味</th>
|
||||||
<th>色澤</th>
|
<th>色澤</th>
|
||||||
<th>雜異物</th>
|
<th>雜異物</th>
|
||||||
<th>鹽度</th>
|
|
||||||
<th>酸度</th>
|
<th>酸度</th>
|
||||||
<th>糖度</th>
|
<th>糖度</th>
|
||||||
|
<th>鹽度</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -102,9 +103,9 @@ const activeTab = ref(tabs[0].label);
|
|||||||
<td>{{ flow.flavor }}</td>
|
<td>{{ flow.flavor }}</td>
|
||||||
<td>{{ flow.color }}</td>
|
<td>{{ flow.color }}</td>
|
||||||
<td>{{ flow.impurities }}</td>
|
<td>{{ flow.impurities }}</td>
|
||||||
<td>{{ flow.actual_Salinity }}</td>
|
|
||||||
<td>{{ flow.actual_PH }}</td>
|
<td>{{ flow.actual_PH }}</td>
|
||||||
<td>{{ flow.actual_Brix }}</td>
|
<td>{{ flow.actual_Brix }}</td>
|
||||||
|
<td>{{ flow.actual_Salinity }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr
|
<tr
|
||||||
v-if="!pot.qcResult || !pot.qcResult.length"
|
v-if="!pot.qcResult || !pot.qcResult.length"
|
||||||
|
|||||||
@ -62,6 +62,7 @@ const onOk = async () => {
|
|||||||
class="my-2"
|
class="my-2"
|
||||||
name="total_capacity"
|
name="total_capacity"
|
||||||
v-if="formState?.type == 1"
|
v-if="formState?.type == 1"
|
||||||
|
readonly
|
||||||
>
|
>
|
||||||
<template #topLeft>總庫存量</template>
|
<template #topLeft>總庫存量</template>
|
||||||
<template #bottomLeft>
|
<template #bottomLeft>
|
||||||
|
|||||||
@ -5,8 +5,9 @@ import {
|
|||||||
getSettingInventory,
|
getSettingInventory,
|
||||||
postSettingInventory,
|
postSettingInventory,
|
||||||
getSettingInventoryLog,
|
getSettingInventoryLog,
|
||||||
|
getInventoryExportData,
|
||||||
} from "@/apis/productSetting";
|
} from "@/apis/productSetting";
|
||||||
import { ref, onMounted, inject, watch } from "vue";
|
import { ref, onMounted, inject, watch, computed } from "vue";
|
||||||
import useActiveBtn from "@/hooks/useActiveBtn";
|
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||||
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
@ -106,6 +107,15 @@ const onSearch = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const exportFile = async () => {
|
||||||
|
const res = await getInventoryExportData({
|
||||||
|
start_date: dayjs(dateRange.value[0].value).format("YYYY-MM-DD"),
|
||||||
|
end_date: dayjs(dateRange.value[1].value).format("YYYY-MM-DD"),
|
||||||
|
}).catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const openModal = (type, item_id, record) => {
|
const openModal = (type, item_id, record) => {
|
||||||
if (type === 1) {
|
if (type === 1) {
|
||||||
formState.value = {
|
formState.value = {
|
||||||
@ -146,6 +156,21 @@ onMounted(() => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const submitBtns = computed(() => [
|
||||||
|
{
|
||||||
|
title: "搜尋",
|
||||||
|
key: "submit",
|
||||||
|
active: false,
|
||||||
|
onClick: onSearch,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "匯出",
|
||||||
|
key: "export",
|
||||||
|
active: false,
|
||||||
|
onClick: exportFile,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => selectedBtn.value?.key,
|
() => selectedBtn.value?.key,
|
||||||
(key) => {
|
(key) => {
|
||||||
@ -185,9 +210,7 @@ watch(
|
|||||||
:isBottomLabelExist="false"
|
:isBottomLabelExist="false"
|
||||||
class="mr-5"
|
class="mr-5"
|
||||||
/>
|
/>
|
||||||
<button class="btn btn-success" @click.stop.prevent="onSearch">
|
<ButtonGroup class="ml-5" :items="submitBtns" :withLine="false" />
|
||||||
搜尋
|
|
||||||
</button>
|
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,15 +20,21 @@ const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
|||||||
const dateRange = ref([
|
const dateRange = ref([
|
||||||
{
|
{
|
||||||
key: "start_at",
|
key: "start_at",
|
||||||
value: dayjs(),
|
value: dayjs().subtract(30, "day").valueOf(),
|
||||||
dateFormat: "yyyy-MM",
|
dateFormat: "yyyy-MM-dd",
|
||||||
placeholder: "起始日期",
|
placeholder: "起始日期",
|
||||||
monthPicker: true,
|
},
|
||||||
|
{
|
||||||
|
key: "end_at",
|
||||||
|
value: dayjs().valueOf(),
|
||||||
|
dateFormat: "yyyy-MM-dd",
|
||||||
|
placeholder: "結束日期",
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const searchState = ref({
|
const searchState = ref({
|
||||||
start_date: dayjs().format("YYYY-MM"),
|
start_date: dayjs().subtract(30, "day").format("YYYY-MM-DD"),
|
||||||
|
end_date: dayjs().format("YYYY-MM-DD"),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Table 相關變數
|
// Table 相關變數
|
||||||
@ -88,26 +94,6 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
|
||||||
dateRange,
|
|
||||||
(newRange) => {
|
|
||||||
let raw = newRange && newRange[0] && newRange[0].value;
|
|
||||||
let baseDayjs = null;
|
|
||||||
if (raw && typeof raw === "object" && "year" in raw && "month" in raw) {
|
|
||||||
baseDayjs = dayjs(new Date(raw.year, raw.month, 1));
|
|
||||||
} else {
|
|
||||||
baseDayjs = dayjs(raw);
|
|
||||||
}
|
|
||||||
if (!baseDayjs.isValid()) {
|
|
||||||
baseDayjs = dayjs();
|
|
||||||
}
|
|
||||||
searchState.value = {
|
|
||||||
start_date: baseDayjs.format("YYYY-MM"),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
const submit = async (e, type = "") => {
|
const submit = async (e, type = "") => {
|
||||||
e?.preventDefault?.();
|
e?.preventDefault?.();
|
||||||
e?.stopPropagation?.();
|
e?.stopPropagation?.();
|
||||||
@ -181,8 +167,13 @@ onBeforeMount(() => {
|
|||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-wrap items-center">
|
<div class="flex flex-wrap items-center mt-2">
|
||||||
<DateGroup :items="dateRange" />
|
<DateGroup
|
||||||
|
:items="dateRange"
|
||||||
|
:withLine="true"
|
||||||
|
:isTopLabelExist="false"
|
||||||
|
:isBottomLabelExist="false"
|
||||||
|
/>
|
||||||
<ButtonGroup class="ml-5" :items="submitBtns" :withLine="false" />
|
<ButtonGroup class="ml-5" :items="submitBtns" :withLine="false" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user