add:导入、同步功能

This commit is contained in:
2026-01-09 12:36:08 +08:00
parent 13b7e8e4bc
commit fc5171c5e1
11 changed files with 316 additions and 25 deletions

View File

@@ -68,7 +68,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
};
log.info("下发删除AGV指令--{}", Bytes2HexString(b));
// NDCSocketConnectionAutoRun.write(b);
OneNDCSocketConnectionAutoRun.write(b);
System.out.println("下发删除agv指令数据:" + Bytes2HexString(b));
}
@@ -124,7 +124,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
str1 += "优先级 /priority:" + hexToString(prioritylow & 0xFF);
byte[] b = new byte[]{};
if (ObjectUtil.isNotEmpty(inst.getCarno())){
if (ObjectUtil.isNotEmpty(inst.getCarno())) {
int carNo = Integer.parseInt(inst.getCarno());
byte agvnohigh = (byte) IntToHexHigh(carNo);
byte agvnolow = (byte) IntToHexLow(carNo);
@@ -143,7 +143,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
(byte) fhdhigh, (byte) fhdlow,
(byte) agvnohigh, (byte) agvnolow
};
}else {
} else {
b = new byte[]{(byte) 0X87, (byte) 0XCD,
(byte) 0X00, (byte) 0X08,
(byte) 0X00, (byte) 0X12,
@@ -195,8 +195,8 @@ public class NDCAgvServiceImpl implements NDCAgvService {
}
@Override
public byte[] sendAgvOneModeInst(int phase, int index, int result,Instruction inst) {
if (inst.getAgv_inst_type().equals("1")){
public byte[] sendAgvOneModeInst(int phase, int index, int result, Instruction inst) {
if (inst.getAgv_inst_type().equals("1")) {
return sendAgvOneModeInst(phase, index, result);
}
DeviceAppService appService = SpringContextHolder.getBean(DeviceAppServiceImpl.class);
@@ -217,7 +217,7 @@ public class NDCAgvServiceImpl implements NDCAgvService {
}
int startAddress = deviceService.queryAddressBydeviceCode(inst.getStart_point_code());
int nextAddress = deviceService.queryAddressBynextdeviceCode(inst.getNext_point_code());
if (!inst.getAgv_inst_type().equals("1")){
if (!inst.getAgv_inst_type().equals("1")) {
start2Address = deviceService.queryAddressBydeviceCode(inst.getStart_point_code2());
next2Address = deviceService.queryAddressBynextdeviceCode(inst.getNext_point_code2());
}
@@ -234,45 +234,45 @@ public class NDCAgvServiceImpl implements NDCAgvService {
byte indexlow = (byte) IntToHexLow(index);
byte phasehigh = (byte) IntToHexHigh(phase);
byte phaselow = (byte) IntToHexLow(phase);
if (inst.getAgv_inst_type().equals("2")){
if (inst.getAgv_inst_type().equals("2")) {
if (phase == 0x09) {
qhdhigh = (byte) IntToHexHigh(start2Address);
qhdlow = (byte) IntToHexLow(start2Address);
addrHigh = qhdhigh;
addrLow = qhdlow;
}else if (phase == 0x0D) {
} else if (phase == 0x0D) {
fhdhigh = (byte) IntToHexHigh(next2Address);
fhdlow = (byte) IntToHexLow(next2Address);
addrHigh = fhdhigh;
addrLow = fhdlow;
}
}else if (inst.getAgv_inst_type().equals("3")) {
} else if (inst.getAgv_inst_type().equals("3")) {
if (phase == 0x09) {
qhdhigh = (byte) IntToHexHigh(nextAddress);
qhdlow = (byte) IntToHexLow(nextAddress);
addrHigh = qhdhigh;
addrLow = qhdlow;
}else if (phase == 0x11) {
} else if (phase == 0x11) {
qhdhigh = (byte) IntToHexHigh(startLinkAddress);
qhdlow = (byte) IntToHexLow(startLinkAddress);
addrHigh = qhdhigh;
addrLow = qhdlow;
}else if (phase == 0x19){
} else if (phase == 0x19) {
qhdhigh = (byte) IntToHexHigh(nextLinkAddress);
qhdlow = (byte) IntToHexLow(nextLinkAddress);
addrHigh = qhdhigh;
addrLow = qhdlow;
}else if (phase == 0x0D){
} else if (phase == 0x0D) {
fhdhigh = (byte) IntToHexHigh(nextLinkAddress);
fhdlow = (byte) IntToHexLow(nextLinkAddress);
addrHigh = fhdhigh;
addrLow = fhdlow;
}else if (phase == 0x15){
} else if (phase == 0x15) {
fhdhigh = (byte) IntToHexHigh(start2Address);
fhdlow = (byte) IntToHexLow(start2Address);
addrHigh = fhdhigh;
addrLow = fhdlow;
}else if (phase == 0x1D){
} else if (phase == 0x1D) {
fhdhigh = (byte) IntToHexHigh(next2Address);
fhdlow = (byte) IntToHexLow(next2Address);
addrHigh = fhdhigh;

View File

@@ -154,8 +154,8 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
inst.setAgv_jobno(String.valueOf(index));
inst.setSend_status("1");
instructionService.update(inst);
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
}
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
}
//任务完毕
//无车id及状态

View File

@@ -2,6 +2,7 @@
package org.nl.acs.device.rest;
import cn.dev33.satoken.annotation.SaIgnore;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
@@ -392,4 +393,14 @@ public class DeviceController {
return new ResponseEntity<>(HttpStatus.OK);
}
@GetMapping("/reload")
@Log("数据同步")
@ApiOperation("数据同步")
@SaIgnore
//@PreAuthorize("@el.check('task:list')")
public ResponseEntity<Object> reload() {
deviceService.reload();
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -14,7 +14,9 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
@@ -74,4 +76,12 @@ public class StorageCellController {
public void download(HttpServletResponse response, @RequestParam Map whereJson) throws IOException {
storageCellService.download(storageCellService.queryAll(whereJson), response);
}
@PostMapping("/excelImport")
@Log("excel导入")
@ApiOperation("excel导入")
public ResponseEntity<Object> excelImport(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
storageCellService.excelImport(file, request);
return new ResponseEntity<>(HttpStatus.OK);
}
}

View File

@@ -3,7 +3,9 @@ package org.nl.acs.device.service;
import org.nl.acs.device.service.dto.StorageCellDto;
import org.springframework.data.domain.Pageable;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@@ -87,4 +89,12 @@ public interface StorageCellService {
* @throws IOException /
*/
void download(List<StorageCellDto> dtos, HttpServletResponse response) throws IOException;
/**
* 导入数据
* @param file
* @param request
*/
void excelImport(MultipartFile file, HttpServletRequest request);
}

View File

@@ -58,6 +58,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
@@ -76,7 +77,7 @@ public class DeviceServiceImpl implements DeviceService, ApplicationAutoInitial
private final DeviceDriverDefinationAppService deviceDriverDefinationAppService;
private final DeviceAppService deviceAppService;
private final ParamService paramService;
List<StorageCellDto> storageCells = new ArrayList<>();
private List<StorageCellDto> storageCells = new CopyOnWriteArrayList<>();
private Map<String, Integer> storage_address = new HashMap();
Logger logger = LoggerFactory.getLogger(DeviceServiceImpl.class);

View File

@@ -2,16 +2,20 @@
package org.nl.acs.device.service.impl;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.acs.device.service.StorageCellService;
import org.nl.acs.device.service.dto.DeviceDto;
import org.nl.acs.device.service.dto.StorageCellDto;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.common.utils.FileUtil;
@@ -22,9 +26,12 @@ import org.nl.modules.wql.util.WqlUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
@@ -73,7 +80,7 @@ public class StorageCellServiceImpl implements StorageCellService {
public StorageCellDto findById(String storage_id) {
WQLObject wo = WQLObject.getWQLObject("acs_storage_cell");
JSONObject json = wo.query("storage_id ='" + storage_id + "'").uniqueResult(0);
if (ObjectUtil.isNotEmpty(json)){
if (ObjectUtil.isNotEmpty(json)) {
final StorageCellDto obj = json.toJavaObject(StorageCellDto.class);
return obj;
}
@@ -83,8 +90,8 @@ public class StorageCellServiceImpl implements StorageCellService {
@Override
public StorageCellDto findByCode(String code) {
WQLObject wo = WQLObject.getWQLObject("acs_storage_cell");
JSONObject json = wo.query("code ='" + code + "'").uniqueResult(0);
if (ObjectUtil.isNotEmpty(json)){
JSONObject json = wo.query("storage_code ='" + code + "'").uniqueResult(0);
if (ObjectUtil.isNotEmpty(json)) {
final StorageCellDto obj = json.toJavaObject(StorageCellDto.class);
return obj;
}
@@ -95,7 +102,7 @@ public class StorageCellServiceImpl implements StorageCellService {
public StorageCellDto findByAddress(String address) {
WQLObject wo = WQLObject.getWQLObject("acs_storage_cell");
JSONObject json = wo.query("address ='" + address + "'").uniqueResult(0);
if (ObjectUtil.isNotEmpty(json)){
if (ObjectUtil.isNotEmpty(json)) {
final StorageCellDto obj = json.toJavaObject(StorageCellDto.class);
return obj;
}
@@ -167,4 +174,91 @@ public class StorageCellServiceImpl implements StorageCellService {
}
FileUtil.downloadExcel(list, response);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void excelImport(MultipartFile file, HttpServletRequest request) {
if (file == null || file.isEmpty()) {
throw new BadRequestException("文件为空,请添加数据后重新导入");
}
String nickName = SecurityUtils.getCurrentNickName();
String now = DateUtil.now();
WQLObject wo = WQLObject.getWQLObject("acs_storage_cell");
List<StorageCellDto> exists = new ArrayList<>();
List<String> notExists = new ArrayList<>();
List<String> badMsg = new ArrayList<>();
try (InputStream in = file.getInputStream();
ExcelReader reader = ExcelUtil.getReader(in)) {
List<List<Object>> rows = reader.read(1, reader.getRowCount());
for (int i = 0; i < rows.size(); i++) {
int excelRowNo = i + 2;
List<Object> row = rows.get(i);
if (row == null || row.size() < 3 || (ObjectUtil.isEmpty(row.get(0)) && ObjectUtil.isEmpty(row.get(1)) && ObjectUtil.isEmpty(row.get(2)))) {
badMsg.add("" + excelRowNo + "行, 数据不完整!");
continue;
}
Object storage_code = row.get(0);
Object pick_address = row.get(1);
Object drop_address = row.get(2);
if (ObjectUtil.isEmpty(storage_code)) {
badMsg.add("" + excelRowNo + "行,货位编码不能为空");
continue;
}
if (ObjectUtil.isEmpty(pick_address)) {
badMsg.add("" + excelRowNo + "行,取货地址不能为空");
continue;
}
if (ObjectUtil.isEmpty(drop_address)) {
badMsg.add("" + excelRowNo + "行,卸货地址不能为空");
continue;
}
String code = storage_code.toString().trim();
StorageCellDto dto = this.findByCode(code);
if (dto == null) {
notExists.add(code);
continue;
}
Integer pick = Convert.toInt(pick_address, null);
Integer drop = Convert.toInt(drop_address, null);
if (pick == null || drop == null) {
badMsg.add("" + excelRowNo + "行:地址必须是整数(取货/放货)");
continue;
}
dto.setAddress(pick);
dto.setAddress1(drop);
dto.setUpdate_time(now);
dto.setUpdate_by(nickName);
exists.add(dto);
}
} catch (IOException e) {
throw new BadRequestException("读取Excel失败" + e.getMessage());
}
if (!badMsg.isEmpty()) {
throw new BadRequestException("数据格式错误:" + String.join(",", badMsg));
}
if (!notExists.isEmpty()) {
throw new BadRequestException("设备信息不存在:" + String.join(",", notExists));
}
for (StorageCellDto dto : exists) {
JSONObject json = (JSONObject) JSONObject.toJSON(dto);
wo.update(json);
}
}
}

View File

@@ -6,7 +6,7 @@ spring:
druid:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://${DB_HOST:10.4.46.150}:${DB_PORT:3306}/${DB_NAME:hl5q}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true
url: jdbc:log4jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:nl5_acs}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true
username: ${DB_USER:root}
password: ${DB_PWD:123456}
# 初始连接数

View File

@@ -24,4 +24,19 @@ export function edit(data) {
})
}
export default { add, edit, del }
export function reload() {
return request({
url: 'api/device/reload',
method: 'get'
})
}
export function excelImport(data) {
return request({
url: 'api/storageCell/excelImport',
method: 'post',
data
})
}
export default { add, edit, del, excelImport }

View File

@@ -0,0 +1,116 @@
<template>
<el-dialog
title="导入Excel文件"
append-to-body
:visible.sync="dialogVisible"
destroy-on-close
width="400px"
:show-close="true"
@close="close"
@open="open"
>
<el-upload
ref="upload"
class="upload-demo"
action=""
drag
:on-exceed="is_one"
:limit="1"
:auto-upload="false"
:multiple="false"
:show-file-list="true"
:on-change="uploadByJsqd"
:file-list="fileList"
accept=".xlsx,.xls"
>
<i class="el-icon-upload" />
<div class="el-upload__text">
将文件拖到此处
<em>点击上传</em>
</div>
<div slot="tip" class="el-upload__tip">只能上传Excel文件且不超过10MB</div>
</el-upload>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</el-dialog>
</template>
<script>
import crudStorageCell from '@/api/acs/device/storageCell'
import CRUD, { crud } from '@crud/crud'
export default {
name: 'UploadDialog',
mixins: [crud()],
components: {},
props: {
dialogShow: {
type: Boolean,
default: false
},
openParam: {
type: String
}
},
data() {
return {
dialogVisible: false,
fileList: [],
file1: ''
}
},
watch: {
dialogShow: {
handler(newValue, oldValue) {
this.dialogVisible = newValue
}
},
openParam: {
handler(newValue, oldValue) {
this.opendtlParam = newValue
}
}
},
methods: {
open() {
},
close() {
this.$emit('update:dialogShow', false)
},
is_one() {
this.crud.notify('只能上传一个excel文件', CRUD.NOTIFICATION_TYPE.WARNING)
},
// 文件校验方法
beforeAvatarUpload(file) {
// 不能导入大小超过2Mb的文件
if (file.size > 10 * 1024 * 1024) {
return false
}
return true
},
// 文件发生改变就会触发的事件
uploadByJsqd(file) {
this.file1 = file
},
submit() {
if (this.beforeAvatarUpload(this.file1)) {
this.fileList.name = this.file1.name
this.fileList.url = ''
var formdata = new FormData()
formdata.append('file', this.file1.raw)
// excelImport请求接口 formdata传递参数
crudStorageCell.excelImport(formdata).then((res) => {
this.crud.notify('导入成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
this.$emit('tableChanged3', '')
this.$emit('update:dialogShow', false)
})
} else {
this.crud.notify('文件过大请上传小于10MB的文件〜', CRUD.NOTIFICATION_TYPE.WARNING)
}
}
}
}
</script>

View File

@@ -15,7 +15,28 @@
<rrOperation />
</div>
<!--如果想在工具栏加入更多按钮可以使用插槽方式 slot = 'left' or 'right'-->
<crudOperation :permission="permission" />
<crudOperation :permission="permission" >
<el-button
slot="right"
class="filter-item"
size="mini"
type="primary"
icon="el-icon-refresh"
@click="reload"
>
同步
</el-button>
<el-button
slot="right"
class="filter-item"
type="warning"
icon="el-icon-upload2"
size="mini"
@click="uploadShow = true"
>
导入
</el-button>
</crudOperation>
<!--表单组件-->
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
@@ -76,6 +97,7 @@
<!--分页组件-->
<pagination />
</div>
<UploadDialog :dialog-show.sync="uploadShow" @tableChanged3="tableChanged3" />
</div>
</template>
@@ -86,17 +108,19 @@ import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import rrOperation from '@crud/RR.operation'
import UploadDialog from './UploadDialog'
const defaultForm = { storage_id: null, storage_code: null, x: null, y: null, z: null, address: null, address1: null, remark: null, is_active: null, is_delete: null, create_by: null, create_time: null, update_by: null, update_time: null, parent_storage_code: null }
export default {
name: 'StorageCell',
components: { pagination, crudOperation, udOperation, rrOperation },
components: { pagination, crudOperation, udOperation, rrOperation, UploadDialog },
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({ title: '库位管理', url: 'api/storageCell', idField: 'storage_id', sort: 'storage_id,desc', crudMethod: { ...crudStorageCell }})
},
data() {
return {
uploadShow: false,
permission: {
add: ['admin', 'storageCell:add'],
edit: ['admin', 'storageCell:edit'],
@@ -140,7 +164,17 @@ export default {
// 钩子在获取表格数据之前执行false 则代表不获取数据
[CRUD.HOOK.beforeRefresh]() {
return true
}
},
reload() {
crudStorageCell.reload().then(res => {
this.crud.toQuery()
}).catch(err => {
console.log(err.response.data.message)
})
},
tableChanged3() {
this.crud.toQuery()
},
}
}
</script>