Commit 8ed0c156 张东亮

线体定义修改

1 个父辈 98514e2e
此文件类型无法预览
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OnlineStore.Common</RootNamespace> <RootNamespace>OnlineStore.Common</RootNamespace>
<AssemblyName>Common</AssemblyName> <AssemblyName>Common</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>false</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="ConfigHelper">
<HintPath>..\..\dll\ConfigHelper.dll</HintPath>
</Reference>
<Reference Include="log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL"> <Reference Include="log4net, Version=1.2.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\dll\log4net.dll</HintPath> <HintPath>..\..\dll\log4net.dll</HintPath>
......
...@@ -26,175 +26,25 @@ namespace OnlineStore.Common ...@@ -26,175 +26,25 @@ namespace OnlineStore.Common
Interlocked.Increment(ref seq); Interlocked.Increment(ref seq);
return seq; return seq;
} }
public static string GetValue(string keyStr, string storeStr)
{
string key = keyStr + storeStr;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
return GetValue(keyStr);
}
else
{
return config.AppSettings.Settings[key].Value;
}
}
public static decimal GetNumValue(string keyStr, string storeStr)
{
string key = keyStr + storeStr;
decimal a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
return GetNumValue(keyStr);
}
else
{
Decimal.TryParse(config.AppSettings.Settings[key].Value, out a);
}
return a;
}
public static int GetIntValue(string keyStr, string storeStr)
{
string key = keyStr + storeStr;
int a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
return GetIntValue(keyStr);
}
else
{
Int32.TryParse(config.AppSettings.Settings[key].Value, out a);
}
return a;
}
public static string GetValue(string key)
{
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
LOGGER.Error("未找到配置:" + key + ",请检查配置是否完整!");
return "";
}
else
{
return config.AppSettings.Settings[key].Value;
}
}
public static decimal GetNumValue(string key) public static string GetValue(string key, string val = "")
{
decimal a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
LOGGER.Error("未找到配置:" + key + ",请检查配置是否完整!");
return a;
}
else
{
Decimal.TryParse(config.AppSettings.Settings[key].Value, out a);
}
return a;
}
public static int GetIntValue(string key)
{
int a = 0;
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{ {
LOGGER.Error("未找到配置:" + key + ",请检查配置是否完整!"); return ConfigHelper.Config.Get(key, val);
return a;
} }
else public static int GetIntValue(string key, int val = 0)
{ {
Int32.TryParse(config.AppSettings.Settings[key].Value, out a); return ConfigHelper.Config.Get(key, val);
}
return a;
} }
public static void SaveValue(string key, int value) public static void SaveValue(string key, int value)
{ {
SaveValue(key, value.ToString());
}
public static void SaveValue(string key, string value)
{
try try
{ {
if (key.Equals("") || value.Equals("")) ConfigHelper.Config.Set(key, value);
{
//return;
}
//增加的内容写在appSettings段下 <add key="RegCode" value="0"/>
System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if (config.AppSettings.Settings[key] == null)
{
SetValue(key, value);
}
else
{
UpdateConfig(key, value);
}
} }
catch (Exception ex) catch (Exception ex)
{ {
LogUtil.error(LOGGER, "SaveValue保存配置出错:AppKey=" + key + ",AppValue=" + value + "," + ex.StackTrace); LogUtil.error(LOGGER, "SaveValue保存配置出错:AppKey=" + key + ",AppValue=" + value + "," + ex.StackTrace);
} }
} }
/// <summary>
/// 更新配置文件信息
/// </summary>
/// <param name="name">配置文件字段名称</param>
/// <param name="Xvalue">值</param>
private static void UpdateConfig(string name, string Xvalue)
{
try
{
XmlDocument doc = new XmlDocument();
doc.Load(Application.ExecutablePath + ".config");
XmlNode node = doc.SelectSingleNode(@"//add[@key='" + name + "']");
XmlElement ele = (XmlElement)node;
ele.SetAttribute("value", Xvalue);
doc.Save(Application.ExecutablePath + ".config");
}
catch (Exception ex)
{
LogUtil.error(LOGGER, "UpdateConfig保存配置出错:name=" + name + ",Xvalue=" + Xvalue + "," + ex.StackTrace);
}
}
///<summary>
///向.config文件的appKey结写入信息AppValue 保存设置
///</summary>
///<param name="AppKey">节点名</param>
///<param name="AppValue">值</param>
private static void SetValue(String AppKey, String AppValue)
{
try
{
XmlDocument xDoc = new XmlDocument();
xDoc.Load(System.Windows.Forms.Application.ExecutablePath + ".config");
XmlNode xNode;
XmlElement xElem1;
XmlElement xElem2;
xNode = xDoc.SelectSingleNode("//appSettings");
xElem1 = (XmlElement)xNode.SelectSingleNode("//add[@key='" + AppKey + "']");
if (xElem1 != null)
xElem1.SetAttribute("value", AppValue);
else
{
xElem2 = xDoc.CreateElement("add");
xElem2.SetAttribute("key", AppKey);
xElem2.SetAttribute("value", AppValue);
xNode.AppendChild(xElem2);
}
xDoc.Save(System.Windows.Forms.Application.ExecutablePath + ".config");
}
catch (Exception ex)
{
LogUtil.error(LOGGER, "SetValue保存配置出错:AppKey=" + AppKey + ",AppValue=" + AppValue + "," + ex.StackTrace);
}
}
} }
} }
...@@ -53,6 +53,9 @@ ...@@ -53,6 +53,9 @@
<ApplicationIcon>dist.ico</ApplicationIcon> <ApplicationIcon>dist.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="ConfigHelper">
<HintPath>..\..\dll\ConfigHelper.dll</HintPath>
</Reference>
<Reference Include="log4net"> <Reference Include="log4net">
<HintPath>..\..\dll\log4net.dll</HintPath> <HintPath>..\..\dll\log4net.dll</HintPath>
</Reference> </Reference>
......
...@@ -37,8 +37,11 @@ namespace OnlineStore.DISTLineClient ...@@ -37,8 +37,11 @@ namespace OnlineStore.DISTLineClient
private void FrmTest_Load(object sender, EventArgs e) private void FrmTest_Load(object sender, EventArgs e)
{ {
LogUtil.logBox = this.richTextBox1; LogUtil.logBox = this.richTextBox1;
cmbStopList.SelectedIndex = 0;
this.distLine = LineManager.InitStore(); this.distLine = LineManager.InitStore();
LoadIOList();
cmbWriteIO.DataSource = new List<ConfigIO>(LineManager.Config.StoreDOList.Values);
cmbWriteIO.ValueMember = "ProName";
cmbWriteIO.DisplayMember = "DisplayStr";
if (distLine == null) if (distLine == null)
{ {
LogUtil.error(LOGGER, "加载设备失败"); LogUtil.error(LOGGER, "加载设备失败");
...@@ -46,12 +49,13 @@ namespace OnlineStore.DISTLineClient ...@@ -46,12 +49,13 @@ namespace OnlineStore.DISTLineClient
return; return;
} }
timer1.Enabled = true; timer1.Enabled = true;
groupBox5.Text = "AGV调度通信,入料线体 [" + distLine.Config.L1_AgvName + "] ,出料线体 [" + distLine.Config.L2_AgvName + "] "; groupBox5.Text = "AGV调度通信,入料线体 [" + distLine.Config.L1_AgvName + "] ,出料串线体 [" + distLine.Config.L2_AgvName + "] 出包装料线体 [" + distLine.Config.L3_AgvName + "]";
chbDebug.Checked = distLine.IsDebug;
DebugMode(distLine.IsDebug);
this.ShowInTaskbar = true; this.ShowInTaskbar = true;
LoadIOList();
txtname.Text = distLine.Config.L2_AgvName; txtname.Text = distLine.Config.L2_AgvName;
notifyIcon1.Text = ConfigAppSettings.GetValue(Setting_Init.App_Title); notifyIcon1.Text = ConfigAppSettings.GetValue(Setting_Init.App_Title,"分盘线");
HideForm(); HideForm();
this.Opacity = 1; this.Opacity = 1;
...@@ -89,6 +93,12 @@ namespace OnlineStore.DISTLineClient ...@@ -89,6 +93,12 @@ namespace OnlineStore.DISTLineClient
this.SuspendLayout(); //此处为不闪屏,一定要有的! this.SuspendLayout(); //此处为不闪屏,一定要有的!
} }
private void DebugMode(bool isdebug)
{
groupBox6.Enabled = isdebug;
chbDebug.Checked = isdebug;
groupBox5.Enabled = isdebug;
}
private void ReadIOList() private void ReadIOList()
{ {
foreach (string key in DIControlList.Keys) foreach (string key in DIControlList.Keys)
...@@ -298,6 +308,7 @@ namespace OnlineStore.DISTLineClient ...@@ -298,6 +308,7 @@ namespace OnlineStore.DISTLineClient
} }
} }
} }
DebugMode(distLine.IsDebug);
} }
...@@ -331,35 +342,6 @@ namespace OnlineStore.DISTLineClient ...@@ -331,35 +342,6 @@ namespace OnlineStore.DISTLineClient
btn.BackColor = Color.White; btn.BackColor = Color.White;
} }
} }
private void btnInLineRun_Click(object sender, EventArgs e)
{
BtnMove(btnInLineRun, "分盘1线体运转", "分盘1线体停止", IO_Type.L1_Run);
}
private void btnInLInStopDown_Click(object sender, EventArgs e)
{
BtnMove(btnInLInStopDown, "分盘1线体阻挡下降", "分盘1线体阻挡上升", IO_Type.L1_StopDown);
}
private void btnInLOutStopDown_Click(object sender, EventArgs e)
{
BtnMove(btnInLOutStopDown, "分盘1线体出口阻挡下降", "分盘1线体出口阻挡上升", IO_Type.L1_OutStopDown);
}
private void btnOLInStopDown_Click(object sender, EventArgs e)
{
BtnMove(btnOLInStopDown, "分盘2线体阻挡下降", "分盘2线体阻挡上升", IO_Type.L2_StopDown);
}
private void btnOutL_Click(object sender, EventArgs e)
{
BtnMove(btnOutL, "分盘2线体运转", "分盘2线体停止", IO_Type.L2_Run);
}
private void btnOLOutStopDown_Click(object sender, EventArgs e)
{
BtnMove(btnOLOutStopDown, "分盘2线体出口阻挡下降", "分盘2线体出口阻挡上升", IO_Type.L2_OutStopDown);
}
private void btnCloseA_Click(object sender, EventArgs e) private void btnCloseA_Click(object sender, EventArgs e)
{ {
...@@ -398,21 +380,6 @@ namespace OnlineStore.DISTLineClient ...@@ -398,21 +380,6 @@ namespace OnlineStore.DISTLineClient
AgvClient.Dispose(); AgvClient.Dispose();
} }
private void btnStopTDown_Click(object sender, EventArgs e)
{
int value = (int)numericUpDown1.Value;
string iotype = IO_Type.L1_StopDown;
if (cmbStopList.SelectedIndex.Equals(1))
{
iotype = IO_Type.L1_OutStopDown;
}
else if (cmbStopList.SelectedIndex.Equals(2))
{
iotype = IO_Type.L2_StopDown;
}
distLine.StopIOMove(iotype, value);
}
private void chbMoveStop_CheckedChanged(object sender, EventArgs e) private void chbMoveStop_CheckedChanged(object sender, EventArgs e)
{ {
distLine.MoveStop = chbMoveStop.Checked; distLine.MoveStop = chbMoveStop.Checked;
...@@ -424,43 +391,63 @@ namespace OnlineStore.DISTLineClient ...@@ -424,43 +391,63 @@ namespace OnlineStore.DISTLineClient
AgvClient.SetCancelState(chkBoxAGVCancel.Checked); AgvClient.SetCancelState(chkBoxAGVCancel.Checked);
} }
private void btnTranverse_Click(object sender, EventArgs e) private void btnWriteSingleDO_Click(object sender, EventArgs e)
{ {
if (btnTranverse.Text.Equals("横移机构下降")) WriteDO(IO_VALUE.HIGH);
}
private void button2_Click(object sender, EventArgs e)
{
WriteDO(IO_VALUE.LOW);
}
private void WriteDO(IO_VALUE value)
{
string deviceName = txtDoName.Text;
int index = FormUtil.GetIntValue(txtDOIndex);
int time = FormUtil.GetIntValue(txtWriteTime);
if (time > 0)
{ {
IOManager.IOMove(IO_Type.Traverse_Down_SOL, IO_VALUE.LOW); IOManager.instance.WriteSingleDO(deviceName, (byte)0, (ushort)index, value, time);
BtnMove(btnTranverse, "横移机构下降", "横移机构上升", IO_Type.Traverse_Up_SOL);
} }
else else
{ {
IOManager.IOMove(IO_Type.Traverse_Up_SOL, IO_VALUE.LOW); IOManager.instance.WriteSingleDO(deviceName, (byte)0, (ushort)index, value);
BtnMove(btnTranverse, "横移机构上升", "横移机构下降", IO_Type.Traverse_Down_SOL);
} }
} }
IOTextControl selectControl = null;
private void btnTranverseRun_Click(object sender, EventArgs e) private void cmbWriteIO_SelectedIndexChanged(object sender, EventArgs e)
{ {
BtnMove(btnTranverseRun, "横移电机运转", "横移电机停止", IO_Type.Traverse_Run); if (cmbWriteIO.SelectedIndex >= 0)
}
private void btnRollerRun_Click(object sender, EventArgs e)
{ {
BtnMove(btnRollerRun, "滚筒电机运转", "滚筒电机停止", IO_Type.Roller_Run); ConfigIO io = GetSelectDO();
if (io != null)
{
// txtIp.Text = io.DeviceName;
txtDOIndex.Text = io.GetIOAddr().ToString();
txtDoName.Text = io.IO_IP;
IOTextControl newControl = DOControlList[io.ProName];
if (selectControl != null) { selectControl.BackColor = Color.White; }
newControl.BackColor = Color.SkyBlue;
selectControl = newControl;
} }
}
private void btnSwitch_Forward_Click(object sender, EventArgs e) }
private ConfigIO GetSelectDO()
{ {
if (btnSwitch.Text.Equals("料串切换气缸前进")) string text = cmbWriteIO.SelectedValue.ToString();
if (LineManager.Config.StoreDOList.ContainsKey(text))
{ {
IOManager.IOMove(IO_Type.Switch_Forward, IO_VALUE.LOW); ConfigIO io = LineManager.Config.StoreDOList[text];
BtnMove(btnSwitch, "料串切换气缸前进", "料串切换气缸后退", IO_Type.Switch_Back); return io;
} }
else return null;
{
IOManager.IOMove(IO_Type.Switch_Back, IO_VALUE.LOW);
BtnMove(btnSwitch, "料串切换气缸后退", "料串切换气缸前进", IO_Type.Switch_Forward);
} }
private void panel1_Click(object sender, EventArgs e)
{
ConfigHelper.AdvanceConfigForm.ShowEditDialog(this);
} }
} }
} }
...@@ -71,7 +71,7 @@ namespace OnlineStore.DISTLineClient ...@@ -71,7 +71,7 @@ namespace OnlineStore.DISTLineClient
// 如果进程的句柄为0,即代表没有找到该窗体,即该窗体隐藏的情况时 // 如果进程的句柄为0,即代表没有找到该窗体,即该窗体隐藏的情况时
if (process.MainWindowHandle.ToInt32().Equals(0)) if (process.MainWindowHandle.ToInt32().Equals(0))
{ {
string formTitle = ConfigAppSettings.GetValue(Setting_Init.App_Title); string formTitle = ConfigAppSettings.GetValue(Setting_Init.App_Title,"分盘线");
// 获得窗体句柄 // 获得窗体句柄
formhwnd = FindWindow(null, formTitle); formhwnd = FindWindow(null, formTitle);
// 重新显示该窗体并切换到带入到前台 // 重新显示该窗体并切换到带入到前台
......
类型,说明,名称,属性值,设备名称,默认值,描述,电器定义,代码定义,SlaveID, 类型,说明,名称,属性值,设备名称,默认值,描述,电器定义,代码定义,SlaveID,
PRO,IO模块对应的DI数量,IO_DILength,10.85.199.21#16,,,,,,, PRO,IO模块对应的DI数量,IO_DILength,10.85.199.21#16;10.85.199.22#16,,,,,,,
PRO,模块对应的DO数量,IO_DOLength,10.85.199.21#16,,,,,,, PRO,模块对应的DO数量,IO_DOLength,10.85.199.21#16;10.85.199.22#16,,,,,,,
PRO,IO模块IP,PRO_AOI_IP_1,10.85.199.21,,,,,,, PRO,IO模块IP,PRO_AOI_IP_1,10.85.199.21,,,,,,,
PRO,IO模块IP,PRO_AOI_IP_2,10.85.199.22,,,,,,,
,,,,,,,,,, ,,,,,,,,,,
DI,急停,SuddenStop_BTN,0,PRO_AOI_IP_1,0,急停,X741,DI-01,0,
DI,分盘1线入口检测,L1_InCheck,1,PRO_AOI_IP_1,0,分盘1线入口检测,X742,DI-02,0,
DI,分盘1线阻挡检测,L1_StopCheck,2,PRO_AOI_IP_1,0,分盘1线阻挡检测,X743,DI-03,0,
DI,分盘1线出口检测,L1_OutCheck,3,PRO_AOI_IP_1,0,分盘1线出口检测,X744,DI-04,0,
DI,分盘2线入口检测,L2_InCheck,4,PRO_AOI_IP_1,0,分盘2线入口检测,X745,DI-05,0,
DI,分盘2线阻挡检测,L2_StopCheck,5,PRO_AOI_IP_1,0,分盘2线阻挡检测,X746,DI-06,0,
DI,分盘2线出口检测,L2_OutCheck,6,PRO_AOI_IP_1,0,分盘2线出口检测,X747,DI-07,0,
DI,分盘1线人工取料信号,L1_ManualRecSig,7,PRO_AOI_IP_1,0,分盘1线人工取料信号,X748,DI-08,0,
DI,分盘1线顶升上升端,L1_UpDown_Up_Sig,8,PRO_AOI_IP_1,0,分盘1线顶升上升端,X749,DI-09,0,
DI,分盘1线顶升下降端,L1_UpDown_Down_Sig,9,PRO_AOI_IP_1,0,分盘1线顶升下降端,X750,DI-10,0,
DI,分盘2线顶升上升端,L2_UpDown_Up_Sig,10,PRO_AOI_IP_1,0,分盘2线顶升上升端,X751,DI-11,0,
DI,分盘2线顶升下降端,L2_UpDown_Down_Sig,11,PRO_AOI_IP_1,0,分盘2线顶升下降端,X752,DI-12,0,
DI,包装料架检测信号,PackingShelf_Sig,12,PRO_AOI_IP_1,0,包装料架检测信号,X753,DI-13,0,
DI,料串切换气缸前进端,Switch_Forward_Sig,13,PRO_AOI_IP_1,0,料串切换气缸前进端,X754,DI-14,0,
DI,料串切换气缸后退端,Switch_Back_Sig,14,PRO_AOI_IP_1,0,料串切换气缸后退端,X755,DI-15,0,
,,,15,PRO_AOI_IP_1,0,,X756,DI-16,0,
DO,分盘2线驱动电机运转,L2_Run,0,PRO_AOI_IP_1,0,分盘2线驱动电机运转,Y741,D0-01,0,
DO,分盘1线驱动电机运转,L1_Run,1,PRO_AOI_IP_1,0,分盘1线驱动电机运转,Y742,DO-02,0,
DO,分盘1线阻挡1下降,L1_StopDown,2,PRO_AOI_IP_1,0,分盘1线阻挡1下降,Y743,DO-03,0,
DO,分盘1线出口阻挡下降,L1_OutStopDown,3,PRO_AOI_IP_1,0,分盘1线出口阻挡下降,Y744,DO-04,0,
DO,分盘2线阻挡1下降,L2_StopDown,4,PRO_AOI_IP_1,0,分盘2线阻挡1下降,Y745,DO-05,0,
DO,分盘2线出口阻挡下降,L2_OutStopDown,5,PRO_AOI_IP_1,0,分盘2线出口阻挡下降,Y746,DO-06,0,
DO,分盘线横移机构上升SOL,Traverse_Up_SOL,6,PRO_AOI_IP_1,0,分盘线横移机构上升SOL,Y747,DO-07,0,
DO,分盘线横移机构下降SOL,Traverse_Down_SOL,7,PRO_AOI_IP_1,0,分盘线横移机构下降SOL,Y748,DO-08,0,
DO,分盘线横移电机运转,Traverse_Run,8,PRO_AOI_IP_1,0,分盘线横移电机运转,Y749,DO-09,0,
DO,分盘线滚筒电机运转,Roller_Run,9,PRO_AOI_IP_1,0,分盘线滚筒电机运转,Y750,DO-10,0,
DO,料串切换气缸前进,Switch_Forward,10,PRO_AOI_IP_1,0,料串切换气缸前进,Y751,DO-11,0,
DO,料串切换气缸后退,Switch_Back,11,PRO_AOI_IP_1,0,料串切换气缸后退,Y752,DO-12,0,
,,,12,PRO_AOI_IP_1,0,,Y753,DO-13,0,
,,,13,PRO_AOI_IP_1,0,,Y754,DO-14,0,
,,,14,PRO_AOI_IP_1,0,,Y755,DO-15,0,
,,,15,PRO_AOI_IP_1,0,,Y756,DO-16,0,
PRO,IO信号超时时间(毫秒),IOSingle_TimerOut,10000,,,,,,, PRO,IO信号超时时间(毫秒),IOSingle_TimerOut,10000,,,,,,,
PRO,分盘1线AGV节点名称,L1_AgvName,A8,,,,,,, PRO,分盘入料线AGV节点名称,L1_AgvName,A8,,,,,,,
PRO,分盘2线AGV节点名称,L2_AgvName,A7,,,,,,, PRO,分盘出料线AGV节点名称,L2_AgvName,A7,,,,,,,
PRO,分盘包装料出料线AGV节点名称,L3_AgvName,A9,,,,,,,
PRO,分盘线出口RFIDIP,L2Out_RFIDIP,10.85.199.130,,,,,, , PRO,分盘线出口RFIDIP,L2Out_RFIDIP,10.85.199.130,,,,,, ,
PRO,休眠秒数(秒),SleepSeconds,60,,,,,,, PRO,休眠秒数(秒),SleepSeconds,60,,,,,,,
,,,,,,,,,,
DI,急停,SuddenStop_BTN,0,PRO_AOI_IP_1,0,急停,X801,DI-01,0,
DI,分盘入料线入口检测,L1_InCheck,1,PRO_AOI_IP_1,0,分盘入料线入口检测,X802,DI-02,0,
DI,分盘入料线阻挡检测,L1_StopCheck,2,PRO_AOI_IP_1,0,分盘入料线阻挡检测,X803,DI-03,0,
DI,分盘入料线出口检测,L1_OutCheck,3,PRO_AOI_IP_1,0,分盘入料线出口检测,X804,DI-04,0,
DI,分盘出料串线入口检测,L2_InCheck,4,PRO_AOI_IP_1,0,分盘出料串线入口检测,X805,DI-05,0,
DI,分盘出料串线阻挡检测,L2_StopCheck,5,PRO_AOI_IP_1,0,分盘出料串线阻挡检测,X806,DI-06,0,
DI,分盘出料串线出口检测,L2_OutCheck,6,PRO_AOI_IP_1,0,分盘出料串线出口检测,X807,DI-07,0,
DI,料串出料线脚踏信号,L2_ManualRecSig,7,PRO_AOI_IP_1,0,料串出料线脚踏信号,X808,DI-08,0,
DI,分盘入料线顶升上升端,L1_UpDown_Up_Sig,8,PRO_AOI_IP_1,0,分盘入料线顶升上升端,X809,DI-09,0,
DI,分盘入料线顶升下降端,L1_UpDown_Down_Sig,9,PRO_AOI_IP_1,0,分盘入料线顶升下降端,X810,DI-10,0,
DI,分盘出料串线顶升上升端,L2_UpDown_Up_Sig,10,PRO_AOI_IP_1,0,分盘出料串线顶升上升端,X811,DI-11,0,
DI,分盘出料串线顶升下降端,L2_UpDown_Down_Sig,11,PRO_AOI_IP_1,0,分盘出料串线顶升下降端,X812,DI-12,0,
DI,包装料架检测信号(分盘入料线),PackingShelf_Sig,12,PRO_AOI_IP_1,0,包装料架检测信号(分盘入料线),X813,DI-13,0,
DI,料串切换气缸前进端,Switch_Forward_Sig,13,PRO_AOI_IP_1,0,料串切换气缸前进端,X814,DI-14,0,
DI,料串切换气缸后退端,Switch_Back_Sig,14,PRO_AOI_IP_1,0,料串切换气缸后退端,X815,DI-15,0,
,,,15,PRO_AOI_IP_1,0,,X816,DI-16,0,
,,,,,,,,,,
DO,分盘出料串线驱动电机运转,L2_Run,0,PRO_AOI_IP_1,0,分盘出料串线驱动电机运转,Y801,D0-01,0,
DO,分盘入料线驱动电机运转,L1_Run,1,PRO_AOI_IP_1,0,分盘入料线驱动电机运转,Y802,DO-02,0,
DO,分盘入料线阻挡下降,L1_StopDown,2,PRO_AOI_IP_1,0,分盘入料线阻挡下降,Y803,DO-03,0,
DO,分盘入料线出口阻挡下降,L1_OutStopDown,3,PRO_AOI_IP_1,0,分盘入料线出口阻挡下降,Y804,DO-04,0,
DO,分盘出料串线阻挡下降,L2_StopDown,4,PRO_AOI_IP_1,0,分盘出料串线阻挡下降,Y805,DO-05,0,
DO,分盘出料串线出口阻挡下降,L2_OutStopDown,5,PRO_AOI_IP_1,0,分盘出料串线出口阻挡下降,Y806,DO-06,0,
DO,分盘入料线横移机构上升SOL,L1_Traverse_Up_SOL,6,PRO_AOI_IP_1,0,分盘入料线横移机构上升SOL,Y807,DO-07,0,
DO,分盘入料线横移机构下降SOL,L1_Traverse_Down_SOL,7,PRO_AOI_IP_1,0,分盘入料线横移机构下降SOL,Y808,DO-08,0,
DO,分盘入料线横移电机正转,L1_Traverse_Run,8,PRO_AOI_IP_1,0,分盘入料线横移电机正转,Y809,DO-09,0,
DO,料串出料线过渡滚筒电机运转,L2_Roller_Run,9,PRO_AOI_IP_1,0,料串出料线过渡滚筒电机运转,Y810,DO-10,0,
DO,料串切换气缸前进,Switch_Forward,10,PRO_AOI_IP_1,0,料串切换气缸前进,Y811,DO-11,0,
DO,料串切换气缸后退,Switch_Back,11,PRO_AOI_IP_1,0,料串切换气缸后退,Y812,DO-12,0,
DO,分盘入料线横移电机反转,L1_Traverse_BackRun,12,PRO_AOI_IP_1,0,分盘入料线横移电机反转,Y813,DO-13,0,
DO,分盘出料串线横移机构上升SOL,L2_Traverse_Up_SOL,13,PRO_AOI_IP_1,0,分盘出料串线横移机构上升SOL,Y814,DO-14,0,
DO,分盘出料串线横移机构下降SOL,L2_Traverse_Down_SOL,14,PRO_AOI_IP_1,0,分盘出料串线横移机构下降SOL,Y815,DO-15,0,
,,,15,PRO_AOI_IP_1,0,,Y816,DO-16,0,
,,,,,,,,,,
,,,,,,,,,,
DI,包装料架检测信号(料串出料线体出口),L2Out_PkgDect_Sig,0,PRO_AOI_IP_2,0,包装料架检测信号(料串出料线体出口),X821,DI-01,0,
DI,包装料架检测信号(包装料架出料线体出口),L3Out_PkgDect_Sig,1,PRO_AOI_IP_2,0,包装料架检测信号(包装料架出料线体出口),X822,DI-02,0,
DI,包装料架出料线脚踏信号,L3_ManualRecSig,2,PRO_AOI_IP_2,0,包装料架出料线脚踏信号,X823,DI-03,0,
DI,包装料架出料线体横移上升端,L3_UpDown_Up_Sig,3,PRO_AOI_IP_2,0,包装料架出料线体横移上升端,X824,DI-04,0,
DI,包装料架出料线体横移下降端,L3_UpDown_Down_Sig,4,PRO_AOI_IP_2,0,包装料架出料线体横移下降端,X825,DI-05,0,
DI,包装料架出料线入口检测,L3_InCheck,5,PRO_AOI_IP_2,0,包装料架出料线入口检测,X826,DI-06,0,
DI,包装料架出料线阻挡检测,L3_StopCheck,6,PRO_AOI_IP_2,0,包装料架出料线阻挡检测,X827,DI-07,0,
DI,包装料架出料线出口检测,L3_OutCheck,7,PRO_AOI_IP_2,0,包装料架出料线出口检测,X828,DI-08,0,
,,,8,PRO_AOI_IP_2,0,,X829,DI-09,0,
,,,9,PRO_AOI_IP_2,0,,X830,DI-10,0,
,,,10,PRO_AOI_IP_2,0,,X831,DI-11,0,
,,,11,PRO_AOI_IP_2,0,,X832,DI-12,0,
,,,12,PRO_AOI_IP_2,0,,X833,DI-13,0,
,,,13,PRO_AOI_IP_2,0,,X834,DI-14,0,
,,,14,PRO_AOI_IP_2,0,,X835,DI-15,0,
,,,15,PRO_AOI_IP_2,0,,X816,DI-16,0,
,,,,,,,,,,
DO,包装料架出料线驱动电机运转,L3_Run,0,PRO_AOI_IP_2,0,包装料架出料线驱动电机运转,Y821,D0-01,0,
DO,包装料架出料线过渡滚筒电机运转,L3_Roller_Run,1,PRO_AOI_IP_2,0,包装料架出料线过渡滚筒电机运转,Y822,DO-02,0,
DO,料串出料线横移电机运转,L2_Traverse_Run,2,PRO_AOI_IP_2,0,料串出料线横移电机运转,Y823,DO-03,0,
DO,包装料架出料线横移电机运转,L3_Traverse_Run,3,PRO_AOI_IP_2,0,包装料架出料线横移电机运转,Y824,DO-04,0,
DO,包装料架出料线横移机构上升SOL,L3_Traverse_Up_SOL,4,PRO_AOI_IP_2,0,包装料架出料线横移机构上升SOL,Y825,DO-05,0,
DO,包装料架出料线横移机构下降SOL,L3_Traverse_Down_SOL,5,PRO_AOI_IP_2,0,包装料架出料线横移机构下降SOL,Y826,DO-06,0,
DO,包装料架出料线阻挡下降,L3_StopDown,6,PRO_AOI_IP_2,0,包装料架出料线阻挡下降,Y827,DO-07,0,
DO,包装料架出料线出口阻挡下降,L3_OutStopDown,7,PRO_AOI_IP_2,0,包装料架出料线出口阻挡下降,Y828,DO-08,0,
,,,8,PRO_AOI_IP_2,0,,Y829,DO-09,0,
,,,9,PRO_AOI_IP_2,0,,Y830,DO-10,0,
,,,10,PRO_AOI_IP_2,0,,Y831,DO-11,0,
,,,11,PRO_AOI_IP_2,0,,Y832,DO-12,0,
,,,12,PRO_AOI_IP_2,0,,Y833,DO-13,0,
,,,13,PRO_AOI_IP_2,0,,Y834,DO-14,0,
,,,14,PRO_AOI_IP_2,0,,Y835,DO-15,0,
,,,15,PRO_AOI_IP_2,0,,Y836,DO-16,0,
\ No newline at end of file \ No newline at end of file
...@@ -128,8 +128,9 @@ namespace OnlineStore.DeviceLibrary ...@@ -128,8 +128,9 @@ namespace OnlineStore.DeviceLibrary
{ {
//return "进料线出口" + Config.L2_AgvName + ":" + AgvClient.GetAction(Config.L2_AgvName) + ",料架: " + LastInShelfId + "\r\n" + //return "进料线出口" + Config.L2_AgvName + ":" + AgvClient.GetAction(Config.L2_AgvName) + ",料架: " + LastInShelfId + "\r\n" +
// "出料线进口" + Config.L1_AgvName + ":" + AgvClient.GetAction(Config.L1_AgvName) + ",料架: " + LastOutShelfId + "\r\n"; // "出料线进口" + Config.L1_AgvName + ":" + AgvClient.GetAction(Config.L1_AgvName) + ",料架: " + LastOutShelfId + "\r\n";
return "分盘1线入料口" + Config.L1_AgvName + ":" + AgvClient.GetAction(Config.L1_AgvName) + ",料架: " + LastInShelfId + "\r\n" + return "入料线入料口" + Config.L1_AgvName + ":" + AgvClient.GetAction(Config.L1_AgvName) + ",料架: " + LastInShelfId + "\r\n" +
"分盘2线出料口" + Config.L2_AgvName + ":" + AgvClient.GetAction(Config.L2_AgvName) + ",料架: " + LastOutShelfId + "\r\n"; "入库料线出料口" + Config.L2_AgvName + ":" + AgvClient.GetAction(Config.L2_AgvName) + ",料架: " + L2_LastOutShelfId + "\r\n"+
"空料架线出料口" + Config.L3_AgvName + ":" + AgvClient.GetAction(Config.L3_AgvName) + ",料架: " + L3_LastOutShelfId;
} }
#endregion #endregion
...@@ -166,6 +167,11 @@ namespace OnlineStore.DeviceLibrary ...@@ -166,6 +167,11 @@ namespace OnlineStore.DeviceLibrary
needCheckList.Add(IO_Type.L2_OutStopDown); needCheckList.Add(IO_Type.L2_OutStopDown);
needCheckList.Add(IO_Type.L2_StopCheck); needCheckList.Add(IO_Type.L2_StopCheck);
needCheckList.Add(IO_Type.L2_StopDown); needCheckList.Add(IO_Type.L2_StopDown);
needCheckList.Add(IO_Type.L3_InCheck);
needCheckList.Add(IO_Type.L3_OutCheck);
needCheckList.Add(IO_Type.L3_OutStopDown);
needCheckList.Add(IO_Type.L3_StopCheck);
needCheckList.Add(IO_Type.L3_StopDown);
} }
bool agvBusy = false; bool agvBusy = false;
ClientAction currA = AgvClient.GetAction(Config.L2_AgvName); ClientAction currA = AgvClient.GetAction(Config.L2_AgvName);
...@@ -236,6 +242,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -236,6 +242,7 @@ namespace OnlineStore.DeviceLibrary
IsSleep = true; IsSleep = true;
IOManager.IOMove(IO_Type.L1_Run, IO_VALUE.LOW); IOManager.IOMove(IO_Type.L1_Run, IO_VALUE.LOW);
IOManager.IOMove(IO_Type.L2_Run, IO_VALUE.LOW); IOManager.IOMove(IO_Type.L2_Run, IO_VALUE.LOW);
IOManager.IOMove(IO_Type.L3_Run, IO_VALUE.LOW);
} }
else else
{ {
...@@ -243,6 +250,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -243,6 +250,7 @@ namespace OnlineStore.DeviceLibrary
LastBusyTime = DateTime.Now; LastBusyTime = DateTime.Now;
IOManager.IOMove(IO_Type.L1_Run, IO_VALUE.HIGH); IOManager.IOMove(IO_Type.L1_Run, IO_VALUE.HIGH);
IOManager.IOMove(IO_Type.L2_Run, IO_VALUE.HIGH); IOManager.IOMove(IO_Type.L2_Run, IO_VALUE.HIGH);
IOManager.IOMove(IO_Type.L3_Run, IO_VALUE.HIGH);
}; };
} }
#endregion #endregion
......
...@@ -19,7 +19,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -19,7 +19,7 @@ namespace OnlineStore.DeviceLibrary
public static DISTLineBean DISTLine = null; public static DISTLineBean DISTLine = null;
public static DISTLineConfig Config = null; public static DISTLineConfig Config = null;
private static bool isInit = false; private static bool isInit = false;
public static bool IsConnectServer = !ConfigAppSettings.GetValue(Setting_Init.http_server).Equals(""); public static bool IsConnectServer = !ConfigAppSettings.GetValue(Setting_Init.http_server, "http://10.85.160.25/myproject/").Equals("");
public LineManager() public LineManager()
{ {
} }
...@@ -48,7 +48,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -48,7 +48,7 @@ namespace OnlineStore.DeviceLibrary
RobotConfig.ProIOIpMap = new Dictionary<string, string>(); RobotConfig.ProIOIpMap = new Dictionary<string, string>();
if (!isInit) if (!isInit)
{ {
string server = ConfigAppSettings.GetValue(Setting_Init.http_server); string server = ConfigAppSettings.GetValue(Setting_Init.http_server, "http://10.85.160.25/myproject/");
if (server.Equals("")) if (server.Equals(""))
{ {
IsConnectServer = false; IsConnectServer = false;
...@@ -59,7 +59,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -59,7 +59,7 @@ namespace OnlineStore.DeviceLibrary
isInit = true; isInit = true;
string appPath = Application.StartupPath; string appPath = Application.StartupPath;
string linefilePath = appPath + ConfigAppSettings.GetValue(Setting_Init.Line_Config); string linefilePath = appPath + ConfigAppSettings.GetValue(Setting_Init.Line_Config, "\\LineConfig\\DISTLineConfig.csv");
LogUtil.info(LOGGER, " 开始加载分盘流水线配置:" + linefilePath); LogUtil.info(LOGGER, " 开始加载分盘流水线配置:" + linefilePath);
RobotConfig storeConfig = CSVConfigReader.LoadConfig(linefilePath); RobotConfig storeConfig = CSVConfigReader.LoadConfig(linefilePath);
......
...@@ -14,7 +14,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -14,7 +14,7 @@ namespace OnlineStore.DeviceLibrary
{ {
public class AgvClient public class AgvClient
{ {
private static string ServerIp = ConfigAppSettings.GetValue(Setting_Init.AgvServerIp); private static string ServerIp = ConfigAppSettings.GetValue(Setting_Init.AgvServerIp, "127.0.0.1");
private static Asa.AgvClient agvClient; private static Asa.AgvClient agvClient;
public static Dictionary<string, Asa.ClientAction> actionMap = new Dictionary<string, Asa.ClientAction>(); public static Dictionary<string, Asa.ClientAction> actionMap = new Dictionary<string, Asa.ClientAction>();
public static List<string> NodeList = new List<string>(); public static List<string> NodeList = new List<string>();
...@@ -88,6 +88,7 @@ namespace OnlineStore.DeviceLibrary ...@@ -88,6 +88,7 @@ namespace OnlineStore.DeviceLibrary
UpdateAction(id, Asa.ClientAction.Ready); UpdateAction(id, Asa.ClientAction.Ready);
if (id.Equals(LineManager.Config.L1_AgvName)) if (id.Equals(LineManager.Config.L1_AgvName))
{ {
LineManager.DISTLine.LastInShelfId = rfid;
LineManager.DISTLine.UpdateSleep(false); LineManager.DISTLine.UpdateSleep(false);
if (IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.LOW)) if (IOManager.IOValue(IO_Type.L1_InCheck).Equals(IO_VALUE.LOW))
{ {
...@@ -127,11 +128,11 @@ namespace OnlineStore.DeviceLibrary ...@@ -127,11 +128,11 @@ namespace OnlineStore.DeviceLibrary
else if (id.Equals(LineManager.Config.L2_AgvName)) else if (id.Equals(LineManager.Config.L2_AgvName))
{ {
string shefId = LineManager.DISTLine.LastOutShelfId; string shefId = LineManager.DISTLine.L2_LastOutShelfId;
if (IOManager.IOValue(IO_Type.L2_OutCheck).Equals(IO_VALUE.HIGH)) if (IOManager.IOValue(IO_Type.L2_OutCheck).Equals(IO_VALUE.HIGH))
{ {
LineManager.DISTLine.UpdateSleep(false); LineManager.DISTLine.UpdateSleep(false);
LineManager.DISTLine.StopIOMove(IO_Type.L2_OutStopDown, 1500); LineManager.DISTLine.StopIOMove(IO_Type.L2_OutStopDown, 2000);
//agvClient.MayLeave(id); //agvClient.MayLeave(id);
SetStatus(id, shefId, ClientAction.MayLeave); SetStatus(id, shefId, ClientAction.MayLeave);
LogUtil.info(logName + "下降 L2_OutStopDown , " + shefId); LogUtil.info(logName + "下降 L2_OutStopDown , " + shefId);
...@@ -155,6 +156,36 @@ namespace OnlineStore.DeviceLibrary ...@@ -155,6 +156,36 @@ namespace OnlineStore.DeviceLibrary
SetStatus(id, "", ClientAction.None, ClientLevel.High); SetStatus(id, "", ClientAction.None, ClientLevel.High);
} }
} }
else if (id.Equals(LineManager.Config.L3_AgvName))
{
if (IOManager.IOValue(IO_Type.L3_OutCheck).Equals(IO_VALUE.HIGH))
{
string shefId = LineManager.DISTLine.L3_LastOutShelfId;
LineManager.DISTLine.UpdateSleep(false);
LineManager.DISTLine.StopIOMove(IO_Type.L3_OutStopDown, 2000);
//agvClient.MayLeave(id);
SetStatus(id, shefId, ClientAction.MayLeave);
LogUtil.info(logName + "下降 L3_OutStopDown ,"+ shefId);
Task.Factory.StartNew(delegate
{
//两秒后改为离开状态
Thread.Sleep(5000);
LogUtil.info(logName + " ,调用 FinishLeave " + shefId);
SetStatus(id, "", ClientAction.FinishLeave);
Thread.Sleep(5000);
LogUtil.info(logName + " ,处理结束 更新状态为None ");
SetStatus(id, "", ClientAction.None);
});
}
else
{
LogUtil.error(logName + " L3_OutCheck 未检测到料架,无法将料架进入AGV");
SetStatus(id, "", ClientAction.None, ClientLevel.High);
}
}
} }
private static void AgvClient_Arrive(string id, string rfid) private static void AgvClient_Arrive(string id, string rfid)
{ {
......
...@@ -50,7 +50,11 @@ namespace OnlineStore.LoadCSVLibrary ...@@ -50,7 +50,11 @@ namespace OnlineStore.LoadCSVLibrary
/// </summary> /// </summary>
[ConfigProAttribute("L2_AgvName")] [ConfigProAttribute("L2_AgvName")]
public string L2_AgvName { get; set; } public string L2_AgvName { get; set; }
/// <summary>
///PRO,分盘包装料出料线AGV节点名称,L3_AgvName,A9,,,,,,,
/// </summary>
[ConfigProAttribute("L3_AgvName")]
public string L3_AgvName { get; set; }
public double AirCheckSeconds = 60; public double AirCheckSeconds = 60;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>OnlineStore.LoadCSVLibrary</RootNamespace> <RootNamespace>OnlineStore.LoadCSVLibrary</RootNamespace>
<AssemblyName>LoadCSVLibrary</AssemblyName> <AssemblyName>LoadCSVLibrary</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
......
...@@ -19,7 +19,7 @@ namespace UserFromControl.Properties { ...@@ -19,7 +19,7 @@ namespace UserFromControl.Properties {
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。 // (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources { internal class Resources {
...@@ -47,8 +47,8 @@ namespace UserFromControl.Properties { ...@@ -47,8 +47,8 @@ namespace UserFromControl.Properties {
} }
/// <summary> /// <summary>
/// 使用此强类型资源类,为所有资源查找 /// 重写当前线程的 CurrentUICulture 属性,对
/// 重写当前线程的 CurrentUICulture 属性 /// 使用此强类型资源类的所有资源查找执行重写
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { internal static global::System.Globalization.CultureInfo Culture {
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>UserFromControl</RootNamespace> <RootNamespace>UserFromControl</RootNamespace>
<AssemblyName>UserFromControl</AssemblyName> <AssemblyName>UserFromControl</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<TargetFrameworkProfile /> <TargetFrameworkProfile />
</PropertyGroup> </PropertyGroup>
......
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!