Commit 7cda0b7a sunke

Merge remote-tracking branch 'origin/master'

2 个父辈 f797b3aa a4c257e6
......@@ -147,6 +147,18 @@ public class DateUtil {
c.add(Calendar.DAY_OF_YEAR, days);
return c.getTime();
}
/**
* 日期+天数
* @param date
* @param seconds
* @return
*/
public static Date addSeconds(Date date, int seconds){
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.SECOND, seconds);
return c.getTime();
}
public static Date getMinDate(Date date0, Date date1){
return date0.before(date1)? date0 : date1;
......
......@@ -3,16 +3,20 @@ package com.neotel.smfcore.core.order;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.bean.StatusBean;
import com.neotel.smfcore.core.device.enums.OP;
import com.neotel.smfcore.core.device.enums.OP_STATUS;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.enums.ORDER_COLOR;
import com.neotel.smfcore.core.order.service.dao.ILiteOrderDao;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.enums.CHECKOUT_TYPE;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
......@@ -71,6 +75,9 @@ public class LiteOrderCache implements ITaskListener {
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
//其他出库模式一次性全部生成任务
List<StoragePos> lockPosList = storagePosManager.findLockPos(liteOrder.getOrderNo());
if(lockPosList==null){
throw new ValidateException("未找到锁定库位");
}
int taskReelCount = 0;
for (StoragePos lockPos : lockPosList) {
Storage storage = dataCache.getStorageById(lockPos.getStorageId());
......@@ -183,4 +190,149 @@ public class LiteOrderCache implements ITaskListener {
}
}
}
/**
* 锁定物料
*/
public synchronized String checkOutLiteOrder(String orderNo, boolean outBom) {
LiteOrder cacheOrder = liteOrderMap.get(orderNo);
if (cacheOrder != null && !cacheOrder.isTaskFinished() && !cacheOrder.isNew()) {
log.info("工单[" + orderNo + "]正在执行");
return "order.out.executing";
}
if (cacheOrder == null) {
cacheOrder = liteOrderManager.findByOrderNo(orderNo);
}
if (cacheOrder == null) {
return "order.out.notFound";
}
//设置颜色
Set<String> currentColors = new HashSet<>();
for (DataLog dataLog : taskService.getQueueTasks()) {
currentColors.add(dataLog.getLightColor());
}
ORDER_COLOR nextColor = ORDER_COLOR.nextColor(currentColors);
if (nextColor == null) {
log.info("执行工单[" + orderNo + "] outBom=" + outBom + "时,已达最大可执行工单数");
return "order.out.maxOrder";
}
log.info("开始执行工单[" + orderNo + "] outBom=" + outBom);
cacheOrder.setTaskReelCount(0);
cacheOrder.setTaskFinishedTime(-1);
cacheOrder.setFinishedReelCount(0);
if (outBom) {
cacheOrder.setStatus(LITEORDER_STATUS.BOM);
} else {
cacheOrder.setStatus(LITEORDER_STATUS.TAILS);
}
//liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
int taskReelCount = 0;
CHECKOUT_TYPE checkoutType = dataCache.getCheckOutType();
List<String> availableStorageIds = new ArrayList<>();
for (Storage storage : dataCache.getAllStorage().values()) {
//默认所有料仓可用
// StatusBean statusBean =dataCache. getStatus(storage.getCid());
// if (statusBean.isAvailable())
{
availableStorageIds.add(storage.getId());
}
}
//其他出库模式一次性全部生成任务
for (LiteOrderItem orderItem : cacheOrder.getOrderItems()) {
//剩余未出数量
Float totalNum = orderItem.getNeedNum() * cacheOrder.getOrderTimes();
int remainNum = totalNum.intValue() - orderItem.getOutNum();
//此PN未完成
if (remainNum > 0) {
if (outBom) {
//套料出库,设置剩余数量为1,这样就只会出一盘
remainNum = 1;
}
int assignNum = 0;
while (assignNum < remainNum) {
Collection<String> excludePosIds = excludePosIds();
String partNumber = orderItem.getPn();
StoragePos pos = storagePosManager.findPartNumberInStorages(availableStorageIds, partNumber, excludePosIds, checkoutType);
if (pos == null) {
log.error("未找到可以出库的物料[" + partNumber + "]");
break;
} else {
assignNum = assignNum + pos.getBarcode().getAmount();
taskReelCount = taskReelCount + 1;
log.info("工单[" + orderNo + "],任务数[" + taskReelCount + "]出库位置仓位【" + pos.getPosName() + "】RI=[" + pos.getBarcode().getBarcode() + "] PN=[" + partNumber + "] num:" + pos.getBarcode().getAmount());
DataLog task = newTask(pos) ;
task.setSourceId(cacheOrder.getId());
task.setSourceName(cacheOrder.getOrderNo());
task.setSubSourceId(orderItem.getId());
task.setSubSourceInfo(orderItem.getFeederInfo());
task.setType(OP.CHECKOUT);
task.setLightColor(nextColor.getRgb());
task.setStatus(OP_STATUS.WAIT.name());
// task = dataLogDao.save(task);
taskService.addTaskToExecute(task);
}
}
}
}
cacheOrder.setTaskReelCount(taskReelCount);
log.info("工单[" + orderNo + "]任务分配结束,任务数[" + taskReelCount + "]");
//有需要出库的
if (taskReelCount <= 0) {
cacheOrder.finishedTasks();
}
liteOrderManager.save(cacheOrder);
liteOrderMap.put(cacheOrder.getOrderNo(), cacheOrder);
if (taskReelCount <= 0) {
//return "工单无可执行的任务";
return "order.out.noTask";
}
return "";
}
/**
* 防止仓位任务重复,需要排除掉已经分配掉的仓位
*/
public Collection<String> excludePosIds() {
//排除掉正在执行的仓位
List<DataLog> allTasks = taskService.getAllTasks();
Collection<String> operatingPosIds = new HashSet<>();
for (DataLog task : allTasks) {
String posId = task.getPosId();
if (!Strings.isNullOrEmpty(posId)) {
operatingPosIds.add(task.getPosId());
}
}
return operatingPosIds;
}
public DataLog newTask(StoragePos pos) {
DataLog task = new DataLog();
Barcode barcode = pos.getBarcode();
if (barcode != null) {
task.setPartNumber(barcode.getPartNumber());
task.setBarcode(barcode.getBarcode());
task.setNum(barcode.getAmount());
task.setMemo(barcode.getMemo());
}
Storage storage = dataCache.getStorageById(pos.getStorageId());
task.setCid(storage.getCid());
task.setStorageId(storage.getId());
task.setStorageName(storage.getName());
task.setPosId(pos.getId());
task.setPosName(pos.getPosName());
return task;
}
}
......@@ -5,19 +5,27 @@ import com.google.common.collect.Lists;
import com.neotel.smfcore.common.annotation.QueryCondition;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.csv.CsvReader;
import com.neotel.smfcore.common.exception.BadRequestException;
import com.neotel.smfcore.common.exception.ValidateException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.order.LiteOrderCache;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import com.neotel.smfcore.core.order.rest.bean.dto.OrderDto;
import com.neotel.smfcore.core.order.rest.bean.mapstruct.OrderMapper;
import com.neotel.smfcore.core.order.rest.bean.query.OrderQueryCondition;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderItemManager;
import com.neotel.smfcore.core.order.service.manager.ILiteOrderManager;
import com.neotel.smfcore.core.order.service.po.LiteOrder;
import com.neotel.smfcore.core.order.service.po.LiteOrderItem;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.rest.bean.mapstruct.TaskMapper;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.bean.FileProperties;
import com.neotel.smfcore.security.rest.bean.vo.UserPassVo;
import com.neotel.smfcore.security.service.manager.IGroupManager;
import com.neotel.smfcore.security.service.manager.IRoleManager;
......@@ -29,6 +37,7 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
......@@ -41,7 +50,11 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
......@@ -69,6 +82,8 @@ public class OrderController {
@Autowired
private LiteOrderCache liteOrderCache;
@Autowired
private final FileProperties properties;
// @ApiOperation("导出用户数据")
// @GetMapping(value = "/download")
// @PreAuthorize("@el.check('user:list')")
......@@ -78,39 +93,75 @@ public class OrderController {
@ApiOperation("上传工单")
@PostMapping(value = "/upload")
public ResultBean updateAvatar(@RequestParam MultipartFile orderFile){
@AnonymousAccess
public ResultBean updateAvatar(@RequestParam MultipartFile orderFile) {
return null;
String image = "csv";
String fileType = FileUtil.getExtensionName(orderFile.getOriginalFilename());
if (fileType != null && !image.contains(fileType)) {
throw new BadRequestException("文件格式错误!, 仅支持 " + image + " 格式");
}
File folder = new File(properties.getPath(), "pos");
File localFile = FileUtil.upload(orderFile, folder.getAbsolutePath());
List<LiteOrderItem> liteOrderItems = handleOrderCsv(localFile.getAbsolutePath());
if (liteOrderItems == null || liteOrderItems.size() <= 0) {
throw new BadRequestException("文件解析失败");
}
LiteOrder liteOrder = new LiteOrder(localFile.getName(), liteOrderItems);
liteOrder.setSource(localFile.getAbsolutePath());
liteOrder.setStatus(LITEORDER_STATUS.NEW);
LiteOrder dbOrder = liteOrderManager.findByOrderNo(liteOrder.getOrderNo());
if (dbOrder == null) {
log.info("新增加订单:" + liteOrder.getOrderNo());
liteOrder = liteOrderManager.createWithItems(liteOrder);
// TaskService.liteOrderMap.put(liteOrder.getOrderNo(), liteOrder);
} else {
log.info("数据库中已存在工单号为[" + liteOrder.getOrderNo() + "],忽略文件:" + localFile.getAbsolutePath());
throw new BadRequestException("工单号[" + liteOrder.getOrderNo() + "]已存在");
}
return ResultBean.newOkResult("工单上传成功");
}
@ApiOperation("工单出库")
@PostMapping(value = "/out")
@PreAuthorize("@el.check('order:out')")
public ResultBean delete(@RequestBody String orderNo) {
public ResultBean delete(@RequestBody Map<String,String> mapValues) {
String orderNo = mapValues.get("orderNo");
if (orderNo == null) {
throw new BadRequestException("工单号不能为空");
}
LiteOrder liteOrder = liteOrderManager.findByOrderNo(orderNo);
ResultBean resultBean = liteOrderCache.checkOutOrder(liteOrder);
return resultBean;
if (liteOrder == null) {
throw new BadRequestException("未找到工单:" + orderNo);
}
// ResultBean resultBean = liteOrderCache.checkOutOrder(liteOrder);
String result = liteOrderCache.checkOutLiteOrder(orderNo, false);
return ResultBean.newOkResult(result);
}
@ApiOperation("查询工单")
@GetMapping
@PreAuthorize("@el.check('order:list')")
public PageData<OrderDto> query(OrderQueryCondition criteria, Pageable pageable){
public PageData<OrderDto> query(OrderQueryCondition criteria, Pageable pageable) {
User user = userManager.findByUserName(SecurityUtils.getCurrentUsername());
if(user != null){
if (user != null) {
//数据权限
if(!user.getIsAdmin()){
if (!user.getIsAdmin()) {
Set<String> groupIds = user.getGroups();
List<String> groupNames = Lists.newArrayList();
if(!ObjectUtils.isEmpty(groupIds)){
if (!ObjectUtils.isEmpty(groupIds)) {
for (String groupId : groupIds) {
Group group = groupManager.get(groupId);
groupNames.add(group.getGroupName());
}
}
//都没有权限,返回空
if(ObjectUtils.isEmpty(groupNames)){
return new PageData<>(Lists.newArrayList(),0);
if (ObjectUtils.isEmpty(groupNames)) {
return new PageData<>(Lists.newArrayList(), 0);
}
criteria.setSourceList(groupNames);
}
......@@ -118,4 +169,66 @@ public class OrderController {
PageData<LiteOrder> orderList = liteOrderManager.findByPage(QueryHelp.getQuery(criteria), pageable);
return orderMapper.toDto(orderList);
}
private int getCsvIndex(CsvReader csvReader, String titleName, String titleNameEn) {
int index = csvReader.getIndex(titleName, titleNameEn);
if (index == -1) {
log.info("未包含【" + titleName + "】或【" + titleNameEn + "】列");
throw new ValidateException("必须包含[" + titleNameEn + "]列");
}
return index;
}
protected List<LiteOrderItem> handleOrderCsv(String fileURL) {
try {
log.info("开始更解析上传的工单");
List<LiteOrderItem> items = Lists.newArrayList();
CsvReader csvRead = new CsvReader(fileURL);
csvRead.setSkipEmptyRecords(true);//忽略空行
csvRead.setTrimWhitespace(true);//去除空格
csvRead.readHeaders();
int partNumberIndex = csvRead.getIndex("PN", "PN");
int qtyIndex = csvRead.getIndex("NUM", "QTY");
int feederIndex = csvRead.getIndex("FEEDER", "FEEDER");
int row = 1;
int newRowCount = 0;
int updateRowCount = 0;
while (csvRead.readRecord()) {
row++;
String[] lineValues = csvRead.getValues();
String partNumber = lineValues[partNumberIndex];
if (partNumber.isEmpty()) {
log.warn("行[partNumber=" + partNumber + "]中PN 为空,此行忽略");
} else {
int num = 1;
if (qtyIndex != -1) {
String numStr = lineValues[qtyIndex];
if (Strings.isNotBlank(numStr)) {
try {
num = Integer.valueOf(numStr);
} catch (Exception e) {
log.error(partNumber + "的数量:" + numStr + " 不是数字,使用1");
}
}
}
String feeder = "";
if (feederIndex != -1) {
feeder = lineValues[feederIndex];
}
LiteOrderItem item = new LiteOrderItem();
item.setPn(partNumber);
item.setNeedNum(num);
item.setFeederInfo(feeder);
items.add(item);
}
}
return items;
} catch (Exception ex) {
log.error("解析上传的工单出错:" + ex.toString());
}
return null;
}
}
package com.neotel.smfcore.core.order.rest.bean.dto;
import com.neotel.smfcore.core.order.enums.LITEORDER_STATUS;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Transient;
......@@ -11,44 +12,61 @@ import java.util.List;
@Getter
@Setter
public class OrderDto implements Serializable {
@ApiModelProperty(value = "ID")
private String id;
/**
* 订单号
*/
@ApiModelProperty("工单号")
private String orderNo;
/**
* 当前任务盘数
*/
@ApiModelProperty("当前任务盘数")
private int taskReelCount = 0;
/**
* 当前任务已完成盘数
*/
@ApiModelProperty("当前任务已完成盘数")
private int finishedReelCount = 0;
/**
* 订单状态
* 0=新建工单
* 1=首套料正在执行
* 2=首盘料已结束,等待出尾料
* 3=正在出尾料
* 4=尾料已完成
* 5=正在补料
* 6=补料已完成
*/
@ApiModelProperty("订单状态")
private int status = LITEORDER_STATUS.NEW;
/**
* 出库状态, 2表示已完成
*/
@ApiModelProperty("出库状态, 2表示已完成")
private boolean closed = false;
/**
* 工单来源
*/
@ApiModelProperty("工单来源")
private String source = "";
/**
* 任务完成时间(用于关闭页面显示)
*/
@ApiModelProperty("任务完成时间(用于关闭页面显示)")
@Transient
private long taskFinishedTime = -1;
/**
* 套(倍)数
*/
@ApiModelProperty("套(倍)数")
private float orderTimes = 1f;
}
......@@ -31,7 +31,13 @@ public class LiteOrderManagerImpl implements ILiteOrderManager {
@Override
public LiteOrder findByOrderNo(String orderNo) {
return liteOrderDao.findOneByCondition(new String[] {"orderNo"}, new String[] {orderNo});
LiteOrder order= liteOrderDao.findOneByCondition(new String[] {"orderNo"}, new String[] {orderNo});
if(order!=null&& order.getOrderItems()==null){
List<LiteOrderItem> items=liteOrderItemManager.findOrderItems(orderNo);
order.setOrderItems(items);
}
return order;
}
@Override
......
......@@ -205,9 +205,16 @@ public class StorageController {
return ResultBean.newOkResult(resultMsg);
}
/**
*
*/
private int getCsvIndex(CsvReader csvReader, String titleName, String titleNameEn) {
int index = csvReader.getIndex(titleName, titleNameEn);
if (index == -1) {
log.info("未包含【" + titleName + "】或【" + titleNameEn + "】列");
throw new ValidateException("必须包含[" + titleNameEn + "]列");
}
return index;
}
protected String handleStoragePos(String fileURL, String storageId) throws Exception
{
log.info("开始更新料仓【"+storageId+"】的位置信息");
......@@ -220,30 +227,15 @@ public class StorageController {
log.error("Storage id is not exist");
throw new ValidateException("storage.error.notExist");
}
CsvReader csvRead = new CsvReader(fileURL);
csvRead.setSkipEmptyRecords(true);//忽略空行
csvRead.setTrimWhitespace(true);//去除空格
csvRead.readHeaders();
int posIndex = csvRead.getIndex("位置","pos");
if(posIndex == -1){
log.info("未包含【位置】或【pos】列");
throw new ValidateException("必须包含[位置]列");
}
int priIndex = csvRead.getIndex("优先级","pri");
if (priIndex == -1){
log.info("未包含【优先级】或【pri】列");
throw new ValidateException("必须包含[优先级]列");
}
int hIndex = csvRead.getIndex("高度","h");
if (hIndex == -1){
log.info("未包含【高度】或【h】列");
throw new ValidateException("必须包含【高度】列");
}
int wIndex = csvRead.getIndex("宽度","w");
if (wIndex == -1){
log.info("未包含【宽度】或【w】列");
throw new ValidateException("必须包含【宽度】列");
}
int posIndex =getCsvIndex(csvRead, "位置","pos");
int priIndex = getCsvIndex(csvRead,"优先级","pri");
int hIndex = getCsvIndex(csvRead,"高度","h");
int wIndex = getCsvIndex(csvRead,"宽度","w");
int row = 1;
int newRowCount = 0;
......@@ -263,6 +255,7 @@ public class StorageController {
if(posInfo == null){
posInfo = new StoragePos();
posInfo.setPosName(posName);
posInfo.setStorageId(storageId);
newRowCount++;
}else{
updateRowCount++;
......
package com.neotel.smfcore.core.storage.rest;
import com.google.common.base.Strings;
import com.neotel.smfcore.common.bean.PageData;
import com.neotel.smfcore.common.exception.BadRequestException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.QueryHelp;
import com.neotel.smfcore.common.utils.StorageConstants;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.storage.rest.dto.CheckOutDto;
import com.neotel.smfcore.core.storage.rest.dto.StoragePosDto;
import com.neotel.smfcore.core.storage.rest.dto.StoragePosEnabledDto;
import com.neotel.smfcore.core.storage.rest.dto.StoragePosSaveDto;
import com.neotel.smfcore.core.storage.rest.mapstruct.StoragePosMapper;
import com.neotel.smfcore.core.storage.rest.query.StoragePosFindCriteria;
import com.neotel.smfcore.core.storage.rest.query.StoragePosQueryCriteria;
import com.neotel.smfcore.core.storage.service.dao.IStoragePosDao;
import com.neotel.smfcore.core.storage.service.manager.IStoragePosManager;
import com.neotel.smfcore.core.storage.service.po.Storage;
import com.neotel.smfcore.core.storage.service.po.StoragePos;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
......@@ -20,6 +28,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
......@@ -27,9 +36,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.regex.Pattern;
@Slf4j
@RestController
......@@ -46,6 +55,9 @@ public class StoragePosController {
private final StoragePosMapper storagePosMapper;
@Autowired
private DataCache dataCache;
@Autowired
private TaskService taskService;
@ApiOperation("查询库位")
......@@ -144,4 +156,71 @@ public class StoragePosController {
storagePosManager.deletePoss(ids);
return new ResponseEntity<>(HttpStatus.OK);
}
@ApiOperation("查找出库列表")
@GetMapping("/find")
@PreAuthorize("@el.check('storage:list')")
public PageData<StoragePosDto> storagePosFind(StoragePosFindCriteria criteria, Pageable pageable,HttpServletRequest request){
Query query= QueryHelp.getQuery(criteria);
Criteria baseCriteria= Criteria.where("used").is(true);
int componentType = criteria.getType();
String name="";
if(componentType != -1){
int type = componentType;
request.setAttribute("type", componentType);
if(componentType == 41){//锡膏夹具
type = COMPONENT_TYPE.FIXTURE;
name = StorageConstants.PACKAGE_TYPE.SOLDER_FIXTURE.getCode();
}else if(componentType == 42){//PCB夹具
type = COMPONENT_TYPE.FIXTURE;
name = StorageConstants.PACKAGE_TYPE.PCB_FIXTURE.getCode();
}
baseCriteria.and("barcode.type").is(type);
}
String expire = criteria.getExpire();
if(!Strings.isNullOrEmpty(expire)){
if("solder".equalsIgnoreCase(expire)){
baseCriteria.and("barcode.expTime").lte(new Date());
}else if("pcb".equalsIgnoreCase(expire)){
baseCriteria.and("barcode.expireDate").lte(new Date());
}
request.setAttribute("expire",expire);
}
query.addCriteria(baseCriteria);
PageData<StoragePos> pages=storagePosManager.findByPage(query,pageable);
List<StoragePosDto> StoragePosDtos=storagePosMapper.toDto(pages.getContent());
return new PageData(StoragePosDtos,pages.getTotalElements());
}
@ApiOperation("查找出库")
@PutMapping("/checkout")
public ResponseEntity<Object> checkout(@Validated @RequestBody CheckOutDto checkOutDto) {
String isSingleOutStr = checkOutDto.getSingleOut();
boolean isSingleOut = Boolean.valueOf(isSingleOutStr);
String pids = checkOutDto.getPids();
for (String pid : pids.split(";")) {
StoragePos pos = storagePosManager.get(pid);
if (pos == null) {
throw new BadRequestException("位置[" + pid + "]不存在");
}
Storage storage = dataCache.getStorageById(pos.getStorageId());
if (storage == null) {
throw new BadRequestException("料仓[" + pos.getStorageId() + "]不存在");
}
log.info("出库料仓【" + storage.getName() + "_" + storage.getCid() + "】位置仓位【" + pos.getPosName() + "】");
String outResult = taskService.checkout(storage, pos, isSingleOut);
if (!Strings.isNullOrEmpty(outResult)) {
throw new BadRequestException(outResult);
}
}
return new ResponseEntity<>(HttpStatus.OK);
}
}
package com.neotel.smfcore.core.storage.rest.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class CheckOutDto {
@ApiModelProperty("库位号,多个用;分隔")
private String pids;
@ApiModelProperty("是否是单盘出库")
private String singleOut;
}
package com.neotel.smfcore.core.storage.rest.dto;
import com.neotel.smfcore.core.barcode.rest.bean.dto.BarcodeDto;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
......@@ -18,7 +19,7 @@ public class StoragePosDto implements Serializable {
private String storageId;
@ApiModelProperty("条码")
private Barcode barcode;
private BarcodeDto barcode;
@ApiModelProperty("库位号")
private String posName;
......
package com.neotel.smfcore.core.storage.rest.query;
import com.neotel.smfcore.common.annotation.QueryCondition;
import com.neotel.smfcore.common.bean.BetweenData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
@Data
public class StoragePosFindCriteria {
@QueryCondition(blurry = "barcode,posName")
private String blurry;
@QueryCondition(type = QueryCondition.Type.BETWEEN, propName = "updateDate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private BetweenData<Date> createDate;
@QueryCondition
@ApiModelProperty("料仓ID")
private String storageId;
@QueryCondition(propName = "barcode.barcode")
@ApiModelProperty("条码")
private String barcode;
@QueryCondition
@ApiModelProperty("库位号")
private String posName;
@ApiModelProperty("类型")
private int type =-1 ;
@ApiModelProperty("是否过期")
private String expire;
@QueryCondition(blurry = "barcode.providerNumber" )
private String providerNumber;
@QueryCondition(blurry = "barcode.partNumber")
private String partNumber;
@QueryCondition(blurry = "barcode.memo")
private String memo;
@QueryCondition(propName = "barcode.lockId")
private String lockId;
@QueryCondition(blurry = "barcode.batch")
private String batch;
@QueryCondition(blurry = "barcode.provider")
private String provider;
@QueryCondition(blurry = "barcode.otherField1")
private String otherField1;
@QueryCondition(blurry = "barcode.otherField2")
private String otherField2;
@QueryCondition(blurry = "barcode.otherField3")
private String otherField3;
@QueryCondition(blurry = "barcode.otherField4")
private String otherField4;
@QueryCondition(blurry = "barcode.otherField5")
private String otherField5;
}
......@@ -15,11 +15,10 @@
*/
package com.neotel.smfcore.security.rest;
import com.neotel.smfcore.common.utils.*;
import com.neotel.smfcore.security.annotation.AnonymousDeleteMapping;
import com.neotel.smfcore.security.annotation.AnonymousGetMapping;
import com.neotel.smfcore.security.annotation.AnonymousPostMapping;
import com.neotel.smfcore.common.utils.EncryptUtils;
import com.neotel.smfcore.common.utils.StringUtils;
import com.neotel.smfcore.security.bean.RsaProperties;
import com.neotel.smfcore.security.TokenProvider;
import com.neotel.smfcore.security.bean.LoginProperties;
......@@ -28,8 +27,6 @@ import com.neotel.smfcore.security.rest.bean.dto.OnlineUserDto;
import com.neotel.smfcore.security.service.OnlineUserService;
import com.neotel.smfcore.security.rest.bean.dto.AuthUserDto;
import com.neotel.smfcore.security.rest.bean.dto.JwtUserDto;
import com.neotel.smfcore.common.utils.RsaUtils;
import com.neotel.smfcore.common.utils.SecurityUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
......@@ -103,7 +100,8 @@ public class AuthorizationController {
OnlineUserDto onlineUserDto = null;
try {
long seconds = onlineUserService.properties.getTokenValidityInSeconds() / 1000;
onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), browser , ip, address, EncryptUtils.desEncrypt(token), new Date());
Date exTime= DateUtil.addSeconds(new Date(), new Long(seconds).intValue());
onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), browser , ip, address, EncryptUtils.desEncrypt(token), new Date(),exTime);
} catch (Exception e) {
log.error(e.getMessage(),e);
}
......
......@@ -59,6 +59,10 @@ public class OnlineUserDto {
* 登录时间
*/
private Date loginTime;
/**
* 过期时间
*/
private Date expiresTime;
}
......@@ -23,6 +23,8 @@ import com.neotel.smfcore.security.rest.bean.dto.OnlineUserDto;
import com.neotel.smfcore.common.utils.EncryptUtils;
import com.neotel.smfcore.common.utils.FileUtil;
import com.neotel.smfcore.common.utils.StringUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
......@@ -128,7 +130,26 @@ public class OnlineUserService {
* @return /
*/
public OnlineUserDto getOne(String key) {
return (OnlineUserDto)onlineUserMap.get(key);
OnlineUserDto dto = null;
dto = (OnlineUserDto) onlineUserMap.get(key);
if(dto==null) {
//已过期抛异常
throw new ExpiredJwtException(null, null, "token 已过期, 未找到用户信息");
}
Date currTime = new Date();
int result = dto.getExpiresTime().compareTo(new Date());
if (result > 0) {
//更新过期时间
long seconds = properties.getTokenValidityInSeconds() / 1000;
Date exTime = DateUtil.addSeconds(new Date(), new Long(seconds).intValue());
dto.setExpiresTime(exTime);
} else if (result < 0) {
this.kickOut(key);
//已过期抛异常
throw new ExpiredJwtException(null, null, "token 已过期,过期时间:"+dto.getExpiresTime());
}
return dto;
}
/**
......
......@@ -17,6 +17,8 @@ package com.neotel.smfcore.security.service;
import com.neotel.smfcore.common.exception.BadRequestException;
import com.neotel.smfcore.common.exception.EntityNotFoundException;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.Md5Utls;
import com.neotel.smfcore.security.bean.LoginProperties;
import com.neotel.smfcore.security.rest.bean.dto.JwtUserDto;
import com.neotel.smfcore.security.service.manager.IMenuManager;
......@@ -85,6 +87,15 @@ public class UserDetailsServiceImpl implements UserDetailsService {
if (!user.getEnabled()) {
throw new BadRequestException("账号未激活!");
}
if(user.getUsername().equals(Constants.SUPER_USERNAME)){
}else {
//判断激活码是否正确
String code = Md5Utls.getMd5(user.getId(), user.getCreateDate());
if (!code.equals(user.getCheckCode())) {
throw new BadRequestException("账号未激活!");
}
}
List<Long> dataScopes = new ArrayList<>();
jwtUserDto = new JwtUserDto(
user,
......
......@@ -36,8 +36,8 @@ jwt:
token-start-with: Bearer
# 必须使用最少88位的Base64对该令牌进行编码
base64-secret: ZmQ0ZGI5NjQ0MDQwY2I4MjMxY2Y3ZmI3MjdhN2ZmMjNhODViOTg1ZGE0NTBjMGM4NDA5NzYxMjdjOWMwYWRmZTBlZjlhNGY3ZTg4Y2U3YTE1ODVkZDU5Y2Y3OGYwZWE1NzUzNWQ2YjFjZDc0NGMxZWU2MmQ3MjY1NzJmNTE0MzI=
# 令牌过期时间 此处单位/毫秒 ,默认4小时,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 14400000
# 令牌过期时间 此处单位/毫秒 ,默认30分钟,可在此网站生成 https://www.convertworld.com/zh-hans/time/milliseconds.html
token-validity-in-seconds: 1800000
# 在线用户key
online-key: online-token-
# 验证码
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!