opt:越南富佳看板优化、库存增导出功能

This commit is contained in:
2025-12-24 17:42:04 +08:00
parent 55a0d0d63a
commit aaef006ce5
10 changed files with 158 additions and 22 deletions

View File

@@ -1,21 +1,29 @@
package org.nl.wms.basedata_manage.controller;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.base.TableDataInfo;
import org.nl.common.domain.query.PageQuery;
import org.nl.common.logging.annotation.Log;
import org.nl.common.utils.MapOf;
import org.nl.wms.basedata_manage.service.IMdPbStoragevehicleextService;
import org.nl.wms.system_manage.service.columnInfo.ColumnInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
@@ -35,9 +43,40 @@ public class StructIvtController {
@Resource
private final IMdPbStoragevehicleextService iMdPbStoragevehicleextService;
@Autowired
private ColumnInfoService columnInfoService;
@GetMapping
@Log("查询库存")
public ResponseEntity<Object> query(@RequestParam Map whereJson, PageQuery page) {
return new ResponseEntity<>(TableDataInfo.build(iMdPbStoragevehicleextService.queryAll(whereJson, page)), HttpStatus.OK);
}
@PostMapping("/exportFile")
public void exportFile(@RequestBody Map whereJson, PageQuery page, HttpServletResponse response) {
page.setPage(0);
page.setSize(99999);
IPage<JSONObject> pmFormDataDtoIPage = iMdPbStoragevehicleextService.queryAll(whereJson, page);
List<JSONObject> pmFormDataDtos = pmFormDataDtoIPage.getRecords();
List<Map> maps = pmFormDataDtos.stream().map(jsonObject -> {
try {
return jsonObject.toJavaObject(new TypeReference<Map<String, Object>>() {});
} catch (Exception e) {
e.printStackTrace();
return new HashMap();
}
}).collect(Collectors.toList());
try {
columnInfoService.exportFile("md_pb_groupplate", maps, response,
null, MapOf.of(
"material_code","物料编号","material_name","物料名称","sect_name","库区名称"
,"stor_name","仓库名称","struct_name","仓位名称","struct_code","仓位编码"
)
);
} catch (IOException e) {
log.info("EXCEL 导出异常,异常原因=【{}】",e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -112,7 +112,7 @@
<select id="overview" resultType="com.alibaba.fastjson.JSONObject">
select
SUM(CASE WHEN is_used =1 THEN 1 ELSE 0 END) AS totalLocations ,
SUM(CASE WHEN is_used =1 and sect_code ='FJ01' THEN 1 ELSE 0 END) AS totalLocations ,
COUNT(DISTINCT SUBSTRING_INDEX(struct_code, '-', 1)) AS totalShelves ,
SUM(CASE WHEN is_used =1 and storagevehicle_code is not null THEN 1 ELSE 0 END) AS currentInventory ,
SUM(CASE WHEN is_used =1 and storagevehicle_code is null THEN 1 ELSE 0 END) AS availableLocations ,

View File

@@ -441,7 +441,9 @@ public class BigScreenServiceImpl implements BigScreenService {
QueryWrapper<Structattr> structattrWrapper = new QueryWrapper<>();
structattrWrapper.lambda().eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.ne(Structattr::getSect_code,"SSX");
.eq(Structattr::getSect_code,"FJ01")
.ne(Structattr::getSect_code,"SSX")
.ne(Structattr::getSect_code,"FJError");
stats.put("locationCount", iStructattrService.count(structattrWrapper));
// 在库数量
@@ -449,6 +451,7 @@ public class BigScreenServiceImpl implements BigScreenService {
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getSect_code,"FJ01")
.isNotNull(Structattr::getStoragevehicle_code));
stats.put("inventoryCount", inventoryCount);
@@ -459,6 +462,14 @@ public class BigScreenServiceImpl implements BigScreenService {
.eq(SchBaseTask::getIs_delete, Boolean.FALSE)
.eq(SchBaseTask::getTask_status,TaskStatus.FINISHED.getCode()));
stats.put("inboundCount", inboundCount);
// 剩余数量
int remainingCount = iStructattrService.count(
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getSect_code,"FJ01")
.isNull(Structattr::getStoragevehicle_code));
stats.put("remainingCount", remainingCount);
// 出库数量
int outboundCount = iSchBaseTaskService.count(
new QueryWrapper<SchBaseTask>().lambda()

View File

@@ -481,7 +481,9 @@ public class PdaBigScreenServiceImpl implements PdaBigScreenService {
QueryWrapper<Structattr> structattrWrapper = new QueryWrapper<>();
structattrWrapper.lambda().eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.ne(Structattr::getSect_code,"SSX");
.eq(Structattr::getSect_code,"FJ01")
.ne(Structattr::getSect_code,"SSX")
.ne(Structattr::getSect_code,"FJError");
stats.put("locationCount", iStructattrService.count(structattrWrapper));
// 在库数量
@@ -489,6 +491,7 @@ public class PdaBigScreenServiceImpl implements PdaBigScreenService {
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getSect_code,"FJ01")
.isNotNull(Structattr::getStoragevehicle_code));
stats.put("inventoryCount", inventoryCount);
@@ -499,6 +502,14 @@ public class PdaBigScreenServiceImpl implements PdaBigScreenService {
.eq(SchBaseTask::getIs_delete, Boolean.FALSE)
.eq(SchBaseTask::getTask_status,TaskStatus.FINISHED.getCode()));
stats.put("inboundCount", inboundCount);
// 剩余数量
int remainingCount = iStructattrService.count(
new QueryWrapper<Structattr>().lambda()
.eq(Structattr::getStor_code, storCode)
.eq(Structattr::getIs_used, Boolean.TRUE)
.eq(Structattr::getSect_code,"FJ01")
.isNull(Structattr::getStoragevehicle_code));
stats.put("remainingCount", remainingCount);
// 出库数量
int outboundCount = iSchBaseTaskService.count(
new QueryWrapper<SchBaseTask>().lambda()

View File

@@ -60,17 +60,17 @@ public class ColumnInfoServiceImpl implements ColumnInfoService {
}
List<Map<String, Object>> excel_lst = new ArrayList<>();
Map<String, String> map = new LinkedHashMap<>();
if(!CollectionUtils.isEmpty(customizMap)) {
map.putAll(customizMap);
}
if (!StringUtils.isEmpty(tableName)) {
map = this.TableColumn(tableName);
map.putAll(this.TableColumn(tableName));
if (!CollectionUtils.isEmpty(passParam)) {
for (Object s : passParam) {
map.remove(s);
}
}
}
if(!CollectionUtils.isEmpty(customizMap)) {
map.putAll(customizMap);
}
if (CollectionUtils.isEmpty(map)) {
throw new BadRequestException("导出失败,表结构信息失败" + tableName);
}

View File

@@ -9,10 +9,11 @@ spring:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DB_HOST:192.168.81.251}:${DB_PORT:3306}/${DB_NAME:fujia_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
# url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:wms_oulun}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
# url: jdbc:mysql://${DB_HOST:192.168.81.251}:${DB_PORT:3306}/${DB_NAME:fujia_lms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:fujia}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
username: ${DB_USER:root}
password: ${DB_PWD:P@ssw0rd.}
password: ${DB_PWD:123456}
# password: ${DB_PWD:P@ssw0rd.}
# 初始连接数
initial-size: 15
# 最小连接数

BIN
nladmin-ui/dist.rar Normal file

Binary file not shown.

View File

@@ -72,6 +72,10 @@
<div class="stat-title">在库数量</div>
<div class="stat-value">{{ stats.inventoryCount }}</div>
</el-card>
<el-card class="stat-card" shadow="hover">
<div class="stat-title">剩余库位</div>
<div class="stat-value">{{ stats.remainingCount }}</div>
</el-card>
<el-card class="stat-card" shadow="hover">
<div class="stat-title">入库数量</div>
<div class="stat-value">{{ stats.inboundCount }}</div>
@@ -80,11 +84,6 @@
<div class="stat-title">出库数量</div>
<div class="stat-value">{{ stats.outboundCount }}</div>
</el-card>
<el-card class="stat-card" shadow="hover">
<div class="stat-title">运转数量</div>
<div class="stat-value">{{ stats.operationCount }}</div>
</el-card>
</div>
<!-- 任务统计图表 - 合并为一个组件 -->
@@ -158,7 +157,7 @@ export default {
monthTasks: 0,
monthlyAvg: 0,
locationCount: 0,
inventoryCount: 0,
remainingCount: 0,
outboundCount: 0,
operationCount: 0
},

View File

@@ -78,6 +78,14 @@
>
{{ $t('wms.statement.structivt.export_excel') }}
</el-button>-->
<el-button
slot="right"
class="filter-item"
type="primary"
size="mini"
@click="exportExcel"
>导出excel
</el-button>
</crudOperation>
<!--表格渲染-->
<el-table
@@ -86,6 +94,8 @@
:data="crud.data"
size="mini"
style="width: 100%;"
show-summary
:summary-method="getSummaries"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column prop="struct_code" :label="$t('wms.statement.structivt.location_code')" :min-width="flexWidth('struct_code',crud.data,'仓位编码')" />
@@ -109,7 +119,7 @@
</template>
<script>
import crudStructivt from '@/views/wms/statement/structivt/structivt'
import crudStructivt, { exportFile } from '@/views/wms/statement/structivt/structivt'
import CRUD, { presenter, header, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
@@ -150,6 +160,43 @@ export default {
})
},
methods: {
// 导出Excel功能
exportExcel() {
// 构建文件名称仓位管理导出yyyymmdd.xlsx
const now = new Date()
const year = now.getFullYear()
const month = String(now.getMonth() + 1).padStart(2, '0')
const day = String(now.getDate()).padStart(2, '0')
const fileName = `入库管理导出${year}${month}${day}.xlsx`
if (this.query.createTime) {
this.query.start_time = this.query.createTime[0]
this.query.begin_time = this.query.createTime[0]
if (this.query.createTime.length > 1) {
this.query.end_time = this.query.createTime[1]
}
} else {
this.query.start_time = ''
this.query.end_time = ''
}
// 使用导入的exportFile方法调用后端接口
exportFile(this.query).then(res => {
// 创建Blob对象
const blob = new Blob([res], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
// 创建下载链接
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = fileName
// 触发下载
document.body.appendChild(link)
link.click()
// 清理
document.body.removeChild(link)
URL.revokeObjectURL(link.href)
this.crud.notify('导出成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
}).catch(() => {
this.crud.notify('导出失败', CRUD.NOTIFICATION_TYPE.ERROR)
})
},
// 钩子在获取表格数据之前执行false 则代表不获取数据
[CRUD.HOOK.beforeRefresh]() {
return true
@@ -185,6 +232,26 @@ export default {
this.showDtlLoading = false
})
}
},
getSummaries(param) {
const { columns, data } = param
const sums = []
columns.forEach((column, index) => {
if (index === 0) {
sums[index] = '合计'
return
}
if (column.property === 'qty') {
const total = data.reduce((sum, item) => {
const qty = Number(item.qty) || 0
return sum + qty
}, 0)
sums[index] = parseFloat(total).toFixed(3)
} else {
sums[index] = ''
}
})
return sums
}
}
}

View File

@@ -62,4 +62,12 @@ export function excelImport(data) {
})
}
export default { add, edit, del, getStruct, getStructById, getUnits, save, excelImport }
export function exportFile(query) {
return request({
url: 'api/structivt/exportFile',
method: 'post',
data: query,
responseType: 'blob'
})
}
export default { add, edit, del, getStruct, getStructById, getUnits, save, excelImport, exportFile }