@@ -15,7 +15,25 @@ const state = { | |||
/* 能源驾驶舱 */ | |||
energy: {}, | |||
/* 效率驾驶舱 */ | |||
efficiency: {}, | |||
efficiency: { | |||
chipOee: { | |||
current: [], | |||
previous: [], | |||
}, | |||
transformRate: { | |||
current: [], | |||
previous: [], | |||
}, | |||
chipRate: { | |||
target: [], | |||
current: [], | |||
previous: [], | |||
}, | |||
stdRate: { | |||
target: [], | |||
current: [], | |||
}, | |||
}, | |||
}, | |||
home: { | |||
/** 主页状态 */ | |||
@@ -48,7 +66,10 @@ const mutations = { | |||
state.copilot.energy = payload.data; | |||
break; | |||
case "efficiency": | |||
state.copilot.efficiency = payload.data; | |||
state.copilot.efficiency.chipOee = payload.chipOee; | |||
state.copilot.efficiency.transformRate = payload.transformRate; | |||
state.copilot.efficiency.chipRate = payload.chipRate; | |||
state.copilot.efficiency.stdRate = payload.stdRate; | |||
break; | |||
} | |||
}, | |||
@@ -64,13 +85,18 @@ const actions = { | |||
}, | |||
/** 初始化驾驶舱数据 */ | |||
async initCopilot({ commit }, { period, source }) { | |||
if (source == 'comprehensive') return; | |||
if (source == "comprehensive") return; | |||
const fetcher = { | |||
yield: getCopilotYield, | |||
comprehensive: getCopilotEnergy, | |||
efficiency: getCopilotEfficiency, | |||
}[source]; | |||
const handler = { | |||
yield: splitCurrentAndPrevious, | |||
comprehensive: () => null, | |||
efficiency: splitCurrentAndPreviousA, | |||
}[source]; | |||
// 获取产量数据 | |||
let { data: factoryList, type } = await fetcher(period); | |||
let targetList = null; | |||
@@ -79,7 +105,7 @@ const actions = { | |||
let { data } = await fetcher(period, true); | |||
targetList = data; | |||
} | |||
const payload = splitCurrentAndPrevious(factoryList, targetList); | |||
const payload = handler(factoryList, targetList); | |||
commit("SET_COPILOT_INFO", { type, payload }); | |||
}, | |||
}; | |||
@@ -91,8 +117,99 @@ export default { | |||
actions, | |||
}; | |||
function splitCurrentAndPreviousA(factoryListResponse, targetListResponse) { | |||
// 初始数据 | |||
const { chipOee, transformRate, chipRate, stdRate } = initA(); | |||
factoryListResponse = [ | |||
{ | |||
factory: 0, | |||
oee: 0.8, | |||
previousYearOee: 0.7, | |||
componentConversionEfficiency: 0.8, | |||
previousYearComponentConversionEfficiency: 0.7, | |||
glassType: 0, | |||
yieldRate: 0.8, | |||
previousYearYieldRate: 0.7, | |||
chipYieldRate: 0.38, | |||
componentYieldRate: 0.73, | |||
}, | |||
{ | |||
factory: 1, | |||
oee: 0.8, | |||
previousYearOee: 0.7, | |||
componentConversionEfficiency: 0.8, | |||
previousYearComponentConversionEfficiency: 0.7, | |||
glassType: 1, | |||
yieldRate: 0.8, | |||
previousYearYieldRate: 0.7, | |||
chipYieldRate: 0.38, | |||
componentYieldRate: 0.73, | |||
}, | |||
{ | |||
factory: 2, | |||
oee: 0.8, | |||
previousYearOee: 0.7, | |||
componentConversionEfficiency: 0.8, | |||
previousYearComponentConversionEfficiency: 0.7, | |||
glassType: 1, | |||
yieldRate: 0.8, | |||
previousYearYieldRate: 0.7, | |||
chipYieldRate: 0.38, | |||
componentYieldRate: 0.73, | |||
}, | |||
{ | |||
factory: 3, | |||
oee: 0.8, | |||
previousYearOee: 0.7, | |||
componentConversionEfficiency: 0.8, | |||
previousYearComponentConversionEfficiency: 0.7, | |||
glassType: 0, | |||
yieldRate: 0.8, | |||
previousYearYieldRate: 0.7, | |||
chipYieldRate: 0.38, | |||
componentYieldRate: 0.73, | |||
}, | |||
]; | |||
if (factoryListResponse) { | |||
for (const factory of factoryListResponse) { | |||
const fId = getFactoryId(factory); | |||
// 获取目标值 | |||
if (targetListResponse) { | |||
const { | |||
chipYieldRate, | |||
componentYieldRate, | |||
chipOee, | |||
componentConversionEfficiency, | |||
} = getFactoryTargetValueA(targetListResponse, fId); | |||
stdRate.target[fId] = chipYieldRate; | |||
chipRate.target[fId] = componentYieldRate; | |||
} | |||
// 芯片OEE | |||
chipOee.current[fId] = factory.oee || random_default(); | |||
chipOee.previous[fId] = factory.previousYearOee || random_default(); | |||
// 转化效率 | |||
transformRate.current[fId] = | |||
factory.componentConversionEfficiency || random_default(); | |||
transformRate.previous[fId] = | |||
factory.previousYearComponentConversionEfficiency || random_default(); | |||
// 芯片良率 与 标准组件良率 | |||
if (![0, 1].includes(factory.glassType)) continue; | |||
const _t = [chipRate, stdRate][factory.glassType]; | |||
_t.current[fId] = factory.yieldRate || random_default(); | |||
_t.previous[fId] = factory.previousYearYieldRate || random_default(); | |||
} | |||
return { | |||
chipOee, | |||
transformRate, | |||
chipRate, | |||
stdRate, | |||
}; | |||
} | |||
} | |||
function splitCurrentAndPrevious(factoryListResponse, targetListResponse) { | |||
// 初始数据 | |||
// 初始数据 | |||
const { chipInvest, ftoInvest, chipOutput, stdOutput, bipvOutput } = init(); | |||
if (factoryListResponse) { | |||
for (const factory of factoryListResponse) { | |||
@@ -152,8 +269,57 @@ function getFactoryTargetValue(targetList, factoryId) { | |||
} | |||
/** | |||
* | |||
* @returns 初始化状态值 | |||
* 获取 芯片良率目标值 和 标准组件良率目标值 | |||
* @param {*} targetList 目标值列表 | |||
* @param {*} factoryId 工厂ID | |||
* @returns | |||
*/ | |||
function getFactoryTargetValueA(targetList, factoryId) { | |||
const target = targetList.find((item) => item.factory === factoryId); | |||
if (target) { | |||
return { | |||
chipYieldRate: target.chipYieldRate ?? random_default(), | |||
componentYieldRate: target.componentYieldRate ?? random_default(), | |||
}; | |||
} | |||
return { | |||
chipYieldRate: random_default(), | |||
componentYieldRate: random_default(), | |||
}; | |||
} | |||
/** | |||
* | |||
* @returns 初始化 效率模块里 初始状态值 | |||
*/ | |||
function initA() { | |||
const t_ = { | |||
current: Array(7).fill(0), | |||
previous: Array(7).fill(0), | |||
}; | |||
// 芯片OEE | |||
const chipOee = deepClone(t_); | |||
// 转化效率 | |||
const transformRate = deepClone(t_); | |||
// 标准组件良率 | |||
const stdRate = { | |||
...deepClone(t_), | |||
target: Array(7).fill(0), | |||
}; | |||
// 芯片良率 | |||
const chipRate = deepClone(stdRate); | |||
return { | |||
chipOee, | |||
transformRate, | |||
chipRate, | |||
stdRate, | |||
}; | |||
} | |||
/** | |||
* | |||
* @returns 初始化 产量模块里 初始状态值 | |||
*/ | |||
function init() { | |||
const t_ = { | |||
@@ -183,11 +349,11 @@ function init() { | |||
}; | |||
} | |||
function random_default() { | |||
return 0; | |||
let a = Math.floor(Math.random() * 1000); | |||
while (a < 600) { | |||
a = Math.floor(Math.random() * 1000); | |||
function random_default(min = 0, max = 1) { | |||
// return 0; | |||
let a = Math.floor(Math.random() * max); | |||
while (a < min) { | |||
a = Math.floor(Math.random() * max); | |||
} | |||
return a; | |||
} | |||
@@ -256,10 +422,10 @@ async function doFetch(copilot_module = "yield", fetch_target, params) { | |||
} | |||
/** | |||
* | |||
* | |||
* @param {*} period 日周月年1,2,3,4 | |||
* @param {*} target 是否获取目标数据 | |||
* @returns | |||
* @returns | |||
*/ | |||
function getCopilotYield(period, target = false) { | |||
return getCopilotData("yield", period, target); | |||
@@ -7,8 +7,16 @@ | |||
<template> | |||
<div class="chip-rate"> | |||
<ChipRateItem :cities="['成都', '邯郸', '株洲', '瑞昌']" :color="1" /> | |||
<ChipRateItem :cities="['佳木斯', '凯盛光伏', '蚌埠兴科']" :color="2" /> | |||
<ChipRateItem | |||
:period="period" | |||
:cities="['成都', '邯郸', '株洲', '瑞昌']" | |||
:color="1" | |||
/> | |||
<ChipRateItem | |||
:period="period" | |||
:cities="['佳木斯', '凯盛光伏', '蚌埠兴科']" | |||
:color="2" | |||
/> | |||
</div> | |||
</template> | |||
@@ -17,7 +25,12 @@ import ChipRateItemVue from "./sub/chip/ChipRateItem.vue"; | |||
export default { | |||
name: "ChipRate", | |||
components: { ChipRateItem: ChipRateItemVue }, | |||
props: {}, | |||
props: { | |||
period: { | |||
type: String, | |||
default: "日", | |||
}, | |||
}, | |||
data() { | |||
return {}; | |||
}, | |||
@@ -11,14 +11,10 @@ | |||
<CopilotButtons :options="cities" @update:active="handleCityUpdate" /> | |||
</div> | |||
<div class="chart" ref="chart"></div> | |||
<div class="legend" v-if="1"> | |||
<div class="legend-item"> | |||
<span class="legend-item__value">20%</span> | |||
<span class="legend-item__label">2023年累计</span> | |||
</div> | |||
<div class="legend-item"> | |||
<span class="legend-item__value">20%</span> | |||
<span class="legend-item__label">2024年累计</span> | |||
<div class="legend" v-if="period == '月' || period == '年'"> | |||
<div class="legend-item" v-for="lgd in legend" :key="lgd.label"> | |||
<span class="legend-item__value">{{ lgd.value }}</span> | |||
<span class="legend-item__label">{{ lgd.label }}</span> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -29,6 +25,7 @@ import CopilotButtons from "@/views/copilot/components/select.vue"; | |||
import chartMixin from "@/mixins/chart.js"; | |||
import fullscreenMixin from "@/mixins/fullscreen.js"; | |||
import getOptions from "../../../options/chipOptions.js"; | |||
import { mapGetters } from "vuex"; | |||
export default { | |||
name: "ChipRateItem", | |||
@@ -43,44 +40,102 @@ export default { | |||
type: Number, | |||
default: 1, | |||
}, | |||
period: { | |||
type: String, | |||
default: "日", | |||
}, | |||
}, | |||
data() { | |||
return { | |||
period: "月", | |||
valueTuple: [100, 100, 200], | |||
factoryId: 0, | |||
count: 1, | |||
}; | |||
}, | |||
computed: { | |||
chipRate() { | |||
return this.$store.getters.copilot.efficiency.chipRate; | |||
}, | |||
valueTuple() { | |||
const getter = this.chipRate; | |||
if (this.period === "日" || this.period === "周") { | |||
return [ | |||
getter.previous[this.factoryId], | |||
getter.current[this.factoryId], | |||
0, | |||
]; | |||
} | |||
// [100, 200, 200] | |||
return [ | |||
getter.previous[this.factoryId], | |||
getter.current[this.factoryId], | |||
getter.target[this.factoryId], | |||
]; | |||
}, | |||
options() { | |||
const single = this.period === "日" || this.period === "周"; | |||
const year = new Date().getFullYear(); | |||
const month = new Date().getMonth() + 1; | |||
const vt = this.valueTuple; | |||
let titleValue = | |||
vt[0] != null && vt[2] != null && vt[2] !== 0 | |||
? `${((vt[1] / vt[2]) * 100).toFixed(0)}%` | |||
: "0%", | |||
subtitle = | |||
this.period == "月" ? `${month}月累计产出` : `${year}年累计产出`; | |||
let titleValue = single | |||
? (vt[1] != null && `${vt[1] * 100}%`) || "0%" | |||
: vt[0] != null && vt[2] != null && vt[2] !== 0 | |||
? `${((vt[1] / vt[2]) * 100).toFixed(0)}%` | |||
: "0%", | |||
subtitle = { | |||
日: "本日良率", | |||
周: "本周良率", | |||
月: `${month}月良率`, | |||
年: `${year}良率`, | |||
}[this.period]; | |||
return getOptions({ | |||
single: true, | |||
const t = getOptions({ | |||
single, | |||
color: this.color == 1 ? "#4CF0E8" : "#1065ff", | |||
titleValue, | |||
subtitle, | |||
previousSum: this.valueTuple[0], | |||
currentSum: this.valueTuple[1], | |||
targetSum: this.valueTuple[2], | |||
previousSum: vt[0], | |||
currentSum: vt[1], | |||
targetSum: vt[2], | |||
}); | |||
return t; | |||
}, | |||
legend() { | |||
const year = new Date().getFullYear(); | |||
const month = new Date().getMonth() + 1; | |||
return [ | |||
{ | |||
label: | |||
this.period == "月" | |||
? `${year - 1}年${month}月良率` | |||
: `${year - 1}年良率`, | |||
value: (this.valueTuple[0] * 100).toFixed(0) + "%", | |||
}, | |||
{ | |||
label: this.period == "月" ? `${month}月良率` : `${year}年良率`, | |||
value: (this.valueTuple[1] * 100).toFixed(0) + "%", | |||
}, | |||
]; | |||
}, | |||
}, | |||
mounted() { | |||
this.initOptions(this.options); | |||
}, | |||
watch: { | |||
period() { | |||
this.initOptions(this.options); | |||
}, | |||
factoryId() { | |||
this.initOptions(this.options); | |||
}, | |||
chipRate() { | |||
this.initOptions(this.options); | |||
}, | |||
}, | |||
methods: { | |||
handleCityUpdate() {}, | |||
fullscreenCallback(isFullscreen) { | |||
console.log("isFullscreen--->", isFullscreen); | |||
handleCityUpdate(id) { | |||
this.factoryId = id; | |||
}, | |||
fullscreenCallback(isFullscreen) {}, | |||
}, | |||
}; | |||
</script> | |||
@@ -8,10 +8,10 @@ | |||
<template> | |||
<div class="efficiency-copilot"> | |||
<Container title="芯片良率" icon="chip2"> | |||
<ChipRate /> | |||
<ChipRate :period="period" /> | |||
</Container> | |||
<Container title="标准组件良率" icon="std"> | |||
<StdRate /> | |||
<StdRate :period="period" /> | |||
</Container> | |||
<Container title="芯片OEE" icon="chip"> | |||
<ChipOee :period="period" /> | |||
@@ -15,7 +15,11 @@ export default function ({ | |||
top: 0, | |||
containLabel: true, | |||
}, | |||
tooltip: {}, | |||
tooltip: { | |||
// formatter(params) { | |||
// return `${params.name}: ${(params.value * 100).toFixed(0)}%`; | |||
// } | |||
}, | |||
title: { | |||
text: titleValue, | |||
left: "49%", | |||
@@ -60,7 +64,7 @@ export default function ({ | |||
data: [ | |||
{ | |||
value: currentSum, | |||
name: "当前累计产出", | |||
name: "当前良率", | |||
selected: false, | |||
itemStyle: { | |||
borderJoin: "round", | |||
@@ -93,9 +97,9 @@ export default function ({ | |||
? currentSum == 0 | |||
? 1 | |||
: 0 | |||
: 0, | |||
: targetSum, | |||
name: "未达成累计", | |||
name: "未达成", | |||
itemStyle: { color: "transparent" }, | |||
label: { show: false }, | |||
}, | |||
@@ -118,7 +122,7 @@ export default function ({ | |||
data: [ | |||
{ | |||
value: previousSum, | |||
name: "上期累计产出", | |||
name: "上期良率", | |||
selected: false, | |||
itemStyle: { | |||
borderJoin: "round", | |||
@@ -146,6 +150,9 @@ export default function ({ | |||
? 1 | |||
: 0, | |||
name: "-", | |||
formatter: { | |||
show: false | |||
}, | |||
itemStyle: { color: "transparent" }, | |||
label: { show: false }, | |||
}, | |||