This repository has been archived on 2025-11-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AUTS_OLD/UTS_Core/UTSModule/Station/RowNode.vb

789 lines
26 KiB
VB.net
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Imports System.Drawing
Imports System.Text
Imports System.Xml
Imports UTS_Core.UTSModule.Production
Imports UTS_Core.UTSModule.Test.Command
Namespace UTSModule.Station
Public NotInheritable Class RowNode
#Region "初始化"
Sub New()
RowType = RowTypeEnum.Flow
AuthByType(RowType)
Pause = False
Action = False
RecordName = String.Empty
Retry = 0
RetryInterval = 100
[Label] = String.Empty
Description = String.Empty
ErrorCode = String.Empty
ErrorMessage = String.Empty
CommandType = String.Empty
Command = String.Empty
Parameters = New List(Of TestCmdParam)
SaveToDb = False
ControlType = String.Empty
Children = New List(Of RowNode)()
Expanded = True
AllChildCount = 0
RowNodes = New RowNodeCollection(Me)
RowListIndex = 0
RowList = New List(Of RowNode)()
RowList.Add(Me)
End Sub
''' <summary>
''' 模块名称
''' </summary>
''' <returns></returns>
Public Property [Label] As String
''' <summary>
''' 控制命令类型
''' </summary>
''' <returns></returns>
Public Property ControlType As String
''' <summary>
''' 当前流程步骤的解释
''' </summary>
''' <returns></returns>
Public Property Description As String
''' <summary>
''' 调试模式下运行到当前节点后,暂停运行
''' </summary>
''' <returns></returns>
Public Property Pause() As Boolean
''' <summary>
''' 当前流程步骤是否允许执行
''' </summary>
''' <returns></returns>
Public Property Action As Boolean
''' <summary>
''' 当前流程步骤是否会被执行
''' </summary>
''' <returns></returns>
Public Property IsRunning As Boolean
''' <summary>
''' 当前流程步骤执行结果是否保存至数据库,FALSE则为临时变量
''' </summary>
''' <returns></returns>
Public Property SaveToDb() As Boolean
Public Property RecordName As String
Public Property Retry As Integer
Public Property RetryInterval As Integer
Public Property ErrorCode As String
Public Property ErrorMessage As String
Public Property CommandType As String
Public Property Command As String
Public Property Parameters() As List(Of TestCmdParam)
Private _rowType As RowTypeEnum
''' <summary>
''' 行的类型
''' </summary>
''' <returns></returns>
Public Property RowType As RowTypeEnum
Get
Return _rowType
End Get
Set
_rowType = Value
AuthByType(Value)
End Set
End Property
''' <summary>
''' 行节点关联的站流程
''' </summary>
''' <returns></returns>
Public Property StationPlan() As StationTestPlan
''' <summary>
''' 行节点执行结果信息
''' </summary>
''' <returns></returns>
Public Property TestReturn As TestCommandReturn
''' <summary>
''' 节点树的所有节点集合
''' </summary>
''' <returns></returns>
Public Property RowList As List(Of RowNode)
''' <summary>
''' 节点所属节点数组的位置,从0开始即头结点的的索引
''' </summary>
''' <returns></returns>
Public Property RowListIndex() As Integer
''' <summary>
''' 节点的级别,可见节点级别从0开始
''' </summary>
''' <returns></returns>
Public Property RowLever As Integer
''' <summary>
''' 节点在父节点中的索引,可见节点级别从0开始
''' </summary>
''' <returns></returns>
Public Property RowIndex As Integer
''' <summary>
''' 子节点总数
''' </summary>
''' <returns></returns>
Public ReadOnly Property Count() As Integer
Get
Return Children.Count
End Get
End Property
''' <summary>
''' 所有子节点总数
''' </summary>
''' <returns></returns>
Public Property AllChildCount() As Integer
''' <summary>
''' 行下包含的子行集合
''' </summary>
''' <returns></returns>
Public Property RowNodes() As RowNodeCollection
''' <summary>
''' 当前节点的同级上一节点若当前节点为首节点则返回nothing
''' </summary>
''' <returns></returns>
Public Property PrevNode() As RowNode
''' <summary>
''' 当前节点的同级下一节点若当前节点为尾节点则返回nothing
''' </summary>
''' <returns></returns>
Public Property NextNode() As RowNode
''' <summary>
''' 当前节点的父节点
''' </summary>
''' <returns></returns>
Public Property ParentNode() As RowNode
''' <summary>
''' 当前节点树的起始节点
''' </summary>
''' <returns></returns>
Public Property HeadNode() As RowNode
''' <summary>
''' 内部缓存子节点
''' </summary>
Friend Children As List(Of RowNode)
''' <summary>
''' 处于展开状态
''' </summary>
''' <returns></returns>
Public Property Expanded() As Boolean
''' <summary>
''' 是否允许删除当前节点
''' </summary>
''' <returns></returns>
Public Property CanDelete() As Boolean
''' <summary>
''' 是否允许添加子节点
''' </summary>
''' <returns></returns>
Public Property CanAddChildNode() As Boolean
''' <summary>
''' 允许操作当前节点内容
''' </summary>
''' <returns></returns>
Public Property CanChangeContent() As Boolean
''' <summary>
''' 允许移动节点改变节点的级别
''' </summary>
''' <returns></returns>
Public Property CanChangeLever() As Boolean
''' <summary>
''' 当前节点是否处于重试状态
''' </summary>
''' <returns></returns>
Public Property IsRetry As Boolean
Private Sub AuthByType(type As RowTypeEnum)
Select Case type
Case RowTypeEnum.FixedModule
CanAddChildNode = True
CanChangeContent = False
CanDelete = False
CanChangeLever = False
Case RowTypeEnum.Module
CanAddChildNode = True
CanChangeContent = True
CanDelete = True
CanChangeLever = True
Case RowTypeEnum.Control
CanAddChildNode = True
CanChangeContent = True
CanDelete = True
CanChangeLever = True
Case RowTypeEnum.Flow
CanAddChildNode = False
CanChangeContent = True
CanDelete = True
CanChangeLever = True
End Select
End Sub
#End Region
#Region "节点操作"
''' <summary>
''' 展开节点
''' </summary>
Public Sub Expand()
If Expanded Then Return
Expanded = True
End Sub
''' <summary>
''' 折叠节点
''' </summary>
Public Sub Collapse()
If Expanded = False Then Return
Expanded = False
End Sub
''' <summary>
''' 展开或折叠节点
''' </summary>
Public Sub Toggle()
Expanded = Not Expanded
End Sub
''' <summary>
''' 增加子节点
''' </summary>
Public Sub AddNode(node As RowNode)
If CanAddChildNode Then
RowNodes.Add(node)
Else
ParentNode.InsertNode(RowIndex + 1, node)
End If
End Sub
''' <summary>
''' 插入子节点
''' </summary>
Public Sub InsertNode(index As Integer, childNode As RowNode)
If CanAddChildNode Then
RowNodes.Insert(index, childNode)
Else
ParentNode.InsertNode(index, childNode)
End If
' ParentNode.InsertNode(index, childNode)
End Sub
Public Sub RemoveChildNode(childNode As RowNode)
If childNode.CanDelete = False Then Return
RowNodes.Remove(childNode)
End Sub
Public Sub RemoveChildAt(index As Integer)
If index >= RowNodes.Count Then Return
Dim child As RowNode = CType(RowNodes.Item(index), RowNode)
If child.CanDelete = False Then Return
RowNodes.RemoveAt(index)
End Sub
''' <summary>
''' 移除本身节点
''' </summary>
Public Function Remove() As Boolean
' If CanDelete = False Then Return False
ParentNode.RowNodes.Remove(Me)
Return True
End Function
''' <summary>
''' 清空节点所有子节点
''' </summary>
Public Sub Clear()
RowNodes.Clear()
End Sub
''' <summary>
''' 节点上移
''' </summary>
Public Sub MoveUp()
If RowIndex = 0 Then Return
If Remove() = False Then Return
ParentNode.RowNodes.Insert(RowIndex - 1, Me)
End Sub
''' <summary>
''' 节点下移
''' </summary>
Public Sub MoveDown()
If RowIndex = ParentNode.RowNodes.Count - 1 Then Return
If Remove() = False Then Return
ParentNode.RowNodes.Insert(RowIndex + 1, Me)
End Sub
''' <summary>
''' 节点左移
''' </summary>
Public Sub MoveLeft()
If RowLever = 0 Then Return
If Remove() = False Then Return
ParentNode.ParentNode.RowNodes.Insert(ParentNode.RowIndex + 1, Me)
End Sub
''' <summary>
''' 节点右移
''' </summary>
Public Sub MoveRight()
If RowIndex = 0 Then Return
' If CanChangeLever = False Then Return
If Remove() = False Then Return
Dim rNode As RowNode = CType(ParentNode.RowNodes(RowIndex - 1), RowNode)
rNode.RowNodes.Add(Me)
End Sub
''' <summary>
''' 节点深复制,创建一个完全相同信息的节点
''' </summary>
''' <returns></returns>
Public Function Clone() As RowNode
Dim cpNode As New RowNode
With cpNode
.RowType = RowType
.Action = Action
.RecordName = RecordName
.Retry = Retry
.RetryInterval = RetryInterval
.[Label] = String.Copy(Label)
.Description = String.Copy(Description)
.ErrorCode = String.Copy(ErrorCode)
.ErrorMessage = String.Copy(ErrorMessage)
.CommandType = String.Copy(CommandType)
.Command = String.Copy(Command)
.Parameters = New List(Of TestCmdParam)
For Each param As TestCmdParam In Parameters
.Parameters.Add(param.Clone())
Next
.RowNodes = New RowNodeCollection(cpNode)
.Children = New List(Of RowNode)()
'todo:克隆功能待重写
For Each child As RowNode In Children
.RowNodes.Add(child.Clone())
Next
End With
Return cpNode
End Function
#End Region
#Region "节点样式"
Public Enum RowTypeEnum
''' <summary>
''' 固定模块
''' </summary>
FixedModule
''' <summary>
''' 模块,可以当作跳转入口
''' </summary>
[Module]
''' <summary>
''' 控制
''' </summary>
Control
''' <summary>
''' 流程
''' </summary>
Flow
End Enum
#End Region
#Region "节点风格"
Public Shared Property NodeStyles() As Dictionary(Of RowTypeEnum, RowNodeStyle)
''' <summary>
''' 默认的初始化节点风格
''' </summary>
Public Shared Sub InitNodeStyles()
NodeStyles = New Dictionary(Of RowTypeEnum, RowNodeStyle) From {
{RowTypeEnum.FixedModule, New RowNodeStyle(RowTypeEnum.FixedModule)},
{RowTypeEnum.Module, New RowNodeStyle(RowTypeEnum.Module)},
{RowTypeEnum.Control, New RowNodeStyle(RowTypeEnum.Control)},
{RowTypeEnum.Flow, New RowNodeStyle(RowTypeEnum.Flow)}
}
End Sub
Private Shared Function LoadNodeStyle(nodeList As XmlNodeList) As RowNodeStyle
Dim nodeStyle As New RowNodeStyle
Dim xe As XmlElement
For Each node As XmlNode In nodeList
xe = CType(node, XmlElement)
Select Case xe.LocalName
Case "Font"
Dim fStyle As FontStyle = CType([Enum].Parse(GetType(FontStyle), xe.GetAttribute("FontStyle")), FontStyle)
Dim fSize As Single = CSng(xe.GetAttribute("FontSize"))
nodeStyle.NodeFont = New Font(xe.InnerText, fSize, fStyle)
Case "ForeColor"
nodeStyle.NodeForeColor = Color.FromArgb(CInt(xe.InnerText))
Case "BackColor"
nodeStyle.NodeBackColor = Color.FromArgb(CInt(xe.InnerText))
Case "ImageKey"
nodeStyle.NodeImageKey = xe.InnerText
Case "ShowRecord"
nodeStyle.ShowRecord = CType(xe.InnerText, Boolean)
Case "ShowLabel"
nodeStyle.ShowLabel = CType(xe.InnerText, Boolean)
Case "ShowDescription"
nodeStyle.ShowDescription = CType(xe.InnerText, Boolean)
Case "ShowAction"
nodeStyle.ShowAction = CType(xe.InnerText, Boolean)
Case "ShowRecord"
nodeStyle.ShowRecord = CType(xe.InnerText, Boolean)
Case "ShowRetry"
nodeStyle.ShowRetry = CType(xe.InnerText, Boolean)
Case "ShowRetryInterval"
nodeStyle.ShowRetryInterval = CType(xe.InnerText, Boolean)
Case "ShowErrorCode"
nodeStyle.ShowErrorCode = CType(xe.InnerText, Boolean)
Case "ShowErrorMessage"
nodeStyle.ShowErrorMessage = CType(xe.InnerText, Boolean)
Case "ShowCommand"
nodeStyle.ShowCommand = CType(xe.InnerText, Boolean)
Case "ShowParameter"
nodeStyle.ShowParameter = CType(xe.InnerText, Boolean)
Case Else
Throw New Exception($"LoadRowNodes Unknown LocalName:{xe.LocalName}")
End Select
Next
Return nodeStyle
End Function
''' <summary>
''' 从本地文件中初始化节点风格
''' </summary>
''' <param name="path"></param>
Public Shared Sub LoadNodeStyles(path As String)
NodeStyles = New Dictionary(Of RowTypeEnum, RowNodeStyle)()
Dim xd As New XmlDocument()
xd.Load(path)
Dim xe As XmlElement
Dim nodeList As XmlNodeList = xd.SelectSingleNode($"NodeStyles").ChildNodes
For Each node As XmlNode In nodeList
xe = CType(node, XmlElement)
Select Case xe.LocalName
Case "NodeStyle"
Dim type As RowTypeEnum = CType([Enum].Parse(GetType(RowTypeEnum), xe.GetAttribute("Type")), RowTypeEnum)
NodeStyles.Add(type, LoadNodeStyle(xe.ChildNodes))
Case Else
Throw New Exception($"LoadNodeStyles Unknown LocalName:{xe.LocalName}")
End Select
Next
End Sub
Public Shared Sub SaveNodeStyles(path As String)
Dim xws As New XmlWriterSettings
With xws
.Indent = True
.NewLineOnAttributes = False
.Encoding = New UTF8Encoding(False)
End With
Using xw As XmlWriter = XmlWriter.Create(path, xws)
xw.WriteStartDocument()
xw.WriteStartElement($"NodeStyles") '创建跟节点
For Each nodeStyle As KeyValuePair(Of RowTypeEnum, RowNodeStyle) In NodeStyles
xw.WriteStartElement($"NodeStyle") '创建表属性节点
xw.WriteAttributeString("Type", nodeStyle.Key.ToString())
xw.WriteStartElement($"Font") '创建表属性节点
xw.WriteAttributeString("FontSize", nodeStyle.Value.NodeFont.Size.ToString())
xw.WriteAttributeString("FontStyle", nodeStyle.Value.NodeFont.Style.ToString())
xw.WriteString(nodeStyle.Value.NodeFont.Name.ToString())
xw.WriteEndElement()
xw.WriteElementString("ForeColor", nodeStyle.Value.NodeForeColor.ToArgb().ToString())
xw.WriteElementString("BackColor", nodeStyle.Value.NodeBackColor.ToArgb().ToString())
xw.WriteElementString("ImageKey", nodeStyle.Value.NodeImageKey)
If nodeStyle.Value.ShowRowType Then xw.WriteElementString("ShowRecord", nodeStyle.Value.ShowRowType.ToString())
If nodeStyle.Value.ShowLabel Then xw.WriteElementString("ShowLabel", nodeStyle.Value.ShowLabel.ToString())
If nodeStyle.Value.ShowDescription Then xw.WriteElementString("ShowDescription", nodeStyle.Value.ShowDescription.ToString())
If nodeStyle.Value.ShowAction Then xw.WriteElementString("ShowAction", nodeStyle.Value.ShowAction.ToString())
If nodeStyle.Value.ShowRecord Then xw.WriteElementString("ShowRecord", nodeStyle.Value.ShowRecord.ToString())
If nodeStyle.Value.ShowRetry Then xw.WriteElementString("ShowRetry", nodeStyle.Value.ShowRetry.ToString())
If nodeStyle.Value.ShowRetryInterval Then xw.WriteElementString("ShowRetryInterval", nodeStyle.Value.ShowRetryInterval.ToString())
If nodeStyle.Value.ShowErrorCode Then xw.WriteElementString("ShowErrorCode", nodeStyle.Value.ShowErrorCode.ToString())
If nodeStyle.Value.ShowErrorMessage Then xw.WriteElementString("ShowErrorMessage", nodeStyle.Value.ShowErrorMessage.ToString())
If nodeStyle.Value.ShowCommand Then xw.WriteElementString("ShowCommand", nodeStyle.Value.ShowCommand.ToString())
If nodeStyle.Value.ShowParameter Then xw.WriteElementString("ShowParameter", nodeStyle.Value.ShowParameter.ToString())
xw.WriteEndElement()
Next
xw.WriteEndElement()
xw.WriteEndDocument()
End Using
End Sub
#End Region
#Region "节点保存与加载"
Public Sub SaveRowNode(xw As XmlWriter)
xw.WriteStartElement($"RowNode") '创建单元格节点
xw.WriteElementString("RowType", RowType.ToString())
If String.IsNullOrEmpty(Label) = False Then xw.WriteElementString("Label", Label)
xw.WriteElementString("Action", Action.ToString())
If String.IsNullOrEmpty(ControlType) = False Then xw.WriteElementString("ControlType", ControlType)
If String.IsNullOrEmpty(CommandType) = False Then xw.WriteElementString("CommandType", CommandType)
If String.IsNullOrEmpty(Command) = False Then xw.WriteElementString("Command", Command)
If String.IsNullOrEmpty(Description) = False Then xw.WriteElementString("Description", Description)
xw.WriteElementString("Retry", Retry.ToString())
xw.WriteElementString("RetryInterval", RetryInterval.ToString())
xw.WriteElementString("SaveToDb", SaveToDb.ToString())
If String.IsNullOrEmpty(RecordName) = False Then xw.WriteElementString("RecordName", RecordName)
If String.IsNullOrEmpty(ErrorCode) = False Then xw.WriteElementString("ErrorCode", ErrorCode)
If String.IsNullOrEmpty(ErrorMessage) = False Then xw.WriteElementString("ErrorMessage", ErrorMessage)
For Each parameter As TestCmdParam In Parameters
xw.WriteStartElement($"Parameter") '创建跟节点
xw.WriteAttributeString("Type", parameter.Type)
xw.WriteAttributeString("Desc", parameter.Desc)
xw.WriteAttributeString("LowerLimit", parameter.LowerLimit)
xw.WriteAttributeString("UpperLimit", parameter.UpperLimit)
xw.WriteString(parameter.Value)
xw.WriteEndElement()
Next
If RowNodes.Count > 0 Then
SaveRowNodes(xw, RowNodes)
End If
xw.WriteEndElement()
End Sub
Public Shared Sub SaveRowNodes(xw As XmlWriter, nodes As RowNodeCollection)
xw.WriteStartElement($"RowNodes") '创建单元格节点
For Each node As RowNode In nodes
node.SaveRowNode(xw)
Next
xw.WriteEndElement()
End Sub
''' <summary>
''' 导出为XML文件
''' </summary>
''' <param name="path">文件路径</param>
Public Sub ExportToXml(path As String)
Dim xws As New XmlWriterSettings
With xws
.Indent = True
.NewLineOnAttributes = False
.Encoding = New UTF8Encoding(False)
End With
Using xw As XmlWriter = XmlWriter.Create(path, xws)
xw.WriteStartDocument()
SaveRowNode(xw)
xw.WriteEndDocument()
End Using
End Sub
''' <summary>
''' 加载行节点
''' </summary>
''' <param name="nodeList"></param>
''' <param name="rowCollection"></param>
Public Shared Sub LoadRowNodes(nodeList As XmlNodeList, rowCollection As RowNodeCollection)
Dim xe As XmlElement
For Each node As XmlNode In nodeList
xe = CType(node, XmlElement)
Select Case xe.LocalName
Case "RowNode"
Dim row As New RowNode
rowCollection.Add(row)
row.LoadFormXmlNodeList(xe.ChildNodes)
Case Else
Throw New Exception($"LoadRowNodes Unknown LocalName:{xe.LocalName}")
End Select
Next
End Sub
Public Sub LoadFormXmlNodeList(nodeList As XmlNodeList)
Dim xe As XmlElement
For Each node As XmlNode In nodeList
xe = CType(node, XmlElement)
Select Case xe.LocalName
Case "RowType"
RowType = CType([Enum].Parse(GetType(RowTypeEnum), xe.InnerText), RowTypeEnum)
Case "Description"
Description = xe.InnerText
Case "Label"
Label = xe.InnerText
Case "ControlType"
ControlType = xe.InnerText
Case "Action"
Action = CBool(xe.InnerText)
Case "SaveToDb"
SaveToDb = CBool(xe.InnerText)
Case "RecordName"
RecordName = xe.InnerText
Case "Retry"
Retry = CInt(xe.InnerText)
Case "RetryInterval"
RetryInterval = CInt(xe.InnerText)
Case "ErrorCode"
ErrorCode = xe.InnerText
Case "ErrorMessage"
ErrorMessage = xe.InnerText
Case "CommandType"
CommandType = xe.InnerText
Case "Command"
Command = xe.InnerText
Case "Parameter"
Dim param As New TestCmdParam With {
.Type = xe.GetAttribute("Type"),
.Desc = xe.GetAttribute("Desc"),
.LowerLimit = xe.GetAttribute("LowerLimit"),
.UpperLimit = xe.GetAttribute("UpperLimit"),
.Value = xe.InnerText
}
Parameters.Add(param)
Case "RowNodes"
RowNodes.Clear()
LoadRowNodes(xe.ChildNodes, RowNodes)
Case Else
Throw New Exception($"LoadRowNode Unknown LocalName:{xe.LocalName}")
End Select
Next
End Sub
Public Sub LoadFormXml(path As String)
Dim xd As New XmlDocument()
xd.Load(path)
Dim nodeList As XmlNodeList = xd.SelectSingleNode($"RowNode").ChildNodes
LoadFormXmlNodeList(nodeList)
End Sub
#End Region
End Class
End Namespace