新增回到首頁按鈕 | 優化視角設定邏輯 | 調整權限清除邏輯 | 更新庫存顯示邏輯
This commit is contained in:
parent
2948a95b56
commit
a002901d26
@ -39,6 +39,7 @@ const {
|
|||||||
subComponents,
|
subComponents,
|
||||||
clearSprites,
|
clearSprites,
|
||||||
updateTemp,
|
updateTemp,
|
||||||
|
fitToView,
|
||||||
} = useSystemStatusByBaja();
|
} = useSystemStatusByBaja();
|
||||||
|
|
||||||
// 用於存儲 meter label 的 2D 位置
|
// 用於存儲 meter label 的 2D 位置
|
||||||
@ -182,6 +183,28 @@ onUnmounted(() => {
|
|||||||
)
|
)
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
|
<!-- 回到 Home 視角 -->
|
||||||
|
<div class="absolute top-0 right-[26%] z-30">
|
||||||
|
<button
|
||||||
|
class="p-4"
|
||||||
|
@click="fitToView()"
|
||||||
|
aria-label="回到初始視角"
|
||||||
|
title="回到初始視角"
|
||||||
|
>
|
||||||
|
<!-- Home Icon -->
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="25"
|
||||||
|
height="25"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill="currentColor"
|
||||||
|
d="m21.743 12.331l-9-10c-.379-.422-1.107-.422-1.486 0l-9 10a1 1 0 0 0-.17 1.076c.16.361.518.593.913.593h2v7a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-4h4v4a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-7h2a.998.998 0 0 0 .743-1.669"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<p class="absolute z-10 top-14 left-[27%]">
|
<p class="absolute z-10 top-14 left-[27%]">
|
||||||
更新時間 : {{ props.realTime }}
|
更新時間 : {{ props.realTime }}
|
||||||
</p>
|
</p>
|
||||||
@ -246,7 +269,7 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.homeViewWrapper {
|
.homeViewWrapper {
|
||||||
transform: scale(1.5) translateX(350%) translateY(0%) !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heatbar {
|
.heatbar {
|
||||||
|
@ -141,6 +141,8 @@ export default function useSystemStatusByBaja() {
|
|||||||
} = JSON.parse(searchParams.value.target_position);
|
} = JSON.parse(searchParams.value.target_position);
|
||||||
const newTarget = new THREE.Vector3(x1, y1, z1);
|
const newTarget = new THREE.Vector3(x1, y1, z1);
|
||||||
forgeViewer.value.navigation.setView(newPosition, newTarget);
|
forgeViewer.value.navigation.setView(newPosition, newTarget);
|
||||||
|
// 強制 up vector 為 Z 軸朝上,確保視角水平
|
||||||
|
forgeViewer.value.navigation.setCameraUpVector(new THREE.Vector3(0, 0, 1));
|
||||||
};
|
};
|
||||||
|
|
||||||
const hideAllObjects = (instanceTree, filDbids = []) => {
|
const hideAllObjects = (instanceTree, filDbids = []) => {
|
||||||
@ -497,5 +499,6 @@ export default function useSystemStatusByBaja() {
|
|||||||
clearSprites,
|
clearSprites,
|
||||||
clearSingleSprite,
|
clearSingleSprite,
|
||||||
updateTemp,
|
updateTemp,
|
||||||
|
fitToView,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -88,16 +88,19 @@ router.beforeEach(async (to, from, next) => {
|
|||||||
if (location.pathname.includes("logoutConfirm")) {
|
if (location.pathname.includes("logoutConfirm")) {
|
||||||
document.cookie = "JWT-Authorization=";
|
document.cookie = "JWT-Authorization=";
|
||||||
auth.user.token = "";
|
auth.user.token = "";
|
||||||
|
auth.clearAuthPage && auth.clearAuthPage();
|
||||||
// 清除 cookie token
|
// 清除 cookie token
|
||||||
next({ path: "/login" });
|
next({ path: "/login" });
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((authRequired && !token) || to.path === "/") {
|
if ((authRequired && !token) || to.path === "/") {
|
||||||
auth.user.token = "";
|
auth.user.token = "";
|
||||||
|
auth.clearAuthPage && auth.clearAuthPage();
|
||||||
next({ path: "/login" });
|
next({ path: "/login" });
|
||||||
} else if (!authRequired) {
|
} else if (!authRequired) {
|
||||||
document.cookie = "JWT-Authorization=";
|
document.cookie = "JWT-Authorization=";
|
||||||
auth.user.token = "";
|
auth.user.token = "";
|
||||||
|
auth.clearAuthPage && auth.clearAuthPage();
|
||||||
} else {
|
} else {
|
||||||
auth.user.token = token;
|
auth.user.token = token;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,32 @@
|
|||||||
import { defineStore } from "pinia";
|
import { defineStore } from "pinia";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const AUTH_PAGE_KEY = "pccv_auth_page";
|
||||||
|
|
||||||
const useUserInfoStore = defineStore("userInfo", () => {
|
const useUserInfoStore = defineStore("userInfo", () => {
|
||||||
const user = ref({
|
const user = ref({
|
||||||
token: "",
|
token: "",
|
||||||
expires: 0,
|
expires: 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
const auth_page = ref([]);
|
// 初始化時從 sessionStorage 載入
|
||||||
|
const storedAuthPage = sessionStorage.getItem(AUTH_PAGE_KEY);
|
||||||
|
const auth_page = ref(storedAuthPage ? JSON.parse(storedAuthPage) : []);
|
||||||
|
|
||||||
const updateAuthPage = (data) => {
|
const updateAuthPage = (data) => {
|
||||||
auth_page.value = data;
|
auth_page.value = data;
|
||||||
|
sessionStorage.setItem(AUTH_PAGE_KEY, JSON.stringify(data));
|
||||||
};
|
};
|
||||||
|
|
||||||
return { user, auth_page, updateAuthPage };
|
// 提供一個清除權限的方法(例如登出時用)
|
||||||
|
const clearAuthPage = () => {
|
||||||
|
auth_page.value = [];
|
||||||
|
sessionStorage.removeItem(AUTH_PAGE_KEY);
|
||||||
|
};
|
||||||
|
|
||||||
|
return { user, auth_page, updateAuthPage, clearAuthPage };
|
||||||
});
|
});
|
||||||
|
|
||||||
export default useUserInfoStore;
|
export default useUserInfoStore;
|
||||||
|
@ -1,8 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card rounded-md bg-neutral text-neutral-content shadow-sm shadow-gray-400">
|
<div class="card rounded-md bg-neutral text-neutral-content shadow-sm shadow-gray-400">
|
||||||
<div class="card-body text-xs px-1 py-2">
|
<div class="card-body text-xs px-1 py-2">
|
||||||
<p>安全存量: {{ safety_stock }} 噸</p>
|
<p>備註: {{
|
||||||
<p>目前存量: {{ current_stock }} 噸</p>
|
item_id === 1
|
||||||
|
? ""
|
||||||
|
: item_id === 2
|
||||||
|
? "1、2、5、6槽"
|
||||||
|
: item_id === 3
|
||||||
|
? "3、4槽"
|
||||||
|
: "其他"
|
||||||
|
}} </p>
|
||||||
|
<p>最大存量: {{ current_stock }} 噸</p>
|
||||||
<p>{{ updateTime }}</p>
|
<p>{{ updateTime }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -10,7 +18,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
defineProps({
|
defineProps({
|
||||||
safety_stock: {
|
item_id: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
@ -14,7 +14,7 @@ const getCompletion = async () => {
|
|||||||
title: item.name,
|
title: item.name,
|
||||||
percentage: item.percentage,
|
percentage: item.percentage,
|
||||||
current_stock: item.current_stock,
|
current_stock: item.current_stock,
|
||||||
safety_stock: item.safety_stock,
|
item_id: item.item_id,
|
||||||
updateTime: dayjs(item.updated_at).format("YYYY-MM-DD HH:mm:ss"),
|
updateTime: dayjs(item.updated_at).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
@ -47,7 +47,7 @@ onMounted(() => {
|
|||||||
v-for="(card, index) in descriptionCards"
|
v-for="(card, index) in descriptionCards"
|
||||||
:key="index"
|
:key="index"
|
||||||
:title="card.title"
|
:title="card.title"
|
||||||
:safety_stock="card.safety_stock"
|
:item_id="card.item_id"
|
||||||
:current_stock="card.current_stock"
|
:current_stock="card.current_stock"
|
||||||
:updateTime="card.updateTime"
|
:updateTime="card.updateTime"
|
||||||
/>
|
/>
|
||||||
|
@ -59,7 +59,7 @@ import { twMerge } from "tailwind-merge";
|
|||||||
:class="
|
:class="
|
||||||
twMerge(
|
twMerge(
|
||||||
'text-2xl border-2 border-slate-400 rounded-full',
|
'text-2xl border-2 border-slate-400 rounded-full',
|
||||||
item.qcResult ? item.qcResult.trim() : 'text-slate-400'
|
typeof item.qcResult === 'string' ? item.qcResult.trim() : 'text-slate-400'
|
||||||
)
|
)
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
|
@ -154,11 +154,11 @@ watch(searchParams, (newVal, oldValue) => {
|
|||||||
key: 1,
|
key: 1,
|
||||||
active: parseInt(newVal?.Cumulant) === 1,
|
active: parseInt(newVal?.Cumulant) === 1,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: "累積數據",
|
// title: "累積數據",
|
||||||
key: 2,
|
// key: 2,
|
||||||
active: parseInt(newVal?.Cumulant) === 2,
|
// active: parseInt(newVal?.Cumulant) === 2,
|
||||||
},
|
// },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -180,13 +180,13 @@ onMounted(() => {
|
|||||||
? parseInt(searchParams.value.Cumulant) === 1
|
? parseInt(searchParams.value.Cumulant) === 1
|
||||||
: true,
|
: true,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
title: "累積數據",
|
// title: "累積數據",
|
||||||
key: 2,
|
// key: 2,
|
||||||
active: searchParams.value.Cumulant
|
// active: searchParams.value.Cumulant
|
||||||
? parseInt(searchParams.value.Cumulant) === 2
|
// ? parseInt(searchParams.value.Cumulant) === 2
|
||||||
: false,
|
// : false,
|
||||||
},
|
// },
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,8 +12,8 @@ const columns = [
|
|||||||
title: "設備名稱",
|
title: "設備名稱",
|
||||||
key: "device_name",
|
key: "device_name",
|
||||||
width: "30%",
|
width: "30%",
|
||||||
filter: true,
|
// filter: true,
|
||||||
sort: true,
|
// sort: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "點位",
|
title: "點位",
|
||||||
@ -22,8 +22,8 @@ const columns = [
|
|||||||
{
|
{
|
||||||
title: "數值",
|
title: "數值",
|
||||||
key: "value",
|
key: "value",
|
||||||
sort: true,
|
// sort: true,
|
||||||
filter: true,
|
// filter: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "記錄時間",
|
title: "記錄時間",
|
||||||
|
@ -15,7 +15,7 @@ const emit = defineEmits(["pushData", "resetModalForm"]);
|
|||||||
|
|
||||||
const settingScheme = yup.object({
|
const settingScheme = yup.object({
|
||||||
total_capacity: yup.number().required("必填").min(0, "不能小於0"),
|
total_capacity: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
safety_stock: yup.number().required("必填").min(0, "不能小於0"),
|
// safety_stock: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
current_stock: yup.number().required("必填").min(0, "不能小於0"),
|
current_stock: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ const onOk = async () => {
|
|||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Input
|
<!-- <Input
|
||||||
:value="formState"
|
:value="formState"
|
||||||
class="my-2"
|
class="my-2"
|
||||||
name="safety_stock"
|
name="safety_stock"
|
||||||
@ -82,9 +82,15 @@ const onOk = async () => {
|
|||||||
formErrorMsg.safety_stock
|
formErrorMsg.safety_stock
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input> -->
|
||||||
<Input :value="formState" class="my-2" name="current_stock">
|
<Input :value="formState" class="my-2" name="current_stock">
|
||||||
<template #topLeft>{{formState?.type == 1 ? "目前存量" : "入庫量"}}</template>
|
<template #topLeft>{{
|
||||||
|
formState?.type == 1
|
||||||
|
? "每周盤點量"
|
||||||
|
: formState?.item_id == 1
|
||||||
|
? "本周醱酵量"
|
||||||
|
: "每日過濾量"
|
||||||
|
}}</template>
|
||||||
<template #bottomLeft>
|
<template #bottomLeft>
|
||||||
<span class="text-error text-base">{{
|
<span class="text-error text-base">{{
|
||||||
formErrorMsg.current_stock
|
formErrorMsg.current_stock
|
||||||
|
@ -16,8 +16,8 @@ const { openToast } = inject("app_toast");
|
|||||||
const settingColumns = [
|
const settingColumns = [
|
||||||
{ title: "項目", key: "name" },
|
{ title: "項目", key: "name" },
|
||||||
{ title: "總庫存量(噸)", key: "total_capacity" },
|
{ title: "總庫存量(噸)", key: "total_capacity" },
|
||||||
{ title: "安全存量(噸)", key: "safety_stock" },
|
// { title: "安全存量(噸)", key: "safety_stock" },
|
||||||
{ title: "目前存量(噸)", key: "current_stock" },
|
{ title: "每周盤點量(噸)", key: "current_stock" },
|
||||||
{ title: "更新時間", key: "updated_at" },
|
{ title: "更新時間", key: "updated_at" },
|
||||||
{ title: "功能", key: "operation" },
|
{ title: "功能", key: "operation" },
|
||||||
];
|
];
|
||||||
@ -25,8 +25,8 @@ const settingColumns = [
|
|||||||
const recordColumns = [
|
const recordColumns = [
|
||||||
{ title: "項目", key: "item_name", filter: true },
|
{ title: "項目", key: "item_name", filter: true },
|
||||||
{ title: "總庫存量(噸)", key: "total_capacity" },
|
{ title: "總庫存量(噸)", key: "total_capacity" },
|
||||||
{ title: "安全存量(噸)", key: "safety_stock" },
|
// { title: "安全存量(噸)", key: "safety_stock" },
|
||||||
{ title: "目前存量(噸)", key: "current_stock" },
|
{ title: "每周盤點量(噸)", key: "current_stock" },
|
||||||
{ title: "操作類型", key: "type" },
|
{ title: "操作類型", key: "type" },
|
||||||
{ title: "最後修改者", key: "user_name", filter: true },
|
{ title: "最後修改者", key: "user_name", filter: true },
|
||||||
{ title: "日期", key: "time", sort: true },
|
{ title: "日期", key: "time", sort: true },
|
||||||
@ -113,7 +113,7 @@ const openModal = (type, item_id, record) => {
|
|||||||
item_id: item_id,
|
item_id: item_id,
|
||||||
name: record.name,
|
name: record.name,
|
||||||
total_capacity: record.total_capacity,
|
total_capacity: record.total_capacity,
|
||||||
safety_stock: record.safety_stock,
|
// safety_stock: record.safety_stock,
|
||||||
current_stock: record.current_stock,
|
current_stock: record.current_stock,
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user