feat(wmsstorage): 新增导出校验功能并优化导出流程
This commit is contained in:
parent
545ac4478e
commit
178cc058e1
@ -99,6 +99,23 @@ public class WmsStorageController {
|
|||||||
return success(BeanUtils.toBean(pageResult, WmsStorageRespVO.class));
|
return success(BeanUtils.toBean(pageResult, WmsStorageRespVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/exportCheck")
|
||||||
|
@Operation(summary = "导出新中大入/出库主 Excel(使用模板)")
|
||||||
|
@PreAuthorize("@ss.hasPermission('heli:wms-storage:export')")
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public CommonResult<List<WmsStorageRespVO>> exportCheck(@RequestParam("ids") String ids) {
|
||||||
|
// 处理数据,更新导出状态
|
||||||
|
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(false, ids);
|
||||||
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
|
if (!objects.getT1()) {
|
||||||
|
// list 统计ID,用,分割
|
||||||
|
String idList = list.stream().map(WmsStorageDO::getId).map(String::valueOf).collect(Collectors.joining(","));
|
||||||
|
return CommonResult.error(10010, idList);
|
||||||
|
}
|
||||||
|
return CommonResult.success(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/export")
|
@GetMapping("/export")
|
||||||
@Operation(summary = "导出新中大入/出库主 Excel(使用模板)")
|
@Operation(summary = "导出新中大入/出库主 Excel(使用模板)")
|
||||||
@PreAuthorize("@ss.hasPermission('heli:wms-storage:export')")
|
@PreAuthorize("@ss.hasPermission('heli:wms-storage:export')")
|
||||||
@ -108,7 +125,7 @@ public class WmsStorageController {
|
|||||||
@RequestParam("ids") String ids,
|
@RequestParam("ids") String ids,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
// 处理数据,更新导出状态
|
// 处理数据,更新导出状态
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(ids);
|
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
||||||
List<WmsStorageDO> list = objects.getT2();
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
if (!objects.getT1()) {
|
if (!objects.getT1()) {
|
||||||
// list 统计单据编号,用,分割
|
// list 统计单据编号,用,分割
|
||||||
@ -219,7 +236,7 @@ public class WmsStorageController {
|
|||||||
public void exportWmsStorageExcel(@RequestParam("stockType") Integer stockType,
|
public void exportWmsStorageExcel(@RequestParam("stockType") Integer stockType,
|
||||||
@RequestParam("ids") String ids,
|
@RequestParam("ids") String ids,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(ids);
|
Tuple2<Boolean, List<WmsStorageDO>> objects = wmsStorageService.processWsmStorage(true, ids);
|
||||||
List<WmsStorageDO> list = objects.getT2();
|
List<WmsStorageDO> list = objects.getT2();
|
||||||
|
|
||||||
// 导出 Excel - 两个sheet
|
// 导出 Excel - 两个sheet
|
||||||
@ -232,7 +249,7 @@ public class WmsStorageController {
|
|||||||
boolean isInbound = stockType == 1;
|
boolean isInbound = stockType == 1;
|
||||||
String typeName = isInbound ? "入库" : "出库";
|
String typeName = isInbound ? "入库" : "出库";
|
||||||
String fileName = URLEncoder.encode("新中大" + typeName + "单导出").replaceAll("\\+", "%20");
|
String fileName = URLEncoder.encode("新中大" + typeName + "单导出").replaceAll("\\+", "%20");
|
||||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xls");
|
||||||
|
|
||||||
// 创建ExcelWriter
|
// 创建ExcelWriter
|
||||||
com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
com.alibaba.excel.ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
||||||
|
|||||||
@ -54,7 +54,6 @@ public interface WmsStorageService {
|
|||||||
*/
|
*/
|
||||||
PageResult<WmsStorageDO> getWmsStoragePage(WmsStoragePageReqVO pageReqVO);
|
PageResult<WmsStorageDO> getWmsStoragePage(WmsStoragePageReqVO pageReqVO);
|
||||||
|
|
||||||
// 返回两个结果
|
Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids);
|
||||||
Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(String ids);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -113,7 +113,7 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(String ids) {
|
public Tuple2<Boolean, List<WmsStorageDO>> processWsmStorage(Boolean isExport, String ids) {
|
||||||
// 分割并转换为 Long 类型
|
// 分割并转换为 Long 类型
|
||||||
List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
|
List<Long> idList = Arrays.stream(ids.split(",")).map(Long::valueOf).collect(Collectors.toList());
|
||||||
if (!idList.isEmpty()) {
|
if (!idList.isEmpty()) {
|
||||||
@ -128,7 +128,7 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
if (!errWmsStorageDOS.isEmpty()) {
|
if (!errWmsStorageDOS.isEmpty()) {
|
||||||
return Tuples.of(false, errWmsStorageDOS);
|
return Tuples.of(false, errWmsStorageDOS);
|
||||||
}
|
}
|
||||||
// 如果状态为已导出,则remove
|
if (isExport) {
|
||||||
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
for (WmsStorageDO wmsStorageDO : wmsStorageDOS) {
|
||||||
// 获取当前用户信息
|
// 获取当前用户信息
|
||||||
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
Long loginUserId = SecurityFrameworkUtils.getLoginUserId();
|
||||||
@ -139,6 +139,7 @@ public class WmsStorageServiceImpl implements WmsStorageService {
|
|||||||
List<WmsStorageDetailDO> wmsStorageDetailDOS = wmsStorageDetailMapper.selectList(WmsStorageDetailDO::getXzdWmsId, wmsStorageDO.getId());
|
List<WmsStorageDetailDO> wmsStorageDetailDOS = wmsStorageDetailMapper.selectList(WmsStorageDetailDO::getXzdWmsId, wmsStorageDO.getId());
|
||||||
wmsStorageDO.setDetailList(wmsStorageDetailDOS);
|
wmsStorageDO.setDetailList(wmsStorageDetailDOS);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return Tuples.of(true, wmsStorageDOS);
|
return Tuples.of(true, wmsStorageDOS);
|
||||||
}
|
}
|
||||||
return Tuples.of(false, Collections.emptyList());
|
return Tuples.of(false, Collections.emptyList());
|
||||||
|
|||||||
@ -60,6 +60,13 @@ export const deleteWmsStorage = async (id: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 导出新中大入/出库主 Excel
|
// 导出新中大入/出库主 Excel
|
||||||
|
export const exportCheck = async (ids: String) => {
|
||||||
|
return await request.get({
|
||||||
|
url: `/heli/wms-storage/exportCheck`,
|
||||||
|
params: { ids }
|
||||||
|
}, { showErrorMessage: false })
|
||||||
|
}
|
||||||
|
|
||||||
export const exportWmsStorage = async (stockType: Number, ids: String) => {
|
export const exportWmsStorage = async (stockType: Number, ids: String) => {
|
||||||
return await request.download({
|
return await request.download({
|
||||||
url: `/heli/wms-storage/export`,
|
url: `/heli/wms-storage/export`,
|
||||||
@ -67,7 +74,6 @@ export const exportWmsStorage = async (stockType: Number, ids: String) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 入库库存业务类型
|
* 入库库存业务类型
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -168,6 +168,9 @@ service.interceptors.response.use(
|
|||||||
} else if (code === 500) {
|
} else if (code === 500) {
|
||||||
ElMessage.error(t('sys.api.errMsg500'))
|
ElMessage.error(t('sys.api.errMsg500'))
|
||||||
return Promise.reject(new Error(msg))
|
return Promise.reject(new Error(msg))
|
||||||
|
} else if (code === 10010) {
|
||||||
|
// 导出校验失败,不显示错误提示,直接返回完整数据
|
||||||
|
return Promise.reject(data)
|
||||||
} else if (code === 901) {
|
} else if (code === 901) {
|
||||||
ElMessage.error({
|
ElMessage.error({
|
||||||
offset: 300,
|
offset: 300,
|
||||||
|
|||||||
@ -45,15 +45,22 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
<el-button @click="handleQuery">
|
||||||
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
<Icon icon="ep:search" class="mr-5px" />
|
||||||
|
搜索
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetQuery">
|
||||||
|
<Icon icon="ep:refresh" class="mr-5px" />
|
||||||
|
重置
|
||||||
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
plain
|
plain
|
||||||
@click="handleExportSelected"
|
@click="handleExportSelected"
|
||||||
:disabled="selectedRows.length === 0"
|
:disabled="selectedRows.length === 0"
|
||||||
>
|
>
|
||||||
<Icon icon="ep:download" class="mr-5px" /> 单据导出
|
<Icon icon="ep:download" class="mr-5px" />
|
||||||
|
单据导出
|
||||||
</el-button>
|
</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
@ -62,9 +69,13 @@
|
|||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="loading" :data="list" class="hl-table"
|
v-loading="loading"
|
||||||
|
:data="list"
|
||||||
|
class="hl-table"
|
||||||
ref="multipleTableRef"
|
ref="multipleTableRef"
|
||||||
@selection-change="handleSelectionChange" :row-class-name="tableRowClassName">
|
@selection-change="handleSelectionChange"
|
||||||
|
:row-class-name="tableRowClassName"
|
||||||
|
>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
fixed
|
fixed
|
||||||
type="selection"
|
type="selection"
|
||||||
@ -81,14 +92,22 @@
|
|||||||
<el-table-column fixed="left" label="单据状态" min-width="120" align="center" prop="status">
|
<el-table-column fixed="left" label="单据状态" min-width="120" align="center" prop="status">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag v-if="scope.row.status === 1" type="success">
|
<el-tag v-if="scope.row.status === 1" type="success">
|
||||||
<Icon icon="ep:check" class="mr-5px" />未导出
|
<Icon icon="ep:check" class="mr-5px" />
|
||||||
|
未导出
|
||||||
</el-tag>
|
</el-tag>
|
||||||
<el-tag v-if="scope.row.status === 2" type="warning">
|
<el-tag v-if="scope.row.status === 2" type="warning">
|
||||||
<Icon icon="ep:close" class="mr-5px" />已导出
|
<Icon icon="ep:close" class="mr-5px" />
|
||||||
|
已导出
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="单据编号" fixed="left" min-width="180" align="center" prop="stockNo" />
|
<el-table-column
|
||||||
|
label="单据编号"
|
||||||
|
fixed="left"
|
||||||
|
min-width="180"
|
||||||
|
align="center"
|
||||||
|
prop="stockNo"
|
||||||
|
/>
|
||||||
<el-table-column label="仓库" min-width="200" align="center" prop="whName" />
|
<el-table-column label="仓库" min-width="200" align="center" prop="whName" />
|
||||||
<el-table-column label="业务日期" width="120" align="center" prop="busiDate">
|
<el-table-column label="业务日期" width="120" align="center" prop="busiDate">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
@ -141,7 +160,7 @@ import {
|
|||||||
HeliStorageStatusDict,
|
HeliStorageStatusDict,
|
||||||
getHeliStockTypeLabel
|
getHeliStockTypeLabel
|
||||||
} from '@/api/heli/wmsstorage'
|
} from '@/api/heli/wmsstorage'
|
||||||
import {ElTable} from "element-plus";
|
import { ElTable } from 'element-plus'
|
||||||
|
|
||||||
defineOptions({ name: 'WmsStorage' })
|
defineOptions({ name: 'WmsStorage' })
|
||||||
|
|
||||||
@ -243,11 +262,43 @@ const handleExportSelected = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
|
||||||
// 提取选中的ID列表,用,分隔拼接
|
// 提取选中的ID列表,用,分隔拼接
|
||||||
|
|
||||||
const ids = selectedRows.value.map((row) => row.id).join(',')
|
const ids = selectedRows.value.map((row) => row.id).join(',')
|
||||||
// 调用后端导出接口
|
// 调用后端校验接口
|
||||||
|
try {
|
||||||
|
const checkData = await WmsStorageApi.exportCheck(ids)
|
||||||
|
} catch (e: any) {
|
||||||
|
// 获取错误信息中的 ID 列表
|
||||||
|
let idStr = ''
|
||||||
|
if (typeof e === 'string') {
|
||||||
|
idStr = e
|
||||||
|
} else if (e.msg) {
|
||||||
|
idStr = e.msg
|
||||||
|
} else if (e.response?.data?.msg) {
|
||||||
|
idStr = e.response.data.msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除 msg 中可能存在的中文后缀
|
||||||
|
idStr = idStr.replace('存在', '')
|
||||||
|
|
||||||
|
// 分割msg,获取ID数组
|
||||||
|
const msg = idStr.split(',')
|
||||||
|
// 在selectedRows中找到对应ID的序号集合
|
||||||
|
const errorIndices = msg
|
||||||
|
.map((id) => {
|
||||||
|
const index = selectedRows.value.findIndex((row) => row.id === parseInt(id))
|
||||||
|
return index + 1 // 序号从1开始
|
||||||
|
})
|
||||||
|
.filter((index) => index > 0) // 过滤掉未找到的
|
||||||
|
// 转换为字符串用逗号分割 errorIndices从小到大排序,是数字
|
||||||
|
errorIndices.sort((a, b) => a - b)
|
||||||
|
const errorIndicesStr = errorIndices.join(',')
|
||||||
|
message.error(`行 (${errorIndicesStr} )存在已导出的数据,请刷新界面。`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 校验通过,继续导出
|
||||||
|
try {
|
||||||
const data = await WmsStorageApi.exportWmsStorage(selectedRows.value[0].stockType, ids)
|
const data = await WmsStorageApi.exportWmsStorage(selectedRows.value[0].stockType, ids)
|
||||||
download.excel(data, `新中大单据_${new Date().getTime()}.xls`)
|
download.excel(data, `新中大单据_${new Date().getTime()}.xls`)
|
||||||
message.success(`成功导出 ${selectedRows.value.length} 条数据`)
|
message.success(`成功导出 ${selectedRows.value.length} 条数据`)
|
||||||
@ -257,6 +308,7 @@ const handleExportSelected = async () => {
|
|||||||
console.error('导出失败:', error)
|
console.error('导出失败:', error)
|
||||||
message.error('导出失败,请稍后重试')
|
message.error('导出失败,请稍后重试')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化 **/
|
/** 初始化 **/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user