<!-- filename: index.vue author: liubin date: 2023-09-04 09:34:52 description: 设备质量分析 --> <template> <div class="app-container" style="flex: 1; height: 1px; display: flex; flex-direction: column;"> <!-- 搜索工作栏 --> <SearchBar :formConfigs="searchBarFormConfig" ref="search-bar" @headBtnClick="handleSearchBarBtnClick" /> <el-row type="flex" style="flex: 1;"> <el-col class="custom-tabs" style="flex: 1;"> <el-tabs v-model="activeName" :stretch="true" @tab-click="handleTabClick"> <el-tab-pane :label="'数据列表'" name="table"> <!-- 列表 --> <base-table :table-props="tableProps" :page="queryParams.pageNo" :limit="queryParams.pageSize" :table-data="list" @emitFun="handleEmitFun" :max-height="tableH"></base-table> </el-tab-pane> <el-tab-pane :label="'\u3000柱状图\u3000'" name="graph"> <div v-if="activeName == 'graph'" class="graph" style="height: 100%; display: flex; flex-direction: column"> <div class="blue-title">各设备加工数量</div> <LineChart v-if="list && list.length" :list="list" /> <div v-else class="no-data-bg"></div> </div> </el-tab-pane> </el-tabs> </el-col> </el-row> </div> </template> <script> import moment from 'moment'; import LineChart from './components/lineChart.vue'; export default { name: 'QualityAnalysis', components: { LineChart }, props: {}, data() { const now = new Date(); const [y, m, d] = [now.getFullYear(), now.getMonth(), now.getDate()]; return { dialogVisible: false, tableH: this.tableHeight(260), urls: { page: '/analysis/equipment-analysis/quality', }, activeName: 'table', // defaults to 'table' searchBarFormConfig: [ // 产品 // { // __index: 'product', // type: 'select', // label: '产品', // placeholder: '请选择产品', // param: 'productId', // }, // 产线 { __index: 'line', type: 'select', label: '产线', placeholder: '请选择产线', param: 'lineId', }, // 时间段 { type: 'datePicker', label: '时间段', dateType: 'daterange', // datetimerange // format: 'yyyy-MM-dd HH:mm:ss', format: 'yyyy-MM-dd', // valueFormat: 'timestamp', valueFormat: 'yyyy-MM-dd HH:mm:ss', rangeSeparator: '-', startPlaceholder: '开始日期', endPlaceholder: '结束日期', defaultTime: ['00:00:00', '23:59:59'], param: 'recordTime', defaultSelect: [ new Date(y, m, d) .toLocaleString() .split('/') .map((item, index) => { if (index == 1 || index == 2) return item.padStart(2, '0'); return item; }) .join('-'), new Date(y, m, d, 23, 59, 59) .toLocaleString() .split('/') .map((item, index) => { if (index == 1 || index == 2) return item.padStart(2, '0'); return item; }) .join('-'), ], }, { type: 'button', btnName: '查询', name: 'search', color: 'primary', }, // { // type: 'separate', // }, // { // type: 'button', // btnName: '列表数据', // name: 'tableVersion', // color: 'text btn-table', // }, // { // type: 'separate', // }, // { // type: 'button', // btnName: '图形分析', // name: 'graphVersion', // color: 'text btn-graph', // }, ], // 动态的 props tableProps: [ { // width: 160, prop: 'sectionName', label: '工段', }, { // width: 160, prop: 'equipmentName', label: '设备名称', }, { // width: 160, prop: 'products', label: '产品名称', }, { // width: 160, prop: 'totalQuantity', label: '加工数量', }, { // width: 160, prop: 'okQuantity', label: '合格数量', }, { // width: 160, prop: 'nokQuantity', label: '不合格数量', }, { // width: 160, prop: 'passRate', label: '合格率', }, ], lineChartConfig: { grid: { top: 88, left: 56, right: 56, bottom: 56, }, legend: { top: 0, left: 0, padding: 5, icon: 'roundRect', itemWidth: 12, itemHeight: 12, itemGap: 20, textStyle: { fontSize: 14, lineHeight: 14, }, }, xAxis: { type: 'category', data: ['设备1', '设备2', '设备3', '设备4', '设备5'], }, yAxis: { type: 'value', name: '合格率', nameLocation: 'end', nameTextStyle: { fontSize: 14, align: 'right', }, nameGap: 26, }, series: [ { name: '产线1', data: [150, 230, 224, 218, 135], type: 'line', smooth: true, }, { name: '产线2', data: [111, 224, 42, 11, 24], type: 'line', smooth: true, }, { name: '产线3', data: [218, 112, 331, 44, 99], type: 'line', smooth: true, }, { name: '产线4', data: [3, 221, 42, 553, 311], type: 'line', smooth: true, }, ], }, // 查询参数 queryParams: { pageNo: 1, pageSize: 10, lineId: null, productId: null, recordTime: [], }, list: [], }; }, computed: {}, created() { this.fillLineOptions(); this.fillProductOptions(); }, mounted() { window.addEventListener('resize', () => { this.tableH = this.tableHeight(260) }) this.$refs['search-bar'].headBtnClick('search'); }, methods: { handleTabClick(tab, event) { // console.log('tab event', tab, event); // tab is el-tab vue component. }, async fillLineOptions() { const { data } = await this.$axios({ url: '/base/core-production-line/listAll', method: 'get', }); const cfg = this.searchBarFormConfig.find( (item) => item.__index == 'line' ); this.$set( cfg, 'selectOptions', data.map((item) => ({ id: item.id, name: item.name, })) ); }, async fillProductOptions() { const { data } = await this.$axios({ url: '/base/core-product/listAll', method: 'get', }); const cfg = this.searchBarFormConfig.find( (item) => item.__index == 'product' ); this.$set( cfg, 'selectOptions', data.map((item) => ({ id: item.id, name: item.name, })) ); }, async getList() { const { data } = await this.$axios({ url: '/analysis/equipment-analysis/quality', method: 'get', params: { lineId: this.queryParams.lineId || null, productId: this.queryParams.productId || null, recordTime: this.queryParams.recordTime || null, }, }); this.list = data.map((item) => ({ ...item, products: item.products?.join(','), })); }, handleSearchBarBtnClick(btn) { // debugger; switch (btn.btnName) { case 'search': this.queryParams.lineId = btn.lineId; this.queryParams.productId = btn.productId; this.queryParams.recordTime = btn.recordTime ? btn.recordTime.map((time) => moment(new Date(time)).format('YYYY-MM-DD HH:mm:ss') ) : null; this.$nextTick(() => { this.getList(); }); break; case 'tableVersion': this.dialogClose(); break; case 'graphVersion': this.dialogShow(); break; } }, handleEmitFun({ action, payload }) {}, dialogShow() { this.dialogVisible = true; }, dialogClose() { this.dialogVisible = false; }, }, }; </script> <style scoped lang="scss"> :deep(.searchBar) { .el-button.btn-table { color: rgb(0, 130, 130); border: 1px solid rgb(0, 130, 130); padding: 8px 10px; border: 1px solid rgb(0, 130, 130); padding: 8px 10px; &:hover { border-color: #fff; color: #fff; background: rgb(0, 130, 130); } } .el-button.btn-graph { color: rgb(130, 0, 130); border: 1px solid rgb(130, 0, 130); padding: 8px 10px; &:hover { border-color: #fff; color: #fff; background: rgb(130, 0, 130); } } } :deep(.custom-tabs) { .el-tabs { height: 100%; } .el-tabs__header { margin-bottom: 8px; display: inline-block; transform: translateY(-12px); } .el-tabs__item { padding-left: 0 !important; padding-right: 0 !important; line-height: 36px !important; height: 36px; } .el-tabs__content { height: calc(100% - 48px); } #pane-graph { height: 100%; } } .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>