更新各模块导出和图表导出

This commit is contained in:
XingCheng3
2026-06-27 14:53:56 +08:00
parent c79dc76994
commit 3415f76ff4
13 changed files with 373 additions and 46 deletions

1
.gitignore vendored
View File

@@ -13,3 +13,4 @@ package-lock.json
*.ntvs*
*.njsproj
*.sln
dist.zip

BIN
dist.zip

Binary file not shown.

View File

@@ -408,8 +408,15 @@ function getBlob(url, cb) {
xhr.responseType = 'blob'
xhr.onload = function() {
if (xhr.status === 200) {
const name = xhr.getResponseHeader('content-disposition').split('=')[1]
var filename = decodeURIComponent(name)
const disposition = xhr.getResponseHeader('content-disposition')
let filename = 'export.xlsx'
if (disposition && disposition.indexOf('=') > -1) {
const name = disposition.split('=')[1]
filename = decodeURIComponent(name)
} else {
const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)
filename = 'export_' + timestamp + '.xlsx'
}
cb(xhr.response, filename)
}
}

View File

@@ -141,10 +141,16 @@ export default {
const param = [
['开始日期', this.dateTime[0]],
['结束日期', this.dateTime[1]],
['电表号', this.meterCode || '']
['电表号', this.meterCode || ''],
['PageCurrent', 1],
['PageSize', 99999999],
['PageCount', '1111', 'int', '1'],
['ItemCount', '1111', 'int', '1']
]
const Data = this.CreateData('2001', '能耗_日汇总_视图_分页查询', param)
this.exportExcel_NPOI(Data)
const exportData = JSON.parse(this.CreateData('2005', '能耗_日汇总_视图_分页查询', param))
exportData.exportColumns = '电表号,开始电能,结束电能,结算日期,结算电能'
exportData.exportFileName = '设备能耗信息_'
this.exportExcel_NPOI(JSON.stringify(exportData))
},
// 分页处理 - 改变每页数量

View File

@@ -77,7 +77,10 @@
<span class="header-title">
<i class="el-icon-document-copy"></i> 订单列表
</span>
<span class="header-count"> {{ filteredData.length }} </span>
<div class="header-actions">
<span class="header-count"> {{ filteredData.length }} </span>
<el-button type="success" size="mini" icon="el-icon-download" @click="exportExcel">导出</el-button>
</div>
</div>
<el-table v-loading="loading" :data="filteredData" :header-cell-style="headerCellStyle"
:row-class-name="tableRowClassName" border stripe highlight-current-row max-height="550"
@@ -298,6 +301,16 @@ export default {
itemWidth: 12,
itemHeight: 12
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '订单执行进度_状态分布'
}
}
},
series: [{
type: 'pie',
radius: ['45%', '70%'],
@@ -389,6 +402,16 @@ export default {
top: '20',
bottom: '30'
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '订单执行进度_甘特图'
}
}
},
xAxis: {
type: 'time',
axisLabel: {
@@ -455,6 +478,21 @@ export default {
this.showDelayedOnly = false
this.setDefaultDate()
this.queryData()
},
exportExcel() {
if (this.filteredData.length === 0) {
this.$message.warning('暂无数据可导出')
return
}
const param = [
['开始时间', this.dateRange[0] + ' 00:00:00'],
['结束时间', this.dateRange[1] + ' 23:59:59'],
['执行状态', this.showDelayedOnly ? -1 : this.statusFilter]
]
const exportData = JSON.parse(this.CreateData('2005', '生产分析_订单进度_查询', param))
exportData.exportColumns = '订单号,产品型号,生产类型,计划开始时间=计划时间,生产开始时间=开始时间,生产完成时间=完成时间,状态文本=状态,是否延期=预警'
exportData.exportFileName = '订单执行进度_'
this.exportExcel_NPOI(JSON.stringify(exportData))
}
}
}
@@ -626,6 +664,12 @@ export default {
color: #8c8c8c;
}
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
.order-id {
font-weight: 600;
color: #1890ff;

View File

@@ -352,6 +352,16 @@ export default {
top: '20',
bottom: '30'
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '产品节拍统计_工位过站详情'
}
}
},
xAxis: {
type: 'time',
axisLabel: {
@@ -451,8 +461,10 @@ export default {
['发动机号', this.searchForm.productId || ''],
['订单号', this.searchForm.orderId || '']
]
const Data = this.CreateData('2001', '生产分析_产品节拍_汇总_查询', param)
this.exportExcel_NPOI(Data)
const exportData = JSON.parse(this.CreateData('2005', '生产分析_产品节拍_汇总_查询', param))
exportData.exportColumns = '产品编号,订单号,产品型号,上线时间,下线时间,总生产时间,过站工位数,合格工位数'
exportData.exportFileName = '产品节拍统计_'
this.exportExcel_NPOI(JSON.stringify(exportData))
},
handleSizeChange(val) {
this.pagination.pageSize = val

View File

@@ -407,6 +407,16 @@ export default {
top: '40',
bottom: '60'
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '质量趋势分析_质量趋势曲线'
}
}
},
dataZoom: [
{ type: 'inside', start: 0, end: 100 },
{ type: 'slider', start: 0, end: 100, height: 20, bottom: 10 }

View File

@@ -80,6 +80,7 @@
<span class="header-title">
<i class="el-icon-document"></i> 工位效率明细
</span>
<el-button type="success" size="mini" icon="el-icon-download" @click="exportExcel">导出</el-button>
</div>
<el-table v-loading="loading" :data="tableData" :header-cell-style="headerCellStyle"
:row-class-name="tableRowClassName" border stripe size="small" max-height="400">
@@ -275,6 +276,16 @@ export default {
top: '30',
bottom: '50'
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '工位效率分析_平均节拍对比'
}
}
},
xAxis: {
type: 'category',
data: stations,
@@ -346,6 +357,16 @@ export default {
data: ['过站数量', '合格数量'],
top: 0
},
toolbox: {
right: 10,
top: 0,
feature: {
saveAsImage: {
title: '下载',
name: '工位效率分析_产品吞吐量'
}
}
},
grid: {
left: '50',
right: '30',
@@ -419,6 +440,20 @@ export default {
resetSearch() {
this.setDefaultDate()
this.queryData()
},
exportExcel() {
if (this.tableData.length === 0) {
this.$message.warning('暂无数据可导出')
return
}
const param = [
['开始时间', this.dateRange[0] + ' 00:00:00'],
['结束时间', this.dateRange[1] + ' 23:59:59']
]
const exportData = JSON.parse(this.CreateData('2005', '生产分析_工位效率_统计_查询', param))
exportData.exportColumns = '工位号,过站数量,平均节拍,最长节拍,最短节拍,合格数量,合格率'
exportData.exportFileName = '工位效率分析_'
this.exportExcel_NPOI(JSON.stringify(exportData))
}
}
}

View File

@@ -467,8 +467,14 @@ export default {
param[4] = ['工位号', this.stationNumberValue || '']
param[5] = ['订单号', this.orderNumberValue || '']
param[6] = ['合格标志', this.isQualifiedValue]
var Data = this.CreateData('2001', '质量数据查询_综合查询新', param)
this.exportExcel_NPOI(Data)
param[7] = ['PageCurrent', 1]
param[8] = ['PageSize', 99999999]
param[9] = ['PageCount', '1111', 'int', '1']
param[10] = ['ItemCount', '1111', 'int', '1']
var exportData = JSON.parse(this.CreateData('2005', '质量数据_发动机质量数据_各个工位_视图_发动机型号_综合查询', param))
exportData.exportColumns = '工位号,订单号,发动机型号=型号,发动机号=总成编号,测量位置,测量项目,测量值,测量单位,上限值=值上限,下限值=值下限,生产日期,合格标志'
exportData.exportFileName = '质量数据查询_'
this.exportExcel_NPOI(JSON.stringify(exportData))
} else {
this.$message.warning('暂无数据')
}

View File

@@ -306,8 +306,14 @@ export default {
param[3] = ['订单号', this.orderNumberValue || '']
param[4] = ['工位号', this.stationNumberValue || '']
param[5] = ['工位号N', this.stationNumberValueN || '']
var Data = this.CreateData('2001', '质量数据查询_测量数据发动机在线状态_报表_NEW新', param)
this.exportExcel_NPOI(Data)
param[6] = ['PageCurrent', 1]
param[7] = ['PageSize', 99999999]
param[8] = ['PageCount', '1111', 'int', '1']
param[9] = ['ItemCount', '1111', 'int', '1']
var exportData = JSON.parse(this.CreateData('2005', '质量数据查询_测量数据发动机在线状态_查询_NEW', param))
exportData.exportColumns = '工位号,订单号,发动机号=产品编号,机型=型号,到达时间,离开时间,在线时间=在线时间(s),是否合格'
exportData.exportFileName = '过站信息查询_'
this.exportExcel_NPOI(JSON.stringify(exportData))
} else {
this.$message.warning('暂无数据')
}

View File

@@ -15,6 +15,8 @@
<el-button icon="el-icon-circle-plus" size="small" type="primary" @click="createMachineType()">
新增机型
</el-button>
<el-button icon="el-icon-download" size="small" type="success" @click="exportExcel()">导出</el-button>
<el-button icon="el-icon-upload2" size="small" type="warning" @click="importDialogVisible = true">导入</el-button>
</div>
<el-table
v-loading="loading"
@@ -70,10 +72,10 @@
</el-card>
<!-- 新增/编辑机型对话框 -->
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
center
<el-dialog
:title="dialogTitle"
:visible.sync="dialogVisible"
center
width="900px"
@close="resetForm()">
<el-form ref="machineForm" :model="machineForm" :rules="formRules" label-position="right" label-width="100px">
@@ -84,8 +86,8 @@
<div class="station-config-grid">
<div v-for="station in stationList" :key="station.工位号" class="station-config-item">
<el-form-item :label="station.工位号" label-width="80px">
<el-input-number
v-model="machineForm.stationConfig[station.工位号]"
<el-input-number
v-model="machineForm.stationConfig[station.工位号]"
:min="0"
:step="1"
:precision="0"
@@ -103,10 +105,43 @@
<el-button size="small" type="primary" @click="submitForm()"> </el-button>
</div>
</el-dialog>
<!-- 导入对话框 -->
<el-dialog title="批量导入机型" :visible.sync="importDialogVisible" width="700px" @close="resetImport()">
<input ref="fileInput" type="file" accept=".xlsx,.xls" style="display:none" @change="handleFileSelect"/>
<div style="border: 2px dashed #d9d9d9; padding: 40px; text-align: center; border-radius: 6px; cursor: pointer;" @click="$refs.fileInput.click()">
<i class="el-icon-upload" style="font-size: 50px; color: #409EFF;"></i>
<div style="margin-top: 10px; font-size: 14px;">点击选择Excel文件或将文件拖到此处</div>
<div style="margin-top: 5px; font-size: 12px; color: #999;">支持 .xlsx .xls 格式</div>
</div>
<div v-if="importFileName" style="margin-top: 15px; padding: 10px; background: #f5f7fa; border-radius: 4px;">
<i class="el-icon-document"></i> {{ importFileName }}
</div>
<el-divider></el-divider>
<div style="margin-bottom: 15px;">
<div style="font-weight: bold; margin-bottom: 10px;">选择导入方式</div>
<el-radio-group v-model="importMode" style="width: 100%;">
<el-radio :label="1" style="display: block; margin-bottom: 10px;">
<span style="font-weight: bold;">增量导入</span>
<div style="color: #909399; font-size: 12px; margin-left: 24px;">产品型号已存在则跳过不存在则新增推荐</div>
</el-radio>
<el-radio :label="2" style="display: block;">
<span style="font-weight: bold; color: #F56C6C;">全量导入</span>
<div style="color: #909399; font-size: 12px; margin-left: 24px;">先清空所有机型数据再导入Excel中的全部数据慎用</div>
</el-radio>
</el-radio-group>
</div>
<div slot="footer">
<el-button size="small" @click="importDialogVisible = false"> </el-button>
<el-button size="small" type="primary" :loading="importLoading" :disabled="!importFileName" @click="submitImport()">确定导入</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import XLSX from 'xlsx'
export default {
data() {
return {
@@ -126,7 +161,12 @@ export default {
productType: [
{ required: true, message: '请输入产品型号', trigger: 'blur' }
]
}
},
importDialogVisible: false,
importFileName: '',
importFile: null,
importLoading: false,
importMode: 1
}
},
created() {
@@ -308,6 +348,164 @@ export default {
this.machineForm.productType = ''
this.originalProductType = ''
this.initStationConfig()
},
// 导出Excel
exportExcel() {
if (this.tableData.length === 0) {
this.$message.warning('暂无数据')
return
}
const param = []
if (this.searchProductType) {
param.push(['产品型号_check', 1])
param.push(['产品型号', this.searchProductType])
} else {
param.push(['产品型号_check', 0])
}
const exportData = JSON.parse(this.CreateData('2005', 'MES_基本变量_机型代码_查询数据', param))
exportData.exportColumns = ['产品型号'].concat(this.stationList.map(station => station.工位号)).join(',')
exportData.exportFileName = '产品型号_'
this.exportExcel_NPOI(JSON.stringify(exportData))
},
// 选择文件
handleFileSelect(e) {
const file = e.target.files[0]
if (!file) return
this.importFile = file
this.importFileName = file.name
},
// 提交导入
submitImport() {
if (!this.importFile) {
this.$message.warning('请选择文件')
return
}
const modeText = this.importMode === 2 ? '全量导入(将清空所有现有数据)' : '增量导入'
this.$confirm(`确认执行${modeText}`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.importLoading = true
const reader = new FileReader()
reader.onload = (e) => {
try {
const data = new Uint8Array(e.target.result)
const workbook = XLSX.read(data, { type: 'array' })
const sheet = workbook.Sheets[workbook.SheetNames[0]]
const jsonData = XLSX.utils.sheet_to_json(sheet, { header: 1 })
if (jsonData.length < 2) {
this.$message.error('Excel文件内容为空')
this.importLoading = false
return
}
const headers = jsonData[0]
const stationHeaders = headers.slice(1)
const validStations = this.stationList.map(s => s.工位号)
const invalidStations = stationHeaders.filter(h => !validStations.includes(h))
if (invalidStations.length > 0) {
this.$message.error(`Excel中包含无效工位号: ${invalidStations.join(', ')}`)
this.importLoading = false
return
}
const importList = []
for (let i = 1; i < jsonData.length; i++) {
const row = jsonData[i]
if (!row[0]) continue
const productType = String(row[0]).trim()
const stationConfig = []
stationHeaders.forEach((station, index) => {
const value = row[index + 1]
stationConfig.push({
工位号: station,
程序号: value === null || value === undefined || value === '' ? 0 : parseInt(value) || 0
})
})
importList.push({ productType, stationConfig })
}
if (importList.length === 0) {
this.$message.warning('没有有效数据')
this.importLoading = false
return
}
if (this.importMode === 2) {
this.clearAllData().then(() => {
this.batchImport(importList, 0)
}).catch(() => {
this.importLoading = false
})
} else {
this.batchImport(importList, 0)
}
} catch (error) {
this.$message.error('解析Excel失败: ' + error.message)
this.importLoading = false
}
}
reader.readAsArrayBuffer(this.importFile)
}).catch(() => {})
},
// 清空所有数据
clearAllData() {
return new Promise((resolve, reject) => {
const deletePromises = this.tableData.map(row => {
const param = [['产品型号', row.产品型号]]
const data = this.CreateData('12', 'MES_基本变量_机型代码_删除', param)
return this.ExecDatabase(data)
})
Promise.all(deletePromises).then(() => {
resolve()
}).catch(() => {
this.$message.error('清空数据失败')
reject()
})
})
},
// 批量导入
batchImport(list, index) {
if (index >= list.length) {
this.importLoading = false
this.importDialogVisible = false
this.$message.success(`导入完成,共导入 ${list.length} 条数据`)
this.searchData()
return
}
const item = list[index]
const configJson = JSON.stringify(item.stationConfig)
const param = [
['产品型号', item.productType],
['工位配置', configJson]
]
const data = this.CreateData('12', 'MES_基本变量_机型代码_增加', param)
this.ExecDatabase(data).then(response => {
setTimeout(() => this.batchImport(list, index + 1), 50)
}).catch(() => {
setTimeout(() => this.batchImport(list, index + 1), 50)
})
},
// 重置导入
resetImport() {
this.importFileName = ''
this.importFile = null
this.importMode = 1
if (this.$refs.fileInput) {
this.$refs.fileInput.value = ''
}
}
}
}

View File

@@ -40,9 +40,9 @@
<el-table-column align="center" label="排序" prop="排序" width="60" />
<el-table-column align="center" fixed label="" type="expand" width="35">
<template slot-scope="props">
<div :key="props.row && props.row.订单号" style="margin: 5px 10px;width: 1400px;z-index: 99;">
<div :key="getPlanRowKey(props.row)" style="margin: 5px 10px;width: 1400px;z-index: 99;">
<h4 style="margin: 5px 0; color: #606266;">工序任务进度</h4>
<el-table :key="props.row && props.row.订单号" :data="tableDataWorkProcess"
<el-table :key="getPlanRowKey(props.row)" :data="tableDataWorkProcess"
:header-cell-style="{ background: '#f0f2f5', color: '#606266' }" border class="main" max-height="300px"
size="mini" style="width: 100%;" tooltip-effect="dark">
<el-table-column align="center" label="任务ID" prop="任务ID" width="300" />
@@ -117,7 +117,7 @@
<el-tag v-else size="mini" type="info">未知</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="操作" width="200" fixed="right">
<el-table-column align="center" label="操作" width="220" fixed="right">
<template slot-scope="scope">
<el-button v-if="scope.row.订单状态 == 3" icon="el-icon-position" size="mini" type="text"
@click="planIssue(scope.row)">
@@ -391,8 +391,8 @@ export default {
this.tableData = result
this.tableDataSnapshot = nextSnapshot
if (this.expandsDetail.length) {
const expandedOrder = this.expandsDetail[0]
const matchedRow = this.tableData.find(item => item.订单号 === expandedOrder)
const expandedKey = this.expandsDetail[0]
const matchedRow = this.tableData.find(item => this.getPlanRowKey(item) === expandedKey)
if (matchedRow) {
this.selectPlan(matchedRow, [matchedRow])
} else {
@@ -417,7 +417,9 @@ export default {
})
},
selectPlan(row, expandedRows) {
if (!expandedRows || !expandedRows.length || !row) {
const rowKey = this.getPlanRowKey(row)
const isExpanded = Array.isArray(expandedRows) && expandedRows.some(item => this.getPlanRowKey(item) === rowKey)
if (!isExpanded || !row) {
this.expandsDetail = []
this.tableDataWorkProcess = []
return
@@ -427,7 +429,7 @@ export default {
const Data = this.CreateData('11', '生产计划_派工订单_工序任务_计划查询', param)
this.ExecDatabase(Data).then(response => {
this.tableDataWorkProcess = response.data
this.expandsDetail = [row.订单号]
this.expandsDetail = [rowKey]
console.log('工序任务数据:', this.tableDataWorkProcess)
}).catch(error => {
console.error('工序任务查询失败', error)
@@ -435,7 +437,13 @@ export default {
})
},
getRowKeys(row) {
return row.订单号
return this.getPlanRowKey(row)
},
getPlanRowKey(row) {
if (!row) {
return ''
}
return String(row.ID || row.工件编号 || `${row.订单号 || ''}_${row.产品ID || ''}_${row.产品型号 || ''}`)
},
creatOrder(formName) {
this.dialogFormVisible = true
@@ -700,7 +708,7 @@ export default {
}
},
handleManualJob(row, jobType) {
const parentRow = this.tableData.find(item => this.expandsDetail.includes(item.订单号))
const parentRow = this.tableData.find(item => this.expandsDetail.includes(this.getPlanRowKey(item)))
if (!parentRow) {
this.$message.warning('请先展开订单查看工序任务')
return

View File

@@ -368,24 +368,19 @@ export default {
},
exportExcel() {
if (this.tableData.length !== 0) {
let engineTypeValue_check, statePlan_check, importTime_check, releaseTime_check
this.importTime ? importTime_check = 1 : (importTime_check = 0, this.importTime = '')
this.engineTypeValue ? engineTypeValue_check = 1 : (engineTypeValue_check = 0, this.engineTypeValue = '')
this.statePlanValue ? statePlan_check = 1 : (statePlan_check = 0, this.statePlanValue = '')
this.releaseTime ? releaseTime_check = 1 : (releaseTime_check = 0, this.releaseTime = '')
var param = []
param[0] = ['导入时间_check', importTime_check]
param[1] = ['导入开始时间', this.importTime[0]]
param[2] = ['导入完成时间', this.importTime[1]]
param[3] = ['下发时间_check', releaseTime_check]
param[4] = ['下发开始时间', this.releaseTime[0]]
param[5] = ['下发完成时间', this.releaseTime[1]]
param[6] = ['产品型号_check', engineTypeValue_check]
param[7] = ['产品型号', this.engineTypeValue]
param[8] = ['订单状态_check', statePlan_check]
param[9] = ['订单状态', this.statePlanValue]
var Data = this.CreateData('2001', 'MES_计划BOM_发动机订单计划_订单导出新', param)
this.exportExcel_NPOI(Data)
param[0] = ['零件号', this.partCodeValue]
param[1] = ['导入开始时间', this.importTime[0] + ' ' + '00:00:00']
param[2] = ['导入完成时间', this.importTime[1] + ' ' + '23:59:59']
param[3] = ['产品型号', this.engineTypeValue]
param[4] = ['PageCurrent', 1]
param[5] = ['PageSize', 99999999]
param[6] = ['PageCount', '1111', 'int', '1']
param[7] = ['ItemCount', '1111', 'int', '1']
var exportData = JSON.parse(this.CreateData('2005', 'MES_计划BOM_发动机订单计划_下发查询', param))
exportData.exportColumns = '变速箱总成号=总成编号,订单号,零件号=总成号,计划开始时间=计划开始日期,计划完成时间=计划完成日期,上线时间=总装上线时间,下线时间=总装下线时间,测试上线时间,测试下线时间'
exportData.exportFileName = '计划状态查看_'
this.exportExcel_NPOI(JSON.stringify(exportData))
} else {
this.$message.warning('暂无数据')
}
@@ -475,4 +470,3 @@ export default {
background: #f0f9eb;
}
</style>