diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdProcessVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdProcessVo.java index a23650fed..04f6d3832 100644 --- a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdProcessVo.java +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdProcessVo.java @@ -7,6 +7,8 @@ import com.klp.common.annotation.ExcelDictFormat; import com.klp.common.convert.ExcelDictConvert; import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import java.util.Date; import java.util.List; @@ -47,6 +49,19 @@ public class SchProdProcessVo { @ExcelProperty(value = "备注") private String remark; + /** + * 创建者 + */ + @ExcelProperty(value = "创建者") + private String createBy; + + /** + * 创建时间 + */ + @ExcelProperty(value = "创建时间") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + /** * 工艺步骤列表 */ diff --git a/klp-ui/src/views/cost/comprehensive.vue b/klp-ui/src/views/cost/comprehensive.vue index 53073a236..1c08f505e 100644 --- a/klp-ui/src/views/cost/comprehensive.vue +++ b/klp-ui/src/views/cost/comprehensive.vue @@ -23,6 +23,7 @@ 列配置 价格管理 异常分析 + 折线图统计 {{ inputMode ? '录入' : '查看' }} @@ -334,6 +335,16 @@ + + + + + + + + + + @@ -352,6 +363,7 @@ import { listProductionLine } from "@/api/wms/productionLine" import { listRollGrindAll } from "@/api/mes/roll/rollGrind" import { listEnergyRecord, addEnergyRecord, updateEnergyRecord } from "@/api/ems/energyRecord" import AnomalyAnalysis from "./components/AnomalyAnalysis" +import * as echarts from 'echarts' function parseDateRange(detailDate) { const d = (detailDate || '').slice(0, 10) @@ -485,7 +497,8 @@ export default { priceOpen: false, priceList: [], priceSaving: false, backfilling: false, progressOpen: false, progressTitle: '', progressTasks: [], - anomalyOpen: false, anomalyMap: {} + anomalyOpen: false, anomalyMap: {}, + chartOpen: false, _chartInstances: [] } }, computed: { @@ -575,6 +588,17 @@ export default { }, tableData() { return [...this.summaryRows, ...this.gridRows] + }, + chartDataCols() { + if (!this.gridRows.length) return [] + return this.displayCols.filter(col => { + if (col.$type === 'detail') { + const key = 'q' + col.itemId + return this.gridRows.some(r => r[key] != null) + } + const key = 'mv' + col.mIdx + return this.gridRows.some(r => r[key] != null) + }) } }, watch: { configOpen(v) { if (!v) this.rpOpen = false } }, @@ -1144,7 +1168,7 @@ export default { }, /* helpers */ - async loadLines() { const r = await listProductionLine({ pageSize: 999 }); this.lineOptions = r.rows || [] }, + async loadLines() {const r = await listProductionLine({ pageSize: 999 }); this.lineOptions = r.rows || [] }, lineName(row) { if (row.lineType) { const found = this.lineOptions.find(l => l.lineId == row.lineType); @@ -1173,6 +1197,60 @@ export default { if (!set) return false return set.has(String(itemId)) }, + + /* charts */ + buildChartOption(col) { + const rows = this.gridRows.filter(r => r.detailDate).sort((a,b) => a.detailDate.localeCompare(b.detailDate)) + const dates = rows.map(r => r.detailDate.slice(0,10)) + const makeOption = (title, series) => ({ + title: { text: title, left: 'center', textStyle: { fontSize: 12 } }, + tooltip: { trigger: 'axis' }, + legend: series.length > 1 ? { top: 'bottom', textStyle: { fontSize: 11 } } : undefined, + xAxis: { type: 'category', data: dates, axisLabel: { rotate: 30, fontSize: 10 } }, + yAxis: { type: 'value', axisLabel: { fontSize: 10 } }, + grid: { left: 50, right: 16, top: 36, bottom: 40 }, + series + }) + if (col.$type === 'detail') { + const label = (col.itemName || col.itemCode) + (col.unit ? '('+col.unit+')' : '') + if (col.isShift) { + return makeOption(label, [ + { name: '甲班', type: 'line', data: rows.map(r => { const v = parseFloat(r['q'+col.itemId+'_1']); return isNaN(v) ? 0 : v }), smooth: true }, + { name: '乙班', type: 'line', data: rows.map(r => { const v = parseFloat(r['q'+col.itemId+'_2']); return isNaN(v) ? 0 : v }), smooth: true } + ]) + } + return makeOption(label, [{ type: 'line', data: rows.map(r => { const v = parseFloat(r['q'+col.itemId]); return isNaN(v) ? 0 : v }), smooth: true }]) + } + // metric + const label = (col.metricName || '') + (col.unit ? '('+col.unit+')' : '') + if (col.isShift) { + return makeOption(label, [ + { name: '甲班', type: 'line', data: rows.map(r => { const v = parseFloat(r['mv'+col.mIdx+'_1']); return isNaN(v) ? 0 : v }), smooth: true }, + { name: '乙班', type: 'line', data: rows.map(r => { const v = parseFloat(r['mv'+col.mIdx+'_2']); return isNaN(v) ? 0 : v }), smooth: true } + ]) + } + return makeOption(label, [{ type: 'line', data: rows.map(r => { const v = parseFloat(r['mv'+col.mIdx]); return isNaN(v) ? 0 : v }), smooth: true }]) + }, + renderCharts() { + this.disposeCharts() + this.$nextTick(() => { + this._chartInstances = [] + this.chartDataCols.forEach((col, idx) => { + const el = this.$refs['chart_'+idx] + if (!el || !el[0]) return + const chart = echarts.init(el[0]) + chart.setOption(this.buildChartOption(col)) + this._chartInstances.push(chart) + }) + }) + }, + disposeCharts() { + if (this._chartInstances) { + this._chartInstances.forEach(c => c.dispose()) + this._chartInstances = [] + } + }, + async loadItems() { if (!this.allItems.length) { const r = await listItem({ pageNum:1, pageSize:999 }); this.allItems = r.rows || [] } }, async loadAllMetrics(rid) { const q = { pageNum:1, pageSize:99999 }; if (rid) q.reportId = rid @@ -1231,4 +1309,9 @@ export default { /deep/ .summary-row td .cell { color: #303133; } .summary-label { font-weight: bold; color: #303133; padding: 0 5px; } .summary-val { font-weight: bold; color: #303133; } +/deep/ .chart-fullscreen { width: 100% !important; max-width: 100% !important; height: 100vh !important; margin: 0 !important; } +/deep/ .chart-fullscreen .el-dialog__body { height: calc(100vh - 90px); overflow: auto; padding: 16px 20px; } +/deep/ .chart-fullscreen .el-dialog__header { padding: 12px 20px; } +.chart-grid { display: flex; flex-wrap: wrap; } +.chart-item { width: 33.33%; padding: 6px; box-sizing: border-box; } diff --git a/klp-ui/src/views/wms/post/aps/processes.vue b/klp-ui/src/views/wms/post/aps/processes.vue index fd2e15a8e..05a3dc16a 100644 --- a/klp-ui/src/views/wms/post/aps/processes.vue +++ b/klp-ui/src/views/wms/post/aps/processes.vue @@ -1,210 +1,214 @@ - - - - - - - - - 筛选 - 重置 - - - 新增工艺 - - 共 {{ total }} 条 + + + + + + 搜索 + 重置 + + + 新建工序方案 + + + + + + + + P{{ String(seqIndex($index)).padStart(3, '0') }} + + + + + + + + + {{ step.stepName }} + → + - - - + + - + + + + + + + + 编辑 + 删除 + + + - - - - - - {{ item.processName }} - - - - - - - {{ item.processDesc || '暂无描述' }} - - - 备注: {{ item.remark || '-' }} - - - - 暂无工艺数据 - - - - - + + + - - - - - - - 工艺基本信息 - - - - 工艺名称 - {{ currentProcess.processName }} - - 工艺描述 - {{ currentProcess.processDesc || '-' }} - - 备注 - {{ currentProcess.remark || '-' }} - - - - + + - - - - 工艺步骤({{ stepList.length }} 步) - 新增步骤 - - - - - - - - {{ step.stepName }} - - - - - - {{ step.remark }} - - - - - - - - - - - - - - - - - - - - - - + + + + 新建工序方案 + + + + - + - - - - - - - - - - - - - -