新增庫存設定相關API串接及介面調整 | 優化即時溫度與冷藏溫度數據獲取邏輯 | 調整儀表板顯示內容
This commit is contained in:
parent
f4d26271a4
commit
07a9acb077
@ -9,7 +9,7 @@ import {
|
|||||||
POST_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
POST_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||||
GET_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
GET_DASHBOARD_PRODUCT_TARGET_SETTING_API,
|
||||||
GET_DASHBOARD_PRODUCT_HISTORY_API,
|
GET_DASHBOARD_PRODUCT_HISTORY_API,
|
||||||
GET_DASHBOARD_PRODUCT_TASK_API
|
GET_DASHBOARD_PRODUCT_TASK_API,
|
||||||
} from "./api";
|
} from "./api";
|
||||||
import instance from "@/util/request";
|
import instance from "@/util/request";
|
||||||
import apihandler from "@/util/apihandler";
|
import apihandler from "@/util/apihandler";
|
||||||
@ -37,10 +37,9 @@ export const getDashboardDevice = async ({ option }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const getDashboardOptionRealTimeData = async ({ option }) => {
|
export const getDashboardOptionRealTimeData = async ({ option }) => {
|
||||||
const res = await instance.post( GET_DASHBOARD_REALTIME_DATA_API, {
|
const res = await instance.get(GET_DASHBOARD_REALTIME_DATA_API, {
|
||||||
option: parseInt(option),
|
params: { option: parseInt(option) },
|
||||||
});
|
});
|
||||||
|
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
msg: res.msg,
|
msg: res.msg,
|
||||||
code: res.code,
|
code: res.code,
|
||||||
@ -91,7 +90,6 @@ export const getDashboardTemp = async ({
|
|||||||
timeInterval,
|
timeInterval,
|
||||||
tempOption,
|
tempOption,
|
||||||
});
|
});
|
||||||
console.log(res);
|
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
msg: res.msg,
|
msg: res.msg,
|
||||||
code: res.code,
|
code: res.code,
|
||||||
@ -155,5 +153,4 @@ export const getDashboardProductTask = async () => {
|
|||||||
msg: res.msg,
|
msg: res.msg,
|
||||||
code: res.code,
|
code: res.code,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
|
@ -2,3 +2,6 @@ export const POST_CHANGE_GROUP_VALUE_API = `api/Weight/ChangeGroupValue`;
|
|||||||
|
|
||||||
export const GET_CHECKWEIGHER_API = `/api/HistoryData/GetCheckWeigherNow`;
|
export const GET_CHECKWEIGHER_API = `/api/HistoryData/GetCheckWeigherNow`;
|
||||||
export const POST_SETTING_TYPE_API = `/SituationRoom/SetProduct`;
|
export const POST_SETTING_TYPE_API = `/SituationRoom/SetProduct`;
|
||||||
|
export const GET_SETTING_INVENTORY_API = `/SituationRoom/GetInventory`;
|
||||||
|
export const POST_SETTING_INVENTORY_API = `/SituationRoom/SaveInventory`;
|
||||||
|
export const GET_SETTING_INVENTORY_LOG_API = `/SituationRoom/GetInventoryLog`;
|
||||||
|
@ -4,10 +4,13 @@ import {
|
|||||||
POST_CHANGE_GROUP_VALUE_API,
|
POST_CHANGE_GROUP_VALUE_API,
|
||||||
GET_CHECKWEIGHER_API,
|
GET_CHECKWEIGHER_API,
|
||||||
POST_SETTING_TYPE_API,
|
POST_SETTING_TYPE_API,
|
||||||
|
GET_SETTING_INVENTORY_API,
|
||||||
|
POST_SETTING_INVENTORY_API,
|
||||||
|
GET_SETTING_INVENTORY_LOG_API,
|
||||||
} from "./api";
|
} from "./api";
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
return apihandler(res.code, res.data, {
|
return apihandler(res.code, res.data, {
|
||||||
msg: res.msg,
|
msg: res.msg,
|
||||||
@ -35,3 +38,37 @@ export const postProductSettingType = async (data) => {
|
|||||||
isSuccess: false,
|
isSuccess: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getSettingInventory = async () => {
|
||||||
|
const res = await instance.get(GET_SETTING_INVENTORY_API);
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
isSuccess: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const postSettingInventory = async (data) => {
|
||||||
|
const res = await instance.post(POST_SETTING_INVENTORY_API, data);
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
isSuccess: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getSettingInventoryLog = async ({ start_time, end_time }) => {
|
||||||
|
const res = await instance.get(GET_SETTING_INVENTORY_LOG_API, {
|
||||||
|
params: {
|
||||||
|
start_time,
|
||||||
|
end_time,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return apihandler(res.code, res.data, {
|
||||||
|
msg: res.msg,
|
||||||
|
code: res.code,
|
||||||
|
isSuccess: false,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
@ -105,6 +105,18 @@ watch(
|
|||||||
{ immediate: true }
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 新增監聽 title 變化
|
||||||
|
watch(
|
||||||
|
() => props.title,
|
||||||
|
(newTitle) => {
|
||||||
|
if (chart.value) {
|
||||||
|
chartOption.value.title.text = newTitle;
|
||||||
|
chart.value.setOption(chartOption.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
chart,
|
chart,
|
||||||
});
|
});
|
||||||
|
@ -73,7 +73,7 @@ const curWidth = computed(() => {
|
|||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:readonly="readonly"
|
:readonly="readonly"
|
||||||
:required="required"
|
:required="required"
|
||||||
class="text-lg text-white bg-transparent w-full input input-bordered rounded-md px-3 border-info focus-within:border-info read-only:bg-base-300 read-only:text-zinc-500 read-only:border-0 read-only:focus-within:outline-0 read-only:focus:outline-0"
|
class="text-lg text-white bg-transparent w-full input input-bordered rounded-md px-3 border-info focus-within:border-info read-only:bg-base-300 read-only:text-zinc-300 read-only:border-0 read-only:focus-within:outline-0 read-only:focus:outline-0"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
v-else
|
v-else
|
||||||
|
@ -5,7 +5,7 @@ export default function useFormErrorMessage(scheme) {
|
|||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// formErrorMsg.value = scheme
|
// formErrorMsg.value = scheme
|
||||||
if (scheme) {
|
if (scheme && scheme.fields) {
|
||||||
formErrorMsg.value = Object.fromEntries(
|
formErrorMsg.value = Object.fromEntries(
|
||||||
Object.keys(scheme.fields).map((f) => [f, ""])
|
Object.keys(scheme.fields).map((f) => [f, ""])
|
||||||
);
|
);
|
||||||
@ -41,9 +41,11 @@ export default function useFormErrorMessage(scheme) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateScheme = (scheme) => {
|
const updateScheme = (scheme) => {
|
||||||
formErrorMsg.value = Object.fromEntries(
|
if (scheme && scheme.fields) {
|
||||||
Object.keys(scheme.fields).map((f) => [f, ""])
|
formErrorMsg.value = Object.fromEntries(
|
||||||
);
|
Object.keys(scheme.fields).map((f) => [f, ""])
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return { formErrorMsg, handleSubmit, handleErrorReset, updateScheme };
|
return { formErrorMsg, handleSubmit, handleErrorReset, updateScheme };
|
||||||
|
@ -1,30 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="card 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-3 py-4">
|
<div class="card-body text-xs px-1 py-2">
|
||||||
<p>安全庫存量: {{ inventory }} 頓</p>
|
<p>安全存量: {{ safety_stock }} 頓</p>
|
||||||
<p>目標庫存量: {{ targetInventory }} 頓</p>
|
<p>目前存量: {{ current_stock }} 頓</p>
|
||||||
<p> {{ updateTime }}</p>
|
<p>{{ updateTime }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
defineProps({
|
defineProps({
|
||||||
inventory: {
|
safety_stock: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
targetInventory: {
|
current_stock: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
lastIncrease: {
|
updateTime: {
|
||||||
type: Number,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
updateTime: {
|
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,7 @@ import LineChart from "@/components/chart/LineChart.vue";
|
|||||||
import { SECOND_CHART_COLOR } from "@/constant";
|
import { SECOND_CHART_COLOR } from "@/constant";
|
||||||
import { getDashboardEnergy } from "@/apis/dashboard";
|
import { getDashboardEnergy } from "@/apis/dashboard";
|
||||||
import { twMerge } from "tailwind-merge";
|
import { twMerge } from "tailwind-merge";
|
||||||
import { ref, computed, onMounted, watch } from "vue";
|
import { ref, computed, onMounted, watch, onUnmounted } from "vue";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
const weeks = ["週日", "週一", "週二", "週三", "週四", "週五", "週六"];
|
const weeks = ["週日", "週一", "週二", "週三", "週四", "週五", "週六"];
|
||||||
@ -11,32 +11,30 @@ const weeks = ["週日", "週一", "週二", "週三", "週四", "週五", "週
|
|||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
const getEnergyData = async () => {
|
const getEnergyData = async () => {
|
||||||
const res = await getDashboardEnergy();
|
const res = await getDashboardEnergy();
|
||||||
console.log(res.data);
|
if (res.isSuccess) {
|
||||||
data.value = res.data;
|
data.value = res.data?.electric || [];
|
||||||
|
} else {
|
||||||
|
console.error("獲取用電量數據失敗:", res.message);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 假資料產生器
|
let timer = null;
|
||||||
function generateFakeData() {
|
|
||||||
const names = ["上週", "本週"];
|
|
||||||
const now = dayjs();
|
|
||||||
return names.map((full_name, idx) => ({
|
|
||||||
full_name,
|
|
||||||
data: Array.from({ length: 7 }).map((_, i) => ({
|
|
||||||
time: now.subtract(6 - i, "day").toISOString(),
|
|
||||||
value: Math.round(Math.random() * 100 + 200 + idx * 50), // 200~350
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// getEnergyData();
|
getEnergyData();
|
||||||
|
timer = setInterval(() => {
|
||||||
|
getEnergyData();
|
||||||
|
}, 600000); // 每10分鐘
|
||||||
|
});
|
||||||
|
|
||||||
// // 每10分鐘
|
onUnmounted(() => {
|
||||||
// setInterval(() => {
|
if (timer) {
|
||||||
// getEnergyData();
|
clearInterval(timer);
|
||||||
// }, 600000);
|
timer = null;
|
||||||
|
}
|
||||||
data.value = generateFakeData();
|
if (electricity_chart.value && electricity_chart.value.chart) {
|
||||||
|
electricity_chart.value.chart.dispose();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const electricity_chart = ref(null);
|
const electricity_chart = ref(null);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import LineChart from "@/components/chart/LineChart.vue";
|
import LineChart from "@/components/chart/LineChart.vue";
|
||||||
import { SECOND_CHART_COLOR } from "@/constant";
|
import { SECOND_CHART_COLOR } from "@/constant";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { ref, inject, onMounted, watch } from "vue";
|
import { ref, onMounted, watch, onUnmounted } from "vue";
|
||||||
import { getDashboardTemp } from "@/apis/dashboard";
|
import { getDashboardTemp } from "@/apis/dashboard";
|
||||||
import useSearchParams from "@/hooks/useSearchParam";
|
import useSearchParams from "@/hooks/useSearchParam";
|
||||||
|
|
||||||
@ -55,86 +55,55 @@ const defaultChartOption = ref({
|
|||||||
|
|
||||||
const frozen_temp_chart = ref(null);
|
const frozen_temp_chart = ref(null);
|
||||||
|
|
||||||
// 假資料產生器
|
|
||||||
function generateFakeFrozenData() {
|
|
||||||
const names = ["冷藏槽A", "冷藏槽B"];
|
|
||||||
const now = dayjs();
|
|
||||||
return names.map((full_name, idx) => ({
|
|
||||||
full_name,
|
|
||||||
data: Array.from({ length: 12 }).map((_, i) => ({
|
|
||||||
time: now.subtract(55 - i * 5, "minute").toISOString(),
|
|
||||||
value: Math.round(Math.random() * 3 + 2 + idx * 2), // 2~7度
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
|
|
||||||
const getData = async (timeInterval) => {
|
const getData = async () => {
|
||||||
// showChartLoading(frozen_temp_chart.value.chart);
|
|
||||||
const res = await getDashboardTemp({
|
const res = await getDashboardTemp({
|
||||||
timeInterval, // 時間間隔=>1.4.8
|
timeInterval: 1, // 時間間隔=>1.4.8
|
||||||
tempOption: 2, // 1:即時溫度;2:冷藏溫度
|
tempOption: 2, // 1:即時溫度;2:冷藏溫度
|
||||||
});
|
});
|
||||||
console.log(res);
|
|
||||||
if (res.isSuccess) {
|
if (res.isSuccess) {
|
||||||
data.value = res.data?.freezer;
|
data.value = res.data || [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(
|
watch(data, (newValue) => {
|
||||||
searchParams,
|
if (newValue?.length > 0) {
|
||||||
(newValue, oldValue) => {
|
frozen_temp_chart.value.chart.setOption({
|
||||||
if (
|
legend: {
|
||||||
newValue[intervalType] &&
|
data: newValue.map(({ full_name }) => full_name),
|
||||||
newValue[intervalType] !== oldValue[intervalType]
|
},
|
||||||
) {
|
xAxis: {
|
||||||
window.clearInterval(timeoutTimer.value);
|
data: newValue[0]?.data.map(({ time }) => dayjs(time).format("HH:mm")),
|
||||||
getData(parseInt(newValue[intervalType]));
|
},
|
||||||
timeoutTimer.value = setInterval(() => {
|
series: newValue.map(({ full_name, data: seriesData }, index) => ({
|
||||||
getData(parseInt(newValue[intervalType]));
|
name: full_name,
|
||||||
}, 60000);
|
type: "line",
|
||||||
}
|
data: seriesData.map(({ value }) => value),
|
||||||
},
|
showSymbol: false,
|
||||||
{
|
itemStyle: {
|
||||||
deep: true,
|
color: SECOND_CHART_COLOR[index],
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
|
let timer = null;
|
||||||
|
|
||||||
watch(
|
|
||||||
data,
|
|
||||||
(newValue) => {
|
|
||||||
// clearChart(frozen_temp_chart.value.chart);
|
|
||||||
newValue.length > 0 &&
|
|
||||||
frozen_temp_chart.value.chart.setOption({
|
|
||||||
legend: {
|
|
||||||
data: newValue.map(({ full_name }) => full_name),
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
data: newValue[0]?.data.map(({ time }) =>
|
|
||||||
dayjs(time).format("HH:mm")
|
|
||||||
),
|
|
||||||
},
|
|
||||||
series: newValue.map(({ full_name, data }, index) => ({
|
|
||||||
name: full_name,
|
|
||||||
type: "line",
|
|
||||||
data: data.map(({ value }) => value),
|
|
||||||
showSymbol: false,
|
|
||||||
itemStyle: {
|
|
||||||
color: SECOND_CHART_COLOR[index],
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
// frozen_temp_chart.value.chart.hideLoading();
|
|
||||||
},
|
|
||||||
{ deep: true }
|
|
||||||
);
|
|
||||||
const timeoutTimer = ref("");
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// getData(1);
|
getData();
|
||||||
// timeoutTimer.value = setInterval(() => {
|
timer = setInterval(() => {
|
||||||
// getData(1);
|
getData();
|
||||||
// }, 60000);
|
}, 60 * 1000);
|
||||||
data.value = generateFakeFrozenData();
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -2,28 +2,14 @@
|
|||||||
import LineChart from "@/components/chart/LineChart.vue";
|
import LineChart from "@/components/chart/LineChart.vue";
|
||||||
import { SECOND_CHART_COLOR } from "@/constant";
|
import { SECOND_CHART_COLOR } from "@/constant";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { ref, watch, onMounted } from "vue";
|
import { ref, watch, onMounted, onUnmounted } from "vue";
|
||||||
import useActiveBtn from "@/hooks/useActiveBtn";
|
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||||
import { getDashboardTemp } from "@/apis/dashboard";
|
import { getDashboardTemp } from "@/apis/dashboard";
|
||||||
import useSearchParams from "@/hooks/useSearchParam";
|
import useSearchParams from "@/hooks/useSearchParam";
|
||||||
import useDashboardOption from "@/hooks/useDashboardOption";
|
|
||||||
|
|
||||||
const { searchParams } = useSearchParams();
|
const { searchParams } = useSearchParams();
|
||||||
const intervalType = "immediateTemp";
|
const intervalType = "immediateTemp";
|
||||||
|
|
||||||
// 假資料產生器
|
|
||||||
function generateFakeData() {
|
|
||||||
const names = ["二重釜-溫度", "調理鍋-溫度", "調理鍋-糖度"];
|
|
||||||
const now = dayjs();
|
|
||||||
return names.map((full_name, idx) => ({
|
|
||||||
full_name,
|
|
||||||
data: Array.from({ length: 12 }).map((_, i) => ({
|
|
||||||
time: now.subtract(55 - i * 5, "minute").toISOString(),
|
|
||||||
value: Math.round(Math.random() * 10 + 20 + idx * 5), // 20~35
|
|
||||||
})),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
const other_real_temp_chart = ref(null);
|
const other_real_temp_chart = ref(null);
|
||||||
const defaultChartOption = ref({
|
const defaultChartOption = ref({
|
||||||
tooltip: {
|
tooltip: {
|
||||||
@ -39,10 +25,10 @@ const defaultChartOption = ref({
|
|||||||
bottom: "0%",
|
bottom: "0%",
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
top: "10%",
|
top: "5%",
|
||||||
left: "0%",
|
left: "0%",
|
||||||
right: "0%",
|
right: "0%",
|
||||||
bottom: "10%",
|
bottom: "20%",
|
||||||
containLabel: true,
|
containLabel: true,
|
||||||
},
|
},
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@ -72,7 +58,6 @@ const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
|||||||
const data = ref([]);
|
const data = ref([]);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
data.value = generateFakeData();
|
|
||||||
setItems([
|
setItems([
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -94,58 +79,33 @@ onMounted(() => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
// const getData = async (timeInterval, typeOption) => {
|
|
||||||
// // showChartLoading(other_real_temp_chart.value.chart);
|
|
||||||
// const res = await getDashboardTemp({
|
|
||||||
// timeInterval, // 時間間隔=>1.4.8
|
|
||||||
// tempOption: 1, // 1:即時溫度;2:冷藏溫度
|
|
||||||
// typeOption, // 1:仙草;2:愛玉;3:紅茶
|
|
||||||
// });
|
|
||||||
// if (res.isSuccess) {
|
|
||||||
// data.value = res.data[selectedBtn.value.typeOption];
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// const timeoutTimer = ref("");
|
const getData = async (typeOption) => {
|
||||||
|
const res = await getDashboardTemp({
|
||||||
|
timeInterval: 1, // 時間間隔=>1.4.8
|
||||||
|
tempOption: 1,
|
||||||
|
typeOption, // 1:二重釜-溫度;2:調理鍋-溫度;3:二重釜-糖度
|
||||||
|
});
|
||||||
|
if (res.isSuccess) {
|
||||||
|
data.value = res.data || [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// watch(
|
let timer = null;
|
||||||
// selectedBtn,
|
|
||||||
// (newValue) => {
|
|
||||||
// window.clearInterval(timeoutTimer.value);
|
|
||||||
// getData(
|
|
||||||
// parseInt(searchParams.value[intervalType] || 1),
|
|
||||||
// newValue.typeOption
|
|
||||||
// );
|
|
||||||
// timeoutTimer.value = setInterval(() => {
|
|
||||||
// getData(
|
|
||||||
// parseInt(searchParams.value[intervalType] || 1),
|
|
||||||
// newValue.typeOption
|
|
||||||
// );
|
|
||||||
// }, 60000);
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// deep: true,
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// watch(
|
watch(
|
||||||
// searchParams,
|
selectedBtn,
|
||||||
// (newValue, oldValue) => {
|
(newValue) => {
|
||||||
// if (
|
window.clearInterval(timer);
|
||||||
// newValue[intervalType] &&
|
getData(newValue.key);
|
||||||
// newValue[intervalType] !== oldValue[intervalType]
|
timer = setInterval(() => {
|
||||||
// ) {
|
getData(newValue.key);
|
||||||
// window.clearInterval(timeoutTimer.value);
|
}, 60 * 1000);
|
||||||
// getData(parseInt(newValue[intervalType]), selectedBtn.value.typeOption);
|
},
|
||||||
// timeoutTimer.value = setInterval(() => {
|
{
|
||||||
// getData(parseInt(newValue[intervalType]), selectedBtn.value.typeOption);
|
deep: true,
|
||||||
// }, 60000);
|
}
|
||||||
// }
|
);
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// deep: true,
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
watch(data, (newValue) => {
|
watch(data, (newValue) => {
|
||||||
// clearChart(other_real_temp_chart.value.chart);
|
// clearChart(other_real_temp_chart.value.chart);
|
||||||
@ -157,10 +117,10 @@ watch(data, (newValue) => {
|
|||||||
xAxis: {
|
xAxis: {
|
||||||
data: newValue[0]?.data.map(({ time }) => dayjs(time).format("HH:mm")),
|
data: newValue[0]?.data.map(({ time }) => dayjs(time).format("HH:mm")),
|
||||||
},
|
},
|
||||||
series: newValue.map(({ full_name, data }, index) => ({
|
series: newValue.map(({ full_name, data: seriesData }, index) => ({
|
||||||
name: full_name,
|
name: full_name,
|
||||||
type: "line",
|
type: "line",
|
||||||
data: data.map(({ value }) => value),
|
data: seriesData.map(({ value }) => value),
|
||||||
showSymbol: false,
|
showSymbol: false,
|
||||||
itemStyle: {
|
itemStyle: {
|
||||||
color: SECOND_CHART_COLOR[index],
|
color: SECOND_CHART_COLOR[index],
|
||||||
@ -170,6 +130,13 @@ watch(data, (newValue) => {
|
|||||||
}
|
}
|
||||||
// other_real_temp_chart.value.chart.hideLoading();
|
// other_real_temp_chart.value.chart.hideLoading();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (timer) {
|
||||||
|
clearInterval(timer);
|
||||||
|
timer = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -1,51 +1,29 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import LiquidfillChart from "@/components/chart/LiquidfillChart.vue";
|
import LiquidfillChart from "@/components/chart/LiquidfillChart.vue";
|
||||||
import { ref, onMounted, provide, watch, inject } from "vue";
|
import { ref, onMounted, provide, watch, inject } from "vue";
|
||||||
import { getDashboardProductCompletion } from "@/apis/dashboard";
|
import { getSettingInventory } from "@/apis/productSetting";
|
||||||
import DashboardDescriptionCard from "./DashboardDescriptionCard.vue";
|
import DashboardDescriptionCard from "./DashboardDescriptionCard.vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
// 假資料
|
const descriptionCards = ref([]);
|
||||||
const production_data = ref([]);
|
|
||||||
|
|
||||||
const progress_data = ref([]);
|
const progress_data = ref([]);
|
||||||
const getCompletion = async () => {
|
|
||||||
// 註解掉 API 呼叫,使用假資料
|
|
||||||
// const res = await getDashboardProductCompletion();
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
production_data.value.push(Math.floor(Math.random() * 100));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const descriptionCards = [
|
const getCompletion = async () => {
|
||||||
{
|
const res = await getSettingInventory();
|
||||||
title: "發酵槽",
|
descriptionCards.value = res.data.map((item) => ({
|
||||||
inventory: 38,
|
title: item.name,
|
||||||
targetInventory: 12,
|
percentage: item.percentage,
|
||||||
lastIncrease: 12,
|
current_stock: item.current_stock,
|
||||||
updateTime: "2025-05-16 15:30",
|
safety_stock: item.safety_stock,
|
||||||
},
|
updateTime: dayjs(item.updated_at).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
{
|
}));
|
||||||
title: "醋池",
|
};
|
||||||
inventory: 45,
|
|
||||||
targetInventory: 15,
|
|
||||||
lastIncrease: 8,
|
|
||||||
updateTime: "2025-05-16 16:00",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "澄清醋",
|
|
||||||
inventory: 22,
|
|
||||||
targetInventory: 10,
|
|
||||||
lastIncrease: 5,
|
|
||||||
updateTime: "2025-05-16 16:30",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
provide("dashboard_product_complete", { getCompletion, progress_data });
|
provide("dashboard_product_complete", { getCompletion, progress_data });
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getCompletion();
|
getCompletion();
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -53,30 +31,13 @@ onMounted(() => {
|
|||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h3 class="text-info font-bold text-xl text-center">原醋即時庫存量</h3>
|
<h3 class="text-info font-bold text-xl text-center">原醋即時庫存量</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="w-full grid grid-cols-3">
|
<div class="w-full grid grid-cols-3">
|
||||||
<div>
|
<div v-for="(card, idx) in descriptionCards.slice(0, 3)" :key="idx">
|
||||||
<LiquidfillChart
|
<LiquidfillChart
|
||||||
id="dashboard_mesona_production"
|
:id="`dashboard_product_${idx}`"
|
||||||
title="發酵槽"
|
:title="card.title || ''"
|
||||||
:value="production_data[0]"
|
:value="card.percentage || 0"
|
||||||
color="#facd91"
|
:color="idx === 0 ? '#facd91' : idx === 1 ? '#7dd7df' : '#8cce30'"
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<LiquidfillChart
|
|
||||||
id="dashboard_aiyu_production"
|
|
||||||
title="醋池"
|
|
||||||
:value="production_data[1]"
|
|
||||||
color="#7dd7df"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<LiquidfillChart
|
|
||||||
id="dashboard_blackTea_production"
|
|
||||||
title="澄清醋"
|
|
||||||
:value="production_data[2]"
|
|
||||||
color="#8cce30"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -86,9 +47,8 @@ onMounted(() => {
|
|||||||
v-for="(card, index) in descriptionCards"
|
v-for="(card, index) in descriptionCards"
|
||||||
:key="index"
|
:key="index"
|
||||||
:title="card.title"
|
:title="card.title"
|
||||||
:inventory="card.inventory"
|
:safety_stock="card.safety_stock"
|
||||||
:targetInventory="card.targetInventory"
|
:current_stock="card.current_stock"
|
||||||
:lastIncrease="card.lastIncrease"
|
|
||||||
:updateTime="card.updateTime"
|
:updateTime="card.updateTime"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, defineProps, inject, watch } from "vue";
|
import { ref, computed, defineProps, inject, watch } from "vue";
|
||||||
import * as yup from "yup";
|
import * as yup from "yup";
|
||||||
import "yup-phone-lite";
|
import "yup-phone-lite";
|
||||||
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
|
import useFormErrorMessage from "@/hooks/useFormErrorMessage";
|
||||||
@ -11,35 +11,35 @@ const props = defineProps({
|
|||||||
formState: Object,
|
formState: Object,
|
||||||
itemData: Array,
|
itemData: Array,
|
||||||
});
|
});
|
||||||
const emit = defineEmits(["pushData"]);
|
const emit = defineEmits(["pushData", "resetModalForm"]);
|
||||||
|
|
||||||
const dateItem = ref([
|
const settingScheme = yup.object({
|
||||||
{
|
total_capacity: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
key: "start_time",
|
|
||||||
name: "start_time",
|
|
||||||
value: dayjs(),
|
|
||||||
dateFormat: "yyyy-MM-dd",
|
|
||||||
placeholder: "請輸入日期",
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const itemScheme = yup.object({
|
|
||||||
start_time: yup.date().required("必填"),
|
|
||||||
itemName: yup.string().required("必填"),
|
|
||||||
safety_stock: yup.number().required("必填").min(0, "不能小於0"),
|
safety_stock: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
target_stock: yup.number().required("必填").min(0, "不能小於0"),
|
current_stock: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const recordScheme = yup.object({
|
||||||
|
current_stock: yup.number().required("必填").min(0, "不能小於0"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const itemScheme = computed(() => {
|
||||||
|
return props.formState && props.formState.type === 1
|
||||||
|
? settingScheme
|
||||||
|
: recordScheme;
|
||||||
});
|
});
|
||||||
|
|
||||||
const { formErrorMsg, handleSubmit, handleErrorReset, updateScheme } =
|
const { formErrorMsg, handleSubmit, handleErrorReset, updateScheme } =
|
||||||
useFormErrorMessage(itemScheme);
|
useFormErrorMessage(itemScheme.value);
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
handleErrorReset();
|
handleErrorReset();
|
||||||
|
emit("resetModalForm");
|
||||||
inventory_setting_modal.close();
|
inventory_setting_modal.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOk = async () => {
|
const onOk = async () => {
|
||||||
const value = await handleSubmit(itemScheme, props.formState);
|
const value = await handleSubmit(itemScheme.value, props.formState);
|
||||||
emit("pushData", { ...value });
|
emit("pushData", { ...value });
|
||||||
onCancel();
|
onCancel();
|
||||||
};
|
};
|
||||||
@ -48,55 +48,46 @@ const onOk = async () => {
|
|||||||
<template>
|
<template>
|
||||||
<Modal
|
<Modal
|
||||||
id="inventory_setting_modal"
|
id="inventory_setting_modal"
|
||||||
:title="
|
:title="props.formState?.type == 1 ? '設定' : '入庫'"
|
||||||
props.formState?.start_time ? '修改原醋庫存列表' : '新增原醋庫存列表'
|
|
||||||
"
|
|
||||||
:onCancel="onCancel"
|
:onCancel="onCancel"
|
||||||
:width="710"
|
:width="710"
|
||||||
>
|
>
|
||||||
<template #modalContent>
|
<template #modalContent>
|
||||||
<form ref="form" class="mt-5 w-full flex flex-wrap justify-between">
|
<form ref="form" class="mt-5 w-full flex flex-wrap justify-between">
|
||||||
<DateGroup
|
<Input :value="formState" class="my-2" name="name" readonly>
|
||||||
class="my-2"
|
<template #topLeft>項目</template>
|
||||||
:items="dateItem"
|
</Input>
|
||||||
inputClass="w-full shadow-none"
|
<Input
|
||||||
:required="true"
|
|
||||||
>
|
|
||||||
<template #topLeft>日期</template>
|
|
||||||
<template #bottomLeft
|
|
||||||
><span class="text-error text-base">
|
|
||||||
{{ formErrorMsg.start_time }}
|
|
||||||
</span></template
|
|
||||||
>
|
|
||||||
</DateGroup>
|
|
||||||
<Select
|
|
||||||
:value="formState"
|
:value="formState"
|
||||||
class="my-2"
|
class="my-2"
|
||||||
selectClass="border-info focus-within:border-info"
|
name="total_capacity"
|
||||||
name="itemName"
|
v-if="formState?.type == 1"
|
||||||
Attribute="full_name"
|
|
||||||
:options="props.itemData"
|
|
||||||
>
|
>
|
||||||
<template #topLeft>品名</template>
|
<template #topLeft>總庫存量</template>
|
||||||
<template #bottomLeft>
|
<template #bottomLeft>
|
||||||
<span class="text-error text-base">{{
|
<span class="text-error text-base">{{
|
||||||
formErrorMsg.itemName
|
formErrorMsg.total_capacity
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Select>
|
</Input>
|
||||||
<Input :value="formState" class="my-2" name="safety_stock">
|
<Input
|
||||||
<template #topLeft>安全庫存量</template>
|
:value="formState"
|
||||||
|
class="my-2"
|
||||||
|
name="safety_stock"
|
||||||
|
v-if="formState?.type == 1"
|
||||||
|
>
|
||||||
|
<template #topLeft>安全存量</template>
|
||||||
<template #bottomLeft>
|
<template #bottomLeft>
|
||||||
<span class="text-error text-base">{{
|
<span class="text-error text-base">{{
|
||||||
formErrorMsg.safety_stock
|
formErrorMsg.safety_stock
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
<Input :value="formState" class="my-2" name="target_stock">
|
<Input :value="formState" class="my-2" name="current_stock">
|
||||||
<template #topLeft>目標庫存量</template>
|
<template #topLeft>目前存量</template>
|
||||||
<template #bottomLeft>
|
<template #bottomLeft>
|
||||||
<span class="text-error text-base">{{
|
<span class="text-error text-base">{{
|
||||||
formErrorMsg.target_stock
|
formErrorMsg.current_stock
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</Input>
|
</Input>
|
||||||
|
@ -1,33 +1,35 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import Table from "@/components/customUI/Table.vue";
|
import Table from "@/components/customUI/Table.vue";
|
||||||
import InventorySettingAddModal from "./InventorySettingAddModal.vue";
|
import InventorySettingAddModal from "./InventorySettingAddModal.vue";
|
||||||
import { postChangeGroupValue, getCheckWeigher } from "@/apis/productSetting";
|
import {
|
||||||
import { ref, onMounted, inject } from "vue";
|
getSettingInventory,
|
||||||
|
postSettingInventory,
|
||||||
|
getSettingInventoryLog,
|
||||||
|
} from "@/apis/productSetting";
|
||||||
|
import { ref, onMounted, inject, watch } from "vue";
|
||||||
|
import useActiveBtn from "@/hooks/useActiveBtn";
|
||||||
|
const { items, changeActiveBtn, setItems, selectedBtn } = useActiveBtn();
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
const { openToast } = inject("app_toast");
|
const { openToast } = inject("app_toast");
|
||||||
|
|
||||||
const columns = [
|
const settingColumns = [
|
||||||
{
|
{ title: "項目", key: "name" },
|
||||||
title: "日期",
|
{ title: "總庫存量", key: "total_capacity" },
|
||||||
key: "date",
|
{ title: "安全存量", key: "safety_stock" },
|
||||||
},
|
{ title: "目前存量", key: "current_stock" },
|
||||||
{
|
{ title: "更新時間", key: "updated_at" },
|
||||||
title: "品名",
|
{ title: "功能", key: "operation" },
|
||||||
key: "full_name",
|
];
|
||||||
},
|
|
||||||
{
|
const recordColumns = [
|
||||||
title: "安全庫存量",
|
{ title: "項目", key: "item_name", filter: true },
|
||||||
key: "safety",
|
{ title: "總庫存量", key: "total_capacity" },
|
||||||
},
|
{ title: "安全存量", key: "safety_stock" },
|
||||||
{
|
{ title: "目前存量", key: "current_stock" },
|
||||||
title: "目標庫存量",
|
{ title: "操作類型", key: "type" },
|
||||||
key: "target",
|
{ title: "最後修改者", key: "user_name", filter: true },
|
||||||
},
|
{ title: "日期", key: "time", sort: true },
|
||||||
{
|
|
||||||
title: "操作",
|
|
||||||
key: "operation",
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const dataSource = ref([]);
|
const dataSource = ref([]);
|
||||||
@ -53,35 +55,38 @@ const dateRange = ref([
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const searchState = ref({
|
const searchState = ref({
|
||||||
itemName: "all",
|
|
||||||
start_time: dayjs().subtract(30, "day").format("YYYY-MM-DD"),
|
start_time: dayjs().subtract(30, "day").format("YYYY-MM-DD"),
|
||||||
end_time: dayjs().format("YYYY-MM-DD"),
|
end_time: dayjs().format("YYYY-MM-DD"),
|
||||||
});
|
});
|
||||||
|
|
||||||
const formState = ref({
|
const formState = ref({});
|
||||||
start_time: "",
|
|
||||||
itemName: 1,
|
|
||||||
safety_stock: 0,
|
|
||||||
target_stock: 0,
|
|
||||||
});
|
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
const getDataSource = async () => {
|
const getDataSource = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
// const res = await getCheckWeigher();
|
const res = await getSettingInventory();
|
||||||
// dataSource.value = res.data;
|
if (!res.isSuccess) {
|
||||||
|
dataSource.value = [];
|
||||||
|
} else {
|
||||||
|
dataSource.value = res.data.map((item) => ({
|
||||||
|
...item,
|
||||||
|
updated_at: dayjs(item.updated_at).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const pushDataSource = async (data) => {
|
const pushDataSource = async (value) => {
|
||||||
loading.value = true;
|
const res = await postSettingInventory(value);
|
||||||
// 檢查是新增還是修改
|
if (res.isSuccess) {
|
||||||
|
getDataSource();
|
||||||
loading.value = false;
|
} else {
|
||||||
|
openToast("error", res.msg, "#account_user_modal");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSearch = () => {
|
const onSearch = async () => {
|
||||||
// 搜尋邏輯
|
// 搜尋邏輯
|
||||||
searchState.value.start_time = dayjs(dateRange.value[0].value).format(
|
searchState.value.start_time = dayjs(dateRange.value[0].value).format(
|
||||||
"YYYY-MM-DD"
|
"YYYY-MM-DD"
|
||||||
@ -90,81 +95,122 @@ const onSearch = () => {
|
|||||||
"YYYY-MM-DD"
|
"YYYY-MM-DD"
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log("搜尋條件:", searchState.value);
|
const res = await getSettingInventoryLog(searchState.value);
|
||||||
|
if (!res.isSuccess) {
|
||||||
|
dataSource.value = [];
|
||||||
|
} else {
|
||||||
|
dataSource.value = res.data.map((item) => ({
|
||||||
|
...item,
|
||||||
|
time: dayjs(item.time).format("YYYY-MM-DD HH:mm:ss"),
|
||||||
|
}));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const openModal = (record) => {
|
const openModal = (type, item_id, record) => {
|
||||||
if (record) {
|
if (type === 1) {
|
||||||
formState.value = { ...record };
|
formState.value = {
|
||||||
|
type: 1,
|
||||||
|
item_id: item_id,
|
||||||
|
name: record.name,
|
||||||
|
total_capacity: record.total_capacity,
|
||||||
|
safety_stock: record.safety_stock,
|
||||||
|
current_stock: record.current_stock,
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
resetModalForm();
|
formState.value = {
|
||||||
|
type: 2,
|
||||||
|
item_id: item_id,
|
||||||
|
name: record.name,
|
||||||
|
current_stock: record.current_stock,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
inventory_setting_modal.showModal();
|
inventory_setting_modal.showModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
const resetModalForm = () => {
|
const resetModalForm = () => {
|
||||||
formState.value = {
|
formState.value = {};
|
||||||
start_time: "",
|
|
||||||
itemName: 1,
|
|
||||||
safety_stock: 0,
|
|
||||||
target_stock: 0,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 刪除功能
|
|
||||||
const removeAccount = async () => {};
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getDataSource();
|
setItems([
|
||||||
|
{
|
||||||
|
title: "設定",
|
||||||
|
key: "setting",
|
||||||
|
active: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "紀錄",
|
||||||
|
key: "record",
|
||||||
|
active: false,
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => selectedBtn.value?.key,
|
||||||
|
(key) => {
|
||||||
|
dataSource.value = [];
|
||||||
|
if (key === "setting") {
|
||||||
|
getDataSource();
|
||||||
|
} else if (key === "record") {
|
||||||
|
onSearch();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex justify-start items-center mb-3">
|
<InventorySettingAddModal
|
||||||
<h3 class="text-xl mr-5">原醋庫存列表</h3>
|
@pushData="pushDataSource"
|
||||||
<InventorySettingAddModal
|
:formState="formState"
|
||||||
@pushData="pushDataSource"
|
:itemData="itemData"
|
||||||
:formState="formState"
|
@resetModalForm="resetModalForm"
|
||||||
:itemData="itemData"
|
/>
|
||||||
/>
|
<div class="w-full custom-border p-4 mb-4">
|
||||||
<button
|
<div class="flex flex-wrap items-center justify-start">
|
||||||
class="btn btn-sm btn-success mr-3"
|
<ButtonGroup
|
||||||
@click.stop.prevent="openModal(null)"
|
:items="items"
|
||||||
>
|
:withLine="true"
|
||||||
<font-awesome-icon :icon="['fas', 'plus']" />新增
|
class="mr-5"
|
||||||
</button>
|
:onclick="(e, item) => changeActiveBtn(item)"
|
||||||
</div>
|
/>
|
||||||
<Table :columns="columns" :dataSource="dataSource" :loading="loading">
|
<template v-if="selectedBtn?.key === 'record'">
|
||||||
<template #beforeTable>
|
<DateGroup
|
||||||
<div class="flex items-center gap-5 mb-8">
|
:items="dateRange"
|
||||||
<Select
|
:withLine="true"
|
||||||
:value="searchState"
|
:isTopLabelExist="false"
|
||||||
class=""
|
:isBottomLabelExist="false"
|
||||||
selectClass="border-info focus-within:border-info"
|
class="mr-5"
|
||||||
name="itemName"
|
/>
|
||||||
Attribute="full_name"
|
<button class="btn btn-success" @click.stop.prevent="onSearch">
|
||||||
:options="[{ full_name: '全品項', key: 'all' }, ...itemData]"
|
|
||||||
>
|
|
||||||
</Select>
|
|
||||||
<DateGroup :items="dateRange" :withLine="true" />
|
|
||||||
<button class="btn btn-outline-success" @click.stop.prevent="onSearch">
|
|
||||||
搜尋
|
搜尋
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
</div>
|
||||||
|
</div>
|
||||||
|
<Table
|
||||||
|
:columns="selectedBtn?.key === 'setting' ? settingColumns : recordColumns"
|
||||||
|
:dataSource="dataSource"
|
||||||
|
:loading="loading"
|
||||||
|
>
|
||||||
<template #bodyCell="{ record, column, index }">
|
<template #bodyCell="{ record, column, index }">
|
||||||
<template v-if="column.key === 'operation'">
|
<template v-if="column.key === 'operation'">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-success text-white mr-2"
|
class="btn btn-sm btn-success text-white mr-2"
|
||||||
@click.stop.prevent="() => openModal(record)"
|
@click.stop.prevent="() => openModal(1, record.item_id, record)"
|
||||||
>
|
>
|
||||||
修改
|
設定
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-error text-white"
|
class="btn btn-sm btn-success text-white mr-2"
|
||||||
@click.stop.prevent="() => removeAccount(record.id)"
|
@click.stop.prevent="() => openModal(2, record.item_id, record)"
|
||||||
|
:disabled="record?.item_id == 2"
|
||||||
>
|
>
|
||||||
刪除
|
入庫
|
||||||
</button>
|
</button>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
|
Loading…
Reference in New Issue
Block a user