Commit 4c744f63 顾剑亮

优化逻辑

1 个父辈 1f1b7d9d
......@@ -40,10 +40,13 @@
<add key="FLEET_IP" value="10.85.199.3"/>
<add key="FLEET_Send" value="true"/>
<add key="WebService" value="http://10.85.196.40:8089/"/>
<!--<add key="WebService" value="http://10.211.55.23:8089/"/>-->
<add key="AGV_BATTERY_MAX" value="100"/>
<add key="AGV_BATTERY_MIN" value="40"/>
<add key="4C_AGV" value="32"/>
<add key="4D_AGV" value="25"/>
<add key="PlaceName" value="D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,4cwash,4dwash,storage"/>
<add key="Use_32" value="false"/>
<add key="Use_25" value="false"/>
<add key="Work_32" value="4C"/>
<add key="Work_25" value="4D"/>
<add key="PlaceName" value="D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,4Cwash,4Dwash,storage"/>
</appSettings>
</configuration>
\ No newline at end of file
......@@ -24,33 +24,25 @@ namespace AGVControl_Steel
public static System.Configuration.Configuration appConfig;
public static log4net.ILog log;
public static string[] PLACE_NAME;
/// <summary>
/// 仓库对接完成
/// </summary>
public static bool StorageDockFinish;
public static bool FLEET_SEND;
public static bool StorageDockFinish = false;
public static bool StorageDockAlway = false;
public const int AGV_CALL_SLEEP = 2000;
public const string STORAGE_ENTER_4C = "4c_enter";
public const string STORAGE_ENTER_4D = "4d_enter";
public const string STORAGE_ENTER_4C = "4C_enter";
public const string STORAGE_ENTER_4D = "4D_enter";
public const string STORAGE_LEAVE = "leave";
public const string STORAGE_IO_ON = "di_on";
public const string STORAGE_IO_OFF = "di_off";
public const string WORKSHOP_4D = "4d";
public const string WORKSHOP_4C = "4c";
public const string MISSION_TAKE_OFF_SHELF = "Placeqisdashelf";
public const string MISSION_TAKE_ON_SHELF = "Pickupqisdashelf";
public const string MISSION_MOVE_4C_4D = "MoveDoor-4C-4D";
public const string MISSION_MOVE_4D_4C = "MoveDoor-4D-4C";
public const string MISSION_CHARGE_4D = "AutoCharge4D";
public const string MISSION_CHARGE_4C = "AutoCharge4C";
public const string MISSION_STANDBY_4D = "Move4DStandby";
public const string MISSION_STANDBY_4C = "Move4CStandby";
public const string MISSION_MOVE_WASH_4D = "Move4DWash";
public const string MISSION_MOVE_WASH_4C = "Move4CWash";
public const string MISSION_PASS_DOOR_INTO = "PassDoorInto";
public const string MISSION_CHARGE = "AutoCharge";
public const string MISSION_STANDBY = "MoveStandby";
public const string MISSION_MOVE_WASH = "MoveWash";
public const string MISSION_MOVE_STORAGE = "MoveSteelstorage";
public const string MISSION_MOVE_D1 = "MoveSteelD1";
public const string MISSION_MOVE_D2 = "MoveSteelD2";
......
......@@ -82,7 +82,7 @@ namespace BLL
string name = "";
bool find = false;
string s = info.Workshop.Substring(1, 1).ToUpper();
string s = info.Workshop.Substring(1, 1);
for (int i = 0; i < Common.PLACE_NAME.Length; i++)
{
name = Common.PLACE_NAME[i];
......@@ -292,44 +292,18 @@ namespace BLL
public Job GetSteelJob(AgvInfo info)
{
if (info.Battery < info.BatteryMin)
return null;
//TEST
string s = "";
for (int i = 0; i < oldSteelWork.Count; i++)
s += oldSteelWork[i].Place + ";";
Common.log.Debug("TEST oldSteelWork=" + s);
s = "";
for (int i = 0; i < newSteelWork.Count; i++)
s += newSteelWork[i].From + "," + newSteelWork[i].Place + "; ";
Common.log.Debug("TEST newSteelWork=" + s);
int newSteelIndex = newSteelWork.FindIndex(s => s.From.StartsWith(info.Workshop) && s.From == s.Place);
int storageIndex = storageWork.FindIndex(s => s.Place.StartsWith(info.Workshop));
#region 回收回收钢板
string name = "";
if (info.Workshop == Common.WORKSHOP_4C)
name = "C";
else if (info.Workshop == Common.WORKSHOP_4D)
name = "D";
int index = oldSteelWork.FindIndex(s => s.Place.StartsWith(name));
if (index > -1)
{
Common.log.Info(info.Workshop + "回收钢板回收");
return new TakeOldJob();
}
else
{
Common.log.Debug("没有找到" + info.Workshop + "回收钢板任务");
}
#endregion
#region 清洗点呼叫
index = newSteelWork.FindIndex(s => s.From.StartsWith(info.Workshop) && s.From == s.Place);
if (index > -1)
if (newSteelIndex > -1)
{
info.SteelFrom = newSteelWork[index].From;
info.SteelFrom = newSteelWork[newSteelIndex].From;
Common.log.Info(info.Workshop + "清洗点呼叫");
return new WashPointJob();
}
......@@ -340,8 +314,7 @@ namespace BLL
#endregion
#region 仓库入架子出钢板
index = storageWork.FindIndex(s => s.Place.StartsWith(info.Workshop));
if (index > -1)
if (storageIndex > -1)
{
info.SteelFrom = "storage";
Common.log.Info("4D仓库呼叫");
......@@ -353,6 +326,53 @@ namespace BLL
}
#endregion
#region 回收钢板
string name = info.Workshop.Substring(1, 1);
int oldSteelIndex = oldSteelWork.FindIndex(s => s.Place.StartsWith(name));
if (oldSteelIndex > -1)
{
Common.log.Info(info.Workshop + "回收钢板回收");
return new TakeOldJob();
}
else
{
Common.log.Debug("没有找到" + info.Workshop + "回收钢板任务");
}
//string name = info.Workshop.Substring(1, 1);
//List<SteelWork> sw = oldSteelWork.FindAll(s => s.Place.StartsWith(name));
//if (sw.Count == 0)
//{
// Common.log.Debug("没有找到" + info.Workshop + "回收钢板任务");
//}
//else
//{
// bool find = false;
// for (int i = 0; i < sw.Count; i++)
// {
// TimeSpan span = DateTime.Now - sw[i].DateTime;
// if (span.TotalMinutes >= 2)
// {
// find = true;
// break;
// }
// }
// if (find)
// {
// Common.log.Info(info.Workshop + "回收钢板任务");
// return new TakeOldJob();
// }
// else
// {
// Common.log.Debug("有" + info.Workshop + "回收钢板任务,但没有到2分钟,暂时不回收。");
// }
//}
#endregion
return null;
}
......
......@@ -156,10 +156,7 @@ namespace Webs
try
{
from = from.ToLower();
place = place.ToLower();
if (from != place) place = place.ToUpper();
int index = Array.FindIndex(Common.PLACE_NAME, s => s == from);
int index = Array.FindIndex(Common.PLACE_NAME, s => s.ToLower() == from.ToLower());
if (index == -1)
{
......@@ -168,12 +165,13 @@ namespace Webs
}
else
{
from = Common.PLACE_NAME[index];
bool find = true;
string[] arr = place.Split(',');
for (int i = 0; i < arr.Length; i++)
{
if (arr[i] == "STORAGE") arr[i] = arr[i].ToLower();
index = Array.FindIndex(Common.PLACE_NAME, s => s == arr[i]);
index = Array.FindIndex(Common.PLACE_NAME, s => s.ToLower() == arr[i].ToLower());
if (index == -1)
{
......@@ -184,7 +182,7 @@ namespace Webs
}
else
{
Common.steelManage.NewSteelWorkAdd(from, arr[i]);
Common.steelManage.NewSteelWorkAdd(from, Common.PLACE_NAME[index]);
find = true;
}
}
......@@ -211,44 +209,40 @@ namespace Webs
/// <returns></returns>
private Result Storage(string place)
{
Result res = new Result();
Result res = new Result { Code = 0, Msg = "OK" };
try
{
string s = place.ToLower();
switch(s)
if (s == Common.STORAGE_ENTER_4C.ToLower())
{
case Common.STORAGE_ENTER_4C:
res.Code = 0;
res.Msg = "OK,4C";
Common.steelManage.StorageWorkAdd(s);
break;
case Common.STORAGE_ENTER_4D:
res.Code = 0;
Common.steelManage.StorageWorkAdd(Common.STORAGE_ENTER_4C);
}
else if (s == Common.STORAGE_ENTER_4D.ToLower())
{
res.Msg = "OK,4D";
Common.steelManage.StorageWorkAdd(s);
break;
case Common.STORAGE_LEAVE:
res.Code = 0;
res.Msg = "OK";
Common.steelManage.StorageWorkAdd(s);
break;
case Common.STORAGE_IO_ON:
res.Code = 0;
res.Msg = "OK";
Common.steelManage.StorageWorkAdd(Common.STORAGE_ENTER_4D);
}
else if (s == Common.STORAGE_LEAVE.ToLower())
{
Common.steelManage.StorageWorkAdd(Common.STORAGE_LEAVE);
}
else if (s == Common.STORAGE_IO_ON.ToLower())
{
Common.StorageDockFinish = true;
UpdateStorageIO();
break;
case Common.STORAGE_IO_OFF:
res.Code = 0;
res.Msg = "OK";
}
else if (s == Common.STORAGE_IO_OFF.ToLower())
{
Common.StorageDockFinish = false;
UpdateStorageIO();
break;
default:
res = new Result { Code = -2, Msg = "Not find place=" + place };
}
else
{
res.Code = -2;
res.Msg = "Not find place=" + place;
Common.log.Info("没有找到" + place);
break;
}
}
catch (Exception ex)
......@@ -264,6 +258,7 @@ namespace Webs
{
if (Common.lblStorageIO == null) return;
int.TryParse(Common.lblStorageIO.Tag.ToString(), out int n);
if (Common.StorageDockAlway) Common.StorageDockFinish = true;
string s = Common.StorageDockFinish ? "ON" : "OFF";
Common.lblStorageIO.Text = string.Format("仓库IO信号 {0} ({1})", s, n);
Common.lblStorageIO.BackColor = Common.StorageDockFinish ? Color.Lime : Color.Red;
......
......@@ -93,15 +93,14 @@ namespace Model
private void MoveDoor(AgvInfo info)
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_MOVE_4C_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_MOVE_4D_4C;
mission = Common.MISSION_PASS_DOOR_INTO + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
chargeStep.Msg = info.FullName + "在" + info.Workshop.ToUpper() + "车间,先过车间门";
chargeStep.Msg = info.FullName + "在" + info.Workshop + "车间,先过车间门";
chargeStep.NextStep(ChargeStep.WaitWorkshopDoor);
}
else
......@@ -112,16 +111,15 @@ namespace Model
private void MoveCharge(AgvInfo info)
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_CHARGE_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_CHARGE_4C;
mission = Common.MISSION_CHARGE + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
info.Place = "充电位";
chargeStep.Msg = info.FullName + "在" + info.Workshop + "车间,去充电位";
chargeStep.Msg = info.FullName + "在" + info.Workshop + "车间去充电位," + mission;
chargeStep.NextStep(ChargeStep.WaitChargeStation);
}
else
......
......@@ -20,7 +20,10 @@ namespace Model
{
if (missionMoveStep.IsEqual(MissionMoveStep.None))
{
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
getStateTime = 0;
......
......@@ -20,31 +20,9 @@ namespace Model
if (sendNewStep.IsEqual(SendNewStep.None))
{
dockTime = 0;
info.FillSteelCount();
sendNewStep.Msg = info.FullName + "等待任务";
sendNewStep.NextStep(SendNewStep.FindMission);
}
else if (sendNewStep.IsEqual(SendNewStep.FindMission))
{
rtn = Common.steelManage.FindNewSteelWork(info);
if (rtn)
{
if (info.IsSelfWorkshop())
{
sendNewStep.Msg = info.FullName + "找到任务,开始执行";
sendNewStep.NextStep(SendNewStep.FindLine);
}
else
{
MoveDoor(info);
}
}
//else
//{
// sendNewStep.Msg = info.FullName + "没有找到任务";
// sendNewStep.NextStep(SendNewStep.End);
//}
}
else if (sendNewStep.IsEqual(SendNewStep.WaitWorkshopDoor))
{
rtn = Common.mir.Get_MissionState_Fleet(info.Authorization, id, out string state);
......@@ -67,30 +45,53 @@ namespace Model
}
else if (sendNewStep.IsEqual(SendNewStep.FindLine))
{
if (info.IsSteelEmpty())
rtn = Common.steelManage.FindNewSteelWork(info, out string place);
if (rtn)
{
if (place == "storage")
{
sendNewStep.Msg = info.FullName + "钢板已全部取走";
sendNewStep.NextStep(SendNewStep.End);
if (info.Is4DWorkshop())
{
info.Place = place;
mission = "MoveSteel" + info.Place;
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
sendNewStep.Msg = info.FullName + "发送任务" + mission;
sendNewStep.NextStep(SendNewStep.MoveLine);
}
else
{
rtn = Common.steelManage.FindNewSteelWork(info, out string place);
if (rtn)
MoveDoor4D(info);
}
}
else
{
if (info.IsSelfWorkshop())
{
info.Place = place;
mission = "MoveSteel" + info.Place;
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
sendNewStep.Msg = info.FullName + "发送任务" + mission;
sendNewStep.NextStep(SendNewStep.MoveLine);
info.SteelCountAdd();
}
else
{
MoveDoor(info);
}
}
}
else
{
sendNewStep.Msg = info.FullName + "没有后续新钢板任务";
sendNewStep.NextStep(SendNewStep.End);
}
}
}
else if (sendNewStep.IsEqual(SendNewStep.MoveLine))
{
rtn = Common.mir.Get_MissionState_Fleet(info.Authorization, id, out string state);
......@@ -104,7 +105,6 @@ namespace Model
delayGetSignal = 0;
sendNewStep.Msg = info.FullName + "等待到位信号";
sendNewStep.NextStep(SendNewStep.GetSingle);
}
else
{
......@@ -126,6 +126,12 @@ namespace Model
{
if (Common.StorageDockFinish)
{
//入库的同时又有出库,需要删除出库任务。
if (info.Workshop == "4C")
Common.steelManage.StorageWorkDel(Common.STORAGE_ENTER_4C);
else if (info.Workshop == "4D")
Common.steelManage.StorageWorkDel(Common.STORAGE_ENTER_4D);
Common.steelManage.NewSteelWorkDel(info.SteelFrom, info.Place);
sendNewStep.Msg = info.FullName + "已到位,等待离开信号";
sendNewStep.NextStep(SendNewStep.WaitStorageLeave);
......@@ -145,7 +151,10 @@ namespace Model
{
dockTime++;
mission = "MoveSteel" + info.Place;
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
sendNewStep.Msg = info.FullName + "信号没有到位,第" + dockTime + "次重发任务" + mission;
sendNewStep.NextStep(SendNewStep.MoveLine);
}
......@@ -166,7 +175,11 @@ namespace Model
{
info.SteelFrom = "";
info.ClearSteelCount();
Job job = Common.steelManage.GetSteelJob(info);
if (job == null)
return new StandbyJob();
else
return job;
}
else if (sendNewStep.IsEqual(SendNewStep.Error))
{
......@@ -176,15 +189,32 @@ namespace Model
private void MoveDoor(AgvInfo info)
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_MOVE_4C_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_MOVE_4D_4C;
mission = Common.MISSION_PASS_DOOR_INTO + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
sendNewStep.Msg = info.FullName + "在其他车间,先过车间门";
sendNewStep.NextStep(SendNewStep.WaitWorkshopDoor);
}
else
{
sendNewStep.Msg = info.FullName + "发送" + mission + "任务失败";
}
}
private void MoveDoor4D(AgvInfo info)
{
mission = Common.MISSION_PASS_DOOR_INTO + "4D";
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
sendNewStep.Msg = info.FullName + "在" + info.Workshop + "车间,先过车间门";
sendNewStep.Msg = info.FullName + "在其他车间,先过车间门";
sendNewStep.NextStep(SendNewStep.WaitWorkshopDoor);
}
else
......@@ -196,7 +226,7 @@ namespace Model
private enum SendNewStep
{
None,
FindMission,
//FindMission,
WaitWorkshopDoor,
FindLine,
MoveLine,
......
......@@ -89,15 +89,14 @@ namespace Model
private void MoveDoor(AgvInfo info)
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_MOVE_4C_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_MOVE_4D_4C;
mission = Common.MISSION_PASS_DOOR_INTO + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
standbyStep.Msg = info.FullName + "在" + info.Workshop + "车间,先过车间门";
standbyStep.Msg = info.FullName + "在其他车间,先过车间门";
standbyStep.NextStep(StandbyStep.WaitWorkshopDoor);
}
else
......@@ -108,12 +107,11 @@ namespace Model
private void MoveStandby(AgvInfo info)
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_STANDBY_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_STANDBY_4C;
mission = Common.MISSION_STANDBY + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
info.Place = "待机位";
......
......@@ -50,8 +50,11 @@ namespace Model
Common.steelManage.FindStorageWork(info, out string place);
info.Place = place;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, Common.MISSION_MOVE_STORAGE, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, Common.MISSION_MOVE_STORAGE, out id);
if (rtn)
{
storageStep.Msg = info.FullName + "去4D仓库";
......@@ -88,7 +91,8 @@ namespace Model
if (Common.StorageDockFinish)
{
Common.steelManage.StorageWorkDel(info.Place);
storageStep.NextStep(StorageStep.End);
storageStep.Msg = info.FullName + "已到位,等待离开信号";
storageStep.NextStep(StorageStep.WaitStorageLeave);
}
else
{
......@@ -105,7 +109,10 @@ namespace Model
{
dockTime++;
mission = "MoveSteel" + info.Place;
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
storageStep.Msg = info.FullName + "信号没有到位,第" + dockTime + "次重发任务" + mission;
storageStep.NextStep(StorageStep.GoStorage);
}
......@@ -113,10 +120,23 @@ namespace Model
delayGetSignal++;
}
}
else if (storageStep.IsEqual(StorageStep.End))
else if (storageStep.IsEqual(StorageStep.WaitStorageLeave))
{
if (Common.steelManage.FindStorageWorkLeave())
{
Common.steelManage.StorageWorkDelLeave();
storageStep.Msg = info.FullName + "收到离开信号";
return new StandbyJob();
}
else if (Common.steelManage.FindNewSteelWork(info))
{
return new SendNewJob();
}
}
else if (storageStep.IsEqual(StorageStep.End))
{
}
else if (storageStep.IsEqual(StorageStep.Error))
{
}
......@@ -125,7 +145,15 @@ namespace Model
private void MoveDoor(AgvInfo info)
{
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, Common.MISSION_MOVE_4C_4D, out id);
string name = Common.MISSION_PASS_DOOR_INTO;
if (info.Workshop.Substring(1, 1) == "C")
name += info.Workshop.Substring(0, 1) + "D";
else
name += info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, name, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, name, out id);
if (rtn)
{
storageStep.Msg = info.FullName + "在" + info.Workshop + "车间,先过车间门";
......@@ -144,6 +172,7 @@ namespace Model
GoStorage,
WaitStorage,
GetSingle,
WaitStorageLeave,
Error,
End
}
......
......@@ -61,16 +61,15 @@ namespace Model
}
else if (takeOldStep.IsEqual(TakeOldStep.GoWashPoint))
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_MOVE_WASH_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_MOVE_WASH_4C;
mission = Common.MISSION_MOVE_WASH + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
info.Place = "4D清洗点";
takeOldStep.Msg = info.FullName + "去" + info.Workshop.ToUpper() + "清洗点";
takeOldStep.Msg = info.FullName + "去" + info.Workshop + "清洗点";
takeOldStep.NextStep(TakeOldStep.WaitWashPoint);
}
else
......@@ -101,7 +100,11 @@ namespace Model
else if (takeOldStep.IsEqual(TakeOldStep.End))
{
info.ClearSteelCount();
Job job = Common.steelManage.GetSteelJob(info);
if (job == null)
return new StandbyJob();
else
return job;
}
return this;
......@@ -115,7 +118,10 @@ namespace Model
name = place;
info.Place = name;
mission = "MoveSteel" + name;
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
takeOldStep.Msg = info.FullName + "发送任务," + mission;
takeOldStep.NextStep(TakeOldStep.MoveLine);
info.SteelCountAdd();
......
......@@ -21,15 +21,14 @@ namespace Model
}
else if (washPointStep.IsEqual(WashPointStep.GoWashPoint))
{
if (info.Workshop == Common.WORKSHOP_4D)
mission = Common.MISSION_MOVE_WASH_4D;
else if (info.Workshop == Common.WORKSHOP_4C)
mission = Common.MISSION_MOVE_WASH_4C;
mission = Common.MISSION_MOVE_WASH + info.Workshop;
if (Common.FLEET_SEND)
rtn = Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, mission, out id);
else
rtn = Common.mir.Add_Mission(info.IP, info.Authorization, mission, out id);
if (rtn)
{
washPointStep.Msg = info.FullName + "去" + info.Workshop.ToUpper() + "清洗点";
washPointStep.Msg = info.FullName + "去" + info.Workshop + "清洗点";
washPointStep.NextStep(WashPointStep.WaitWashPoint);
}
else
......
......@@ -124,16 +124,16 @@ namespace Model
{
if (Position.Y < 55)
{
if (Workshop == Common.WORKSHOP_4D)
if (Workshop.IndexOf('D') > 0)
return true;
else if (Workshop == Common.WORKSHOP_4C)
else if (Workshop.IndexOf('C') > 0)
return false;
}
else if (Position.Y > 62)
{
if (Workshop == Common.WORKSHOP_4D)
if (Workshop.IndexOf('D') > 0)
return false;
else if (Workshop == Common.WORKSHOP_4C)
else if (Workshop.IndexOf('C') > 0)
return true;
}
......
......@@ -218,46 +218,45 @@ namespace Model
}
}
// /// <summary>
// /// 添加任务到任务队列
// /// </summary>
// /// <param name="info"></param>
// /// <param name="mission_id"></param>
// /// <returns></returns>
// public bool Add_Mission(AgvInfo info, string mission_id)
// {
// try
// {
// //防止上一个任务已执行但返回失败时,删除任务
// Del_Mission(info);
// var key = Common.agvMission.Where(qq => qq.Value == mission_id).Select(qq => qq.Key);
// info.CurTaskName = key.ToList()[0];
// Common.log.Info(string.Format("{0} Add_Mission [{1}]", info.Name, key.ToList()[0]));
/// <summary>
/// 添加任务到小车自身任务队列
/// </summary>
/// <param name="ip"></param>
/// <param name="authorization"></param>
/// <param name="missionName"></param>
/// <param name="id"></param>
/// <returns></returns>
public bool Add_Mission(string ip, string authorization, string missionName, out string id)
{
id = null;
// string url = "http://" + info.IP + "/api/v2.0.0/mission_queue";
// string body = "{\"mission_id\":\"" + mission_id + "\"}";
try
{
string url = "http://" + ip + "/api/v2.0.0/mission_queue";
string body = "{\"mission_id\":\"" + MissionList[missionName] + "\"}";
LOG.Info(string.Format("URL:{0} Body:{1}", url, body));
// string json = HttpPost(url, info.IP, info.Authorization, body);
// Common.log.Info(string.Format("URL: {0}; Body: {1}", url, body)+"\n"+"Return: " + json);
// if (string.IsNullOrWhiteSpace(json)) return false;
string json = HttpPost(url, ip, authorization, body);
LOG.Info("Return:" + json);
if (string.IsNullOrWhiteSpace(json)) return false;
// JavaScriptSerializer serializer = new JavaScriptSerializer();
// Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
// if (dic == null) return false;
JavaScriptSerializer serializer = new JavaScriptSerializer();
Dictionary<string, object> dic = (Dictionary<string, object>)serializer.DeserializeObject(json);
if (dic == null) return false;
// string s = dic["mission_id"].ToString();
// if (s == mission_id)
// return true;
// else
// return false;
// }
// catch (Exception ex)
// {
// Common.log.Error(ex);
// return false;
// }
// }
id = dic["id"].ToString();
string missionId = dic["mission_id"].ToString();
if (missionId == MissionList[missionName])
return true;
else
return false;
}
catch (Exception ex)
{
LOG.Error(ex);
return false;
}
}
/// <summary>
/// 添加任务到Fleet任务队列
......
......@@ -52,17 +52,21 @@ namespace AGVControl_Steel
{
string[] str = lines[i].Split(',');
if (str.Length != 4) continue;
string isUse = "false";
if (Common.appConfig.AppSettings.Settings[str[0]] == null)
string key = "Use_" + str[0];
if (Common.appConfig.AppSettings.Settings[key] == null)
{
Common.appConfig.AppSettings.Settings.Add(str[0], "false");
Common.appConfig.AppSettings.Settings.Add(key, "false");
Common.appConfig.Save();
System.Configuration.ConfigurationManager.RefreshSection("appSettings");
}
else
{
isUse = Common.appConfig.AppSettings.Settings[str[0]].Value;
isUse = Common.appConfig.AppSettings.Settings[key].Value;
}
key = "Work_" + str[0];
Model.AgvInfo info = new Model.AgvInfo
{
FleetID = str[0],
......@@ -71,7 +75,8 @@ namespace AGVControl_Steel
Authorization = str[3],
IsAuto = Convert.ToBoolean(isUse),
BatteryMax = Convert.ToInt32(Common.appConfig.AppSettings.Settings["AGV_BATTERY_MAX"].Value),
BatteryMin = Convert.ToInt32(Common.appConfig.AppSettings.Settings["AGV_BATTERY_MIN"].Value)
BatteryMin = Convert.ToInt32(Common.appConfig.AppSettings.Settings["AGV_BATTERY_MIN"].Value),
Workshop = Common.appConfig.AppSettings.Settings[key].Value
};
Common.agvInfos.Add(info);
}
......@@ -89,18 +94,19 @@ namespace AGVControl_Steel
Common.log.Info("读取配置文件 " + Common.PATH_AGV_MISSION);
//Common.LINE_NAME_4D = Common.appConfig.AppSettings.Settings["4D_Line"].Value.Split(',');
//Common.LINE_NAME_4C = Common.appConfig.AppSettings.Settings["4C_Line"].Value.Split(',');
//Common.STORE_NAME = Common.appConfig.AppSettings.Settings["Store"].Value.Split(',');
Common.PLACE_NAME = Common.appConfig.AppSettings.Settings["PlaceName"].Value.Split(',');
Common.FLEET_SEND = Convert.ToBoolean(Common.appConfig.AppSettings.Settings["FLEET_Send"].Value);
string id = Common.appConfig.AppSettings.Settings["4D_AGV"].Value;
int idx = Common.agvInfos.FindIndex(match => match.FleetID == id);
if (idx > -1) Common.agvInfos[idx].Workshop = Common.WORKSHOP_4D;
id = Common.appConfig.AppSettings.Settings["4C_AGV"].Value;
idx = Common.agvInfos.FindIndex(match => match.FleetID == id);
if (idx > -1) Common.agvInfos[idx].Workshop = Common.WORKSHOP_4C;
//string id = Common.appConfig.AppSettings.Settings["4D_AGV"].Value;
//int idx = Common.agvInfos.FindIndex(match => match.FleetID == id);
//if (idx > -1) Common.agvInfos[idx].Workshop = Common.WORKSHOP_4D;
//id = Common.appConfig.AppSettings.Settings["4C_AGV"].Value;
//idx = Common.agvInfos.FindIndex(match => match.FleetID == id);
//if (idx > -1) Common.agvInfos[idx].Workshop = Common.WORKSHOP_4C;
......
......@@ -81,12 +81,13 @@ namespace AGVControl_Steel
{
if (e.RowIndex == -1) return;
AgvInfo info = Common.agvInfos[e.RowIndex];
string key = "Use_" + info.FleetID;
if (e.ColumnIndex == DgvName.Columns.Count - 2) //最后二列,自动/手动
{
info.IsAuto = !info.IsAuto;
DgvName.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = info.IsAuto.ToString();
Common.appConfig.AppSettings.Settings[info.FleetID].Value = info.IsAuto.ToString();
Common.appConfig.AppSettings.Settings[key].Value = info.IsAuto.ToString();
Common.appConfig.Save();
System.Configuration.ConfigurationManager.RefreshSection("appSettings");
Common.log.Info("手动修改 " + info.Name + " IsUse=" + info.IsAuto);
......@@ -102,7 +103,7 @@ namespace AGVControl_Steel
info.IsAuto = false;
info.Place = "";
DgvName.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = info.IsAuto.ToString();
Common.appConfig.AppSettings.Settings[info.FleetID].Value = info.IsAuto.ToString();
Common.appConfig.AppSettings.Settings[key].Value = info.IsAuto.ToString();
Common.appConfig.Save();
System.Configuration.ConfigurationManager.RefreshSection("appSettings");
}
......@@ -118,7 +119,10 @@ namespace AGVControl_Steel
if (LstMission.SelectedIndex == -1) return;
AgvInfo info = Common.agvInfos[idx];
if (Common.FLEET_SEND)
Common.mir.Add_Mission_Fleet(info.FleetID, info.Authorization, LstMission.Text, out string id);
else
Common.mir.Add_Mission(info.IP, info.Authorization, LstMission.Text, out string id);
}
private void BtnMissionClear_Click(object sender, EventArgs e)
......@@ -137,7 +141,7 @@ namespace AGVControl_Steel
int idx = DgvName.SelectedCells[0].RowIndex;
if (idx < 0) return;
AgvInfo info = Common.agvInfos[DgvName.SelectedRows[0].Index];
AgvInfo info = Common.agvInfos[idx];
Common.mir.State_Ready(info.IP, info.Authorization);
}
......@@ -147,7 +151,7 @@ namespace AGVControl_Steel
int idx = DgvName.SelectedCells[0].RowIndex;
if (idx < 0) return;
AgvInfo info = Common.agvInfos[DgvName.SelectedRows[0].Index];
AgvInfo info = Common.agvInfos[idx];
Common.mir.State_Pause(info.IP, info.Authorization);
}
......@@ -255,10 +259,32 @@ namespace AGVControl_Steel
Common.steelManage.StorageWorkDelAll();
}
}
#endregion
private void ChkMissionDebug_CheckedChanged(object sender, EventArgs e)
{
BtnOldSteelWorkAdd.Enabled = ChkMissionDebug.Checked;
BtnOldSteelWorkDel.Enabled = ChkMissionDebug.Checked;
BtnOldSteelWorkDelAll.Enabled = ChkMissionDebug.Checked;
BtnNewSteelWorkAdd.Enabled = ChkMissionDebug.Checked;
BtnNewSteelWorkDel.Enabled = ChkMissionDebug.Checked;
BtnNewSteelWorkDelAll.Enabled = ChkMissionDebug.Checked;
BtnStorageWorkAdd.Enabled = ChkMissionDebug.Checked;
BtnStorageWorkDel.Enabled = ChkMissionDebug.Checked;
BtnStorageWorkDelAll.Enabled = ChkMissionDebug.Checked;
ChkStorageIO.Enabled = ChkMissionDebug.Checked;
}
private void ChkStorageIO_CheckedChanged(object sender, EventArgs e)
{
Common.StorageDockAlway = ChkStorageIO.Checked;
}
#endregion
private void BtnClearLog_Click(object sender, EventArgs e)
{
TxtLog.Text = "";
}
}
}
......@@ -117,9 +117,6 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="DgvName.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="Column1.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
......@@ -141,114 +138,6 @@
<metadata name="Column8.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tabControl1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tabPage2.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tableLayoutPanel5.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TxtAgvMission0.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TxtLog.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="TxtAgvMission1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LblStorageIO.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LblWeb.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tabPage3.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LblMissionHint.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tableLayoutPanel1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LstStorage.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LstOldSteel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LstNewSteel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tableLayoutPanel2.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnOldSteelWorkDelAll.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnOldSteelWorkDel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnOldSteelWorkAdd.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tableLayoutPanel3.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnNewSteelWorkDelAll.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnNewSteelWorkDel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnNewSteelWorkAdd.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tableLayoutPanel4.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnStorageWorkDelAll.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnStorageWorkDel.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnStorageWorkAdd.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label2.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="label3.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="tabPage1.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnMissionPause.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnMissionRun.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnMissionClear.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnMissionAdd.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="LstMission.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="$this.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
......
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
......@@ -37,16 +37,16 @@
</logger>
</log4net>
<appSettings>
<add key="FLEET_IP" value="10.85.199.3" />
<add key="FLEET_Send" value="true" />
<add key="WebService" value="http://10.85.196.40:8089/" />
<add key="AGV_BATTERY_MAX" value="100" />
<add key="AGV_BATTERY_MIN" value="40" />
<add key="4C_AGV" value="32" />
<add key="4D_AGV" value="25" />
<add key="PlaceName" value="D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,4cwash,4dwash,storage" />
<add key="32" value="false" />
<add key="25" value="false" />
<add key="26" value="false" />
<add key="FLEET_IP" value="10.85.199.3"/>
<add key="FLEET_Send" value="true"/>
<add key="WebService" value="http://10.85.196.40:8089/"/>
<!--<add key="WebService" value="http://10.211.55.23:8089/"/>-->
<add key="AGV_BATTERY_MAX" value="100"/>
<add key="AGV_BATTERY_MIN" value="40"/>
<add key="Use_32" value="false"/>
<add key="Use_25" value="false"/>
<add key="Work_32" value="4C"/>
<add key="Work_25" value="4D"/>
<add key="PlaceName" value="D1,D2,D3,D4,D5,D6,D7,D8,D9,D10,D11,D12,D13,D14,D15,D16,C1,C2,C3,C4,C5,C6,C7,C8,C9,C10,C11,C12,C13,C14,C15,C16,4Cwash,4Dwash,storage"/>
</appSettings>
</configuration>
\ No newline at end of file
......@@ -22,14 +22,14 @@ MoveSteelD12,201e368d-f2ae-11ea-8452-94c691a7387d
MoveSteelD14,445106a1-f2ae-11ea-8452-94c691a7387d
MoveSteelD15,002b3e45-f105-11ea-a03e-94c691a7387d
MoveSteelD16,15a766ac-f2a2-11ea-8452-94c691a7387d
Move4CWash,691e75ab-f2b0-11ea-8452-94c691a7387d
Move4DWash,e52ae766-f2ab-11ea-8452-94c691a7387d
Move4CStandby,2dd387ce-f2b0-11ea-8452-94c691a7387d
Move4DStandby,21ca7ffe-f29e-11ea-8452-94c691a7387d
MoveWash4C,691e75ab-f2b0-11ea-8452-94c691a7387d
MoveWash4D,e52ae766-f2ab-11ea-8452-94c691a7387d
MoveStandby4C,2dd387ce-f2b0-11ea-8452-94c691a7387d
MoveStandby4D,21ca7ffe-f29e-11ea-8452-94c691a7387d
AutoCharge4C,8ed7b459-f2b0-11ea-8452-94c691a7387d
AutoCharge4D,2f0a31b1-f2ab-11ea-8452-94c691a7387d
MoveDoor-4C-4D,d67f31c8-ca7e-11ea-9a66-94c691a7387d
MoveDoor-4D-4C,fd6e26ac-c1bf-11ea-9a66-94c691a7387d
PassDoorInto4D,d67f31c8-ca7e-11ea-9a66-94c691a7387d
PassDoorInto4C,fd6e26ac-c1bf-11ea-9a66-94c691a7387d
MoveSteelstorage,418c9064-f2ac-11ea-8452-94c691a7387d
Pickupqisdashelf,f2acdcae-e524-11ea-b003-0001299a3f0e
Placeqisdashelf,4001120d-e525-11ea-b003-0001299a3f0e
\ No newline at end of file
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!