Commit dc0fc73d sunke

Init

0 个父辈
此文件类型无法预览
此文件的差异被折叠, 点击展开。
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.neotel</groupId>
<artifactId>webBox</artifactId>
<version>1.27.614</version>
<name>webBox</name>
<description>webBox</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.neotel.webbox;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebBoxApplication {
public static void main(String[] args) {
SpringApplication.run(WebBoxApplication.class, args);
}
}
package com.neotel.webbox.capacity;
import com.neotel.webbox.capacity.bean.*;
import com.neotel.webbox.capacity.data.BaseDataCache;
import com.neotel.webbox.capacity.method.AssignMethod1;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@Slf4j
@RestController
public class BoxRestController {
@RequestMapping("/baseData")
public ResultBean baseData() {
Map<String,Object> map = new HashMap<>();
List<BoxData> boxDataList = new ArrayList<>(BaseDataCache.getBoxDataList());
boxDataList.sort(new Comparator<BoxData>() {
@Override
public int compare(BoxData o1, BoxData o2) {
return o1.getBoxName().compareTo(o2.getBoxName());
}
});
map.put("boxDataList",boxDataList);
Collection<ReelData> reelNameList = BaseDataCache.getReelDataList();
Map<Integer,List<Integer>> reelSizeMap = new HashMap<>();
for (ReelData reelData : reelNameList) {
int reelSize = reelData.getReelSize();
List<Integer> reelHeightList = reelSizeMap.get(reelSize);
if(reelHeightList == null){
reelHeightList = new ArrayList<>();
}
int reelHeight = reelData.getReelHeight();
reelHeightList.add(reelHeight);
reelHeightList.sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
reelSizeMap.put(reelSize,reelHeightList);
}
map.put("reelSizeMap",reelSizeMap);
return ResultBean.newOkResult(map);
}
@RequestMapping("/capacity")
public ResultBean capacityCalculation(@RequestBody Map<String,String> paramMap) {
try{
String boxName = paramMap.get("boxName");
log.info("收到计算料仓数量请求:" + boxName);
BoxData boxData = BaseDataCache.getBoxData(boxName);
if(boxData == null){
String msg = "未找到"+boxName+"对应的料仓";
log.warn(msg);
return ResultBean.newErrorResult(101,msg);
}
List<RequestItem> requestList = new ArrayList<>();
for (Map.Entry<String, String> item : paramMap.entrySet()) {
if(item.getKey().equals("boxName")){
continue;
}
ReelData reelData = BaseDataCache.getReelData(item.getKey());
if(reelData == null){
String msg = "未找到"+boxName+"对应的料盘"+ item.getKey();
log.warn(msg);
return ResultBean.newErrorResult(102,msg);
}
log.info("料盘需求" + item.getKey() + ":" + item.getValue());
int num = Integer.valueOf(item.getValue());
requestList.add(new RequestItem(num,reelData));
}
if(requestList.isEmpty()){
String msg = "Params Error";
log.warn(msg);
return ResultBean.newErrorResult(102,msg);
}
BoxResult boxResult = AssignMethod1.averageAssignToBox(boxData,requestList);
log.info("方案一共需要"+boxResult.getBoxList().size()+"个料仓");
for (ReelItem reelItem : boxResult.getReelItemList()) {
log.info(reelItem.getSizeStr()+" 料盘需求:" + reelItem.getNeedNum() + " 容量:" + reelItem.getCapacity());
}
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("boxCount", boxResult.getBoxList().size());
List<Map<String,Object>> capacityItems = new ArrayList<>();
for (ReelItem reelItem : boxResult.getReelItemList()) {
Map<String,Object> dataMap = new HashMap<>();
int needNum = reelItem.getNeedNum();
int capacity = reelItem.getCapacity();
int w = reelItem.getW();
int h = reelItem.getH();
dataMap.put("w",w);
dataMap.put("h",h);
dataMap.put("capacity",capacity);
dataMap.put("needNum",needNum);
capacityItems.add(dataMap);
}
resultMap.put("boxName",boxName);
resultMap.put("capacityItems",capacityItems);
return ResultBean.newOkResult(resultMap);
}catch (Exception e){
log.error("计算料仓数量时发生异常",e);
return ResultBean.newErrorResult(500,"Error");
}
}
}
package com.neotel.webbox.capacity.bean;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BoxData {
/**
* 料仓名称
*/
@ExcelProperty("料仓名称")
private String boxName;
/**
* 料仓高度
*/
@ExcelProperty("料仓高度")
private int boxHeight;
/**
* 料仓不可用高度655
*/
@ExcelProperty("不可用高度")
private int boxInvalidHeight = 655;
/**
* 料仓口高度
*/
@ExcelProperty("仓门高度")
private int doorHeight = 1160;
/**
* 进口下部可用高度
*/
@ExcelProperty("进口下部")
private int doorDownHeight;
/**
* 列数
*/
@ExcelProperty("列数")
private int columnCount;
/**
* 纯放此规格料盘的容量
* @return
*/
public int getBoxPureSizeCapacity(ReelData reelData){
//每一列可放料盘数量
int columnPureSizeCapacity = getColumnPureSizeCapacity(reelData.getPressHeight(),reelData);
//入料口下部可放料盘数量
int entranceUpCapacity = getDoorUpCapacity(reelData.getPressHeight(),reelData);
//入料口下部可放料盘数量
int entranceDownCapacity = getDoorDownCapacity(reelData.getPressHeight(),reelData);
int total = 6 * columnPureSizeCapacity + entranceUpCapacity + entranceDownCapacity;
return total;
}
/**
* 料仓列可用高度,总高-不可用高度(下方电气板) - 压紧轴占用高度
*/
public int getColumnValidHeight(int pressHeight){
return getBoxHeight() - getBoxInvalidHeight() - pressHeight;
}
/**
* 入料口上方可用空间(总高度 - 门高度 - 下方高度 - 压紧高度)
*/
public int getDoorUpValidHeight(int pressHeight){
int columnValidHeight = getBoxHeight() - this.getDoorHeight() -getBoxInvalidHeight() - pressHeight;
return columnValidHeight;
}
/**
* 入料口下方可用空间(下方高度 - 压紧高度)
*/
public int getDoorDownValidHeight(int pressHeight){
int columnValidHeight = getDoorDownHeight()/* - pressHeight*/;
return columnValidHeight;
}
/**
* 整列可放料盘数
*/
public int getColumnPureSizeCapacity(int pressHeight, ReelData reelData){
int columnValidHeight = getColumnValidHeight(pressHeight);
//每一列可放料盘数量
int columnPureSizeCapacity = getColumnPureSizeCapacity(columnValidHeight, reelData.getReelSize(), reelData.getReelSlotHeight(), false);
return columnPureSizeCapacity;
}
/**
* 入料口上方可放料盘数
*/
public int getDoorUpCapacity(int pressHeight, ReelData reelData){
return getColumnPureSizeCapacity(getDoorUpValidHeight(pressHeight),reelData.getReelSize(), reelData.getReelSlotHeight(), false);
}
/**
* 入料口下方可放料盘数
*/
public int getDoorDownCapacity(int pressHeight, ReelData reelData){
return getColumnPureSizeCapacity(this.getDoorDownValidHeight(pressHeight),reelData.getReelSize(), reelData.getReelSlotHeight(), true);
}
/**
* 根据可用空间和料盘尺寸计算料盘容量
* @param reelSize 料盘尺寸
* @param validHeight 可用高度
* @param reelSpaceHeight 单个格子占用高度
* @param isDoorDown 是否是入口下方空间
* @return 容量
*/
private int getColumnPureSizeCapacity(int validHeight, int reelSize, int reelSpaceHeight, boolean isDoorDown){
int countPerColumn = validHeight / reelSpaceHeight;
//如果不是入料口下方,每一列上部可多放一盘
if(!isDoorDown){
if(reelSize == 7 || validHeight % reelSpaceHeight != 0){
//如果有空余可以再放一盘,7寸盘可以多放一盘
countPerColumn = countPerColumn + 1;
}
}
//每个格子可放料盘数,7寸盘为2盘,其他为1
int countPerUnit = 1;
if(reelSize == 7){
countPerUnit = 2;
}
int capacity = countPerColumn * countPerUnit;
return capacity;
}
public int getTotalValidHeight(int pressHeight){
return this.getColumnCount() * getColumnValidHeight(pressHeight) + getDoorUpValidHeight(pressHeight) + this.getDoorDownValidHeight(pressHeight);
}
/**
* 是否有效
* @return
*/
public boolean isValid() {
return !boxName.isEmpty()
&& boxHeight >= 1000
&& boxInvalidHeight >= 100
&& doorHeight >=100
&& doorDownHeight >=100
&& columnCount >= 1;
}
}
package com.neotel.webbox.capacity.bean;
import com.neotel.webbox.capacity.box.Box;
import lombok.Getter;
import lombok.Setter;
import java.util.*;
@Getter
@Setter
public class BoxResult {
private List<Box> boxList;
private List<RequestItem> requestList = new ArrayList<>();
public List<ReelItem> getReelItemList(){
List<ReelItem> reelItemList = initRequestNum(requestList);
if(boxList != null){
for (Box box : boxList) {
for (ReelItem boxReelItem : box.getCapacity().values()) {
reelItemList = addBoxCapacityToResult(reelItemList,boxReelItem);
}
}
}
return reelItemList;
}
private List<ReelItem> addBoxCapacityToResult(List<ReelItem> reelItemList, ReelItem boxReelItem){
for (ReelItem totalReelItem : reelItemList) {
if(totalReelItem.getSizeStr().equals(boxReelItem.getSizeStr())){
totalReelItem.addCapacity(boxReelItem.getCapacity());
return reelItemList;
}
}
//未找到,新添加一个
reelItemList.add(boxReelItem);
return reelItemList;
}
private List<ReelItem> initRequestNum(Collection<RequestItem> requestList){
List<ReelItem> reelItemList = new ArrayList<>();
for (RequestItem reelRequestItem : requestList) {
ReelItem reelItem = new ReelItem();
reelItem.setW(reelRequestItem.getReelData().getReelSize());
reelItem.setH(reelRequestItem.getReelData().getReelHeight());
reelItem.setNeedNum(reelRequestItem.getNum());
reelItemList.add(reelItem);
}
return reelItemList;
}
}
package com.neotel.webbox.capacity.bean;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ReelData {
/**
* 料盘尺寸
*/
@ExcelProperty("料盘尺寸")
private int reelSize;
/**
* 料盘高度
*/
@ExcelProperty("料盘厚度")
private int reelHeight;
/**
* 压紧张开高度
*/
@ExcelProperty("压紧张开高度")
private int pressHeight;
/**
* 料盘占用空间高度
*/
@ExcelProperty("料格占用高度")
private int reelSlotHeight;
/**
* 最小模组单元
*/
private int minUnit = 3;
/**
* 是否是7寸盘
*/
public boolean is7Reel(){
return reelSize == 7;
}
public String getReelSizeStr(){
return reelSize + " x " + reelHeight;
}
public boolean isValid() {
return reelSize >= 7
&& reelHeight >= 8
&& pressHeight >= 10
&& reelSlotHeight >= 10;
}
}
package com.neotel.webbox.capacity.bean;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ReelItem {
private int w;
private int h;
private int needNum;
private int capacity;
public void addCapacity(int num){
capacity = capacity + num;
}
public String getSizeStr(){
return w + " x " + h;
}
}
package com.neotel.webbox.capacity.bean;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class RequestItem {
public RequestItem(int num, ReelData reelData) {
this.num = num;
this.reelData = reelData;
}
/**
* 需求数量
*/
private int num;
/**
* 料盘数量
*/
private ReelData reelData;
/**
* 需要纯料仓的数量
*/
private int pureBoxCount;
/**
* 放完纯料仓后剩余数量
*/
private int remainNum;
/**
* 剩余物料需要的总高度
*/
public int getRemainNeedHeight(){
int reelCount = remainNum;
if(reelData.is7Reel()){
//7寸盘,每行放2个
reelCount = reelCount /2;
if(remainNum % 2 != 0){
reelCount = reelCount + 1;
}
}
return reelCount * reelData.getReelSlotHeight();
}
public String getReelSizeStr(){
return reelData.getReelSizeStr();
}
}
package com.neotel.webbox.capacity.bean;
public class ResultBean {
private int code;
private String msg;
private Object data;
public static ResultBean newOkResult(Object data){
ResultBean resultBean = new ResultBean();
resultBean.setMsg("OK");
resultBean.setData(data);
return resultBean;
}
public static ResultBean newErrorResult(int code, String msg){
ResultBean resultBean = new ResultBean();
resultBean.setCode(code);
resultBean.setMsg(msg);
resultBean.setData("");
return resultBean;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
package com.neotel.webbox.capacity.box;
import com.neotel.webbox.capacity.bean.BoxData;
import com.neotel.webbox.capacity.bean.ReelItem;
import lombok.Getter;
import lombok.Setter;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
public class Box {
/**
* 标准列数量
*/
private int columnCount;
/**
* 标准列
*/
private Column column;
private Column doorUp;
private Column doorDown;
public static Box newBox(BoxData boxData,int maxPressHeight){
int validColumnHeight = boxData.getColumnValidHeight(maxPressHeight);
int doorUpValidHeight = boxData.getDoorUpValidHeight(maxPressHeight);
int doorDownValidHeight = boxData.getDoorDownValidHeight(maxPressHeight);
Box box = new Box();
Column doorDown = new Column(doorDownValidHeight);
box.setDoorDown(doorDown);
Column doorUp = new Column(doorUpValidHeight);
box.setDoorUp(doorUp);
Column column = new Column(validColumnHeight);
box.setColumn(column);
return box;
}
/**
* 获取料仓的容量明细
*/
public Map<String, ReelItem> getCapacity(){
Map<String,ReelItem> capacityMap = new HashMap<>();
for (int i = 0; i < getColumnCount(); i++) {
capacityMap = addToMap(capacityMap, column.getColumnCapacity());
}
capacityMap = addToMap(capacityMap, doorDown.getColumnCapacity());
capacityMap = addToMap(capacityMap, doorUp.getColumnCapacity());
return capacityMap;
}
private Map<String,ReelItem> addToMap(Map<String,ReelItem> capacityMap,Map<String,ReelItem> columnMap){
for (Map.Entry<String, ReelItem> entry : columnMap.entrySet()) {
String sizeStr = entry.getKey();
ReelItem capacityItem = capacityMap.get(sizeStr);
if(capacityItem == null){
capacityItem = new ReelItem();
capacityItem.setW(entry.getValue().getW());
capacityItem.setH(entry.getValue().getH());
}
int capacity = capacityItem.getCapacity() + entry.getValue().getCapacity();
capacityItem.setCapacity(capacity);
capacityMap.put(sizeStr,capacityItem);
}
return capacityMap;
}
}
package com.neotel.webbox.capacity.box;
import com.neotel.webbox.capacity.bean.ReelData;
import com.neotel.webbox.capacity.bean.ReelItem;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.compress.utils.Lists;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Getter
@Setter
public class Column {
public Column(int validHeight) {
this.validHeight = validHeight;
this.remainHeight = validHeight;
}
private int validHeight;
private int remainHeight;
private List<SlotUnit> slotUnitList = Lists.newArrayList();
public SlotUnit getSlotUnit(ReelData reelData){
for (SlotUnit slotUnit : slotUnitList) {
if(slotUnit.getReelData().equals(reelData)){
return slotUnit;
}
}
return null;
}
public SlotUnit mergeSlotUnit(SlotUnit newSlotUnit){
if(newSlotUnit == null){
return null;
}
SlotUnit existSlotUnit = getSlotUnit(newSlotUnit.getReelData());
if(existSlotUnit != null){
int mergeCount = newSlotUnit.getReelCount() + existSlotUnit.getReelCount();
newSlotUnit.setReelCount(mergeCount);
remainHeight = remainHeight + existSlotUnit.getSlotHeight();
slotUnitList.remove(existSlotUnit);
}
return addSlotUnit(newSlotUnit);
}
/**
* 将模组加入列中, 返回加入结果,如果没放入返回null
*/
public SlotUnit addSlotUnit(SlotUnit slotUnit){
if(slotUnit == null){
return null;
}
int slotHeight = slotUnit.getSlotHeight();
if(slotHeight > remainHeight){
return null;
}
remainHeight = remainHeight - slotHeight;
slotUnitList.add(slotUnit);
return slotUnit;
}
public Map<String,ReelItem> getColumnCapacity(){
Map<String,ReelItem> capacityMap = new HashMap<>();
for (SlotUnit slotUnit : getSlotUnitList()) {
String reelSizeStr = slotUnit.getReelData().getReelSizeStr();
ReelItem capacityItem = capacityMap.get(reelSizeStr);
if(capacityItem == null){
capacityItem = new ReelItem();
capacityItem.setW(slotUnit.getReelData().getReelSize());
capacityItem.setH(slotUnit.getReelData().getReelHeight());
}
int columnCapacity = slotUnit.getReelCount();
int capacity = capacityItem.getCapacity() + columnCapacity;
capacityItem.setCapacity(capacity);
capacityMap.put(reelSizeStr,capacityItem);
}
return capacityMap;
}
}
package com.neotel.webbox.capacity.box;
import com.neotel.webbox.capacity.bean.ReelData;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class SlotUnit {
public SlotUnit(ReelData reelData, int reelCount) {
this.reelData = reelData;
this.reelCount = reelCount;
}
private ReelData reelData;
private int reelCount;
public int getSlotHeight(){
int count = reelCount;
if(reelData.is7Reel()){
//7寸盘,一行摆2个
count = reelCount / 2;
if(count < reelData.getMinUnit()){
//小于最小单元,需要进行补充
count = reelData.getMinUnit();
reelCount = count * 2;
}else{
if(reelCount % 2 != 0){
count = count + 1;
reelCount = reelCount + 1;
}
}
}
int reelSlotHeight = reelData.getReelSlotHeight();
return count * reelSlotHeight;
}
}
package com.neotel.webbox.capacity.data;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.neotel.webbox.capacity.bean.*;
import com.neotel.webbox.capacity.method.AssignMethod1;
import com.neotel.webbox.capacity.method.AssignMethod2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.net.URL;
import java.util.*;
@Slf4j
@Component
public class BaseDataCache {
/**
* 料仓基础数据
*/
private static Map<String,BoxData> boxDataMap = new HashMap<>();
/**
* 料盘单元基础数据
*/
private static Map<String, ReelData> reelDataMap = new HashMap<>();
@PostConstruct
public void readExcel() {
try {
InputStream fileStream = null;
File file = new File("data.xlsx");
if(file.exists()){
log.info("加载包外数据文件:" + file.getAbsolutePath());
fileStream = new FileInputStream(file);
}else{
URL baseDir = ResourceUtils.getURL("classpath:data.xlsx");
fileStream = baseDir.openStream();
log.info("加载默认数据文件:" + baseDir.getPath());
}
// 写法1
try(ExcelReader excelReader = EasyExcel.read(fileStream).build()) {
// 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
ReadSheet readSheet1 =
EasyExcel.readSheet(0).head(BoxData.class).registerReadListener(new ReadListener<BoxData>(){
@Override
public void invoke(BoxData data, AnalysisContext analysisContext) {
if(data.isValid()){
log.info("加载到料仓{}数据",data.getBoxName());
boxDataMap.put(data.getBoxName(),data);
}else{
log.error("料仓表第{}行数据{}异常,忽略", analysisContext.getCurrentRowNum(),data.getBoxName());
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("料仓数据加载完成,共加载" + boxDataMap.size() +"条有效数据");
}
}).build();
ReadSheet readSheet2 = EasyExcel.readSheet(1).head(ReelData.class).registerReadListener(new ReadListener<ReelData>() {
@Override
public void invoke(ReelData reelData, AnalysisContext analysisContext) {
if(reelData.isValid()){
log.info("加载到盘{}数据",reelData.getReelSizeStr());
reelDataMap.put(reelData.getReelSizeStr(),reelData);
}else{
log.error("料仓表第{}行数据{}异常,忽略", analysisContext.getCurrentRowNum(),reelData.getReelSizeStr());
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("料盘数据加载完成,共加载" + reelDataMap.size() +"条有效数据");
}
}).build();
// 这里注意 一定要把sheet1 sheet2 一起传进去,不然有个问题就是03版的excel 会读取多次,浪费性能
excelReader.read(readSheet1, readSheet2);
}
// BoxData boxData = getBoxData("SISO1");
// List<RequestItem> testList = testData();
// BoxResult boxResult = AssignMethod1.averageAssignToBox(boxData,testList);
// log.info("方案一共需要"+boxResult.getBoxList().size()+"个料仓");
// for (ReelItem reelItem : boxResult.getReelItemList()) {
// log.info(reelItem.getSizeStr()+" 料盘需求:" + reelItem.getNeedNum() + " 容量:" + reelItem.getCapacity());
// }
//testList = testData();
// boxResult = AssignMethod2.assignToBox(boxData,testList);
// log.info("方案二共需要"+boxResult.getBoxList().size()+"个料仓");
// for (ReelItem reelItem : boxResult.getReelItemList()) {
// log.info(reelItem.getSizeStr()+" 料盘需求:" + reelItem.getNeedNum() + " 容量:" + reelItem.getCapacity());
// }
} catch (FileNotFoundException e) {
log.error("未找到数据文件",e);
} catch (Exception ex){
log.error("读取数据异常",ex);
}
}
private static List<RequestItem> testData(){
List<RequestItem> requestList = new ArrayList<>();
ReelData reelData = getReelData("7 x 8");
ReelData reelData2 = getReelData("13 x 24");
ReelData reelData3 = getReelData("13 x 12");
ReelData reelData4 = getReelData("7 x 12");
RequestItem item2 = new RequestItem(100,reelData2);
requestList.add(item2);
RequestItem item = new RequestItem(3300,reelData);
requestList.add(item);
RequestItem item3 = new RequestItem(150,reelData3);
requestList.add(item3);
RequestItem item4 = new RequestItem(1250,reelData4);
requestList.add(item4);
return requestList;
}
public static Collection<ReelData> getReelDataList(){
return reelDataMap.values();
}
public static Collection<BoxData> getBoxDataList(){
return boxDataMap.values();
}
public static BoxData getBoxData(String boxName){
return boxDataMap.get(boxName);
}
public static ReelData getReelData(String reelSizeStr){
return reelDataMap.get(reelSizeStr);
}
}
package com.neotel.webbox.capacity.method;
import com.neotel.webbox.capacity.bean.*;
import com.neotel.webbox.capacity.box.Box;
import com.neotel.webbox.capacity.box.Column;
import com.neotel.webbox.capacity.box.SlotUnit;
import com.neotel.webbox.capacity.method.BasicMethod;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
/**
* 平均分配到每台料仓
*/
@Slf4j
public class AssignMethod1 extends BasicMethod {
public static BoxResult averageAssignToBox(BoxData boxData, List<RequestItem> requestList){
//最大的压紧张开高度
int maxPressHeight = 0;
int totalRemainNeedHeight = 0;
//是否只有一种料需求
boolean onlyOneRequest = requestList.size() == 1;
for (RequestItem requestItem : requestList) {
ReelData rd = requestItem.getReelData();
//纯放此料盘料仓容量
int pureBoxCapacity = boxData.getBoxPureSizeCapacity(requestItem.getReelData());
int pureBoxCount = requestItem.getNum()/pureBoxCapacity;
int remainNum = requestItem.getNum() % pureBoxCapacity;
if(onlyOneRequest){
log.info("只有一种规格物料,使用纯料仓");
if(remainNum > 0){
remainNum = 0;
pureBoxCount = pureBoxCount + 1;
}
}
requestItem.setPureBoxCount(pureBoxCount);
requestItem.setRemainNum(remainNum);
log.info("料盘["+rd.getReelSizeStr()+"]总需求:"+requestItem.getNum()+"需要纯料仓"+ pureBoxCount+"个,每个料仓可放:"+pureBoxCapacity+"盘,剩余:"+ remainNum+"盘需要放到混合仓");
totalRemainNeedHeight = totalRemainNeedHeight + requestItem.getRemainNeedHeight();
if(rd.getPressHeight() > maxPressHeight){
maxPressHeight = rd.getPressHeight();
}
}
List<Box> mixBoxList = new ArrayList<>();
if(!onlyOneRequest){
int mixBoxTotalValidHeight = boxData.getTotalValidHeight(maxPressHeight);
//估算混合仓数量
Float estimateMixBoxCount = 1.0f * totalRemainNeedHeight / mixBoxTotalValidHeight;
int mixBoxCount = estimateMixBoxCount.intValue();
if(estimateMixBoxCount - mixBoxCount > 0){
mixBoxCount = mixBoxCount + 1;
}
log.info("剩余物料需要 " + mixBoxCount +" 个混合仓");
for(int i = 1; i<= mixBoxCount; i++){
mixBoxList.add(Box.newBox(boxData,maxPressHeight));
}
//从需求大到小排序,优先满足大需求
requestList.sort(new Comparator<RequestItem>() {
@Override
public int compare(RequestItem o1, RequestItem o2) {
return o2.getNum() - o1.getNum();
}
});
int columnValidHeight = boxData.getColumnValidHeight(maxPressHeight);
//标准列
Column column = new Column(columnValidHeight);
//先每列均分,如果有剩余,安排到料仓口的上下位置
for (RequestItem requestItem : requestList) {
int totalRemainNum = requestItem.getRemainNum();
int totalColumn = mixBoxList.size() * boxData.getColumnCount();
int countPerColumn = totalRemainNum/totalColumn;
int assignReelCount = 0;
if(requestItem.getReelData().is7Reel()){
//7寸盘会填充,这里不需要填充
countPerColumn = countPerColumn /2 * 2;
}
SlotUnit slotUnit = getValidSlotUnit(countPerColumn, requestItem.getReelData(),column.getRemainHeight());
slotUnit = column.addSlotUnit(slotUnit);
//为null表示一个没填充进去, 不为null可能只填充了一部分
if(slotUnit != null){
assignReelCount = slotUnit.getReelCount() * totalColumn;
log.info("添加"+assignReelCount+"个"+ requestItem.getReelSizeStr()+"料盘到标准列,每列"+ slotUnit.getReelCount()+"个料盘");
}
//没有安排的料盘,安排到料口的上下两部分
int notArrangedNum = totalRemainNum - assignReelCount;
for (Box box : mixBoxList) {
Column doorDown = box.getDoorDown();
SlotUnit doorDownAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorDown.getRemainHeight());
doorDownAddUnit = doorDown.addSlotUnit(doorDownAddUnit);
if(doorDownAddUnit != null){
log.info("添加"+doorDownAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列");
notArrangedNum = notArrangedNum - doorDownAddUnit.getReelCount();
}
Column doorUp = box.getDoorUp();
SlotUnit doorUpAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorUp.getRemainHeight());
doorUpAddUnit = doorUp.addSlotUnit(doorUpAddUnit);
if(doorUpAddUnit != null){
log.info("添加"+doorUpAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列");
notArrangedNum = notArrangedNum - doorUpAddUnit.getReelCount();
}
}
requestItem.setRemainNum(notArrangedNum);
if(notArrangedNum > 0){
//还有未安排的料盘,如果标准列有位置就添加进去,如果没有那就是放不下了
log.warn(""+notArrangedNum+"个"+ requestItem.getReelSizeStr()+"无处安放");
}
}
//填充料盘(需求数量最多的)
RequestItem fillRequestItem = null;
//用剩余的空间去放还未满足的料盘
for (RequestItem requestItem : requestList) {
if(fillRequestItem == null || requestItem.getNum() > fillRequestItem.getNum()){
fillRequestItem = requestItem;
}
int remainNum = requestItem.getRemainNum();
int addCount = fillToColumn(column,remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到标准列,无处安放料盘数为:" + remainNum);
}
if(remainNum > 0){
for (Box box : mixBoxList) {
addCount = fillToColumn(box.getDoorUp(),remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列,无处安放料盘数为:" + remainNum);
}
addCount = fillToColumn(box.getDoorDown(),remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列,无处安放料盘数为:" + remainNum);
}
}
}
}
//进行填充
int fillCount = fillToColumn(column,-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到标准列,标准列空闲高度为:" + column.getRemainHeight());
}else{
log.info("标准列空闲高度为: " + column.getRemainHeight()+" ");
}
for (Box box : mixBoxList) {
fillCount = fillToColumn(box.getDoorUp(),-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口上方列,其空闲高度为:" + box.getDoorUp().getRemainHeight());
}else{
log.info("门口上方列空闲高度为:" + box.getDoorUp().getRemainHeight()+" ");
}
fillCount = fillToColumn(box.getDoorDown(),-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口下方列,其空闲高度为:" + box.getDoorDown().getRemainHeight());
}else{
log.info("门口下方列空闲高度为:" + box.getDoorDown().getRemainHeight()+" ");
}
}
for (Box box : mixBoxList) {
box.setColumn(column);
box.setColumnCount(boxData.getColumnCount());
}
}
return getBoxResult(requestList,boxData,mixBoxList);
}
}
package com.neotel.webbox.capacity.method;
import com.neotel.webbox.capacity.bean.BoxData;
import com.neotel.webbox.capacity.bean.BoxResult;
import com.neotel.webbox.capacity.bean.ReelData;
import com.neotel.webbox.capacity.bean.RequestItem;
import com.neotel.webbox.capacity.box.Box;
import com.neotel.webbox.capacity.box.Column;
import com.neotel.webbox.capacity.box.SlotUnit;
import lombok.extern.slf4j.Slf4j;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
@Slf4j
public class AssignMethod2 extends BasicMethod{
public static BoxResult assignToBox(BoxData boxData, List<RequestItem> requestList){
//从厚到薄排充,先放厚的,再放薄的
requestList.sort(new Comparator<RequestItem>() {
@Override
public int compare(RequestItem o1, RequestItem o2) {
int reelHeightDiff = o2.getReelData().getReelHeight() - o1.getReelData().getReelHeight();
if(reelHeightDiff == 0){
return o2.getReelData().getReelSize() - o1.getReelData().getReelSize();
}
return reelHeightDiff;
}
});
for (RequestItem requestItem : requestList) {
ReelData rd = requestItem.getReelData();
//纯放此料盘料仓容量
int pureBoxCapacity = boxData.getBoxPureSizeCapacity(requestItem.getReelData());
int pureBoxCount = requestItem.getNum()/pureBoxCapacity;
int remainNum = requestItem.getNum() % pureBoxCapacity;
requestItem.setPureBoxCount(pureBoxCount);
requestItem.setRemainNum(remainNum);
log.info("料盘["+rd.getReelSizeStr()+"]总需求:"+requestItem.getNum()+"需要纯料仓"+ pureBoxCount+"个,每个料仓可放:"+pureBoxCapacity+"盘,剩余:"+ remainNum+"盘需要放到混合仓");
}
List<Box> mixBoxList = new ArrayList<>();
Box mixBox = null;
//填充料盘(需求数量最多的)
RequestItem fillRequestItem = null;
for (RequestItem requestItem : requestList) {
ReelData rd = requestItem.getReelData();
if(fillRequestItem == null || requestItem.getNum() > fillRequestItem.getNum()){
fillRequestItem = requestItem;
}
while (requestItem.getRemainNum() > 0){
if(!isBoxCanPutIn(mixBox,rd)){
log.info("开启一个混合仓,开始放"+ rd.getReelSizeStr()+"的料盘");
int pressHeight = rd.getPressHeight();
mixBox = Box.newBox(boxData,pressHeight);
int columnValidHeight = boxData.getColumnValidHeight(pressHeight);
//标准列
Column column = new Column(columnValidHeight);
mixBox.setColumn(column);
mixBox.setColumnCount(boxData.getColumnCount());
mixBoxList.add(mixBox);
}
requestItem = assignToMixBox(requestItem,mixBox);
}
}
int fillCount = 0;
for (Box box : mixBoxList) {
fillCount = fillToColumn(box.getColumn(),-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到标准列,标准列空闲高度为:" + box.getColumn().getRemainHeight());
}else{
log.info("标准列空闲高度为: " + box.getColumn().getRemainHeight()+" ");
}
fillCount = fillToColumn(box.getDoorUp(),-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口上方列,其空闲高度为:" + box.getDoorUp().getRemainHeight());
}else{
log.info("门口上方列空闲高度为:" + box.getDoorUp().getRemainHeight()+" ");
}
fillCount = fillToColumn(box.getDoorDown(),-1,fillRequestItem.getReelData());
if(fillCount > 0){
log.info("填充"+fillCount+"个"+ fillRequestItem.getReelSizeStr()+"料盘到门口下方列,其空闲高度为:" + box.getDoorDown().getRemainHeight());
}else{
log.info("门口下方列空闲高度为:" + box.getDoorDown().getRemainHeight()+" ");
}
}
return getBoxResult(requestList,boxData,mixBoxList);
}
private static boolean isBoxCanPutIn(Box mixBox, ReelData rd){
if(mixBox == null){
return false;
}
if(mixBox.getColumn().getRemainHeight() > rd.getReelSlotHeight()){
return true;
}
if(mixBox.getColumn().getRemainHeight() > rd.getReelSlotHeight()){
return true;
}
if(mixBox.getColumn().getRemainHeight() > rd.getReelSlotHeight()){
return true;
}
return false;
}
private static RequestItem assignToMixBox(RequestItem requestItem, Box mixBox){
int totalRemainNum = requestItem.getRemainNum();
int totalColumn = mixBox.getColumnCount();
int countPerColumn = totalRemainNum/totalColumn;
if(requestItem.getReelData().is7Reel()){
//7寸盘会填充,这里不需要填充
countPerColumn = countPerColumn /2 * 2;
}
int assignReelCount = 0;
SlotUnit slotUnit = getValidSlotUnit(countPerColumn, requestItem.getReelData(),mixBox.getColumn().getRemainHeight());
slotUnit = mixBox.getColumn().addSlotUnit(slotUnit);
//为null表示一个没填充进去, 不为null可能只填充了一部分
if(slotUnit != null){
assignReelCount = slotUnit.getReelCount() * totalColumn;
log.info("添加"+assignReelCount+"个"+ requestItem.getReelSizeStr()+"料盘到标准列,每列"+ slotUnit.getReelCount()+"个料盘");
}
//没有安排的料盘,安排到料口的上下两部分
int notArrangedNum = totalRemainNum - assignReelCount;
Column doorDown = mixBox.getDoorDown();
SlotUnit doorDownAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorDown.getRemainHeight());
doorDownAddUnit = doorDown.addSlotUnit(doorDownAddUnit);
if(doorDownAddUnit != null){
log.info("添加"+doorDownAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列");
notArrangedNum = notArrangedNum - doorDownAddUnit.getReelCount();
}
Column doorUp = mixBox.getDoorUp();
SlotUnit doorUpAddUnit = getValidSlotUnit(notArrangedNum, requestItem.getReelData(), doorUp.getRemainHeight());
doorUpAddUnit = doorUp.addSlotUnit(doorUpAddUnit);
if(doorUpAddUnit != null){
log.info("添加"+doorUpAddUnit.getReelCount()+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列");
notArrangedNum = notArrangedNum - doorUpAddUnit.getReelCount();
}
requestItem.setRemainNum(notArrangedNum);
if(notArrangedNum > 0){
//还有未安排的料盘,如果标准列有位置就添加进去,如果没有那就是放不下了
log.warn(""+notArrangedNum+"个"+ requestItem.getReelSizeStr()+"无处安放");
}
int remainNum = notArrangedNum;
int addCount = fillToColumn(mixBox.getColumn(),remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到标准列,无处安放料盘数为:" + remainNum);
}
if(remainNum > 0){
addCount = fillToColumn(mixBox.getDoorUp(),remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口上方列,无处安放料盘数为:" + remainNum);
}
addCount = fillToColumn(mixBox.getDoorDown(),remainNum,requestItem.getReelData());
if(addCount > 0){
remainNum = remainNum - addCount;
requestItem.setRemainNum(remainNum);
log.info("添加"+addCount+"个"+ requestItem.getReelSizeStr()+"料盘到门口下方列,无处安放料盘数为:" + remainNum);
}
}
requestItem.setRemainNum(remainNum);
return requestItem;
}
}
package com.neotel.webbox.capacity.method;
import com.neotel.webbox.capacity.bean.BoxData;
import com.neotel.webbox.capacity.bean.BoxResult;
import com.neotel.webbox.capacity.bean.ReelData;
import com.neotel.webbox.capacity.bean.RequestItem;
import com.neotel.webbox.capacity.box.Box;
import com.neotel.webbox.capacity.box.Column;
import com.neotel.webbox.capacity.box.SlotUnit;
import java.util.ArrayList;
import java.util.List;
public class BasicMethod {
protected static SlotUnit getValidSlotUnit(int requestReelCount, ReelData reelData, int validHeight){
if(requestReelCount <=0){
return null;
}
//剩余空间可放多少层料格
int slotCount = validHeight/reelData.getReelSlotHeight();
if(slotCount < reelData.getMinUnit()){
//可放料格层数不到一个模组
return null;
}
int validReelCount = slotCount;
if(reelData.is7Reel()){
validReelCount = validReelCount * 2;
}
if(validReelCount >= requestReelCount){
//可以全部放下
return new SlotUnit(reelData,requestReelCount);
}
//只可以放下部分
return new SlotUnit(reelData,validReelCount);
}
protected static int fillToColumn(Column column, int remainCount, ReelData reelData){
if(remainCount > 0 || remainCount == -1){
//剩余空间可放多少层料格
int slotCount = column.getRemainHeight()/reelData.getReelSlotHeight();
if(remainCount!= -1 && slotCount > remainCount){
slotCount = remainCount;
}
SlotUnit existSlotUnit = column.getSlotUnit(reelData);
int existCount = 0;
if(existSlotUnit == null){
//不存在同尺寸料格,需要判断最小模组
if(slotCount < reelData.getMinUnit()){
//可放料格层数不到一个模组,尝试扩展已存在的料盘
return 0;
}
}else{
existCount = existSlotUnit.getReelCount();
}
int reelCount = slotCount;
if(reelData.is7Reel()){
reelCount = reelCount * 2;
}
SlotUnit newSlotUnit = new SlotUnit(reelData, reelCount);
SlotUnit mergeSlotUnit = column.mergeSlotUnit(newSlotUnit);
if(mergeSlotUnit != null){
int addCount = mergeSlotUnit.getReelCount() - existCount;
return addCount;
}
}
return 0;
}
protected static Column getPureColumn(int validHeight, BoxData boxData, ReelData reelData,int pureCapacity){
Column column = new Column(validHeight);
column.setRemainHeight(0);
List<SlotUnit> slotUnitList = new ArrayList<>();
SlotUnit unit = new SlotUnit(reelData,pureCapacity);
slotUnitList.add(unit);
column.setSlotUnitList(slotUnitList);
return column;
}
protected static BoxResult getBoxResult(List<RequestItem> requestList, BoxData boxData, List<Box> mixBoxList){
List<Box> boxes = new ArrayList<>();
for (RequestItem requestItem : requestList){
ReelData reelData = requestItem.getReelData();
int pressHeight = reelData.getPressHeight();
for (int i = 0; i < requestItem.getPureBoxCount(); i++) {
Box box = new Box();
box.setColumnCount(boxData.getColumnCount());
int standColumnValidHeight = boxData.getColumnValidHeight(pressHeight);
int pureColumnCapacity = boxData.getColumnPureSizeCapacity(reelData.getPressHeight(), reelData);
Column standColumn = getPureColumn(standColumnValidHeight,boxData,reelData,pureColumnCapacity);
box.setColumn(standColumn);
int doorDownValidHeight = boxData.getDoorDownValidHeight(pressHeight);
int pureDoorDownCapacity = boxData.getDoorDownCapacity(reelData.getPressHeight(), reelData);
Column doorDown = getPureColumn(doorDownValidHeight,boxData,reelData,pureDoorDownCapacity);
box.setDoorDown(doorDown);
int doorUpValidHeight = boxData.getDoorUpValidHeight(pressHeight);
int pureDoorUpCapacity = boxData.getDoorUpCapacity(reelData.getPressHeight(), reelData);
Column doorUp = getPureColumn(doorUpValidHeight,boxData,reelData,pureDoorUpCapacity);
box.setDoorUp(doorUp);
boxes.add(box);
}
}
for (Box box : mixBoxList) {
boxes.add(box);
}
BoxResult boxResult = new BoxResult();
boxResult.setBoxList(boxes);
boxResult.setRequestList(requestList);
return boxResult;
}
}
package com.neotel.webbox.util;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.util.MapUtils;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.neotel.webbox.capacity.box.Box;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
@Slf4j
public class ExcelUtil {
public static void downloadExcel(HttpServletResponse response){
// 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
try {
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 这里 需要指定写用哪个class去写
try (ExcelWriter excelWriter = EasyExcel.write(fileName, Box.class).build()) {
// 这里注意 如果同一个sheet只要创建一次
WriteSheet writeSheet = EasyExcel.writerSheet("模板").registerWriteHandler(new I18nCellWriteHandler()).build();
// 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来
for (int i = 0; i < 5; i++) {
// 分页去数据库查询数据 这里可以去数据库查询每一页的数据
//List<DemoData> data = data();
//excelWriter.write(data, writeSheet);
}
}
} catch (Exception e) {
log.error("下载Excel出错",e);
// 重置response
response.reset();
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
Map<String, String> map = MapUtils.newHashMap();
map.put("status", "failure");
map.put("message", "下载文件失败" + e.getMessage());
ObjectMapper objectMapper = new ObjectMapper();
String resultStr = null;
try {
resultStr = objectMapper.writeValueAsString(map);
response.getWriter().println(resultStr);
} catch (Exception ex) {
log.error("下载Excel时转换Json出错",ex);
}
}
}
}
package com.neotel.webbox.util;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Row;
import java.util.ArrayList;
import java.util.List;
public class I18nCellWriteHandler implements CellWriteHandler {
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
if (isHead) {
List<String> originHeadNames = head.getHeadNameList();
List<String> newHeadNameList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(originHeadNames)) {
for (String originHeadName : originHeadNames) {
String headName = originHeadName;
if(originHeadName.startsWith("$")){
//需要进行转换
headName = originHeadName;
}
newHeadNameList.add(headName);
}
head.setHeadNameList(newHeadNameList);
}
}
CellWriteHandler.super.beforeCellCreate(writeSheetHolder, writeTableHolder, row, head, columnIndex, relativeRowIndex, isHead);
}
}
server.port = 8080
\ No newline at end of file \ No newline at end of file
此文件类型无法预览
package com.neotel.webbox;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class WebBoxApplicationTests {
@Test
void contextLoads() {
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!