首頁:小卡串資料、今日生產目標串api | 即時告警:預設全選並搜尋
This commit is contained in:
parent
49560b3dd5
commit
f4d26271a4
@ -7,4 +7,5 @@ export const GET_DASHBOARD_ROOM_TEMP_API = `/SituationRoom/GetFormulaRoomStatusD
|
||||
export const GET_DASHBOARD_ENERGY_API = `/SituationRoom/GetEnergeData`;
|
||||
export const POST_DASHBOARD_PRODUCT_TARGET_SETTING_API = `/SituationRoom/SetTargetSetting`;
|
||||
export const GET_DASHBOARD_PRODUCT_TARGET_SETTING_API = `/SituationRoom/GetTargetSetting`
|
||||
export const GET_DASHBOARD_PRODUCT_HISTORY_API = `/SituationRoom/GetProductionHistory`
|
||||
export const GET_DASHBOARD_PRODUCT_HISTORY_API = `/SituationRoom/GetProductionHistory`;
|
||||
export const GET_DASHBOARD_PRODUCT_TASK_API = `/SituationRoom/GetProductionTask`;
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
POST_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||
GET_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||
GET_DASHBOARD_PRODUCT_HISTORY_API,
|
||||
GET_DASHBOARD_PRODUCT_TASK_API
|
||||
} from "./api";
|
||||
import instance from "@/util/request";
|
||||
import apihandler from "@/util/apihandler";
|
||||
@ -147,3 +148,12 @@ export const getDashboardProductRecord = async ({ start_time, end_time }) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getDashboardProductTask = async () => {
|
||||
const res = await instance.get(GET_DASHBOARD_PRODUCT_TASK_API);
|
||||
|
||||
return apihandler(res.code, res.data, {
|
||||
msg: res.msg,
|
||||
code: res.code,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -151,11 +151,28 @@ const openModal = async (record) => {
|
||||
}
|
||||
};
|
||||
|
||||
watch(searchParams, (newValue) => {
|
||||
if (newValue.system_tag) {
|
||||
watch(
|
||||
() => ({
|
||||
isAck: searchParams.value.isAck,
|
||||
isRecover: searchParams.value.isRecover,
|
||||
Start_date: searchParams.value.start_created_at,
|
||||
End_date: searchParams.value.end_created_at,
|
||||
system_tag: searchParams.value.system_tag,
|
||||
}),
|
||||
(val) => {
|
||||
// 判斷所有必要欄位都已經有值
|
||||
if (
|
||||
val.isAck !== undefined &&
|
||||
val.isRecover !== undefined &&
|
||||
val.Start_date &&
|
||||
val.End_date &&
|
||||
val.system_tag
|
||||
) {
|
||||
search();
|
||||
}
|
||||
});
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
);
|
||||
|
||||
provide("alert_modal", { model_data, search, updateEditRecord });
|
||||
provide("alert_table", { openModal, updateEditRecord, dataSource, search, tableLoading });
|
||||
|
@ -11,7 +11,7 @@ const changeCheckedItem = () => {
|
||||
if (checkedItem.value.length === store.subSys.length) {
|
||||
changeParams({
|
||||
...searchParams.value,
|
||||
system_tag: [],
|
||||
system_tag: [store.subSys[0]?.main_system_tag+`_`+store.subSys[0]?.sub_system_tag],
|
||||
});
|
||||
} else {
|
||||
changeParams({
|
||||
@ -53,7 +53,7 @@ watch(searchParams, (newValue) => {
|
||||
if (!newValue.system_tag) {
|
||||
changeParams({
|
||||
...newValue,
|
||||
system_tag: [store.subSys[0]?.main_system_tag+`_`+store.subSys[0]?.sub_system_tag],
|
||||
system_tag: store.subSys.map(({ main_system_tag, sub_system_tag }) => main_system_tag+`_`+sub_system_tag),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -53,18 +53,6 @@ const vesselsData = computed(() => {
|
||||
return data.map((vessel) => ({
|
||||
...vessel,
|
||||
activeTab: getDeviceActiveTab(vessel.name),
|
||||
SIP: [
|
||||
{
|
||||
count: "1",
|
||||
startTime: "08:00",
|
||||
endTime: "08:30",
|
||||
},
|
||||
{
|
||||
count: "2",
|
||||
startTime: "14:00",
|
||||
endTime: "14:30",
|
||||
},
|
||||
],
|
||||
}));
|
||||
});
|
||||
|
||||
@ -84,12 +72,12 @@ const cookingPotData = computed(() => {
|
||||
|
||||
// 冷藏室資料
|
||||
const refrigerationData = computed(() => {
|
||||
return props.realTimeData?.refrigerationData[0] || {};
|
||||
return props.realTimeData?.refrigerationData || [];
|
||||
});
|
||||
|
||||
// 電錶資料
|
||||
const meterData = computed(() => {
|
||||
const data = props.realTimeData?.refrigerationData || [];
|
||||
const data = props.realTimeData?.meterData || [];
|
||||
return data.sort((a, b) => a.name.localeCompare(b.name));
|
||||
});
|
||||
|
||||
@ -117,7 +105,7 @@ const valveData = computed(() => {
|
||||
v-for="(vessel, index) in vesselsData"
|
||||
:key="index"
|
||||
:vessel="vessel"
|
||||
:tabs="tabs"
|
||||
:tabs="tabs.filter(tab => tab.label !== '品檢')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,92 +1,35 @@
|
||||
<script setup>
|
||||
import { ref, onMounted, computed } from "vue";
|
||||
import { ref, onMounted, onUnmounted, computed } from "vue";
|
||||
import { getDashboardProductTask } from "@/apis/dashboard";
|
||||
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||
|
||||
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||
|
||||
// 配方假資料
|
||||
const recipe_data = ref([]);
|
||||
recipe_data.value = [
|
||||
{
|
||||
id: 1,
|
||||
productName: "蘋果醋",
|
||||
status: "調理中",
|
||||
completionRate: 0.7, // 70%
|
||||
details: [
|
||||
{ pot: "第1鍋", location: "包裝室", status: "生產中" },
|
||||
{ pot: "第2鍋", location: "充填室", status: "生產中" },
|
||||
{ pot: "第3鍋", location: "調理桶甲", status: "生產中" },
|
||||
{ pot: "第4鍋", location: "調理桶乙", status: "生產中" },
|
||||
{ pot: "第5鍋", location: "調理桶丙", status: "生產中" },
|
||||
{ pot: "第6鍋", location: "調理桶丁", status: "生產中" },
|
||||
{
|
||||
pot: "第7鍋",
|
||||
location: "二重釜大-梅精醋\n二重釜小-加熱",
|
||||
status: "生產中",
|
||||
},
|
||||
{ pot: "第8鍋", location: "", status: "備料" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
productName: "梅子醋",
|
||||
status: "尚未生產",
|
||||
completionRate: 0,
|
||||
details: [],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
productName: "桑葚醋",
|
||||
status: "尚未生產",
|
||||
completionRate: 0,
|
||||
details: [],
|
||||
},
|
||||
];
|
||||
const formulaData = ref([]);
|
||||
const productData = ref([]);
|
||||
const loading = ref(false);
|
||||
|
||||
// 成品假資料
|
||||
const finished_data = ref([]);
|
||||
finished_data.value = [
|
||||
{
|
||||
id: 1,
|
||||
productName: "111018",
|
||||
status: "已完成",
|
||||
completionRate: 1, // 100%
|
||||
details: [
|
||||
{ pot: "第1鍋", location: "包裝室", status: "生產中" },
|
||||
{ pot: "第2鍋", location: "充填室", status: "生產中" },
|
||||
// { pot: "第3鍋", location: "調理桶甲", status: "生產中" },
|
||||
// { pot: "第4鍋", location: "調理桶乙", status: "生產中" },
|
||||
// { pot: "第5鍋", location: "調理桶丙", status: "生產中" },
|
||||
// { pot: "第6鍋", location: "調理桶丁", status: "生產中" },
|
||||
// {
|
||||
// pot: "第7鍋",
|
||||
// location: "二重釜大-梅精醋\n二重釜小-加熱",
|
||||
// status: "生產中",
|
||||
// },
|
||||
// { pot: "第8鍋", location: "", status: "備料" },
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
productName: "121062N",
|
||||
status: "尚未生產",
|
||||
completionRate: 0,
|
||||
details: [],
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
productName: "113579",
|
||||
status: "尚未生產",
|
||||
completionRate: 0,
|
||||
details: [],
|
||||
},
|
||||
];
|
||||
let timer = null;
|
||||
|
||||
const fetchProductTask = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getDashboardProductTask();
|
||||
formulaData.value = res?.data?.formula || [];
|
||||
productData.value = res?.data?.product || [];
|
||||
} catch (e) {
|
||||
formulaData.value = [];
|
||||
productData.value = [];
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const production_data = computed(() => {
|
||||
if (selectedBtn.value?.key === 1) {
|
||||
return recipe_data.value; // 返回配方資料
|
||||
return formulaData.value;
|
||||
} else if (selectedBtn.value?.key === 2) {
|
||||
return finished_data.value; // 返回成品資料
|
||||
return productData.value;
|
||||
}
|
||||
return [];
|
||||
});
|
||||
@ -116,6 +59,17 @@ onMounted(() => {
|
||||
active: false,
|
||||
},
|
||||
]);
|
||||
fetchProductTask();
|
||||
timer = setInterval(() => {
|
||||
fetchProductTask();
|
||||
}, 60 * 1000);
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (timer) {
|
||||
clearInterval(timer);
|
||||
timer = null;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -144,7 +98,7 @@ onMounted(() => {
|
||||
/>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-base ">{{ selectedProduct.productName }}</span>
|
||||
<p class="text-base my-4">{{ selectedProduct.name }}</p>
|
||||
</template>
|
||||
</div>
|
||||
<div className="h-60 overflow-x-auto">
|
||||
@ -154,27 +108,35 @@ onMounted(() => {
|
||||
<th>品名</th>
|
||||
<th>狀態</th>
|
||||
<th>生產進度</th>
|
||||
<th>功能</th>
|
||||
<th v-if="selectedBtn?.key === 1">功能</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead v-else>
|
||||
<tr>
|
||||
<th>鍋次</th>
|
||||
<th>位置</th>
|
||||
<th
|
||||
v-if="
|
||||
selectedProduct.details &&
|
||||
selectedProduct.details.length &&
|
||||
selectedBtn?.key === 1
|
||||
"
|
||||
>
|
||||
鍋次
|
||||
</th>
|
||||
<th>狀態</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<!-- 產品列表 -->
|
||||
<template v-if="!selectedProduct">
|
||||
<tr v-for="item in production_data" :key="item.id">
|
||||
<td>{{ item.productName }}</td>
|
||||
<tr v-for="item in production_data" :key="item.name">
|
||||
<td>{{ item.name }}</td>
|
||||
<td>{{ item.status }}</td>
|
||||
<td>{{ (item.completionRate * 100).toFixed(0) }}%</td>
|
||||
<td>
|
||||
<td>{{ item.progress }}</td>
|
||||
<td v-if="item.details && item.details.length">
|
||||
<button
|
||||
class="btn btn-xs btn-outline-info"
|
||||
@click="showDetails(item)"
|
||||
:disabled="!item.details || item.details.length === 0"
|
||||
>
|
||||
詳細
|
||||
</button>
|
||||
@ -183,14 +145,21 @@ onMounted(() => {
|
||||
</template>
|
||||
<!-- 詳細資料 -->
|
||||
<template v-else>
|
||||
<tr v-for="(detail, index) in selectedProduct.details" :key="index">
|
||||
<td>{{ detail.pot }}</td>
|
||||
<td>{{ detail.location }}</td>
|
||||
<tr
|
||||
v-if="selectedProduct.details && selectedProduct.details.length"
|
||||
v-for="(detail, index) in selectedProduct.details"
|
||||
:key="index"
|
||||
>
|
||||
<td v-if="selectedBtn?.key === 1">{{ detail.batch }}</td>
|
||||
<td>{{ detail.status }}</td>
|
||||
</tr>
|
||||
<tr v-else>
|
||||
<td colspan="3" class="text-center">無詳細資料</td>
|
||||
</tr>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="loading" class="text-center mt-2">載入中...</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -1,5 +1,6 @@
|
||||
<script setup>
|
||||
defineProps({ data: Array });
|
||||
import { twMerge } from "tailwind-merge";
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
@ -8,50 +9,62 @@ defineProps({ data: Array });
|
||||
:key="index"
|
||||
class="stats shadow bg-slate-200"
|
||||
>
|
||||
<div class="stat p-2">
|
||||
<div class="w-24 stat p-2">
|
||||
<div class="bg-green-600 rounded-lg p-2 shadow-lg shadow-slate-400">
|
||||
<div class="text-sm text-slate-100">第{{ item.batch }}鍋</div>
|
||||
<div class="text-sm font-bold text-slate-100">{{ item.product }}</div>
|
||||
<div class="text-sm text-slate-100">第{{ item.batch || "__" }}鍋</div>
|
||||
<div class="text-sm font-bold text-slate-100">
|
||||
{{ item.product || " " }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat p-2">
|
||||
<div class="text-sm font-bold text-slate-800">{{ item.equipment }}</div>
|
||||
</div>
|
||||
<div class="w-26 stat items-center p-2">
|
||||
<div class="text-base font-bold text-slate-800">{{ item.name }}</div>
|
||||
<div class="text-sm text-slate-800">{{ item.status }}</div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
<div class="text-2xl text-slate-800">
|
||||
<FontAwesomeIcon :icon="['fas', 'temperature-high']" />
|
||||
</div>
|
||||
<div class="w-15 stat items-center text-center p-2">
|
||||
<FontAwesomeIcon
|
||||
class="text-2xl text-slate-800 mx-auto"
|
||||
:icon="['fas', 'temperature-high']"
|
||||
/>
|
||||
<div class="text-sm text-slate-800">{{ item.temperature }}</div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
<div :class="['text-2xl',
|
||||
item.sterilization == '殺菌NG' ? 'text-red-700' : 'text-slate-800',
|
||||
]">
|
||||
<FontAwesomeIcon :icon="['far', 'clock']" />
|
||||
</div>
|
||||
<div :class="['text-sm',
|
||||
item.sterilization == '殺菌NG' ? 'text-red-700' : 'text-slate-800',
|
||||
]">{{ item.sterilization }}</div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
<div
|
||||
:class="[
|
||||
'text-2xl',
|
||||
item.sugarStatus == 'warning' ? 'text-red-700' : 'text-slate-800',
|
||||
'w-15 stat items-center text-center p-2',
|
||||
item.sterilization == '殺菌完成'
|
||||
? 'text-green-700'
|
||||
: 'text-slate-800',
|
||||
]"
|
||||
>
|
||||
<FontAwesomeIcon :icon="['fas', 'tint']" />
|
||||
<FontAwesomeIcon :icon="['far', 'clock']" class="text-2xl mx-auto" />
|
||||
<div class="text-sm">
|
||||
{{ item.sterilization }}
|
||||
</div>
|
||||
<div :class="['text-sm',
|
||||
item.sugarStatus == 'warning' ? 'text-red-700' : 'text-slate-800',
|
||||
]">糖{{ item.sugar }}</div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
<div :class="`text-2xl ${item.materialColor}`">
|
||||
<FontAwesomeIcon :icon="['fas', 'circle']" class="border-2 border-slate-400 rounded-full"/>
|
||||
<div
|
||||
:class="[
|
||||
'w-15 stat items-center text-center p-2',
|
||||
typeof item.sugar !== 'number' ? 'text-red-700' : 'text-slate-800',
|
||||
]"
|
||||
>
|
||||
<FontAwesomeIcon class="text-2xl mx-auto" :icon="['fas', 'tint']" />
|
||||
<div class="text-sm">
|
||||
{{ item.sugar }}
|
||||
</div>
|
||||
<div class="text-sm text-slate-800">{{ item.material }}</div>
|
||||
</div>
|
||||
<div class="w-15 stat items-center text-center p-2">
|
||||
<div>
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'circle']"
|
||||
:class="
|
||||
twMerge(
|
||||
'text-2xl border-2 border-slate-400 rounded-full',
|
||||
item.qcResult ? item.qcResult.trim() : 'text-slate-400'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<div class="text-sm text-slate-800">{{ item.qcName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
pot: Object,
|
||||
tabs: Array
|
||||
tabs: Array,
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
@ -29,41 +29,105 @@ const props = defineProps({
|
||||
<div class="p-0">
|
||||
<div v-if="pot.activeTab2.value === '生產資訊'">
|
||||
<ul class="leading-7 tracking-wider text-slate-700 px-2">
|
||||
<li><b>品名:</b> {{ pot.product }}</li>
|
||||
<li><b>鍋次:</b> 第{{ pot.batch }}鍋</li>
|
||||
<li><b>溫度:</b> {{ pot.temperature }}</li>
|
||||
<li><b>糖度:</b> {{ pot.sugar }}</li>
|
||||
<li><b>狀態:</b> {{ pot.status }}</li>
|
||||
<li><b>品名:</b> {{ pot.productInfo?.product }}</li>
|
||||
<li><b>鍋次:</b> 第{{ pot.productInfo?.batch || "__" }}鍋</li>
|
||||
<li><b>溫度:</b> {{ pot.productInfo?.temperature }}</li>
|
||||
<li><b>糖度:</b> {{ pot.productInfo?.sugar }}</li>
|
||||
<li><b>狀態:</b> {{ pot.productInfo?.status }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-else-if="pot.activeTab2.value === '投料進度'">
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm table-pin-rows">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th class="w-10">順序</th>
|
||||
<th>動作</th>
|
||||
<th>原料</th>
|
||||
<th class="w-20">狀態</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(feed, index) in pot.feedProgress"
|
||||
:key="index"
|
||||
class="border-0"
|
||||
>
|
||||
<th>{{ feed.order }}</th>
|
||||
<td>{{ feed.action }}</td>
|
||||
<td>{{ feed.material }}</td>
|
||||
<td>{{ feed.state }}</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!pot.feedProgress || !pot.feedProgress.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="4" class="text-center">無投料進度資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="pot.activeTab2.value === '品檢'">
|
||||
<ul class="leading-7 tracking-wider text-slate-700 px-2">
|
||||
<li><b>品檢時間:</b> {{ pot.inspectionTime }}</li>
|
||||
<li><b>風味:</b> {{ pot.flavor }}</li>
|
||||
<li><b>鹽度:</b> {{ pot.salinity }}</li>
|
||||
<li><b>酸度:</b> {{ pot.acidity }}</li>
|
||||
</ul>
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm table-pin-rows whitespace-nowrap">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th>狀態</th>
|
||||
<th>品檢時間</th>
|
||||
<th>風味</th>
|
||||
<th>色澤</th>
|
||||
<th>雜異物</th>
|
||||
<th>鹽度</th>
|
||||
<th>酸度</th>
|
||||
<th>糖度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(flow, index) in pot.qcResult"
|
||||
:key="index"
|
||||
class="border-0"
|
||||
>
|
||||
<th>{{ flow.state }}</th>
|
||||
<td>{{ flow.time }}</td>
|
||||
<td>{{ flow.flavor }}</td>
|
||||
<td>{{ flow.color }}</td>
|
||||
<td>{{ flow.impurities }}</td>
|
||||
<td>{{ flow.actual_Salinity }}</td>
|
||||
<td>{{ flow.actual_PH }}</td>
|
||||
<td>{{ flow.actual_Brix }}</td>
|
||||
</tr>
|
||||
<tr v-if="!pot.qcResult || !pot.qcResult.length" class="h-28 border-0">
|
||||
<td colspan="8" class="text-center">無品檢資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="pot.activeTab2.value === '流量計'">
|
||||
<div class="">
|
||||
<table class="table table-sm whitespace-nowrap">
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th></th>
|
||||
<th>當前使用量</th>
|
||||
<th>今日累積量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-0">
|
||||
<th class="">補水</th>
|
||||
<td>{{ pot.waterConsumption }}</td>
|
||||
<td>100L</td>
|
||||
<tr
|
||||
v-for="(flow, index) in pot.flowMeterData"
|
||||
:key="index"
|
||||
class="border-0"
|
||||
>
|
||||
<th class="">{{ flow.material }}</th>
|
||||
<td>{{ flow.total }}</td>
|
||||
</tr>
|
||||
<tr class="border-0">
|
||||
<th>補醋</th>
|
||||
<td>{{ pot.aceticAcidConsumption }}</td>
|
||||
<td>100L</td>
|
||||
<tr
|
||||
v-if="!pot.flowMeterData || !pot.flowMeterData.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="2" class="text-center">無流量計資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@ -80,26 +144,19 @@ const props = defineProps({
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-0">
|
||||
<th>
|
||||
第一次
|
||||
</th>
|
||||
<td>2025-06-01T08:00:00</td>
|
||||
<td>2025-06-01T08:30:00</td>
|
||||
<tr
|
||||
v-for="(value, index) in pot.sip"
|
||||
:key="index"
|
||||
class="border-0">
|
||||
<th>{{ value.count }}</th>
|
||||
<td>{{ value.startTime }}</td>
|
||||
<td>{{ value.endTime }}</td>
|
||||
</tr>
|
||||
<tr class="border-0">
|
||||
<th>
|
||||
第二次
|
||||
</th>
|
||||
<td>2025-06-01T09:00:00</td>
|
||||
<td>2025-06-01T09:30:00</td>
|
||||
</tr>
|
||||
<tr class="border-0">
|
||||
<th>
|
||||
第二次
|
||||
</th>
|
||||
<td>2025-06-01T10:00:00</td>
|
||||
<td>2025-06-01T10:30:00</td>
|
||||
<tr
|
||||
v-if="!pot.sip || !pot.sip.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="3" class="text-center">無SIP資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
defineProps({ data: Array })
|
||||
defineProps({ data: Array });
|
||||
</script>
|
||||
<template>
|
||||
<div class="flex flex-col gap-3">
|
||||
@ -8,14 +8,15 @@ defineProps({ data: Array })
|
||||
:key="index"
|
||||
class="stats shadow bg-slate-200"
|
||||
>
|
||||
<div class="stat p-2">
|
||||
<div class="text-sm font-bold text-slate-800">{{ item.equipment }}</div>
|
||||
<div class="text-sm text-slate-800"></div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
<div class="text-sm text-slate-800">
|
||||
<FontAwesomeIcon :icon="['fas', 'temperature-high']" class="fa-2x" />
|
||||
<div class="w-26 stat items-center p-2">
|
||||
<div class="text-sm font-bold text-slate-800">{{ item.name }}</div>
|
||||
<div class="text-sm text-slate-800"> </div>
|
||||
</div>
|
||||
<div class="w-15 stat items-center text-center p-2">
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'temperature-high']"
|
||||
class="text-2xl text-slate-800 mx-auto"
|
||||
/>
|
||||
<div class="text-sm text-slate-800">{{ item.temperature }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -8,20 +8,21 @@ defineProps({ data: Array });
|
||||
:key="index"
|
||||
class="stats shadow bg-slate-200"
|
||||
>
|
||||
<div class="stat p-2">
|
||||
<div class="w-24 stat p-2">
|
||||
<div class="bg-green-600 rounded-lg p-2 shadow-lg shadow-slate-400">
|
||||
<div class="text-sm text-slate-100">第{{ item.batch }}鍋</div>
|
||||
<div class="text-sm font-bold text-slate-100">{{ item.product }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat p-2">
|
||||
<div class="text-sm font-bold text-slate-800">{{ item.equipment }}</div>
|
||||
<div class="w-26 stat items-center p-2">
|
||||
<div class="text-base font-bold text-slate-800">{{ item.name }}</div>
|
||||
<div class="text-sm text-slate-800">{{ item.status }}</div>
|
||||
</div>
|
||||
<div class="stat p-2">
|
||||
<div class="text-2xl text-slate-800">
|
||||
<FontAwesomeIcon :icon="['fas', 'temperature-high']" />
|
||||
</div>
|
||||
<div class="w-15 stat items-center p-2">
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'temperature-high']"
|
||||
class="text-2xl text-slate-800 mx-auto"
|
||||
/>
|
||||
<div class="text-sm text-slate-800">{{ item.temperature }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,11 +1,17 @@
|
||||
<script setup>
|
||||
defineProps({ data: Object });
|
||||
const props = defineProps({ data: { type: Array, default: () => [] } });
|
||||
</script>
|
||||
<template>
|
||||
<div class="stats shadow bg-slate-200">
|
||||
<div class="flex flex-col gap-3">
|
||||
<template v-if="props.data.length">
|
||||
<div
|
||||
v-for="(item, index) in props.data"
|
||||
:key="index"
|
||||
class="stats shadow bg-slate-200"
|
||||
>
|
||||
<div class="stat p-2">
|
||||
<div class="text-sm font-bold text-slate-800">
|
||||
{{ data.name }}
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat text-center p-2">
|
||||
@ -13,8 +19,13 @@ defineProps({ data: Object });
|
||||
<FontAwesomeIcon :icon="['fas', 'temperature-high']" />
|
||||
</div>
|
||||
<div class="text-sm text-slate-800">
|
||||
{{ data.temperature }}
|
||||
{{ item.temperature }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="text-center text-slate-400 py-4">無冷藏室資料</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -10,17 +10,15 @@ import { twMerge } from "tailwind-merge";
|
||||
</div>
|
||||
</div>
|
||||
<div v-for="item in card.groups" :key="item.code" class="stat p-2">
|
||||
<div class="text-2xl">
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'circle']"
|
||||
:class="
|
||||
twMerge(
|
||||
'border-2 border-slate-400 rounded-full',
|
||||
item.status == 'ON' ? 'text-green-500' : 'text-gray-400'
|
||||
'text-2xl border-2 border-slate-400 rounded-full',
|
||||
item.status ? item.status.trim() : 'text-slate-400'
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<span class="text-sm text-slate-800">{{ item.code }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@ const props = defineProps({
|
||||
<template>
|
||||
<div class="card bg-slate-200 text-accent-content rounded-md w-[25rem]">
|
||||
<div class="card-body p-3">
|
||||
<h2 class="card-title">{{ vessel.name }}</h2>
|
||||
<h2 class="card-title">{{ vessel?.name }}</h2>
|
||||
<div
|
||||
role="tablist"
|
||||
class="tabs tabs-boxed tabs-sm bg-opacity-50 shadow-inner shadow-slate-600"
|
||||
@ -29,20 +29,21 @@ const props = defineProps({
|
||||
<div class="p-0">
|
||||
<div v-if="vessel.activeTab.value === '生產資訊'">
|
||||
<ul class="leading-7 tracking-wider text-slate-700 px-2">
|
||||
<li><b>品名:</b> {{ vessel.product }}</li>
|
||||
<li><b>鍋次:</b> 第{{ vessel.batch }}鍋</li>
|
||||
<li><b>狀態:</b> {{ vessel.status }}</li>
|
||||
<li><b>品名:</b> {{ vessel.productInfo?.product }}</li>
|
||||
<li><b>鍋次:</b> 第{{ vessel.productInfo?.batch || "__" }}鍋</li>
|
||||
<li><b>溫度:</b> {{ vessel.productInfo?.temperature }}</li>
|
||||
<li><b>狀態:</b> {{ vessel.productInfo?.status }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-else-if="vessel.activeTab.value === '投料進度'">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm table-pin-rows">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th>順序</th>
|
||||
<th class="w-10">順序</th>
|
||||
<th>動作</th>
|
||||
<th>原料</th>
|
||||
<th>狀態</th>
|
||||
<th class="w-20">狀態</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -56,17 +57,22 @@ const props = defineProps({
|
||||
<td>{{ feed.material }}</td>
|
||||
<td>{{ feed.state }}</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!vessel.feedProgress || !vessel.feedProgress.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="4" class="text-center">無投料進度資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="vessel.activeTab.value === '流量計'">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm table-pin-rows ">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th></th>
|
||||
<th>當前使用量</th>
|
||||
<th>今日累積量</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -76,17 +82,22 @@ const props = defineProps({
|
||||
:key="index"
|
||||
class="border-0"
|
||||
>
|
||||
<th>{{ flow.material }}</th>
|
||||
<td>{{ flow.current }}</td>
|
||||
<th class="w-26">{{ flow.material }}</th>
|
||||
<td>{{ flow.total }}</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!vessel.flowMeterData || !vessel.flowMeterData.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="2" class="text-center">無流量計資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="vessel.activeTab.value === 'SIP'">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-sm">
|
||||
<div class="h-40 overflow-x-auto">
|
||||
<table class="table table-sm table-pin-rows">
|
||||
<thead>
|
||||
<tr class="border-0 bg-slate-300 text-slate-800">
|
||||
<th>次數</th>
|
||||
@ -96,14 +107,20 @@ const props = defineProps({
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(value, index) in vessel.SIP"
|
||||
v-for="(value, index) in vessel.sip"
|
||||
:key="index"
|
||||
class="border-0"
|
||||
>
|
||||
<th >{{ value.count }}</th>
|
||||
<th>{{ value.count }}</th>
|
||||
<td>{{ value.startTime }}</td>
|
||||
<td>{{ value.endTime }}</td>
|
||||
</tr>
|
||||
<tr
|
||||
v-if="!vessel.sip || !vessel.sip.length"
|
||||
class="h-28 border-0"
|
||||
>
|
||||
<td colspan="3" class="text-center">無SIP資料</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -4,6 +4,13 @@ module.exports = {
|
||||
"./node_modules/vue-tailwind-datepicker/**/*.js",
|
||||
],
|
||||
purge: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
|
||||
safelist: [
|
||||
'text-white',
|
||||
'text-green-600',
|
||||
'text-yellow-300',
|
||||
'text-red-700',
|
||||
'text-slate-400'
|
||||
],
|
||||
darkMode: false, // or 'media' or 'class'
|
||||
theme: {
|
||||
extend: {
|
||||
|
Loading…
Reference in New Issue
Block a user