diff --git a/src/api/check/physicalInventory.js b/src/api/check/physicalInventory.js
index 5a0886d..572212e 100644
--- a/src/api/check/physicalInventory.js
+++ b/src/api/check/physicalInventory.js
@@ -124,3 +124,8 @@ export const queryAdjustmentTransSubList = data => createAPI(`/check/physicalInv
export const selectNowUnCountPercent = data => createAPI(`/check/physicalInventory/selectNowUnCountPercent`, 'post', data)
+
+// ==================== 导出功能 ==================== - rqrq
+
+// 后端导出盘点数据到Excel(多sheet)- rqrq
+export const exportCountDataExcel = data => createAPI(`/check/physicalInventory/exportCountDataExcel`, 'post', data, 'download')
\ No newline at end of file
diff --git a/src/views/modules/check/searchPhysicalInventory.vue b/src/views/modules/check/searchPhysicalInventory.vue
index 938a052..0a37649 100644
--- a/src/views/modules/check/searchPhysicalInventory.vue
+++ b/src/views/modules/check/searchPhysicalInventory.vue
@@ -79,14 +79,15 @@
{{ scope.row[item.columnProp] }}
-
+
添加物料
下达
推送
完成
取消
- 删除
+ 删除
+ 导出明细
@@ -410,7 +411,8 @@ import { searchCountHeaderList, createCycleCount, createManualCount, queryMateri
releaseCount, pushCountToWcs, completeCount, cancelCount, deleteCount, searchCountLabelList,
searchCountPalletList, searchCountResultList, searchMaterialSummary, searchOrderTaskByCountNo,
searchOrderTaskDetail, getSysIfCount, updateSysIfCount, queryAdjustmentTransList,
- queryAdjustmentTransSubList,selectNowUnCountPercent } from '@/api/check/physicalInventory'
+ queryAdjustmentTransSubList, selectNowUnCountPercent, exportCountDataExcel } from '@/api/check/physicalInventory'
+import * as XLSX from 'xlsx' // 前端Excel导出 - rqrq
export default {
name: 'searchPhysicalInventory',
@@ -616,7 +618,10 @@ export default {
adjustmentTransLoading: false,
adjustmentTransSubList: [], // 标签明细列表
adjustmentTransSubLoading: false,
- currentAdjustmentTrans: null // 当前选中的事务
+ currentAdjustmentTrans: null, // 当前选中的事务
+
+ // 导出相关 - rqrq
+ exportLoading: false
}
},
mounted() {
@@ -1350,6 +1355,194 @@ export default {
'QTY_DIFF': '#F56C6C'
}
return colorMap[result] || '#909399'
+ },
+
+ // ==================== 导出功能 ==================== - rqrq
+
+ /**
+ * 前端导出Excel(方式一:使用xlsx库在前端生成)- rqrq
+ * @param row 当前行数据
+ */
+ async handleExportFrontend(row) {
+ if (this.exportLoading) return
+ this.exportLoading = true
+ this.$message.success('正在导出数据,请稍候...')
+
+ try {
+ const site = this.$store.state.user.site
+ const countNo = row.countNo
+ const params = { site, countNo }
+
+ // 并行获取所有数据 - rqrq
+ const [labelRes, summaryRes, palletRes, resultRes, adjustmentRes] = await Promise.all([
+ searchCountLabelList(params),
+ searchMaterialSummary(params),
+ searchCountPalletList(params),
+ searchCountResultList(params),
+ queryAdjustmentTransList(params)
+ ])
+
+ const labelList = (labelRes.data && labelRes.data.code === 0) ? labelRes.data.rows || [] : []
+ const summaryList = (summaryRes.data && summaryRes.data.code === 0) ? summaryRes.data.rows || [] : []
+ const palletList = (palletRes.data && palletRes.data.code === 0) ? palletRes.data.rows || [] : []
+ const resultList = (resultRes.data && resultRes.data.code === 0) ? resultRes.data.rows || [] : []
+ const resultDiffList = resultList.filter(item => item.countResult !== 'OK')
+ const adjustmentList = (adjustmentRes.data && adjustmentRes.data.code === 0) ? adjustmentRes.data.rows || [] : []
+
+ // 创建工作簿 - rqrq
+ const wb = XLSX.utils.book_new()
+
+ // Sheet1: 标签明细 - rqrq
+ const labelData = labelList.map(item => ({
+ '标签号': item.unitId,
+ '物料号': item.partNo,
+ '物料描述': item.partDesc,
+ '数量': item.qty,
+ '批号': item.batchNo,
+ '栈板号': item.palletId,
+ '所在层数': item.locationZ,
+ '标签类型': item.labelTypeDesc,
+ '盘点状态': item.countFlagDesc,
+ '盘点人': item.countUser,
+ '盘点时间': this.formatDateTime(item.countDate),
+ '仓库': item.warehouseName,
+ '库位': item.locationName
+ }))
+ const ws1 = XLSX.utils.json_to_sheet(labelData)
+ XLSX.utils.book_append_sheet(wb, ws1, '标签明细')
+
+ // Sheet2: 物料汇总 - rqrq
+ const summaryData = summaryList.map(item => ({
+ '物料号': item.partNo,
+ '物料描述': item.partDesc,
+ '批号': item.batchNo,
+ 'WDR号': item.wdr,
+ '仓库': item.warehouseName,
+ '库位': item.locationName,
+ '标签数': item.labelCount,
+ '总数量': item.totalQty,
+ '栈板数': item.palletCount,
+ '已盘点': item.checkedLabelCount,
+ '进度': item.progressPercent
+ }))
+ const ws2 = XLSX.utils.json_to_sheet(summaryData)
+ XLSX.utils.book_append_sheet(wb, ws2, '物料汇总')
+
+ // Sheet3: 栈板明细 - rqrq
+ const palletData = palletList.map(item => ({
+ '序号': item.seqNo,
+ '栈板号': item.palletId,
+ '标签数': item.labelCount,
+ '已盘点': item.checkedCount,
+ '进度': item.progressPercent,
+ '盘点状态': item.countFlagDesc,
+ '站点区域': item.stationArea,
+ '站点ID': item.stationId,
+ '所在层数': item.locationZ,
+ '盘点人': item.countUser,
+ '盘点时间': this.formatDateTime(item.countDate)
+ }))
+ const ws3 = XLSX.utils.json_to_sheet(palletData)
+ XLSX.utils.book_append_sheet(wb, ws3, '栈板明细')
+
+ // Sheet4: 盘点结果 - rqrq
+ const resultData = resultList.map(item => ({
+ '标签号': item.unitId,
+ '物料号': item.partNo,
+ '物料描述': item.partDesc,
+ '数量': item.qty,
+ '差异数量': item.diffQty,
+ '批号': item.batchNo,
+ '栈板号': item.palletId,
+ '盘点结果': item.countResultDesc,
+ '处理方式': item.handleTypeDesc,
+ '盘点人': item.countUser,
+ '盘点时间': this.formatDateTime(item.countDate),
+ '备注': item.remark
+ }))
+ const ws4 = XLSX.utils.json_to_sheet(resultData)
+ XLSX.utils.book_append_sheet(wb, ws4, '盘点结果')
+
+ // Sheet5: 盘点结果差异 - rqrq
+ const resultDiffData = resultDiffList.map(item => ({
+ '标签号': item.unitId,
+ '物料号': item.partNo,
+ '物料描述': item.partDesc,
+ '数量': item.qty,
+ '差异数量': item.diffQty,
+ '批号': item.batchNo,
+ '栈板号': item.palletId,
+ '盘点结果': item.countResultDesc,
+ '是否处理': item.handleFlagDesc,
+ '处理方式': item.handleTypeDesc,
+ '盘点人': item.countUser,
+ '盘点时间': this.formatDateTime(item.countDate),
+ '备注': item.remark
+ }))
+ const ws5 = XLSX.utils.json_to_sheet(resultDiffData)
+ XLSX.utils.book_append_sheet(wb, ws5, '盘点结果差异')
+
+ // Sheet6: 盘盈盘亏明细 - rqrq
+ const adjustmentData = adjustmentList.map(item => ({
+ '单据号': item.transNo,
+ '事务类型': item.transTypeDesc,
+ '行号': item.itemNo,
+ '物料号': item.partNo,
+ '数量': item.transQty,
+ '批号': item.batchNo,
+ '库位': item.locationId,
+ '方向': item.directionDesc,
+ '仓库': item.warehouseId,
+ '操作人': item.userName
+ }))
+ const ws6 = XLSX.utils.json_to_sheet(adjustmentData)
+ XLSX.utils.book_append_sheet(wb, ws6, '盘盈盘亏明细')
+
+ // 导出文件 - rqrq
+ const fileName = `盘点数据_${countNo}_${this.dayjs().format('YYYYMMDDHHmmss')}.xlsx`
+ XLSX.writeFile(wb, fileName)
+ this.$message.success('导出成功')
+ } catch (error) {
+ console.error('导出失败:', error)
+ this.$alert('导出失败:' + (error.message || error), '错误', { confirmButtonText: '确定' })
+ } finally {
+ this.exportLoading = false
+ }
+ },
+
+ /**
+ * 后端导出Excel(方式二:后端生成Excel文件下载)- rqrq
+ * @param row 当前行数据
+ */
+ handleExportBackend(row) {
+ if (this.exportLoading) return
+ this.exportLoading = true
+ this.$message.success('正在导出数据,请稍候...')
+
+ const params = {
+ site: this.$store.state.user.site,
+ countNo: row.countNo
+ }
+
+ exportCountDataExcel(params).then(response => {
+ // 从响应中获取blob数据 - rqrq
+ const blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
+ const fileName = `盘点数据_${row.countNo}_${this.dayjs().format('YYYYMMDDHHmmss')}.xlsx`
+
+ // 创建下载链接 - rqrq
+ const link = document.createElement('a')
+ link.href = window.URL.createObjectURL(blob)
+ link.download = fileName
+ link.click()
+ window.URL.revokeObjectURL(link.href)
+
+ this.$message.success('导出成功')
+ }).catch(error => {
+ console.error('导出失败:', error)
+ this.$alert('导出失败:' + (error.message || error), '错误', { confirmButtonText: '确定' })
+ }).finally(() => {
+ this.exportLoading = false
+ })
}
}
}