Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
孙克
/
RC1250-AssemblyLine
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit c45757fc
由
LN
编写于
2020-06-09 17:32:59 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
增加库位循环获取逻辑
1 个父辈
3185ffb8
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
319 行增加
和
51 行删除
dll/RFID/Asa.RFID.dll
dll/RFID/Asa.RFID.xml
doc/RC1250佳世达IO模块IP地址及伺服站号配置2020-6-9.xlsx
source/DeviceLibrary/assemblyLine/FeedingEquip_InStore.cs
source/DeviceLibrary/assemblymanager/SServerManager.cs
source/DeviceLibrary/model/InOutParam.cs
dll/RFID/Asa.RFID.dll
查看文件 @
c45757f
此文件类型无法预览
dll/RFID/Asa.RFID.xml
0 → 100644
查看文件 @
c45757f
<?xml version="1.0"?>
<doc>
<assembly>
<name>
Asa.RFID
</name>
</assembly>
<members>
<member
name=
"T:Asa.RFID.ReadAll"
>
<summary>
读取所有RFID
</summary>
</member>
<member
name=
"T:Asa.RFID.ReadAll.ReceivedEvent"
>
<summary>
接收数据包事件
</summary>
<param
name=
"ip"
></param>
<param
name=
"id"
></param>
</member>
<member
name=
"E:Asa.RFID.ReadAll.Received"
>
<summary>
接收数据包
</summary>
</member>
<member
name=
"T:Asa.RFID.ReadAll.ReceiveBufferEvent"
>
<summary>
接收网卡缓存事件
</summary>
<param
name=
"ip"
></param>
<param
name=
"buffer"
></param>
</member>
<member
name=
"E:Asa.RFID.ReadAll.ReceiveBuffer"
>
<summary>
接收网卡缓存
</summary>
</member>
<member
name=
"M:Asa.RFID.ReadAll.#ctor(System.String)"
>
<summary>
读取所有RFID
</summary>
<param
name=
"logName"
>
日志名称
</param>
</member>
<member
name=
"M:Asa.RFID.ReadAll.Start(System.Int32)"
>
<summary>
开启
</summary>
<param
name=
"port"
>
RFID设备的端口
</param>
</member>
<member
name=
"M:Asa.RFID.ReadAll.Stop"
>
<summary>
停止
</summary>
</member>
<member
name=
"M:Asa.RFID.ReadAll.Read(System.String)"
>
<summary>
读取ID号
</summary>
<param
name=
"ip"
></param>
<returns></returns>
</member>
<member
name=
"M:Asa.RFID.ReadAll.Clear(System.String)"
>
<summary>
清除缓存
</summary>
<param
name=
"ip"
></param>
</member>
</members>
</doc>
doc/RC1250佳世达IO模块IP地址及伺服站号配置2020-6-9.xlsx
0 → 100644
查看文件 @
c45757f
此文件类型无法预览
source/DeviceLibrary/assemblyLine/FeedingEquip_InStore.cs
查看文件 @
c45757f
...
...
@@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace
OnlineStore.DeviceLibrary
{
partial
class
FeedingEquip
{
{
protected
override
bool
CheckWaitResult
(
LineMoveInfo
moveInfo
,
WaitResultInfo
wait
)
{
if
(
wait
.
WaitType
.
Equals
(
WaitEnum
.
W101_BatchAxisMove
))
...
...
@@ -673,7 +673,7 @@ namespace OnlineStore.DeviceLibrary
if
(
IOValue
(
IO_Type
.
SL_Location_Check
).
Equals
(
IO_VALUE
.
HIGH
))
{
ReadShelfId
();
if
(
CurrShelfId
.
EndsWith
(
"00"
))
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_33_BatchAxisToP1
);
...
...
@@ -697,7 +697,7 @@ namespace OnlineStore.DeviceLibrary
InLog
(
" 未检测到料架,入料结束"
);
}
}
else
if
(
MoveInfo
.
MoveStep
.
Equals
(
LineMoveStep
.
FI_05_LocationCylinder_Up
))
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_06_BatchAxisToP2
);
...
...
@@ -884,17 +884,28 @@ namespace OnlineStore.DeviceLibrary
}
int
targetPositon
=
Config
.
GetUpdownP2Detial
(
LastHeight
,
LastWidth
);
string
log
=
":移栽伺服下降到P2:"
+
targetPositon
;
InLog
(
"料盘移栽"
+
MoveInfo
.
SLog
+
":
等待空托盘到达
"
+
log
+
""
);
InLog
(
"料盘移栽"
+
MoveInfo
.
SLog
+
": "
+
log
+
""
);
UpdownAxis
.
AbsMove
(
MoveInfo
,
targetPositon
,
Config
.
UpdownAxis_P2Speed
);
}
else
if
(
MoveInfo
.
MoveStep
.
Equals
(
LineMoveStep
.
FI_22_BatchAxisDown
))
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_24_WaitTray
);
MoveInfo
.
WaitList
.
Add
(
WaitResultInfo
.
WaitTime
(
100
));
//int targetPositon = Config.GetUpdownP2Detial(LastHeight, LastWidth);
//string log = ":移栽伺服下降到P2:" + targetPositon;
//InLog("料盘移栽" + MoveInfo.SLog + ":等待空托盘到达 " + log + "");
//UpdownAxis.AbsMove(MoveInfo, targetPositon, Config.UpdownAxis_P2Speed);
FI_23_GetPosID
();
}
else
if
(
MoveInfo
.
MoveStep
.
Equals
(
LineMoveStep
.
FI_23_GetPosID
))
{
if
(
getPosTask
.
IsCompleted
&&
LastPosParam
!=
null
)
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_24_WaitTray
);
MoveInfo
.
WaitList
.
Add
(
WaitResultInfo
.
WaitTime
(
100
));
InLog
(
" "
+
MoveInfo
.
SLog
+
" 开始拦截空托盘 "
+
LastPosParam
.
ToStr
()
+
""
);
}
else
if
(
MoveInfo
.
IsTimeOut
(
120
))
{
WarnMsg
=
MoveInfo
.
Name
+
"["
+
MoveInfo
.
MoveStep
+
"] 获取库位号 超时 ["
+
Math
.
Round
(
MoveInfo
.
StepSpan
().
TotalSeconds
,
1
)
+
"]秒"
;
LogUtil
.
error
(
WarnMsg
,
DeviceID
*
1000
+
30
);
Alarm
(
LineAlarmType
.
IoSingleTimeOut
);
}
}
else
if
(
MoveInfo
.
MoveStep
.
Equals
(
LineMoveStep
.
FI_24_WaitTray
))
//TODO
{
...
...
@@ -902,39 +913,40 @@ namespace OnlineStore.DeviceLibrary
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_25_CylinderDown
);
CylinderMove
(
MoveInfo
,
IO_Type
.
SL_MoveCylinder_Up
,
IO_Type
.
SL_MoveCylinder_Down
);
InLog
(
"料盘移栽"
+
MoveInfo
.
SLog
+
":上料机构下降, 托盘号【"
+
currTrayNum
+
"】,更新托盘为有料,获取库位号 ,"
);
string
code
=
CodeManager
.
ProcessCode
(
LastCodeList
);
lastcode
=
code
;
TrayManager
.
UpdateTrayInfo
(
currTrayNum
,
true
,
ReelType
.
InStore
,
new
InOutParam
(
currTrayNum
,
code
,
""
,
LastHeight
,
LastWidth
,
false
),
""
);
getPosTask
=
Task
.
Factory
.
StartNew
(
delegate
{
int
sTrayNum
=
currTrayNum
;
//更新托盘条码信息
try
{
if
(
code
.
Equals
(
""
))
{
InOutParam
param
=
new
InOutParam
(
sTrayNum
,
code
,
""
,
LastHeight
,
LastWidth
,
true
);
TrayManager
.
UpdateTrayInfo
(
sTrayNum
,
true
,
ReelType
.
InStore
,
param
,
"扫码失败"
);
}
//从服务器获取库位号
string
result
=
SServerManager
.
CodeReceived
(
Name
,
sTrayNum
,
LastCodeList
,
LastHeight
,
LastWidth
,
CurrShelfId
,
DeviceID
);
if
(!
result
.
Equals
(
""
))
{
InOutParam
param
=
new
InOutParam
(
sTrayNum
,
code
,
""
,
LastHeight
,
LastWidth
,
true
);
param
.
rfid
=
CurrShelfId
;
TrayManager
.
UpdateTrayInfo
(
sTrayNum
,
true
,
ReelType
.
InStore
,
param
,
result
);
// TrayManager.UpdateInStoreNG(currTrayNum, true, result);
LogUtil
.
error
(
Name
+
"托盘【"
+
sTrayNum
+
"】"
+
result
);
}
}
catch
(
Exception
ex
)
{
LogUtil
.
error
(
Name
+
"托盘【"
+
sTrayNum
+
"】【"
+
code
+
"】获取库位号报错:"
+
ex
.
ToString
());
}
});
InLog
(
"料盘移栽"
+
MoveInfo
.
SLog
+
":上料机构下降, 托盘号【"
+
currTrayNum
+
"】,更新托盘信息 :"
+
LastPosParam
.
ToShortStr
());
TrayManager
.
UpdateTrayInfo
(
currTrayNum
,
true
,
ReelType
.
InStore
,
LastPosParam
,
LastPosParam
.
NgMsg
);
SServerManager
.
SendPosToStoreCheck
(
Name
,
LastPosParam
);
//string code = CodeManager.ProcessCode(LastCodeList);
//lastcode = code;
//getPosTask = Task.Factory.StartNew(delegate
//{
// int sTrayNum = currTrayNum;
// //更新托盘条码信息
// try
// {
// if (code.Equals(""))
// {
// InOutParam param = new InOutParam(sTrayNum, code, "", LastHeight, LastWidth, true);
// TrayManager.UpdateTrayInfo(sTrayNum, true, ReelType.InStore, param, "扫码失败");
// }
// //从服务器获取库位号
// string result = SServerManager.CodeReceived(Name, sTrayNum, LastCodeList, LastHeight, LastWidth, CurrShelfId, DeviceID);
// if (!result.Equals(""))
// {
// InOutParam param = new InOutParam(sTrayNum, code, "", LastHeight, LastWidth, true);
// param.rfid = CurrShelfId;
// TrayManager.UpdateTrayInfo(sTrayNum, true, ReelType.InStore, param, result);
// // TrayManager.UpdateInStoreNG(currTrayNum, true, result);
// LogUtil.error(Name + "托盘【" + sTrayNum + "】" + result);
// }
// }
// catch (Exception ex)
// {
// LogUtil.error(Name + "托盘【" + sTrayNum + "】【" + code + "】获取库位号报错:" + ex.ToString());
// }
//});
}
else
if
(
MoveInfo
.
IsTimeOut
(
180
))
...
...
@@ -942,8 +954,8 @@ namespace OnlineStore.DeviceLibrary
WarnMsg
=
MoveInfo
.
Name
+
"["
+
MoveInfo
.
MoveType
+
"]["
+
MoveInfo
.
SLog
+
"]等待空托盘到达超时["
+
Math
.
Round
(
MoveInfo
.
StepSpan
().
TotalSeconds
,
1
)
+
"]秒"
;
LogUtil
.
error
(
WarnMsg
,
DeviceID
*
1000
+
22
);
Alarm
(
LineAlarmType
.
IoSingleTimeOut
);
}
}
}
}
else
if
(
MoveInfo
.
MoveStep
.
Equals
(
LineMoveStep
.
FI_25_CylinderDown
))
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_26_CylinderRelax
);
...
...
@@ -1072,6 +1084,57 @@ namespace OnlineStore.DeviceLibrary
#
endregion
}
private
Task
getPosTask
=
null
;
private
InOutParam
LastPosParam
=
null
;
private
void
FI_23_GetPosID
()
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_23_GetPosID
);
InLog
(
"清空LastPosResult,从服务器获取入库库位"
);
MoveInfo
.
WaitList
.
Add
(
WaitResultInfo
.
WaitTime
(
2000
));
LastPosParam
=
null
;
string
code
=
CodeManager
.
ProcessCode
(
LastCodeList
);
lastcode
=
code
;
getPosTask
=
Task
.
Factory
.
StartNew
(
delegate
{
//更新托盘条码信息
try
{
int
count
=
1
;
while
(
MoveInfo
.
MoveType
.
Equals
(
LineMoveType
.
InStore
))
{
//从服务器获取库位号
GetPosResult
result
=
SServerManager
.
GetPosId
(
Name
,
LastCodeList
,
LastHeight
,
LastWidth
,
CurrShelfId
,
DeviceID
);
if
(
result
.
IsTimeOut
)
{
LogUtil
.
error
(
Name
+
"【"
+
code
+
"】第["
+
count
+
"]次 FI_23_GetPosID 超时,等待1s后重新获取"
);
Thread
.
Sleep
(
1000
);
}
else
if
(
result
.
Result
.
Equals
(
99
)
||
result
.
Result
.
Equals
(
100
))
{
LogUtil
.
error
(
Name
+
"【"
+
code
+
"】第["
+
count
+
"]次 FI_23_GetPosID 结果【"
+
result
.
Result
+
"】,等待1s后重新获取"
);
Thread
.
Sleep
(
1000
);
}
else
if
(!
result
.
Msg
.
Equals
(
""
)
)
{
LastPosParam
=
result
.
Param
;
LogUtil
.
error
(
Name
+
"【"
+
code
+
"】第["
+
count
+
"]次 FI_23_GetPosID 失败,入库NG:"
+
result
.
Msg
);
break
;
}
else
{
LastPosParam
=
result
.
Param
;
break
;
}
count
++;
}
}
catch
(
Exception
ex
)
{
LogUtil
.
error
(
Name
+
"【"
+
code
+
"】获取库位号报错:"
+
ex
.
ToString
());
}
});
}
private
void
FI_28_CylinderUp
()
{
MoveInfo
.
NextMoveStep
(
LineMoveStep
.
FI_28_CylinderUp
);
...
...
source/DeviceLibrary/assemblymanager/SServerManager.cs
查看文件 @
c45757f
...
...
@@ -61,10 +61,10 @@ namespace OnlineStore.DeviceLibrary
{
continue
;
}
list
.
Add
(
str
.
Trim
());
list
.
Add
(
str
.
Trim
());
string
code
=
"="
+
width
+
"x"
+
height
+
"="
+
str
.
Trim
();
codeStr
=
codeStr
+
code
+
spiltStr
;
}
}
codeStr
=
CodeManager
.
ReplaceCode
(
codeStr
);
//http://localhost/myproject/service/store/emptyPosForPutin
// 参数:cids: 多个 cid
...
...
@@ -87,7 +87,7 @@ namespace OnlineStore.DeviceLibrary
LineOperation
serverResult
=
JsonHelper
.
DeserializeJsonToObject
<
LineOperation
>(
resultStr
);
if
(
serverResult
==
null
)
{
msg
=
deviceName
+
" 【"
+
codeStr
+
"】结果:没有收到服务器反馈,调用 cancelPutInTask "
;
msg
=
deviceName
+
" 【"
+
codeStr
+
"】结果:没有收到服务器反馈,调用 cancelPutInTask "
;
cancelPutInTask
(
deviceName
,
codeStr
);
return
msg
;
}
...
...
@@ -408,7 +408,7 @@ namespace OnlineStore.DeviceLibrary
if
(
data
==
null
)
{
return
msg
=
deviceName
+
"findTempRfid【 "
+
rfid
+
"】 没有收到服务器反馈"
;
return
msg
=
deviceName
+
"
findTempRfid【 "
+
rfid
+
"】 没有收到服务器反馈"
;
}
else
if
(
data
.
code
.
Equals
(
0
).
Equals
(
false
))
{
...
...
@@ -448,7 +448,7 @@ namespace OnlineStore.DeviceLibrary
if
(
data
==
null
)
{
return
msg
=
deviceName
+
"cancelPutInTask【 "
+
barcode
+
"】 没有收到服务器反馈"
;
return
msg
=
deviceName
+
"
cancelPutInTask【 "
+
barcode
+
"】 没有收到服务器反馈"
;
}
else
if
(
data
.
code
.
Equals
(
0
).
Equals
(
false
))
{
...
...
@@ -463,6 +463,144 @@ namespace OnlineStore.DeviceLibrary
}
return
msg
;
}
public
static
GetPosResult
GetPosId
(
string
deviceName
,
List
<
string
>
codeList
,
int
height
,
int
width
,
string
rfid
,
int
feedEquipId
)
{
GetPosResult
result
=
new
GetPosResult
();
try
{
string
codeStr
=
""
;
List
<
string
>
list
=
new
List
<
string
>();
foreach
(
string
str
in
codeList
)
{
if
(
list
.
Contains
(
str
.
Trim
())
||
String
.
IsNullOrEmpty
(
str
.
Trim
()))
{
continue
;
}
list
.
Add
(
str
.
Trim
());
string
code
=
"="
+
width
+
"x"
+
height
+
"="
+
str
.
Trim
();
codeStr
=
codeStr
+
code
+
spiltStr
;
}
codeStr
=
CodeManager
.
ReplaceCode
(
codeStr
);
//http://localhost/myproject/service/store/emptyPosForPutin
// 参数:cids: 多个 cid
//code: 条码内容
Dictionary
<
string
,
string
>
paramMap
=
new
Dictionary
<
string
,
string
>();
paramMap
.
Add
(
"cids"
,
LineServer
.
GetAllCID
(
feedEquipId
));
paramMap
.
Add
(
"code"
,
codeStr
);
paramMap
.
Add
(
ParamDefine
.
rfid
,
rfid
);
string
server
=
GetAddr
(
Addr_PosForPutin
,
paramMap
);
DateTime
startTime
=
DateTime
.
Now
;
LogUtil
.
info
(
deviceName
+
"【"
+
rfid
+
"】【 "
+
codeStr
+
"】 ,获取入库库位:"
);
string
resultStr
=
HttpHelper
.
Post
(
server
,
""
,
Encoding
.
UTF8
,
10000
,
out
result
.
IsTimeOut
);
LogUtil
.
info
(
deviceName
+
"CodeReceived "
+
FormUtil
.
GetSpanStr
(
DateTime
.
Now
-
startTime
)
+
" 【"
+
server
+
"】【"
+
resultStr
+
"】"
);
if
(
result
.
IsTimeOut
)
{
return
result
;
}
//{"result":"0","msg":"","pos":"11#AC1_18_4_28","barcode":"R506072019102200414","cid":"line-ac-11"}
LineOperation
serverResult
=
JsonHelper
.
DeserializeJsonToObject
<
LineOperation
>(
resultStr
);
if
(
serverResult
==
null
)
{
result
.
Msg
=
deviceName
+
" 【"
+
codeStr
+
"】结果:没有收到服务器反馈,调用 cancelPutInTask "
;
cancelPutInTask
(
deviceName
,
codeStr
);
result
.
Param
=
new
InOutParam
(
0
,
codeStr
,
""
,
height
,
width
,
true
);
result
.
Param
.
rfid
=
rfid
;
result
.
Param
.
InStoreNg
=
true
;
result
.
Param
.
NgMsg
=
"没有收到服务器反馈"
;
return
result
;
}
else
if
((!
string
.
IsNullOrEmpty
(
serverResult
.
msg
))
||
serverResult
.
result
.
Equals
(
0
).
Equals
(
false
))
{
result
.
Result
=
serverResult
.
result
;
result
.
Msg
=
deviceName
+
" 【"
+
codeStr
+
"】结果:"
+
serverResult
.
msg
;
result
.
Param
=
new
InOutParam
(
0
,
codeStr
,
""
,
height
,
width
,
true
);
result
.
Param
.
rfid
=
rfid
;
result
.
Param
.
InStoreNg
=
true
;
result
.
Param
.
NgMsg
=
""
+
serverResult
.
msg
;
return
result
;
}
result
.
Result
=
serverResult
.
result
;
if
(!
serverResult
.
pos
.
Equals
(
""
))
{
// 仓位命名: 4D01020304
//第1和第2位表示楼层(4D)
//第3和第4位表示料仓(01) 01 - 18为流水线料仓, 19 - 24为包装料仓
//第5和第6位表示列(02)
//第7和第8位表示行(03)
//第9和第10位表示隔板位置(04)
//例如: 4D12010124 表示4楼12号料仓第1列第1行架子上的第24个隔板位置
//4D19050208 表示4楼19号料仓(包装料仓)第5列第2行架子上的第8个隔板位置
string
posId
=
serverResult
.
pos
;
//根据库位号查找移栽
// 判断PosID是否已经在入库或者在排队列表中,如果已经存在,加入列表失败
result
.
Param
=
new
InOutParam
(
0
,
serverResult
.
barcode
,
posId
,
height
,
width
);
result
.
Param
.
rfid
=
rfid
;
int
storeId
=
result
.
Param
.
GetStoreId
();
MoveEquip
moveEquip
=
LineManager
.
Line
.
MoveEquipMap
[
storeId
];
if
(
LineManager
.
Line
.
IsReviceInPosId
(
moveEquip
,
posId
))
{
result
.
Param
.
InStoreNg
=
true
;
result
.
Param
.
NgMsg
=
"入库库位重复"
;
result
.
Msg
=
deviceName
+
(
"收到服务器入库命令 "
+
"入库库位重复: "
+
result
.
Param
.
ToStr
()
+
" ,入库失败!"
);
return
result
;
}
LogUtil
.
info
(
deviceName
+
"收到入库命令: "
+
result
.
Param
.
ToStr
()
+
" "
);
}
}
catch
(
Exception
ex
)
{
LogUtil
.
error
(
deviceName
+
" "
,
ex
);
}
return
result
;
}
public
static
void
SendPosToStoreCheck
(
string
deviceName
,
InOutParam
param
)
{
if
(
param
==
null
||
param
.
InStoreNg
)
{
return
;
}
int
storeId
=
param
.
GetStoreId
();
MoveEquip
moveEquip
=
LineManager
.
Line
.
MoveEquipMap
[
storeId
];
if
(
LineServer
.
BoxCanInStore
(
moveEquip
.
DeviceID
))
{
LineServer
.
CheckInStorePos
(
storeId
,
param
);
}
else
{
//等待3秒后重发验证
Task
.
Factory
.
StartNew
(
delegate
{
LogUtil
.
error
(
deviceName
+
"["
+
moveEquip
.
Name
+
" ]入库命令: "
+
param
.
ToStr
()
+
" 给料仓发送验证失败,等待3秒后重发 "
);
Thread
.
Sleep
(
3000
);
LineServer
.
CheckInStorePos
(
storeId
,
param
);
});
}
lock
(
moveEquip
.
waitInListLock
)
{
//如果当前正在出入库中,需要记录下来,等待空闲时执行
LogUtil
.
info
(
deviceName
+
"["
+
moveEquip
.
Name
+
" ]入库命令: "
+
param
.
ToStr
()
+
"加入等待列表中!"
);
moveEquip
.
waitInStoreList
.
Add
(
param
);
}
}
}
public
class
GetPosResult
{
public
string
Msg
=
""
;
/// <summary>
/// 99:暂时不能入库,需要重新获取库位。100:服务器需要更新,需要重新获取库位
/// </summary>
public
int
Result
=
0
;
/// <summary>
/// 获取超时,需要重新获取库位
/// </summary>
public
bool
IsTimeOut
=
false
;
public
InOutParam
Param
=
null
;
}
public
class
RfidData
{
...
...
source/DeviceLibrary/model/InOutParam.cs
查看文件 @
c45757f
...
...
@@ -60,7 +60,7 @@ namespace OnlineStore.DeviceLibrary
/// 是否是入库NG的料盘
/// </summary>
public
bool
InStoreNg
=
false
;
public
string
NgMsg
=
""
;
public
string
ToStr
()
{
return
" ["
+
TrayNumber
+
"] ["
+
WareCode
+
"] ["
+
PosId
+
"] ["
+
PlateW
+
"x"
+
PlateH
+
"],InStoreNg ["
+
InStoreNg
+
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论