Skip to content
切换导航条
切换导航条
当前项目
正在载入...
登录
张东亮
/
Qisda-SO1037-AGVDispatch
转到一个项目
切换导航栏
切换导航栏固定状态
项目
群组
代码片段
帮助
项目
活动
版本库
流水线
图表
问题
0
合并请求
0
维基
网络
创建新的问题
作业
提交
问题看板
文件
提交
网络
比较
分支
标签
Commit 6ab2f9c9
由
张东亮
编写于
2023-05-29 11:44:30 +0800
浏览文件
选项
浏览文件
标签
下载
电子邮件补丁
差异文件
4D到4C逻辑
1 个父辈
f2e11805
显示空白字符变更
内嵌
并排
正在显示
5 个修改的文件
包含
157 行增加
和
5 行删除
DeviceLibrary/DeviceLibrary.csproj
DeviceLibrary/bean/RunStep.cs
DeviceLibrary/bean/job/LineOneToManyJob.cs
DeviceLibrary/bean/jobType/LineOneToManyJobType.cs
DeviceLibrary/manager/MissionManager.cs
DeviceLibrary/DeviceLibrary.csproj
查看文件 @
6ab2f9c
...
@@ -92,7 +92,6 @@
...
@@ -92,7 +92,6 @@
<Compile Include="bean\jobType\F1LiftC1ToLiftD2JobType.cs" />
<Compile Include="bean\jobType\F1LiftC1ToLiftD2JobType.cs" />
<Compile Include="bean\jobType\F1LiftD2ToLiftC1JobType.cs" />
<Compile Include="bean\jobType\F1LiftD2ToLiftC1JobType.cs" />
<Compile Include="bean\jobType\SteelLineToLiftJobType.cs" />
<Compile Include="bean\jobType\SteelLineToLiftJobType.cs" />
<Compile Include="bean\jobType\LineToLineJobType.cs" />
<Compile Include="bean\jobType\RecoveryJobType.cs" />
<Compile Include="bean\jobType\RecoveryJobType.cs" />
<Compile Include="bean\jobType\LineOneToManyJobType.cs" />
<Compile Include="bean\jobType\LineOneToManyJobType.cs" />
<Compile Include="bean\jobType\ToLiftGetShelfJobType.cs" />
<Compile Include="bean\jobType\ToLiftGetShelfJobType.cs" />
...
...
DeviceLibrary/bean/RunStep.cs
查看文件 @
6ab2f9c
...
@@ -353,10 +353,13 @@ namespace DeviceLibrary.bean
...
@@ -353,10 +353,13 @@ namespace DeviceLibrary.bean
/// 顶起料车
/// 顶起料车
/// </summary>
/// </summary>
SD_Line_OneToMany_02_PutShelfOn
,
SD_Line_OneToMany_02_PutShelfOn
,
SD_Line_OneToMany_03_1_CrossDoor
,
SD_Line_OneToMany_03_2_CrossTwoDoor
,
/// <summary>
/// <summary>
/// 去线体
/// 去线体
/// </summary>
/// </summary>
SD_Line_OneToMany_03_ToLine
,
SD_Line_OneToMany_03_ToLine
,
/// <summary>
/// <summary>
/// 到达线体,上报位置
/// 到达线体,上报位置
/// </summary>
/// </summary>
...
@@ -369,6 +372,8 @@ namespace DeviceLibrary.bean
...
@@ -369,6 +372,8 @@ namespace DeviceLibrary.bean
/// 检查下一线体
/// 检查下一线体
/// </summary>
/// </summary>
SD_Line_OneToMany_06_CheckNextLine
,
SD_Line_OneToMany_06_CheckNextLine
,
SD_Line_OneToMany_07_CrossTwoDoor
,
SD_Line_OneToMany_07_CrossDoor
,
/// <summary>
/// <summary>
/// 返回至取料位置
/// 返回至取料位置
/// </summary>
/// </summary>
...
...
DeviceLibrary/bean/job/LineOneToManyJob.cs
查看文件 @
6ab2f9c
...
@@ -21,6 +21,7 @@ namespace DeviceLibrary.bean.job
...
@@ -21,6 +21,7 @@ namespace DeviceLibrary.bean.job
lift
.
LiftStatus
liftStatus
;
lift
.
LiftStatus
liftStatus
;
public
override
Job
Run
(
AgvInfo
agv
)
public
override
Job
Run
(
AgvInfo
agv
)
{
{
Job
job
=
this
;
if
(
JobRunStep
.
IsStep
(
RunStep
.
NONE
))
if
(
JobRunStep
.
IsStep
(
RunStep
.
NONE
))
{
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_01_ToPickUpPosition
);
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_01_ToPickUpPosition
);
...
@@ -51,18 +52,58 @@ namespace DeviceLibrary.bean.job
...
@@ -51,18 +52,58 @@ namespace DeviceLibrary.bean.job
{
{
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
{
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
);
//上报运输状态
//上报运输状态
manager
.
UploadManager
.
UploadTransportStatus
(
new
service
.
model
.
TransportStatus
(
agv
.
CurJob
.
JobParam
.
GetMissionInfo
().
missionId
,
manager
.
UploadManager
.
UploadTransportStatus
(
new
service
.
model
.
TransportStatus
(
agv
.
CurJob
.
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
TransportStatus
.
TypeStr
.
status
,
agv
.
Name
,
agv
.
Place
.
Name
,
service
.
model
.
TransportStatus
.
ModeStr
.
auto
,
service
.
model
.
TransportStatus
.
TypeStr
.
status
,
agv
.
Name
,
agv
.
Place
.
Name
,
service
.
model
.
TransportStatus
.
ModeStr
.
auto
,
$
"取车"
));
$
"取车"
));
runInfo
=
$
"在{JobParam.SrcNode.AliceName}拾取料车完成,去{JobParam.CurTargetNode.AliceName}的放料点"
;
//任务状态变更
//任务状态变更
MissionManager
.
SetMissionState
(
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
MissionState
.
送料
,
out
string
msg
);
MissionManager
.
SetMissionState
(
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
MissionState
.
送料
,
out
string
msg
);
//是否需要跨两个门
if
(
NodeManager
.
NeedCrossTwoDoor
(
agv
,
JobParam
.
SrcNode
,
JobParam
.
CurTargetNode
))
{
JobParam
.
CrossDoor
.
CurNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
CurTargetNode
;
JobParam
.
CrossDoor
.
IsIn
=
true
;
JobParam
.
CrossDoor
.
IsAir
=
false
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_03_2_CrossTwoDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
//是否需要跨门
else
if
(
NodeManager
.
NeedCrossDoor
(
agv
,
JobParam
.
SrcNode
,
JobParam
.
CurTargetNode
,
out
bool
isin
,
out
bool
isair
))
{
JobParam
.
CrossDoor
.
CurNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
CurTargetNode
;
JobParam
.
CrossDoor
.
IsIn
=
isin
;
JobParam
.
CrossDoor
.
IsAir
=
isair
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_03_1_CrossDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
);
runInfo
=
$
"在{JobParam.SrcNode.AliceName}拾取料车完成,去{JobParam.CurTargetNode.AliceName}的放料点"
;
ToTakeShelfOff
(
agv
,
$
"{JobParam.CurTargetNode.Name}"
);
ToTakeShelfOff
(
agv
,
$
"{JobParam.CurTargetNode.Name}"
);
JobRunStep
.
Msg
=
runInfo
;
JobRunStep
.
Msg
=
runInfo
;
}
}
}
}
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_03_2_CrossTwoDoor
))
{
JobParam
.
CrossDoor
.
CurNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
CurTargetNode
;
JobParam
.
CrossDoor
.
IsIn
=
true
;
JobParam
.
CrossDoor
.
IsAir
=
true
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_03_1_CrossDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_03_1_CrossDoor
))
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
);
runInfo
=
$
"去{JobParam.CurTargetNode.AliceName}的放料点"
;
ToTakeShelfOff
(
agv
,
GetTargetName
(
JobParam
.
CurTargetNode
));
JobRunStep
.
Msg
=
runInfo
;
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
))
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
))
{
{
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
...
@@ -126,18 +167,51 @@ namespace DeviceLibrary.bean.job
...
@@ -126,18 +167,51 @@ namespace DeviceLibrary.bean.job
{
{
if
(
JobParam
.
TargetNodes
!=
null
&&
JobParam
.
TargetNodes
.
Count
>
0
)
if
(
JobParam
.
TargetNodes
!=
null
&&
JobParam
.
TargetNodes
.
Count
>
0
)
{
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
);
JobParam
.
CurTargetNode
=
JobParam
.
TargetNodes
[
0
];
JobParam
.
CurTargetNode
=
JobParam
.
TargetNodes
[
0
];
JobParam
.
TargetNodes
.
RemoveAt
(
0
);
JobParam
.
TargetNodes
.
RemoveAt
(
0
);
System
.
Threading
.
Thread
.
Sleep
(
1000
);
System
.
Threading
.
Thread
.
Sleep
(
1000
);
if
(
NodeManager
.
NeedCrossDoor
(
agv
,
agv
.
Place
,
JobParam
.
CurTargetNode
,
out
bool
isin
,
out
bool
isair
))
{
JobParam
.
CrossDoor
.
CurNode
=
agv
.
Place
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
CurTargetNode
;
JobParam
.
CrossDoor
.
IsIn
=
isin
;
JobParam
.
CrossDoor
.
IsAir
=
isair
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_03_1_CrossDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_03_ToLine
);
runInfo
=
$
"去下一线体{JobParam.CurTargetNode.AliceName}的放料点"
;
runInfo
=
$
"去下一线体{JobParam.CurTargetNode.AliceName}的放料点"
;
JobRunStep
.
Msg
=
runInfo
;
JobRunStep
.
Msg
=
runInfo
;
ToTakeShelfOff
(
agv
,
$
"{JobParam.CurTargetNode.Name}"
);
ToTakeShelfOff
(
agv
,
$
"{JobParam.CurTargetNode.Name}"
);
}
}
}
else
else
{
{
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
JobParam
.
GetMissionInfo
().
needBack
)
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
JobParam
.
GetMissionInfo
().
needBack
)
{
{
if
(
NodeManager
.
NeedCrossTwoDoor
(
agv
,
agv
.
Place
,
JobParam
.
SrcNode
))
{
JobParam
.
CrossDoor
.
CurNode
=
agv
.
Place
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
IsIn
=
false
;
JobParam
.
CrossDoor
.
IsAir
=
true
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_07_CrossTwoDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
if
(
NodeManager
.
NeedCrossDoor
(
agv
,
agv
.
Place
,
JobParam
.
SrcNode
,
out
bool
isin
,
out
bool
isair
))
{
JobParam
.
CrossDoor
.
CurNode
=
agv
.
Place
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
IsIn
=
isin
;
JobParam
.
CrossDoor
.
IsAir
=
isair
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_07_CrossDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_07_BackToPickUpPosition
);
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_07_BackToPickUpPosition
);
runInfo
=
$
"{JobParam.CurTargetNode.AliceName}是最后一个线体,分发结束,需要返回{JobParam.SrcNode.Name}的放料点"
;
runInfo
=
$
"{JobParam.CurTargetNode.AliceName}是最后一个线体,分发结束,需要返回{JobParam.SrcNode.Name}的放料点"
;
//任务状态变更
//任务状态变更
...
@@ -145,6 +219,8 @@ namespace DeviceLibrary.bean.job
...
@@ -145,6 +219,8 @@ namespace DeviceLibrary.bean.job
ToTakeShelfOff
(
agv
,
$
"{JobParam.SrcNode.Name}"
);
ToTakeShelfOff
(
agv
,
$
"{JobParam.SrcNode.Name}"
);
JobRunStep
.
Msg
=
runInfo
;
JobRunStep
.
Msg
=
runInfo
;
}
}
}
else
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
!
JobParam
.
GetMissionInfo
().
needBack
)
else
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
!
JobParam
.
GetMissionInfo
().
needBack
)
{
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OnToMany_08_TakeShelfOff
);
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OnToMany_08_TakeShelfOff
);
...
@@ -160,6 +236,24 @@ namespace DeviceLibrary.bean.job
...
@@ -160,6 +236,24 @@ namespace DeviceLibrary.bean.job
}
}
}
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_07_CrossTwoDoor
))
{
JobParam
.
CrossDoor
.
CurNode
=
JobParam
.
CurTargetNode
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
IsIn
=
false
;
JobParam
.
CrossDoor
.
IsAir
=
false
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
SD_Line_OneToMany_07_CrossDoor
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_07_CrossDoor
))
{
JobRunStep
.
ToNextStep
(
RunStep
.
SD_Line_OneToMany_07_BackToPickUpPosition
);
runInfo
=
$
"过门完成,需要返回{JobParam.SrcNode.Name}的放料点"
;
//任务状态变更
MissionManager
.
SetMissionState
(
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
MissionState
.
返回起始地
,
out
string
msg
);
ToTakeShelfOff
(
agv
,
$
"{JobParam.SrcNode.Name}"
);
JobRunStep
.
Msg
=
runInfo
;
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_07_BackToPickUpPosition
))
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
SD_Line_OneToMany_07_BackToPickUpPosition
))
{
{
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
...
@@ -178,6 +272,26 @@ namespace DeviceLibrary.bean.job
...
@@ -178,6 +272,26 @@ namespace DeviceLibrary.bean.job
{
{
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
if
(
agv
.
TaskRunState
.
CheckTaskFinished
(
agv
))
{
{
if
(
NodeManager
.
NeedCrossTwoDoor
(
agv
,
agv
.
Place
,
JobParam
.
SrcNode
))
{
JobParam
.
CrossDoor
.
CurNode
=
agv
.
Place
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
IsIn
=
false
;
JobParam
.
CrossDoor
.
IsAir
=
true
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
END
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
if
(
NodeManager
.
NeedCrossDoor
(
agv
,
agv
.
Place
,
JobParam
.
SrcNode
,
out
bool
isin
,
out
bool
isair
))
{
JobParam
.
CrossDoor
.
CurNode
=
agv
.
Place
;
JobParam
.
CrossDoor
.
NextNode
=
JobParam
.
SrcNode
;
JobParam
.
CrossDoor
.
IsIn
=
isin
;
JobParam
.
CrossDoor
.
IsAir
=
isair
;
GenJobCallBack
(
this
.
GetType
(),
RunStep
.
END
,
JobParam
);
job
=
new
CrossDoorJob
(
JobParam
);
}
else
{
JobRunStep
.
ToNextStep
(
RunStep
.
END
);
JobRunStep
.
ToNextStep
(
RunStep
.
END
);
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
JobParam
.
GetMissionInfo
().
needBack
)
if
(
JobParam
.
GetMissionInfo
()
!=
null
&&
JobParam
.
GetMissionInfo
().
needBack
)
{
{
...
@@ -199,6 +313,8 @@ namespace DeviceLibrary.bean.job
...
@@ -199,6 +313,8 @@ namespace DeviceLibrary.bean.job
MissionManager
.
SetMissionState
(
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
MissionState
.
完成
,
out
string
msg
);
MissionManager
.
SetMissionState
(
JobParam
.
GetMissionInfo
().
missionId
,
service
.
model
.
MissionState
.
完成
,
out
string
msg
);
JobRunStep
.
Msg
=
runInfo
;
JobRunStep
.
Msg
=
runInfo
;
}
}
}
}
}
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
END
))
else
if
(
JobRunStep
.
IsStep
(
RunStep
.
END
))
{
{
...
@@ -214,7 +330,7 @@ namespace DeviceLibrary.bean.job
...
@@ -214,7 +330,7 @@ namespace DeviceLibrary.bean.job
Name
=
agv
.
Name
,
Name
=
agv
.
Name
,
JobParam
=
JobParam
JobParam
=
JobParam
});
});
return
this
;
return
job
;
}
}
}
}
}
}
DeviceLibrary/bean/jobType/LineOneToManyJobType.cs
查看文件 @
6ab2f9c
...
@@ -18,6 +18,8 @@ namespace DeviceLibrary.bean.jobType
...
@@ -18,6 +18,8 @@ namespace DeviceLibrary.bean.jobType
missionInfo
=
manager
.
MissionManager
.
GetLineToLineMission
(
agv
);
missionInfo
=
manager
.
MissionManager
.
GetLineToLineMission
(
agv
);
if
(
missionInfo
==
null
)
if
(
missionInfo
==
null
)
missionInfo
=
manager
.
MissionManager
.
GetStoreToLinesMission
(
agv
);
missionInfo
=
manager
.
MissionManager
.
GetStoreToLinesMission
(
agv
);
if
(
missionInfo
==
null
)
missionInfo
=
manager
.
MissionManager
.
Get4DTo4CLinesMission
(
agv
);
if
(
missionInfo
!=
null
)
if
(
missionInfo
!=
null
)
{
{
Node
src
=
manager
.
NodeManager
.
GetNode
(
missionInfo
.
sourcePoint
,
NodeType
.
Node
);
Node
src
=
manager
.
NodeManager
.
GetNode
(
missionInfo
.
sourcePoint
,
NodeType
.
Node
);
...
...
DeviceLibrary/manager/MissionManager.cs
查看文件 @
6ab2f9c
...
@@ -593,6 +593,36 @@ namespace DeviceLibrary.manager
...
@@ -593,6 +593,36 @@ namespace DeviceLibrary.manager
}
}
return
null
;
return
null
;
}
}
/// <summary>
///
/// </summary>
/// <param name="agv"></param>
/// <returns></returns>
public
static
MissionInfo
Get4DTo4CLinesMission
(
AgvInfo
agv
)
{
MissionInfo
missionInfo
=
null
;
try
{
var
missions
=
GetMissionInfos
().
Where
(
w
=>
w
.
state
!=
MissionState
.
中止
&&
w
.
state
!=
MissionState
.
取消
&&
w
.
state
!=
MissionState
.
完成
).
ToList
();
missionInfo
=
missions
.
Where
(
s
=>
s
.
destinationWorkshop
.
Equals
(
SettingString
.
_4C
)
&&
s
.
sourceWorkshop
.
Equals
(
SettingString
.
_4D
)
&&
//(s.projectType.Equals(ProjectType.PCB领用) || s.projectType.Equals(ProjectType.包材领用))&&
(
s
.
state
==
MissionState
.
创建
)
&&
agv
.
Scope
.
Tasks
.
Contains
(
s
.
projectType
.
ToString
())).
FirstOrDefault
();
if
(
missionInfo
!=
null
&&
AgvCanGetMission
(
missionInfo
))
{
SetMissionOccupied
(
missionInfo
,
agv
);
Log
.
Info
(
$
"执行4D到4C任务[{agv.Name}][目的地] {JsonHelper.SerializeObject(missionInfo)}"
);
return
missionInfo
;
}
}
catch
(
Exception
e
)
{
Log
.
Error
(
"Get4DTo4CLinesMission"
,
e
);
}
return
null
;
}
public
static
void
SetMissionOccupied
(
MissionInfo
missionInfo
,
AgvInfo
agv
)
public
static
void
SetMissionOccupied
(
MissionInfo
missionInfo
,
AgvInfo
agv
)
{
{
SetMissionOccupiedAgv
(
missionInfo
.
missionId
,
agv
.
Name
);
SetMissionOccupiedAgv
(
missionInfo
.
missionId
,
agv
.
Name
);
...
...
编写
预览
支持
Markdown
格式
附加文件
你添加了
0
人
到此讨论。请谨慎行事。
Finish editing this message first!
Cancel
请
注册
或
登录
后发表评论