update 产品质量分析chart

This commit is contained in:
lb 2023-09-19 17:06:19 +08:00
parent c965dfbc5a
commit 71bcd14c72
4 changed files with 289 additions and 81 deletions

View File

@ -50,36 +50,46 @@ export default {
data() { data() {
return { return {
searchBarKeys: ['name', 'code'], searchBarKeys: ['name', 'code'],
// tableBtn: [
// this.$auth.hasPermi('base:equipment-group:update')
// ? {
// type: 'edit',
// btnName: '',
// }
// : undefined,
// this.$auth.hasPermi('base:equipment-group:delete')
// ? {
// type: 'delete',
// btnName: '',
// }
// : undefined,
// ].filter((v) => v),
tableBtn: [ tableBtn: [
this.$auth.hasPermi('base:equipment-group:update') {
? {
type: 'edit', type: 'edit',
btnName: '修改', btnName: '修改',
} },
: undefined, {
this.$auth.hasPermi('base:equipment-group:delete')
? {
type: 'delete', type: 'delete',
btnName: '删除', btnName: '删除',
} },
: undefined, ],
].filter((v) => v),
tableProps: [ tableProps: [
{ prop: 'lineName', label: '产线' }, { prop: 'lineName', label: '产线' },
{ prop: 'sectionName', label: '工段' }, { prop: 'sectionName', label: '工段' },
{ prop: 'equipmentName', label: '设备' }, { prop: 'equipmentName', label: '设备' },
{ {
width: 188, width: 240,
prop: 'mtbf', prop: 'mtbf',
label: '平均故障间隔时间[MTBF](h)', label: '平均故障间隔时间[MTBF](h)',
}, },
{ {
width: 180, width: 240,
prop: 'mttr', prop: 'mttr',
label: '平均维修时间[MTTR](h)', label: '平均维修时间[MTTR](h)',
}, },
{ prop: 'workTime', label: '工作时长(h)' }, { width: 128, prop: 'workTime', label: '工作时长(h)' },
{ prop: 'downTime', label: '故障时长(h)' }, { width: 128, prop: 'downTime', label: '故障时长(h)' },
{ prop: 'downCount', label: '故障次数' }, { prop: 'downCount', label: '故障次数' },
], ],
searchBarFormConfig: [ searchBarFormConfig: [
@ -111,6 +121,8 @@ export default {
], ],
// //
queryParams: { queryParams: {
pageNo: 1,
pageSize: 10,
lineId: null, lineId: null,
factoryId: null, factoryId: null,
recordTime: null, recordTime: null,

View File

@ -15,27 +15,143 @@ import * as echarts from 'echarts';
export default { export default {
name: 'LineChart', name: 'LineChart',
components: {}, components: {},
props: ['config'], props: ['config', 'list'],
data() { data() {
return { return {
chart: null, chart: null,
}; };
}, },
computed: {}, // watch: {
// list: {
// handler(listdata) {
// if (listdata && listdata.length) {
// console.log('[linechart] list changed', listdata);
// const option = this.handleList(listdata);
// this.setOption(option);
// }
// },
// immediate: true,
// },
// },
computed: {
option() {
const opt = [];
this.list.map((eq) => {
/** [设备名, ok数量, 不ok数量] */
opt.push([eq.equipmentName, eq.okQuantity, eq.nokQuantity]);
});
return {
color: ['#8EF0AB', '#288AFF'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
legend: {
itemWidth: 12,
itemHeight: 12,
right: 0,
},
grid: {
left: '1%',
right: '1%',
top: '8%',
bottom: '3%',
containLabel: true,
},
// xAxis: [
// {
// type: 'category',
// data: ['1', '2', '3', '4', '5'],
// },
// ],
// yAxis: [
// {
// type: 'value',
// splitLine: {
// lineStyle: {
// color: '#0001',
// },
// },
// },
// ],
xAxis: {
type: 'category',
axisTick: { show: false },
data: opt.map((item) => item[0]),
},
yAxis: {
type: 'value',
splitLine: {
lineStyle: {
color: '#0001',
},
},
},
series: [
{
name: '不合格数量',
type: 'bar',
barWidth: 20,
stack: 's',
data: opt.map((item) => item[2]),
},
{
name: '合格数量',
type: 'bar',
barWidth: 20,
stack: 's',
data: opt.map((item) => item[1]),
},
],
};
},
},
mounted() { mounted() {
console.log('[linechart] mounted');
this.init(); this.init();
}, },
beforeDestroy() { beforeDestroy() {
if (this.chart) { if (this.chart) {
this.chart.dispose(); this.chart.dispose();
} }
console.log('[linechart] destroyed');
}, },
methods: { methods: {
init() { init() {
console.log('thsi el', this.$el);
if (!this.chart) this.chart = echarts.init(this.$el); if (!this.chart) this.chart = echarts.init(this.$el);
this.chart.setOption(this.config); console.log('[linechart] initialized', this.$el);
this.$nextTick(() => {
this.setOption();
});
}, },
setOption() {
if (this.chart) this.chart.setOption(this.option);
console.log('[linechart] option settled');
},
// handleList(list) {
// /** */
// this.option.series[0].data.splice(0);
// this.option.series[1].data.splice(0);
// this.option.xAxis.data.splice(0);
// list.map((eq) => {
// this.option.xAxis.data.push(eq.equipmentName);
// this.option.series[0].data.push(eq.nokQuantity);
// this.option.series[1].data.push(eq.okQuantity);
// });
// this.setOption();
// // const pureList = list.map((eq) => ({
// // name: eq.equipmentName,
// // ok: eq.okQuantity,
// // nok: eq.nokQuantity,
// // }));
// },
}, },
}; };
</script> </script>
@ -43,7 +159,7 @@ export default {
<style scoped lang="scss"> <style scoped lang="scss">
.line-chart { .line-chart {
padding: 0 12px; padding: 0 12px;
background: #e1e1e1; height: 1px;
min-height: 320px; flex: 1;
} }
</style> </style>

View File

@ -13,6 +13,13 @@
ref="search-bar" ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" /> @headBtnClick="handleSearchBarBtnClick" />
<el-row>
<el-col class="custom-tabs">
<el-tabs
v-model="activeName"
:stretch="true"
@tab-click="handleTabClick">
<el-tab-pane label="数据列表" name="table">
<!-- 列表 --> <!-- 列表 -->
<base-table <base-table
:table-props="tableProps" :table-props="tableProps"
@ -20,17 +27,16 @@
:limit="queryParams.pageSize" :limit="queryParams.pageSize"
:table-data="list" :table-data="list"
@emitFun="handleEmitFun"></base-table> @emitFun="handleEmitFun"></base-table>
</el-tab-pane>
<!-- 图形分析 dialog --> <el-tab-pane label="柱状图" name="graph">
<!-- <base-dialog <div v-if="activeName == 'graph'" class="graph" style="height: 40vh; display: flex; flex-direction: column;">
dialogTitle="图形视角" <div class="blue-title">各设备加工数量</div>
:dialogVisible="dialogVisible" <LineChart :list="list" />
width="60%" </div>
@close="dialogClose" </el-tab-pane>
@cancel="dialogClose" </el-tabs>
@confirm="dialogClose"> </el-col>
<LineChart v-if="dialogVisible" :config="lineChartConfig" /> </el-row>
</base-dialog> -->
</div> </div>
</template> </template>
@ -50,7 +56,7 @@ export default {
urls: { urls: {
page: '/analysis/equipment-analysis/quality', page: '/analysis/equipment-analysis/quality',
}, },
mode: 'table', // defaults to 'table' activeName: 'table', // defaults to 'table'
searchBarFormConfig: [ searchBarFormConfig: [
// //
{ {
@ -242,6 +248,11 @@ export default {
this.getList(); this.getList();
}, },
methods: { methods: {
handleTabClick(tab, event) {
// console.log('tab event', tab, event);
// tab is el-tab vue component.
},
async fillLineOptions() { async fillLineOptions() {
const { data } = await this.$axios({ const { data } = await this.$axios({
url: '/base/production-line/listAll', url: '/base/production-line/listAll',
@ -353,4 +364,38 @@ export default {
} }
} }
} }
:deep(.custom-tabs) {
.el-tabs__header {
margin-bottom: 8px;
display: inline-block;
transform: translateY(-12px);
}
.el-tabs__item {
padding-left: 8px !important;
padding-right: 8px !important;
line-height: 36px !important;
height: 36px;
}
}
.blue-title {
position: relative;
padding: 4px 0;
padding-left: 12px;
font-size: 14px;
&::before {
content: "";
position: absolute;
left: 0;
top: 6px;
height: 16px;
width: 4px;
border-radius: 1px;
background: #0b58ff;
}
}
</style> </style>

View File

@ -10,6 +10,7 @@
<div <div
class="app-container" class="app-container"
style="margin-right: 12px; border-radius: 8px; background: #fff"> style="margin-right: 12px; border-radius: 8px; background: #fff">
<div class="factory-list" style="background: #ccc; height: 36px"></div>
<!-- side bar --> <!-- side bar -->
<div <div
class="side-bar__left" class="side-bar__left"
@ -30,7 +31,10 @@
ref="search-bar" ref="search-bar"
@headBtnClick="handleSearchBarBtnClick" /> @headBtnClick="handleSearchBarBtnClick" />
<transition appear name="vvv" mode="out-in"> <el-row>
<el-col class="custom-tabs">
<el-tabs v-model="activeName" @tab-click="handleTabClick">
<el-tab-pane label="数据列表" name="table">
<base-table <base-table
v-if="mode == 'table'" v-if="mode == 'table'"
:table-props="tableProps" :table-props="tableProps"
@ -45,13 +49,27 @@
:method-list="tableBtn" :method-list="tableBtn"
@clickBtn="handleTableBtnClick" /> --> @clickBtn="handleTableBtnClick" /> -->
</base-table> </base-table>
</el-tab-pane>
<div class="graph" style="height: 56vh;" v-else> <el-tab-pane label="柱状图" name="graph">
<div class="graph" style="height: 56vh">
<!-- graph --> <!-- graph -->
<Graph v-if="list.length" :equipment-list="list" /> <Graph v-if="list.length" :equipment-list="list" />
<div v-else style="color: #c7c7c7; text-align: center; margin-top: 20px;">没有设备</div> <div
v-else
style="
color: #c7c7c7;
text-align: center;
margin-top: 20px;
">
没有设备
</div> </div>
</transition> </div>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
<!-- <transition appear name="vvv" mode="out-in"></transition> -->
</div> </div>
</div> </div>
</div> </div>
@ -152,6 +170,7 @@ export default {
// ], // ],
// }, // },
], ],
activeName: 'table',
searchBarFormConfig: [ searchBarFormConfig: [
{ {
type: 'datePicker', type: 'datePicker',
@ -172,23 +191,23 @@ export default {
name: 'search', name: 'search',
color: 'primary', color: 'primary',
}, },
{ // {
type: 'separate', // type: 'separate',
}, // },
{ // {
type: 'button', // type: 'button',
btnName: '表格', // btnName: '',
name: 'table', // name: 'table',
plain: true, // plain: true,
color: 'success', // color: 'success',
}, // },
{ // {
type: 'button', // type: 'button',
btnName: '图表', // btnName: '',
name: 'graph', // name: 'graph',
plain: true, // plain: true,
color: 'warning', // color: 'warning',
}, // },
// { // {
// type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '', // type: this.$auth.hasPermi('base:equipment-group:export') ? 'button' : '',
// btnName: '', // btnName: '',
@ -197,11 +216,11 @@ export default {
// }, // },
], ],
tableProps: [ tableProps: [
{ prop: 'lineName', label: '产线', }, { prop: 'lineName', label: '产线' },
{ prop: 'sectionName', label: '工段', }, { prop: 'sectionName', label: '工段' },
{ prop: 'externalCode', label: '设备编码', }, { prop: 'externalCode', label: '设备编码' },
{ prop: 'equipmentName', label: '设备名称', }, { prop: 'equipmentName', label: '设备名称' },
{ prop: 'totalQuantity', label: '加工数量', }, { prop: 'totalQuantity', label: '加工数量' },
], ],
mode: 'table', // table | graph mode: 'table', // table | graph
queryParams: { queryParams: {
@ -258,7 +277,11 @@ export default {
const { data } = await this.$axios('/base/factory/getTree'); const { data } = await this.$axios('/base/factory/getTree');
this.sidebarContent = data; this.sidebarContent = data;
this.buildTree(data); this.buildTree(data);
console.log('tree', this.sidebarContent) console.log('tree', this.sidebarContent);
},
handleTabClick(tab, event) {
console.log('handle tab click: ', tab, event);
}, },
handleSidebarItemClick({ label, id, type }) { handleSidebarItemClick({ label, id, type }) {
@ -339,4 +362,16 @@ export default {
/* transform: translateY(0) scaleY(1); */ /* transform: translateY(0) scaleY(1); */
transform: translateY(0); transform: translateY(0);
} }
.custom-tabs >>> .el-tabs__header {
margin-bottom: 8px;
display: inline-block;
transform: translateY(-12px);
}
.custom-tabs >>> .el-tabs__item {
padding-left: 8px !important;
padding-right: 8px !important;
line-height: 36px !important;
height: 36px;
}
</style> </style>