|
@@ -417,6 +417,13 @@
|
|
|
import Bar3DChart from './components/charts/Bar3DChart';
|
|
import Bar3DChart from './components/charts/Bar3DChart';
|
|
|
import DeviceStatusChart from './components/charts/DeviceStatusChart';
|
|
import DeviceStatusChart from './components/charts/DeviceStatusChart';
|
|
|
import BarLineComboChart from './components/charts/BarLineComboChart';
|
|
import BarLineComboChart from './components/charts/BarLineComboChart';
|
|
|
|
|
+ import {
|
|
|
|
|
+ getFactoryProductionDashboardData,
|
|
|
|
|
+ getFactoryProductionDataByPlan,
|
|
|
|
|
+ getFactoryProductionDataByStock,
|
|
|
|
|
+ getFactoryProductionDataByDevice,
|
|
|
|
|
+ getFactoryListByUser
|
|
|
|
|
+ } from '@/api/vis/factoryProductionDashboard';
|
|
|
const inventoryIcon = require('@/assets/png/icon.png');
|
|
const inventoryIcon = require('@/assets/png/icon.png');
|
|
|
|
|
|
|
|
export default {
|
|
export default {
|
|
@@ -479,13 +486,19 @@
|
|
|
immediate: true
|
|
immediate: true
|
|
|
},
|
|
},
|
|
|
factoryId() {
|
|
factoryId() {
|
|
|
- this.loadMockData();
|
|
|
|
|
|
|
+ this.loadDashboardData();
|
|
|
},
|
|
},
|
|
|
dateRange: {
|
|
dateRange: {
|
|
|
handler() {
|
|
handler() {
|
|
|
- this.loadMockData();
|
|
|
|
|
|
|
+ this.loadDashboardData();
|
|
|
},
|
|
},
|
|
|
deep: true
|
|
deep: true
|
|
|
|
|
+ },
|
|
|
|
|
+ activePlanTab() {
|
|
|
|
|
+ this.fetchPlanData();
|
|
|
|
|
+ },
|
|
|
|
|
+ activeInventoryFilter() {
|
|
|
|
|
+ this.fetchInventoryData();
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
data() {
|
|
data() {
|
|
@@ -500,74 +513,57 @@
|
|
|
week: '',
|
|
week: '',
|
|
|
inventoryIcon,
|
|
inventoryIcon,
|
|
|
|
|
|
|
|
- factoryId: 'F001',
|
|
|
|
|
- factoryList: [
|
|
|
|
|
- { id: 'F001', name: '工厂A' },
|
|
|
|
|
- { id: 'F002', name: '工厂B' }
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ factoryId: '',
|
|
|
|
|
+ factoryList: [],
|
|
|
dateRange: [],
|
|
dateRange: [],
|
|
|
|
|
|
|
|
productionStats: {
|
|
productionStats: {
|
|
|
- quantity: 58500,
|
|
|
|
|
|
|
+ quantity: 0,
|
|
|
transformQuantity: [0, 0, 0, 0, 0, 0],
|
|
transformQuantity: [0, 0, 0, 0, 0, 0],
|
|
|
- requiredTotal: 1000,
|
|
|
|
|
- achievementRate: 58.8
|
|
|
|
|
|
|
+ requiredTotal: 0,
|
|
|
|
|
+ achievementRate: 0
|
|
|
},
|
|
},
|
|
|
productionKpi: {
|
|
productionKpi: {
|
|
|
- delayedCount: 29,
|
|
|
|
|
- planAchievementRate: 82,
|
|
|
|
|
- unpublishedCount: 53
|
|
|
|
|
|
|
+ delayedCount: 0,
|
|
|
|
|
+ planAchievementRate: 0,
|
|
|
|
|
+ unpublishedCount: 0
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
fiveCategoryData: [
|
|
fiveCategoryData: [
|
|
|
- { name: '成品', value: 2533 },
|
|
|
|
|
- { name: '半成品', value: 1050 },
|
|
|
|
|
- { name: '在制品', value: 2523 },
|
|
|
|
|
- { name: '废品', value: 58 },
|
|
|
|
|
- { name: '返修品', value: 83 }
|
|
|
|
|
|
|
+ { name: '成品', value: 0 },
|
|
|
|
|
+ { name: '半成品', value: 0 },
|
|
|
|
|
+ { name: '在制品', value: 0 },
|
|
|
|
|
+ { name: '废品', value: 0 },
|
|
|
|
|
+ { name: '返修品', value: 0 }
|
|
|
],
|
|
],
|
|
|
fourNumberBarData: [
|
|
fourNumberBarData: [
|
|
|
- { name: '产品', value: 300 },
|
|
|
|
|
- { name: '物品', value: 260 },
|
|
|
|
|
- { name: '零部件', value: 280 },
|
|
|
|
|
- { name: '备品备件', value: 320 }
|
|
|
|
|
|
|
+ { name: '投入数', value: 0 },
|
|
|
|
|
+ { name: '产出数', value: 0 },
|
|
|
|
|
+ { name: '废品数', value: 0 },
|
|
|
|
|
+ { name: '周转数', value: 0 }
|
|
|
],
|
|
],
|
|
|
|
|
|
|
|
- inventoryLedgerData: [
|
|
|
|
|
- { name: '产品', value: 420 },
|
|
|
|
|
- { name: '物品', value: 300 },
|
|
|
|
|
- { name: '半成品', value: 380 },
|
|
|
|
|
- { name: '零件', value: 260 },
|
|
|
|
|
- { name: '生产设备', value: 110 },
|
|
|
|
|
- { name: '仪表计量', value: 180 },
|
|
|
|
|
- { name: '备品备件', value: 220 }
|
|
|
|
|
- ],
|
|
|
|
|
- inventoryLedgerKeeperData: [
|
|
|
|
|
- { name: '仓管A', value: 360 },
|
|
|
|
|
- { name: '仓管B', value: 300 },
|
|
|
|
|
- { name: '仓管C', value: 280 },
|
|
|
|
|
- { name: '仓管D', value: 330 },
|
|
|
|
|
- { name: '仓管E', value: 250 }
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ inventoryLedgerData: [],
|
|
|
|
|
+ inventoryLedgerKeeperData: [],
|
|
|
activeInventoryFilter: 'category',
|
|
activeInventoryFilter: 'category',
|
|
|
deviceLedger: {
|
|
deviceLedger: {
|
|
|
- categories: ['设备', '工夹刀模具', '仪表计量', '备品备件'],
|
|
|
|
|
- barData: [2907, 1865, 2735, 865],
|
|
|
|
|
- topBarData: [3607, 2385, 3987, 1685],
|
|
|
|
|
- lineData: [78, 65, 86, 72]
|
|
|
|
|
|
|
+ categories: [],
|
|
|
|
|
+ barData: [],
|
|
|
|
|
+ topBarData: [],
|
|
|
|
|
+ lineData: []
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
quality: {
|
|
quality: {
|
|
|
- passRate: 98,
|
|
|
|
|
- failRate: 2,
|
|
|
|
|
- lossRate: 5
|
|
|
|
|
|
|
+ passRate: 0,
|
|
|
|
|
+ failRate: 0,
|
|
|
|
|
+ lossRate: 0
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
planTabs: [
|
|
planTabs: [
|
|
|
{ key: 'all', label: '全部' },
|
|
{ key: 'all', label: '全部' },
|
|
|
{ key: 'monthly', label: '月度滚动计划' },
|
|
{ key: 'monthly', label: '月度滚动计划' },
|
|
|
{ key: 'temporary', label: '临时生产计划' },
|
|
{ key: 'temporary', label: '临时生产计划' },
|
|
|
- { key: 'research', label: '科研计划' }
|
|
|
|
|
|
|
+ { key: 'research', label: '分厂临时计划' }
|
|
|
],
|
|
],
|
|
|
activePlanTab: 'all',
|
|
activePlanTab: 'all',
|
|
|
planRows: []
|
|
planRows: []
|
|
@@ -579,9 +575,9 @@
|
|
|
const now = new Date();
|
|
const now = new Date();
|
|
|
const start = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 30);
|
|
const start = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 30);
|
|
|
this.dateRange = [this.formatDate(start), this.formatDate(now)];
|
|
this.dateRange = [this.formatDate(start), this.formatDate(now)];
|
|
|
|
|
+ this.getFactoryListByData();
|
|
|
},
|
|
},
|
|
|
mounted() {
|
|
mounted() {
|
|
|
- this.loadMockData();
|
|
|
|
|
this.applyScreenSize();
|
|
this.applyScreenSize();
|
|
|
window.addEventListener('resize', this.handleWindowResize);
|
|
window.addEventListener('resize', this.handleWindowResize);
|
|
|
document.addEventListener(
|
|
document.addEventListener(
|
|
@@ -628,6 +624,25 @@
|
|
|
}, 150);
|
|
}, 150);
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
|
|
+ async getFactoryListByData() {
|
|
|
|
|
+ const par = {
|
|
|
|
|
+ type: 1,
|
|
|
|
|
+ size: 9999
|
|
|
|
|
+ };
|
|
|
|
|
+ await getFactoryListByUser(par).then((res) => {
|
|
|
|
|
+ if (res.list && res.list.length > 0) {
|
|
|
|
|
+ this.factoryList = res.list.map((el) => {
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: el.id,
|
|
|
|
|
+ name: el.name
|
|
|
|
|
+ };
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ this.factoryId = this.factoryList.length ? this.factoryList[0].id : '';
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
triggerChartResize() {
|
|
triggerChartResize() {
|
|
|
this.$nextTick(() => {
|
|
this.$nextTick(() => {
|
|
|
window.dispatchEvent(new Event('resize'));
|
|
window.dispatchEvent(new Event('resize'));
|
|
@@ -715,72 +730,250 @@
|
|
|
const paddedStr = String(num ?? 0).padStart(6, '0');
|
|
const paddedStr = String(num ?? 0).padStart(6, '0');
|
|
|
return paddedStr.split('').map((c) => Number(c));
|
|
return paddedStr.split('').map((c) => Number(c));
|
|
|
},
|
|
},
|
|
|
- loadMockData() {
|
|
|
|
|
- // mock:后续你接接口时,将这里替换成 API 请求即可
|
|
|
|
|
- const base = this.factoryId === 'F002' ? 74210 : 58500;
|
|
|
|
|
- this.productionStats.quantity = base;
|
|
|
|
|
- this.productionStats.transformQuantity = this.formatNumber6(base);
|
|
|
|
|
- this.productionStats.requiredTotal =
|
|
|
|
|
- this.factoryId === 'F002' ? 1600 : 1000;
|
|
|
|
|
- this.productionStats.achievementRate =
|
|
|
|
|
- this.factoryId === 'F002' ? 76.2 : 58.8;
|
|
|
|
|
-
|
|
|
|
|
- this.productionKpi.delayedCount = this.factoryId === 'F002' ? 12 : 29;
|
|
|
|
|
- this.productionKpi.planAchievementRate =
|
|
|
|
|
- this.factoryId === 'F002' ? 91 : 82;
|
|
|
|
|
- this.productionKpi.unpublishedCount =
|
|
|
|
|
- this.factoryId === 'F002' ? 18 : 53;
|
|
|
|
|
-
|
|
|
|
|
- this.planRows = [
|
|
|
|
|
|
|
+ normalizeNumber(value) {
|
|
|
|
|
+ const num = Number(value);
|
|
|
|
|
+ return Number.isFinite(num) ? num : 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ normalizePercent(value) {
|
|
|
|
|
+ if (value === null || value === undefined || value === '') return 0;
|
|
|
|
|
+ const text = String(value).replace('%', '').trim();
|
|
|
|
|
+ const num = Number(text);
|
|
|
|
|
+ return Number.isFinite(num) ? Number(num.toFixed(2)) : 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ normalizeNameValueList(list) {
|
|
|
|
|
+ if (!Array.isArray(list)) return [];
|
|
|
|
|
+ return list.map((item) => ({
|
|
|
|
|
+ name: item?.name || '--',
|
|
|
|
|
+ value: this.normalizeNumber(item?.value)
|
|
|
|
|
+ }));
|
|
|
|
|
+ },
|
|
|
|
|
+ getDateType() {
|
|
|
|
|
+ const [start, end] = this.dateRange || [];
|
|
|
|
|
+ if (!start || !end) return 1;
|
|
|
|
|
+ const startDate = new Date(start);
|
|
|
|
|
+ const endDate = new Date(end);
|
|
|
|
|
+ if (
|
|
|
|
|
+ Number.isNaN(startDate.getTime()) ||
|
|
|
|
|
+ Number.isNaN(endDate.getTime())
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return 1;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (start === end) return 1;
|
|
|
|
|
+ if (
|
|
|
|
|
+ startDate.getFullYear() === endDate.getFullYear() &&
|
|
|
|
|
+ startDate.getMonth() === endDate.getMonth()
|
|
|
|
|
+ ) {
|
|
|
|
|
+ return 2;
|
|
|
|
|
+ }
|
|
|
|
|
+ return 3;
|
|
|
|
|
+ },
|
|
|
|
|
+ getBaseParams(extra = {}) {
|
|
|
|
|
+ if (!this.factoryId) return null;
|
|
|
|
|
+ return {
|
|
|
|
|
+ dateType: this.getDateType(),
|
|
|
|
|
+ factoryId: this.factoryId,
|
|
|
|
|
+ ...extra
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ getInventoryStockType(filterType = this.activeInventoryFilter) {
|
|
|
|
|
+ return filterType === 'keeper' ? 2 : 1;
|
|
|
|
|
+ },
|
|
|
|
|
+ mapPlanTabType(tab = this.activePlanTab) {
|
|
|
|
|
+ const tabTypeMap = {
|
|
|
|
|
+ all: 0,
|
|
|
|
|
+ monthly: 1,
|
|
|
|
|
+ temporary: 2,
|
|
|
|
|
+ research: 3
|
|
|
|
|
+ };
|
|
|
|
|
+ return tabTypeMap[tab] ?? 0;
|
|
|
|
|
+ },
|
|
|
|
|
+ mapPlanStatus(status) {
|
|
|
|
|
+ const statusMap = {
|
|
|
|
|
+ 1: '待排产',
|
|
|
|
|
+ 2: '待发布',
|
|
|
|
|
+ 3: '发布失败',
|
|
|
|
|
+ 4: '待生产',
|
|
|
|
|
+ 5: '进行中',
|
|
|
|
|
+ 6: '已完成',
|
|
|
|
|
+ 7: '延期',
|
|
|
|
|
+ 8: '待下达'
|
|
|
|
|
+ };
|
|
|
|
|
+ return statusMap[Number(status)] || '--';
|
|
|
|
|
+ },
|
|
|
|
|
+ formatPlanDate(value) {
|
|
|
|
|
+ if (!value) return '--';
|
|
|
|
|
+ const text = String(value).replace('T', ' ');
|
|
|
|
|
+ return text.slice(0, 10);
|
|
|
|
|
+ },
|
|
|
|
|
+ mapPlanRow(row, planTab = this.activePlanTab) {
|
|
|
|
|
+ const status = Number(row?.status || 0);
|
|
|
|
|
+ return {
|
|
|
|
|
+ planNo: row?.code || '--',
|
|
|
|
|
+ productName: row?.productName || '--',
|
|
|
|
|
+ batchNo: row?.batchNo || '--',
|
|
|
|
|
+ planQty: this.normalizeNumber(row?.planQuantity),
|
|
|
|
|
+ currentProcess: row?.produceRoutingName || '--',
|
|
|
|
|
+ planStart: this.formatPlanDate(row?.plannedStartTime),
|
|
|
|
|
+ planEnd: this.formatPlanDate(row?.plannedEndTime),
|
|
|
|
|
+ isDelayed: status === 7,
|
|
|
|
|
+ statusText: this.mapPlanStatus(status),
|
|
|
|
|
+ type: planTab
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ buildDeviceLedger(list) {
|
|
|
|
|
+ const normalized = Array.isArray(list)
|
|
|
|
|
+ ? list.map((item) => {
|
|
|
|
|
+ const total = this.normalizeNumber(item?.value);
|
|
|
|
|
+ const occupied = this.normalizeNumber(
|
|
|
|
|
+ item?.value2 !== undefined ? item?.value2 : item?.value
|
|
|
|
|
+ );
|
|
|
|
|
+ return {
|
|
|
|
|
+ name: item?.name || '--',
|
|
|
|
|
+ total,
|
|
|
|
|
+ occupied
|
|
|
|
|
+ };
|
|
|
|
|
+ })
|
|
|
|
|
+ : [];
|
|
|
|
|
+ return {
|
|
|
|
|
+ categories: normalized.map((item) => item.name),
|
|
|
|
|
+ barData: normalized.map((item) => item.occupied),
|
|
|
|
|
+ topBarData: normalized.map((item) => item.total),
|
|
|
|
|
+ lineData: normalized.map((item) =>
|
|
|
|
|
+ item.total
|
|
|
|
|
+ ? Number(((item.occupied / item.total) * 100).toFixed(2))
|
|
|
|
|
+ : 0
|
|
|
|
|
+ )
|
|
|
|
|
+ };
|
|
|
|
|
+ },
|
|
|
|
|
+ applyDashboardSummary(data = {}) {
|
|
|
|
|
+ const quantity = this.normalizeNumber(data?.quantity);
|
|
|
|
|
+ this.productionStats.quantity = quantity;
|
|
|
|
|
+ this.productionStats.transformQuantity = this.formatNumber6(quantity);
|
|
|
|
|
+ this.productionStats.requiredTotal = this.normalizeNumber(
|
|
|
|
|
+ data?.totalQuantity
|
|
|
|
|
+ );
|
|
|
|
|
+ this.productionStats.achievementRate = this.normalizePercent(
|
|
|
|
|
+ data?.quantityAchievementRate
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ this.productionKpi.delayedCount = this.normalizeNumber(data?.delayNumber);
|
|
|
|
|
+ this.productionKpi.planAchievementRate = this.normalizePercent(
|
|
|
|
|
+ data?.achievementRate
|
|
|
|
|
+ );
|
|
|
|
|
+ this.productionKpi.unpublishedCount = this.normalizeNumber(
|
|
|
|
|
+ data?.numberToBeProduced
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ this.fiveCategoryData = [
|
|
|
|
|
+ {
|
|
|
|
|
+ name: '成品',
|
|
|
|
|
+ value: this.normalizeNumber(data?.finishedProductQuantity)
|
|
|
|
|
+ },
|
|
|
{
|
|
{
|
|
|
- planNo: 'SCH001',
|
|
|
|
|
- productName: '走查机配件',
|
|
|
|
|
- batchNo: 'NP-26-33',
|
|
|
|
|
- planQty: 88,
|
|
|
|
|
- currentProcess: '走查机',
|
|
|
|
|
- planStart: this.dateRange?.[0] || '2026-02-01',
|
|
|
|
|
- planEnd: this.dateRange?.[1] || '2026-03-01',
|
|
|
|
|
- isDelayed: true,
|
|
|
|
|
- statusText: '延期',
|
|
|
|
|
- type: 'monthly'
|
|
|
|
|
|
|
+ name: '半成品',
|
|
|
|
|
+ value: this.normalizeNumber(data?.semiFinishedProductQuantity)
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
- planNo: 'SCH002',
|
|
|
|
|
- productName: '走查机配件',
|
|
|
|
|
- batchNo: 'NP-26-33',
|
|
|
|
|
- planQty: 88,
|
|
|
|
|
- currentProcess: '走查机',
|
|
|
|
|
- planStart: this.dateRange?.[0] || '2026-02-01',
|
|
|
|
|
- planEnd: this.dateRange?.[1] || '2026-03-01',
|
|
|
|
|
- isDelayed: false,
|
|
|
|
|
- statusText: '进行中',
|
|
|
|
|
- type: 'monthly'
|
|
|
|
|
|
|
+ name: '在制品',
|
|
|
|
|
+ value: this.normalizeNumber(data?.workInProgressQuantity)
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
- planNo: 'TMP031',
|
|
|
|
|
- productName: '工具组件',
|
|
|
|
|
- batchNo: 'TMP-01',
|
|
|
|
|
- planQty: 36,
|
|
|
|
|
- currentProcess: '装配',
|
|
|
|
|
- planStart: this.dateRange?.[0] || '2026-02-01',
|
|
|
|
|
- planEnd: this.dateRange?.[1] || '2026-03-01',
|
|
|
|
|
- isDelayed: false,
|
|
|
|
|
- statusText: '未开始',
|
|
|
|
|
- type: 'temporary'
|
|
|
|
|
|
|
+ name: '废品',
|
|
|
|
|
+ value: this.normalizeNumber(data?.scrapProductQuantity)
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
|
- planNo: 'RW008',
|
|
|
|
|
- productName: '返修件A',
|
|
|
|
|
- batchNo: 'RW-08',
|
|
|
|
|
- planQty: 12,
|
|
|
|
|
- currentProcess: '返修',
|
|
|
|
|
- planStart: this.dateRange?.[0] || '2026-02-01',
|
|
|
|
|
- planEnd: this.dateRange?.[1] || '2026-03-01',
|
|
|
|
|
- isDelayed: false,
|
|
|
|
|
- statusText: '进行中',
|
|
|
|
|
- type: 'research'
|
|
|
|
|
|
|
+ name: '返修品',
|
|
|
|
|
+ value: this.normalizeNumber(data?.reworkProductQuantity)
|
|
|
}
|
|
}
|
|
|
];
|
|
];
|
|
|
|
|
+
|
|
|
|
|
+ this.fourNumberBarData = [
|
|
|
|
|
+ { name: '投入数', value: this.normalizeNumber(data?.inputQuantity) },
|
|
|
|
|
+ { name: '产出数', value: this.normalizeNumber(data?.outputQuantity) },
|
|
|
|
|
+ { name: '废品数', value: this.normalizeNumber(data?.scrapQuantity) },
|
|
|
|
|
+ { name: '周转数', value: this.normalizeNumber(data?.turnoverQuantity) }
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ this.quality.passRate = this.normalizePercent(data?.passRate);
|
|
|
|
|
+ this.quality.failRate = this.normalizePercent(data?.defectiveRate);
|
|
|
|
|
+ this.quality.lossRate = this.normalizePercent(data?.attritionRate);
|
|
|
|
|
+ },
|
|
|
|
|
+ async loadDashboardData() {
|
|
|
|
|
+ const baseParams = this.getBaseParams();
|
|
|
|
|
+ if (!baseParams) return;
|
|
|
|
|
+ await Promise.all([
|
|
|
|
|
+ this.fetchSummaryData(baseParams),
|
|
|
|
|
+ this.fetchInventoryData(baseParams),
|
|
|
|
|
+ this.fetchDeviceData(baseParams),
|
|
|
|
|
+ this.fetchPlanData(baseParams)
|
|
|
|
|
+ ]);
|
|
|
|
|
+ },
|
|
|
|
|
+ async fetchSummaryData(baseParams = this.getBaseParams()) {
|
|
|
|
|
+ if (!baseParams) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const data = await getFactoryProductionDashboardData(baseParams);
|
|
|
|
|
+ this.applyDashboardSummary(data || {});
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取工厂生产综合看板汇总数据失败:', error);
|
|
|
|
|
+ this.applyDashboardSummary({});
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async fetchInventoryData(
|
|
|
|
|
+ baseParams = this.getBaseParams(),
|
|
|
|
|
+ filterType = this.activeInventoryFilter
|
|
|
|
|
+ ) {
|
|
|
|
|
+ if (!baseParams) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const list = await getFactoryProductionDataByStock({
|
|
|
|
|
+ ...baseParams,
|
|
|
|
|
+ stockType: this.getInventoryStockType(filterType)
|
|
|
|
|
+ });
|
|
|
|
|
+ if (filterType !== this.activeInventoryFilter) return;
|
|
|
|
|
+ const normalized = this.normalizeNameValueList(list);
|
|
|
|
|
+ if (filterType === 'keeper') {
|
|
|
|
|
+ this.inventoryLedgerKeeperData = normalized;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.inventoryLedgerData = normalized;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取库存台账数据失败:', error);
|
|
|
|
|
+ if (filterType === 'keeper') {
|
|
|
|
|
+ this.inventoryLedgerKeeperData = [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.inventoryLedgerData = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async fetchDeviceData(baseParams = this.getBaseParams()) {
|
|
|
|
|
+ if (!baseParams) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const list = await getFactoryProductionDataByDevice(baseParams);
|
|
|
|
|
+ this.deviceLedger = this.buildDeviceLedger(list);
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取各类型设备台账数据失败:', error);
|
|
|
|
|
+ this.deviceLedger = this.buildDeviceLedger([]);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ async fetchPlanData(
|
|
|
|
|
+ baseParams = this.getBaseParams(),
|
|
|
|
|
+ planTab = this.activePlanTab
|
|
|
|
|
+ ) {
|
|
|
|
|
+ if (!baseParams) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ const list = await getFactoryProductionDataByPlan({
|
|
|
|
|
+ ...baseParams,
|
|
|
|
|
+ type: this.mapPlanTabType(planTab)
|
|
|
|
|
+ });
|
|
|
|
|
+ if (planTab !== this.activePlanTab) return;
|
|
|
|
|
+ this.planRows = Array.isArray(list)
|
|
|
|
|
+ ? list.map((item) => this.mapPlanRow(item, planTab))
|
|
|
|
|
+ : [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('获取生产计划进度数据失败:', error);
|
|
|
|
|
+ if (planTab === this.activePlanTab) {
|
|
|
|
|
+ this.planRows = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -1402,7 +1595,8 @@
|
|
|
position: relative;
|
|
position: relative;
|
|
|
transform: perspective(260px) rotateX(8deg);
|
|
transform: perspective(260px) rotateX(8deg);
|
|
|
transform-origin: center bottom;
|
|
transform-origin: center bottom;
|
|
|
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.22), 0 0 12px rgba(18, 129, 214, 0.22) inset;
|
|
|
|
|
|
|
+ box-shadow: 0 8px 16px rgba(0, 0, 0, 0.22),
|
|
|
|
|
+ 0 0 12px rgba(18, 129, 214, 0.22) inset;
|
|
|
overflow: hidden;
|
|
overflow: hidden;
|
|
|
}
|
|
}
|
|
|
|
|
|