Commit 33e5cc0f LN

1.增加 loading->ReturnMaterial

1 个父辈 669dc3a0
......@@ -290,8 +290,12 @@ public class RobotBoxHandler extends BaseDeviceHandler {
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String preCid=request.getParameter("preCid");
log.info(" renewPosForPutin 流水线[" + cids + "]重新获取[" + code + "]的入库库位, 需要排除上个料仓,cid=["+preCid+"],并取消入库任务");
return posForPutin(code,cids,preCid);
String rfid = request.getParameter("rfid");
if(ObjectUtil.isEmpty(rfid)){
rfid="";
}
log.info(" renewPosForPutin 流水线[" + cids + "]重新获取[" + code + "]的入库库位, 需要排除上个料仓,cid=["+preCid+"],rfid=["+rfid+"],并取消入库任务");
return posForPutin(code,cids,preCid,rfid);
}
......@@ -312,18 +316,23 @@ public class RobotBoxHandler extends BaseDeviceHandler {
//返回 107=物料已过期,无法入库
//返回108=已有待完成的出入库任务,直接NG
//返回110=接口验证失败,需要去XRay重新点料
String code = request.getParameter("code");
String cids = request.getParameter("cids");
String rfid = request.getParameter("rfid");
if(ObjectUtil.isEmpty(rfid)){
rfid="";
}
String lastPosId = "";
String lineMsg = "";
log.info("流水线[" + cids + "]获取[" + code + "]的入库库位");
return posForPutin(code,cids,"");
log.info("流水线[" + cids + "]获取[" + code + "],rfid=["+rfid+"]的入库库位");
return posForPutin(code,cids,"",rfid);
}
public Map<String, Object> posForPutin(String code,String cids,String preCid){
public Map<String, Object> posForPutin(String code,String cids,String preCid,String rfid){
log.info("posForPutin,code=["+code+"],cids=["+cids+"],preCid=["+preCid+"]");
String lastPosId = "";
String lineMsg = "";
......@@ -529,6 +538,9 @@ public class RobotBoxHandler extends BaseDeviceHandler {
}
}
barcode= ApiCheck(rfid,barcode);
StoragePos pos = taskService.findEmptyPosForPutIn(storages, barcode, "", lastPosId);
if (pos != null) {
......@@ -616,6 +628,21 @@ public class RobotBoxHandler extends BaseDeviceHandler {
return resultMap;
}
private Barcode ApiCheck(String rfid,Barcode barcode){
// String operationId="";
// LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
// if(loadingInfo!=null&&loadingInfo.rfidList.contains(rfid)) {
// operationId= loadingInfo.operationId;
// }
// barcode = MicronApi.API001(operationId, barcode );
// if(barcode==null) {
// throw new ValidateException("smfcore.error.barcode.invalid", "未找到有效的条码");
// }
return barcode;
}
@ApiOperation("更新任务状态")
@PostMapping(value = "/service/store/robotBox/updateLocInfo")
@ResponseBody
......
package com.neotel.smfcore.core.inList.enums.INITEM;
public class INITEM_STATUS {
/**等待中*/
public static int Wait=0;
/**入库中*/
public static int PutIn=1;
/**XRay点料*/
public static int XRay=2;
/**XRay点料结果提交失败*/
public static int XRayFail=3;
/**入库正常完成*/
public static int Success=4;
/**入库通知失败*/
public static int Fail=5;
}
......@@ -8,4 +8,7 @@ public class INLIST_STATUS {
/**正常完成的入库单*/
public static int OK=2;
/**手动结束入库*/
public static int END=2;
}
......@@ -8,6 +8,7 @@ import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Data
......@@ -15,6 +16,15 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
public class InList extends BasePo implements Serializable {
public InList(String name,int s,List<InListItem> items,long startTime,boolean sendEmail) {
setName(name);
this.setStatus(s);
this.setInListItems(items);
this.setStartTime(s);
setSendEmail(sendEmail);
}
/**
* 入库单名称
*/
......@@ -35,4 +45,18 @@ public class InList extends BasePo implements Serializable {
* 超时未完成,已发送邮件通知
*/
private boolean sendEmail=false;
private List<String> rfidList=new ArrayList<>();
/**
* 料架个数
*/
private Integer shelfNum=0;
/**
* 入库模式
*/
private String mode="";
private String operationId="";
}
......@@ -2,7 +2,10 @@ package com.neotel.smfcore.core.inList.service.po;
import cn.hutool.core.util.ObjectUtil;
import com.neotel.smfcore.common.base.BasePo;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.inList.bean.ItemReelInfo;
import com.neotel.smfcore.core.inList.enums.INITEM.INITEM_STATUS;
import com.neotel.smfcore.core.inList.service.manager.impl.InListItemManagerImpl;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
......@@ -23,6 +26,16 @@ public class InListItem extends BasePo implements Serializable {
item.setNum(num);
return item;
}
public static InListItem newMItem(String name, Barcode barcode, String rfid,String posName,int s){
InListItem item=new InListItem();
item.setName(name);
item.setPN(barcode.getPartNumber());
item.setRi(barcode.getBarcode());
item.setRfid(rfid);
item.setPosName(posName);
item.setState(s);
return item;
}
/**
* 入库单名称
*/
......@@ -32,6 +45,7 @@ public class InListItem extends BasePo implements Serializable {
* 物料编号
*/
private String PN;
/**
* 唯一码入库
*/
......@@ -53,6 +67,39 @@ public class InListItem extends BasePo implements Serializable {
/**
* 物料类型,pcb,reel,pizza box,
*/
private String mType;
/**
* 所在的rfid
*/
private String rfid;
/**
* 入库的库位号
*/
private String posName;
/**
* 入库状态,0=未开始,1=验证成功,入库中,2=XRay点料,3=入库提交完成,4=入库提交失败
*
*/
private int state= INITEM_STATUS.Wait;
public boolean isSuccess(){
return state==INITEM_STATUS.Success;
}
public boolean isXray() {
return state == INITEM_STATUS.XRay || state == INITEM_STATUS.XRayFail;
}
public boolean isFailure() {
return state == INITEM_STATUS.Fail;
}
/**
* 入库详情
*/
private List<ItemReelInfo> reelLists;
......
package com.neotel.smfcore.custom.micron1053.api;
public class MODE {
public class APIMODE {
// MBR|REQ|MCL|GR|MATRET|RET|NPI|RACK|PCBPRETASK|MCLPRETASK|LINEPREP|CTRLDISPATCH
public static String MBR="MBR";
public static String REQ="REQ";
......@@ -14,4 +14,17 @@ public class MODE {
public static String MCLPRETASK="MCLPRETASK";
public static String LINEPREP="LINEPREP";
public static String CTRLDISPATCH="CTRLDISPATCH";
// MBR = MBR Loading
// REQ = REQ Loading
// MCL = MCL Loading
// GR = MCLGR Loading
// MATRET = Material Return to KTS
// RET = Material Take out from KTS and Return to Warehouse
// NPI = NPI Dispatch
// RACk = Dispatch to Outside Shelf
// PCBPRETASK = PCB Panel Pretask and dispatch
// MCLPRETASK = MCL Pretask and dispatch
// LINEPREP = LINE PREP Dispatch
// CTRLDISPATCH = Control Dispatch
}
......@@ -91,6 +91,13 @@ public class MicronConfig {
*/
public String api_name_202 = "user/{badgeId}";
/**
* 011参数Source使用配置固定值
*/
public String api_011_Source = "Source";
@Value("${micron.api_name_001:}")
public void setApi_name_001(String api_config) {
if(ObjectUtil.isEmpty(api_config)){
......@@ -220,6 +227,14 @@ public class MicronConfig {
api_name_202 = api_config;
}
@Value("${micron.api_011_Source:}")
public void setApi_011_Source(String api_config) {
if (ObjectUtil.isEmpty(api_config)) {
return;
}
api_011_Source = api_config;
}
@Autowired
private DataCache dataCache;
......
......@@ -52,7 +52,7 @@ public class MicronResult implements Serializable {
}
Object resultStatus = resultMap.get("status");
if (resultStatus != null && !resultStatus.toString().equalsIgnoreCase("PASS")) {
if (resultStatus != null && !resultStatus.toString().equalsIgnoreCase("SUCCESSS")) {
Object msgObj = resultMap.get("message") ;
if(ObjectUtil.isEmpty(msgObj)){
throw new ApiException("smfcore.api.error", "status="+resultStatus);
......
......@@ -2,18 +2,26 @@ package com.neotel.smfcore.custom.micron1053.controller;
import cn.hutool.core.util.ObjectUtil;
import com.neotel.smfcore.common.bean.ResultBean;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.common.utils.JsonUtil;
import com.neotel.smfcore.core.barcode.bean.CodeBean;
import com.neotel.smfcore.core.barcode.enums.COMPONENT_TYPE;
import com.neotel.smfcore.core.barcode.service.manager.IBarcodeManager;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.barcode.utils.CodeResolve;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.inList.service.po.InList;
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.service.po.DataLog;
import com.neotel.smfcore.core.system.util.TaskService;
import com.neotel.smfcore.custom.micron1053.api.MicronApi;
import com.neotel.smfcore.custom.micron1053.bean.MInventory;
import com.neotel.smfcore.custom.micron1053.bean.ML5NgReelInfo;
import com.neotel.smfcore.custom.micron1053.bean.MicronEquipStatus;
import com.neotel.smfcore.custom.micron1053.loading.Bean.LoadingInfo;
import com.neotel.smfcore.custom.micron1053.loading.util.LoadingUtil;
import com.neotel.smfcore.custom.micron1053.util.MicronDataCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import com.neotel.smfcore.security.bean.FileProperties;
......@@ -48,6 +56,11 @@ public class MicronDeviceController {
@Autowired
private IBarcodeManager barcodeManager;
@Autowired
private CodeResolve codeResolve;
@Autowired
private LoadingUtil loadingUtil;
@ApiOperation("单个设备状态更新,可传集合,也可只传一个设备状态 (ML5,CI,R1,R2,R3) (1=正常运行,2=报警) ")
......@@ -320,13 +333,53 @@ public class MicronDeviceController {
@ApiOperation("X-Ray点料完成,更新数量 ")
@PostMapping(value = "/xRayUpdateQty")
@PostMapping(value = "/updateReelQty")
@ResponseBody
@AnonymousAccess
public ResultBean xRayUpdateQty(@RequestBody Map<String,Object> param, HttpServletRequest request) {
String barcode=param.get("barcode").toString();
Integer qty=Integer.parseInt(param.get("qty").toString()) ;
//TODO 更新数量
public ResultBean updateReelQty(@RequestBody Map<String,Object> param, HttpServletRequest request) {
String barcodeStr = param.get("barcode").toString();
Integer qty = Integer.parseInt(param.get("qty").toString());
log.info("X-Ray点料完成:barcode=" + barcodeStr + ",qty=" + qty);
Collection<CodeBean> codeBeans = codeResolve.resolveCodeStr(barcodeStr, COMPONENT_TYPE.COMPONENT);
Barcode barcode = null;
for (CodeBean codeBean : codeBeans) {
if (codeBean.isValid()) {
if (barcode != null) {
String msg = "获取尺寸时找到多个有效条码";
return ResultBean.newErrorResult(105, "smfcore.getSize.error", "获取" + barcodeStr + "尺寸失败:有多个条码");
} else {
barcode = codeBean.getBarcode();
}
}
}
if (barcode == null) {
return ResultBean.newErrorResult(105, "smfcore.getSize.error", "获取" + barcodeStr + "尺寸失败:未找到有效条码");
}
//TODO 更改条码数量
int oldQty = barcode.getAmount();
barcode.setAmount(qty);
barcodeManager.saveBarcode(barcode);
log.info("点料完成,更新条码[" + barcode.getBarcode() + "]数量=[" + qty + "],旧数量[" + oldQty + "]");
//处理入库单
InList inList = loadingUtil.getInlist();
if (inList == null) {
return ResultBean.newOkResult("ok");
}
//上传数量
boolean result = MicronApi.Api008(barcode.getBarcode(), qty, oldQty);
if (result) {
//重新获取库位号
} else {
//更新状态为失败
}
return ResultBean.newOkResult("ok");
}
......@@ -340,4 +393,26 @@ public class MicronDeviceController {
//TODO rfid入库完成
return ResultBean.newOkResult("");
}
@ApiOperation("根据RFID获取入库单号,未开始时返回空")
@PostMapping(value = "/getRfidInList")
@ResponseBody
@AnonymousAccess
public ResultBean getRfidInList(HttpServletRequest request) {
String rfid = request.getParameter("rfid");
//
// Inlist inlist=loadingUtil.getInlist();
// if(inlist==null){
// return ;
// }
//
//
// //TODO 根据rfid获取入库单号
// LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
// if(loadingInfo!=null&&loadingInfo.rfidList.contains(rfid)){
// return ResultBean.newOkResult(loadingInfo.operationId);
// }
return ResultBean.newOkResult("");
}
}
......@@ -27,9 +27,8 @@ public class LoadingInfo implements Serializable {
*/
public String operationId="";
public String inlistName="";
public DateTime startTime;
public List<String> rfidList=new ArrayList<>();
}
package com.neotel.smfcore.custom.micron1053.loading;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
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.common.utils.DateUtil;
import com.neotel.smfcore.common.utils.SecurityUtils;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.inList.enums.INITEM.INITEM_STATUS;
import com.neotel.smfcore.core.inList.enums.INLIST_STATUS;
import com.neotel.smfcore.core.inList.service.manager.IInListManager;
import com.neotel.smfcore.core.inList.service.po.InList;
import com.neotel.smfcore.core.inList.service.po.InListItem;
import com.neotel.smfcore.core.inList.util.InListCache;
import com.neotel.smfcore.custom.micron1053.api.APIMODE;
import com.neotel.smfcore.custom.micron1053.api.MicronApi;
import com.neotel.smfcore.custom.micron1053.loading.Bean.LoadingInfo;
import com.neotel.smfcore.custom.micron1053.loading.dto.MaterialLoadingDto;
import com.neotel.smfcore.custom.micron1053.util.MicronDataCache;
import com.neotel.smfcore.security.annotation.AnonymousAccess;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.util.*;
@Slf4j
@RestController
......@@ -25,27 +40,157 @@ public class LoadingController {
@Autowired
DataCache dataCache;
@Autowired
private InListCache inListCache;
@Autowired
private IInListManager inListManager;
@ApiOperation("lOADING页面数据获取")
@GetMapping("/status")
@ApiOperation("lOADING页面获取列表数据")
@GetMapping("/list")
@AnonymousAccess
public ResultBean loading(HttpServletRequest servletRequest ) {
public ResultBean list(HttpServletRequest servletRequest ) {
LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
if (loadingInfo == null) {
if (loadingInfo == null ||ObjectUtil.isEmpty(loadingInfo.operationId)) {
return ResultBean.newErrorResult(-1,"","未找到信息");
} else {
return ResultBean.newOkResult(getList(loadingInfo.getInlistName()));
}
}
return ResultBean.newOkResult("");
private List<MaterialLoadingDto> getList(String inlistName){
InList inList=inListCache.getInList(inlistName);
Map<String ,MaterialLoadingDto > dtoMap=new HashMap<>();
for (InListItem item :
inList.getInListItems()) {
String mtype = item.getMType();
MaterialLoadingDto dto = dtoMap.getOrDefault(mtype, new MaterialLoadingDto(mtype, 0, 0, 0));
if (item.isSuccess()) {
dto.setSuccessQty(dto.getSuccessQty() + 1);
} else if (item.isFailure()) {
dto.setFailure(dto.getFailure() + 1);
} else if (item.isXray()) {
dto.setXRay(dto.getXRay() + 1);
dtoMap.put(dto.getMaterialType(), dto);
}
}
List<MaterialLoadingDto> resultList=new ArrayList< >();
for (MaterialLoadingDto dto : dtoMap.values()){
resultList.add(dto);
}
if(resultList.size()<=0){
resultList.add(new MaterialLoadingDto(MicronDataCache.PIZZABOX, 2, 5, 6));
resultList.add(new MaterialLoadingDto(MicronDataCache.REEL, 23, 54, 6));
resultList.add(new MaterialLoadingDto(MicronDataCache.PCB, 22, 52, 65));
}
return resultList;
}
@ApiOperation("loading->ReturnMaterial 输入RFID后获取数据")
@PostMapping("/returnMaterial")
@AnonymousAccess
public ResultBean returnMaterial(@RequestBody Object params ) {
List<String> rfids=(List<String>)params ;
if (ObjectUtil.isEmpty((rfids))) {
throw new ValidateException("smfcore.valueCanotNull", "{0}不能为空", new String[]{"rfids"});
}
// String[] rfidArray=rfids.split(",");
LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
if (loadingInfo == null ||ObjectUtil.isEmpty(loadingInfo.operationId)) {
// 接口获取
String id = MicronApi.Api011(APIMODE.MATRET, SecurityUtils.getCurrentUsername(), "");
if (ObjectUtil.isEmpty(id)) {
throw new ValidateException("smfcore.api011.fail", "Api011获取数据失败");
}
loadingInfo=new LoadingInfo(APIMODE.MATRET,id,"", DateTime.now());
loadingInfo.inlistName=id+"-"+ DateUtil.toDateString(loadingInfo.startTime);
dataCache.updateCache(Constants.CACHE_LOADING,loadingInfo);
int count=rfids.size();
// List<String> list = new ArrayList<>(Arrays.asList(rfidArray));
InList inList = new InList(loadingInfo.inlistName, INLIST_STATUS.WAIT, new ArrayList<>(), System.currentTimeMillis(), false);
inList.setMode(loadingInfo.mode);
inList.setShelfNum(count);
inList.setOperationId(loadingInfo.getOperationId());
inList = inListManager.createWithItems(inList);
inListCache.addInListToMap(inList);
return ResultBean.newOkResult(getList(loadingInfo.getInlistName()));
} else {
return ResultBean.newOkResult(loadingInfo);
return ResultBean.newOkResult(getList(loadingInfo.getInlistName()));
}
}
@ApiOperation("loading->ReturnMaterial 页面数据获取")
@GetMapping("/returnMaterial")
@ApiOperation("Retry")
@PostMapping("/Retry")
@AnonymousAccess
public ResultBean returnMaterial(HttpServletRequest servletRequest ) {
return ResultBean.newOkResult("");
public ResultBean retry() {
LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
if (loadingInfo == null ||ObjectUtil.isEmpty(loadingInfo.operationId)) {
return ResultBean.newErrorResult(-1,"smfcore.micron.operationFailure","操作失败");
} else {
//重试,重发指令
log.info("终止入库:"+loadingInfo.getMode()+","+loadingInfo.getOperationId()+" " );
InList inList=inListCache.getInList(loadingInfo.getInlistName());
for (InListItem item :
inList.getInListItems()) {
if(item.isFailure()){
//重发
}
else if(item.getState()== INITEM_STATUS.XRayFail){
//
}
}
inList.setStatus(INLIST_STATUS.END);
inListManager.save(inList);
inListCache.addInListToMap(inList);
return ResultBean.newOkResult(getList(loadingInfo.getInlistName()));
}
}
@ApiOperation("Abort")
@PostMapping("/Abort")
@AnonymousAccess
public ResultBean abort() {
LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
if (loadingInfo == null ||ObjectUtil.isEmpty(loadingInfo.operationId)) {
return ResultBean.newErrorResult(-1,"smfcore.micron.operationFailure","操作失败");
} else {
//结束入库
log.info("终止入库:"+loadingInfo.getMode()+","+loadingInfo.getOperationId()+", " );
InList inList=inListCache.getInList(loadingInfo.getInlistName());
inList.setStatus(INLIST_STATUS.END);
inListManager.save(inList);
inListCache.addInListToMap(inList);
//清空当前入库信息
dataCache.updateCache(Constants.CACHE_LOADING,new LoadingInfo());
return ResultBean.newOkResult("");
}
}
}
package com.neotel.smfcore.custom.micron1053.loading.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MaterialLoadingDto implements Serializable {
@ApiModelProperty("物料类型")
private String materialType;
@ApiModelProperty("成功盘数")
private int successQty;
@ApiModelProperty("去点料盘数")
private int xRay;
@ApiModelProperty("失败盘数")
private int failure;
}
package com.neotel.smfcore.custom.micron1053.loading.util;
import cn.hutool.core.util.ObjectUtil;
import com.neotel.smfcore.common.utils.Constants;
import com.neotel.smfcore.core.barcode.service.po.Barcode;
import com.neotel.smfcore.core.device.util.DataCache;
import com.neotel.smfcore.core.inList.service.manager.IInListItemManager;
import com.neotel.smfcore.core.inList.service.manager.IInListManager;
import com.neotel.smfcore.core.inList.service.po.InList;
import com.neotel.smfcore.core.inList.service.po.InListItem;
import com.neotel.smfcore.core.inList.util.InListCache;
import com.neotel.smfcore.core.system.service.po.DataLog;
import com.neotel.smfcore.custom.micron1053.loading.Bean.LoadingInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.swing.text.html.InlineView;
import java.util.List;
@Service
@Slf4j
public class LoadingUtil {
@Autowired
private DataCache dataCache;
@Autowired
private InListCache inListCache;
@Autowired
private IInListManager inListManager;
@Autowired
private IInListItemManager inListItemManager;
public InList getInlist() {
LoadingInfo loadingInfo = dataCache.getCache(Constants.CACHE_LOADING);
if (loadingInfo == null || ObjectUtil.isEmpty(loadingInfo.operationId)) {
} else {
InList inlist=inListCache.getInList(loadingInfo.getInlistName());
return inlist;
}
return null;
}
//获取库位号成功,增加一个正在入库的
public void AddInListItem(String rfid, Barcode barcode,String posname, int s) {
InList inList = getInlist();
if (inList == null) {
return;
}
String posName = "";
InListItem item = InListItem.newMItem(inList.getName(), barcode, rfid, posname, s);
item = inListItemManager.save(item);
List<InListItem> items = inList.getInListItems();
items.add(item);
inList.setInListItems(items);
inListCache.addInListToMap(inList);
}
}
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!