Imports System.Reflection
Imports UTS_Core.Database
Imports UTS_Core.DebugLog
Imports UTS_Core.UTSModule
Imports UTS_Core.UTSModule.DbConnect
Imports UTS_Core.UTSModule.DbTableModel.Customer

Public Class FrmMain
    Public Property UserInfo As Login.UserInfo

    Public Property Lic As License.License

    Private _ftp As FtpService

    Private Function RunningInstance() As Process
        Dim current As Process = Process.GetCurrentProcess()
        Dim processes() As Process = Process.GetProcessesByName(current.ProcessName)
        For Each p As Process In processes
            If p.Id <> current.Id Then
                If Assembly.GetExecutingAssembly().Location.Replace("/", "\\") = current.MainModule.FileName Then
                    Return p
                End If
            End If
        Next
        Return Nothing
    End Function


    Private Sub FrmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ApplicationLog.WriteInfoLog($"{Application.ProductName} {Application.ProductVersion} 加载中。")

        '加载License
        ShowLoginForm()

        _ftp = New FtpService(UtsRegistry.FtpHost, CInt(Lic.FtpPort), Lic.FtpUser, Lic.FtpPwd)

        Text = $"{Application.ProductName} {Application.ProductVersion})"

        '开启录像软件

        Dim exePath As String = $"{Application.StartupPath}\ScreenCapture\AMCAP.exe"
        If Process.GetProcessesByName("AMCAP").Length = 0 Then
            Try
                ExecuteCmd(exePath)
            Catch ex As Exception
                ApplicationLog.WriteErrorLog($"开启摄像头软件失败！原因：{ex.Message}")
                MsgBox($"开启摄像头软件失败！原因：{ex.Message}")
            End Try
        End If

        '开启截图软件
        exePath = $"{Application.StartupPath}\ScreenCapture\Apowersoft Screen Capture Pro.exe"
        Try
            ExecuteCmd(exePath)
        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"开启截屏软件失败！原因：{ex.Message}")
            MsgBox($"开启截屏软件失败！原因：{ex.Message}")
        End Try

        Dim cmd As String
        Dim dtTable As DataTable
        Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
            db.Open()

            '查询维修类型
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairTypesTable.TableName)
            dtTable = db.ExecuteDataTable(cmd)

            Dim id As Integer
            Dim name As String
            For Each dtRow As DataRow In dtTable.Rows
                id = CInt(dtRow($"{RepairTypesTable.ColNames.ID}"))
                name = CStr(dtRow($"{RepairTypesTable.ColNames.Name}"))

                Dim type As New RepairTypes With {.ID = id, .Name = name}
                _RepairTypes.Add(name, type)

                '查询维修原因
                cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairReasonTable.TableName, $"`{RepairReasonTable.ColNames.RepairType}` = {id}")
                Dim dtReason As DataTable = db.ExecuteDataTable(cmd)
                For Each drReason As DataRow In dtReason.Rows
                    id = CInt(drReason($"{RepairReasonTable.ColNames.ID}"))
                    name = CStr(drReason($"{RepairReasonTable.ColNames.Name}"))

                    type.RepairReason.Add(name, id)
                Next
            Next
            CboRepairType.Items.AddRange(_RepairTypes.Keys.ToArray)


            '查询维修结果
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairResultTable.TableName)
            dtTable = db.ExecuteDataTable(cmd)
            For Each dtRow As DataRow In dtTable.Rows
                id = CInt(dtRow($"{RepairResultTable.ColNames.ID}"))
                name = CStr(dtRow($"{RepairResultTable.ColNames.Name}"))
                _RepairResult.Add(name, id)
            Next
            CboRepairResult.Items.AddRange(_RepairResult.Keys.ToArray)

            cmd = db.CmdHelper.DbDistinctSearch(UtsDb.RemotePrivateDb, $"{RepairLogTable.ColNames.RepairComment}", RepairLogTable.TableName, $"1 = 1 limit 100")
            dtTable = db.ExecuteDataTable(cmd)
            Dim sl As New AutoCompleteStringCollection
            For Each dtRow As DataRow In dtTable.Rows
                sl.Add(dtRow($"{RepairLogTable.ColNames.RepairComment}").ToString)
            Next
            CboRepairScheme.AutoCompleteCustomSource = sl

            db.Close()
        End Using

        ApplicationLog.WriteInfoLog("窗体加载完成。")
    End Sub




    Private _RepairResult As New Dictionary(Of String, Integer)
    Private _RepairSource As New Dictionary(Of String, Integer)

    Private _RepairTypes As New Dictionary(Of String, RepairTypes)

    Public Class RepairTypes
        Public ID As Integer

        Public Name As String

        Public RepairReason As Dictionary(Of String, Integer)

        Sub New()
            RepairReason = New Dictionary(Of String, Integer)

        End Sub

    End Class


    Private Sub FrmMain_Shown(sender As Object, e As EventArgs) Handles MyBase.Shown
        '初始化产品图,默认4张项目图
        ProductImgs = New List(Of ProductRepairImage)
        ProductImgs.Add(New ProductRepairImage With {.Control = TsBtnImg0})
        ProductImgs.Add(New ProductRepairImage With {.Control = TsBtnImg1})
        ProductImgs.Add(New ProductRepairImage With {.Control = TsBtnImg2})
        ProductImgs.Add(New ProductRepairImage With {.Control = TsBtnImg3})
    End Sub


    ''' <summary>
    ''' 显示登录窗口
    ''' </summary>
    Private Sub ShowLoginForm()
        If Login.LoginParams.IsShowLoginForm = False Then Return
        Using frmLogin As New Login.LoginForm
            If frmLogin.ShowDialog() = DialogResult.OK Then
                UserInfo = frmLogin.UserLoginInfo
                Lic = frmLogin.UserLicense
            Else
                Close()
            End If
        End Using
    End Sub



#Region "记录查询"
    Private Sub SearchRepairRecord(sn As String)
        If String.IsNullOrEmpty(sn) Then
            MsgBox($"条码不能为空,请扫码后重试")
            Return
        End If

        '获取SN总表中信息
        Dim barcodeInfo As SnListResult = GetBarcodeInfo(sn)
        If barcodeInfo Is Nothing Then
            MsgBox($“未查询到条码[{ sn}]相关的信息”)
            Return
        End If

        '获取条码所属项目与站位信息
        Dim pInfo As New Project.ProjectInfo(UserInfo.UserId, UserInfo.UserName, barcodeInfo.ProductID, Project.ProjectInfo.InitializeModeEnum.RemoteDatabaseLoad)

        Dim pTestLog As New ProductTestLog
        pTestLog.BarCode = sn
        pTestLog.ProjectIndex = barcodeInfo.ProductID
        pTestLog.ProjectName = pInfo.Name

        '获取条码所有经过站位记录
        pTestLog.StationTestLogs.Clear()
        For sIndex As Integer = 0 To pInfo.Station.Count - 1
            Dim sTestLog As New StationTestLog
            sTestLog.StationIndex = pInfo.Station(sIndex).StationID
            sTestLog.StationName = pInfo.Station(sIndex).Name
            sTestLog.TimeString = barcodeInfo.TestResults(sIndex).TestTime
            sTestLog.Result = barcodeInfo.TestResults(sIndex).TestResult
            sTestLog.ParentProductLog = pTestLog

            '获取条码测试站所有测试记录
            sTestLog.BarcodeTestLogs.Clear()
            Dim dtTable As DataTable = DbConnector.GetTestResult(pTestLog.ProjectIndex, sTestLog.StationIndex, pTestLog.BarCode)

            For Each dtRow As DataRow In dtTable.Rows
                Dim bTestLog As New BarcodeTestLog

                bTestLog.TimeString = dtRow($"{TestLogTable.ColNames.StartTime}").ToString
                bTestLog.ErrorCode = dtRow($"{TestLogTable.ColNames.ErrCode}").ToString
                bTestLog.ParentStationLog = sTestLog

                Dim tmpResult As Object = dtRow($"{TestLogTable.ColNames.TestResult}")
                If IsDBNull(tmpResult) Then
                    bTestLog.Result = Nothing
                Else
                    bTestLog.Result = CBool(tmpResult)
                    If bTestLog.Result = True Then

                    Else

                    End If
                End If

                Dim bytes1(10) As Byte
                Dim bytes2(19) As Byte
                Array.Copy(bytes2, 1, bytes1, 0, 10)

                For col As Integer = TestLogTable.ColNames.ID To dtTable.Columns.Count - 1
                    bTestLog.Fileds.Add(dtTable.Columns(col).ColumnName, dtRow(dtTable.Columns(col).ColumnName).ToString)
                Next

                sTestLog.BarcodeTestLogs.Add(bTestLog)
            Next
            pTestLog.StationTestLogs.Add(sTestLog)
        Next



        '更新测试历史
        If TabRepairSource.SelectedIndex = 0 Then
            UpdateTestLog(TvwTestLog, pTestLog)
        Else
            UpdateTestLog(TvwTestLog_Request, pTestLog)
        End If

        '查询条码历史维修记录
        _productRepairData.DUT_SN = pTestLog.BarCode
        _productRepairData.ProductID = pTestLog.ProjectIndex
        _productRepairData.ErrCode = ""
        _productRepairData.RepairType = -1
    End Sub


    Private Sub BtnSearch_Click(sender As Object, e As EventArgs)
        Dim sn As String = TxtDevSn.Text
        SearchRepairRecord(TxtDevSn.Text)
        TxtDevSn.Focus()
        TxtDevSn.SelectAll()
    End Sub

    Private Sub TxtMarketSn_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtMarketSn.KeyDown
        If e.KeyCode = Keys.Enter Then
            If String.IsNullOrWhiteSpace(TxtMarketSn.Text) Then Return
            SearchRepairRequest(TxtMarketSn.Text)

            SearchRepairRecord(TxtMarketSn.Text)
        End If
    End Sub

    ''' <summary>
    ''' 项目索引
    ''' </summary>
    Private _pid As Integer

    ''' <summary>
    ''' 返修订单号
    ''' </summary>
    Private _num As String

    Private Sub SearchRepairRequest(sn As String)
        If String.IsNullOrEmpty(sn) Then
            MsgBox($"条码不能为空,请扫码后重试")
            Return
        End If

        Dim dtTable As DataTable
        Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
            db.Open()

            Dim cmd As String = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairRequestTable.TableName, $" `Barcode` = '{sn}' Order by ID Desc Limit 1")
            dtTable = db.ExecuteDataTable(cmd, False)

            db.Close()
        End Using

        If dtTable Is Nothing OrElse dtTable.Rows.Count = 0 Then
            MsgBox("未查询到报修记录！")
            Return
        End If

        TvwRepairRequest.Nodes.Clear()
        For Each dtRow As DataRow In dtTable.Rows
            _pid = CInt(dtRow($"{RepairRequestTable.ColNames.ProductID}"))

            Dim pInfo As New Project.ProjectInfo(UserInfo.UserId, UserInfo.UserName, _pid, Project.ProjectInfo.InitializeModeEnum.RemoteDatabaseLoad)

            Dim pNode As New TreeNode($"{pInfo.Name}:{sn}")
            pNode.Nodes.Add($"产品类型：{pInfo.Name}")
            pNode.Nodes.Add($"产品条码：{sn}")
            pNode.Nodes.Add($"报修单号：{dtRow($"{RepairRequestTable.ColNames.RepairRequestNum}")}")
            pNode.Nodes.Add($"不良品来源：{dtRow($"{RepairRequestTable.ColNames.RejectSource}")}")
            pNode.Nodes.Add($"不良代码：{dtRow($"{RepairRequestTable.ColNames.RejectCode}")}")
            pNode.Nodes.Add($"不良说明：{dtRow($"{RepairRequestTable.ColNames.RejectDesc}")}")
            pNode.Nodes.Add($"创建时间：{dtRow($"{RepairRequestTable.ColNames.CreateTime}")}")
            pNode.Nodes.Add($"维修进度：{dtRow($"{RepairRequestTable.ColNames.RepairProgress}")}")
            pNode.Nodes.Add($"维修结果：{dtRow($"{RepairRequestTable.ColNames.RepairResult}")}")

            TvwRepairRequest.Nodes.Add(pNode)

            _num = dtRow($"{RepairRequestTable.ColNames.RepairRequestNum}").ToString
        Next
        TvwRepairRequest.ExpandAll()
    End Sub

    Private Sub TxtDevSn_KeyDown(sender As Object, e As KeyEventArgs) Handles TxtDevSn.KeyDown
        If e.KeyCode = Keys.Enter Then
            If String.IsNullOrWhiteSpace(TxtDevSn.Text) Then Return
            SearchRepairRecord(TxtDevSn.Text)

            lblPassFailDisplay.Text = "Testing"
            lblPassFailDisplay.ForeColor = Color.Yellow

            ' TxtDevSn.Focus()
            ' TxtDevSn.SelectAll()
        End If
    End Sub


    Private Function GetBarcodeInfo(barcode As String) As SnListResult
        '  Dim dtTable As DataTable = DbConnector.GetLocalBarcode(barcode)
        Dim dtTable As DataTable = DbConnector.GetRemoteBarcode(barcode)
        If dtTable.Rows.Count = 0 Then Return Nothing

        Dim dtRow As DataRow = dtTable(0)
        Dim bt As New SnListResult

        bt.BarCode = barcode
        bt.ProductID = CInt(dtRow($"{SnListTable.ColNames.ProductID}"))
        bt.CreateTime = CDate(dtRow($"{SnListTable.ColNames.CreateTime}"))

        bt.TestResults.Clear()
        Dim testTime As String
        Dim testResult As Boolean?

        Dim tmp As Object
        For stationIndex As Integer = 0 To 11
            tmp = dtRow($"S{stationIndex + 1}")
            If IsDBNull(tmp) Then
                If tmp Is Nothing Then
                    Console.WriteLine($"S{stationIndex + 1} is nothing")
                End If

                testTime = Nothing
            Else
                testTime = tmp.ToString()
            End If

            tmp = dtRow($"Result{stationIndex + 1}")
            If IsDBNull(tmp) Then
                testResult = Nothing
            Else
                testResult = CBool(tmp)
            End If

            bt.TestResults.Add(New TResult(testTime, testResult))
        Next

        Return bt
    End Function

    Private Sub UpdateTestLog(tvw As TreeView， pTestLog As ProductTestLog)
        tvw.Nodes.Clear()
        tvw.ExpandAll()
        Dim pNode As TreeNode = tvw.Nodes.Add($"{pTestLog.ProjectName}:{pTestLog.BarCode}")
        pNode.Tag = pTestLog
        For Each sTestLog As StationTestLog In pTestLog.StationTestLogs
            Dim sNode As TreeNode
            If sTestLog.Result Is Nothing Then
                sNode = pNode.Nodes.Add($"{sTestLog.StationName}:NoData")
                sNode.ForeColor = Color.Gray

            ElseIf sTestLog.Result Then
                sNode = pNode.Nodes.Add($"{sTestLog.StationName}:Pass")
                sNode.ForeColor = Color.Green
            Else
                sNode = pNode.Nodes.Add($"{sTestLog.StationName}:Fail")
                sNode.ForeColor = Color.Red
            End If
            sNode.Tag = sTestLog

            For Each bTestLog As BarcodeTestLog In sTestLog.BarcodeTestLogs
                Dim bNode As TreeNode
                If bTestLog.Result Is Nothing Then
                    bNode = sNode.Nodes.Add($"{bTestLog.TimeString}")
                    bNode.ForeColor = Color.Gray
                ElseIf bTestLog.Result Then
                    bNode = sNode.Nodes.Add($"{bTestLog.TimeString}  Pass")
                    bNode.ForeColor = Color.Green
                Else
                    bNode = sNode.Nodes.Add($"{bTestLog.TimeString}  Fail")
                    bNode.ForeColor = Color.Red
                End If

                For Each filed As KeyValuePair(Of String, String) In bTestLog.Fileds
                    bNode.Nodes.Add($"{filed.Key} : {filed.Value}")
                Next
                bNode.Collapse()
                bNode.Tag = bTestLog
            Next
            sNode.Expand()
        Next
        pNode.Expand()
    End Sub


    Public Class SnListResult
        Sub New()
            TestResults = New List(Of TResult)()
        End Sub

        Public Property ProductID() As Integer

        Public Property BarCode() As String

        Public Property CreateTime() As DateTime

        Public Property TestResults() As List(Of TResult)

    End Class


    Public Class TResult
        Sub New(time As String, result As Boolean?)
            TestTime = time
            TestResult = result
        End Sub

        Public Property TestTime As String

        Public Property TestResult() As Boolean?
    End Class


    Public Class ProductTestLog
        Sub New()
            ProjectIndex = -1
            StationTestLogs = New List(Of StationTestLog)
        End Sub

        Public ProjectIndex As Integer

        Public ProjectName As String

        Public BarCode As String

        Public StationTestLogs As List(Of StationTestLog)
    End Class

    Public Class StationTestLog
        Sub New()
            StationIndex = -1
            BarcodeTestLogs = New List(Of BarcodeTestLog)
        End Sub

        Public ParentProductLog As ProductTestLog

        Public StationIndex As Integer

        Public StationName As String

        Public TimeString As String

        Public Result As Boolean?

        Public BarcodeTestLogs As List(Of BarcodeTestLog)
    End Class

    Public Class BarcodeTestLog
        Sub New()
            ErrorCode = String.Empty
            TimeString = String.Empty
            Fileds = New Dictionary(Of String, String)
        End Sub


        Public ParentStationLog As StationTestLog

        Public ErrorCode As String

        Public TimeString As String

        Public Result As Boolean?

        Public Fileds As Dictionary(Of String, String)
    End Class
#End Region


#Region "拍摄"
    ''' <summary>当前编辑产品图像的序号</summary>
    Private _imgIndex As Integer

    ''' <summary>产品处理图像信息，当前上限4</summary>
    Private ProductImgs As List(Of ProductRepairImage)

    ''' <summary>修改图像显示时图像线程锁</summary>
    Private _changeImgLock As New Object

    ''' <summary>从数据库中读取或保存，产品维修数据</summary>
    Private _productRepairData As New ProductRepairData


    Private Sub GetBarcodeRepairLog(barcode As String, ByRef _repairData As ProductRepairData)
        Dim dtTable As DataTable = DbConnector.GetBarcodeRepairLog(barcode)

        If dtTable.Rows.Count = 0 Then Return

        _repairData.ErrCode = ""

    End Sub


    Private Sub TsBtnImg0_Click(sender As Object, e As EventArgs) Handles TsBtnImg3.Click, TsBtnImg2.Click, TsBtnImg1.Click, TsBtnImg0.Click
        Dim index As Integer = CInt(CType(sender, ToolStripButton).Tag)
        If _imgIndex = index Then Return

        For i As Integer = 0 To ProductImgs.Count - 1
            If i = index Then
                ProductImgs(i).Control.Checked = True
            Else
                ProductImgs(i).Control.Checked = False
            End If
        Next

        SyncLock _changeImgLock
            _imgIndex = index
        End SyncLock
    End Sub

    Public Class ProductRepairImage
        Public Property Image As Image

        Public Property ImageName As String

        Public Property ImagePath As String

        Public Property Control As ToolStripButton
    End Class


    Private Sub BtnCommit_Click(sender As Object, e As EventArgs) Handles BtnCommit.Click
        If CboRepairType.SelectedIndex = -1 Then
            MsgBox("请选择返修类型")
            Return
        End If

        If CboRepairReason.SelectedIndex = -1 Then
            MsgBox("请选择返修原因")
            Return
        End If

        If CboRepairResult.SelectedIndex = -1 Then
            MsgBox("请选择返修结果")
            Return
        End If

        If String.IsNullOrWhiteSpace(CboRepairScheme.Text) Then
            MsgBox("请选择或输入返修方案")
            Return
        End If

        Dim barcode As String
        If TabRepairSource.SelectedIndex = 0 Then
            barcode = TxtDevSn.Text

            If String.IsNullOrWhiteSpace(barcode) Then
                MsgBox("请输入待维修产品条码")
                Return
            End If

            Dim node As TreeNode = TvwTestLog.SelectedNode
            If node Is Nothing Then
                MsgBox("请选择维修记录进行维修")
                Return
            End If

            If node.Level <> 2 Then
                MsgBox("请选择有效的站位维修记录进行维修")
                Return
            End If

            ApplicationLog.WriteInfoLog($"产线返修录入，条码：{barcode}")

            Dim tLog As BarcodeTestLog = CType(node.Tag, BarcodeTestLog)

            _productRepairData.ProductID = tLog.ParentStationLog.ParentProductLog.ProjectIndex
            _productRepairData.StationID = tLog.ParentStationLog.StationIndex
            _productRepairData.OrderID = CInt(tLog.Fileds("OrderID"))
            _productRepairData.TestLogID = CInt(tLog.Fileds("ID"))

            _productRepairData.TestPlan = tLog.Fileds("TestPlan")
            _productRepairData.FailSteps = tLog.Fileds("FailSteps")
            Try
                _productRepairData.FailMsg = tLog.Fileds("FailMsg")
            Catch ex As Exception
                ApplicationLog.WriteWarningLog($"填充FailMsg字段失败！原因：{ex.Message}")
                _productRepairData.FailMsg = ""
            End Try
            _productRepairData.ErrCode = tLog.Fileds("ErrCode")

            _productRepairData.DUT_SN = barcode

            _productRepairData.RepairSource = "产线返修"
            _productRepairData.DocuNumber = ""
        Else
            barcode = TxtMarketSn.Text

            If String.IsNullOrWhiteSpace(barcode) Then
                MsgBox("请输入待维修产品条码")
                Return
            End If

            ApplicationLog.WriteInfoLog($"生产返修录入，条码：{barcode}")

            _productRepairData.ProductID = _pid

            _productRepairData.DUT_SN = barcode

            _productRepairData.RepairSource = "市场返修"
            _productRepairData.DocuNumber = _num
        End If

        _productRepairData.RepairDate = Now

        _productRepairData.RepairType = _RepairTypes(CboRepairType.Text).ID
        _productRepairData.RepairReason = _RepairTypes(CboRepairType.Text).RepairReason(CboRepairReason.Text)

        _productRepairData.RepairComment = CboRepairScheme.Text

        _productRepairData.RepairResult = _RepairResult(CboRepairResult.Text)

        _productRepairData.ProductImages.Clear()

        'ftp:图像上传
        For i As Integer = 0 To ProductImgs.Count - 1
            If ProductImgs(i).Image IsNot Nothing Then
                ProductImgs(i).ImageName = $"{_productRepairData.DUT_SN}_{Now:yyyyMMdd_HHmmss}_{i}.jpg"
                ProductImgs(i).ImagePath = $"{Application.StartupPath}\RepairImage\{ProductImgs(i).ImageName}"

                Try
                    ProductImgs(i).Image.Save(ProductImgs(i).ImagePath)
                    _ftp.FtpUpload($"/uts_Manager/AUTS/{Lic.VendorName}/Repair/MasterImg/{ProductImgs(i).ImageName}", ProductImgs(i).ImagePath)
                Catch ex As Exception
                    lblPassFailDisplay.Text = "FAIL"
                    lblPassFailDisplay.ForeColor = Color.Red

                    ApplicationLog.WriteErrorLog($"保存产品图像错误，{ex.Message}")
                    MsgBox($"保存产品图像错误，{ex.Message}")
                    Return
                End Try

                _productRepairData.ProductImages.Add(ProductImgs(i).ImageName)
            Else
                _productRepairData.ProductImages.Add("")
            End If
        Next

        Try
            Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
                db.Open()

                Dim tbName As String = RepairLogTable.TableName
                Dim fileds As Dictionary(Of String, String) = _productRepairData.ToDbFileds
                Dim cmd As String = db.CmdHelper.DbInsert(UtsDb.RemotePrivateDb, tbName, fileds)

                '保存维修记录
                db.ExecuteNonQuery(cmd)

                '更新报修记录
                If TabRepairSource.SelectedIndex = 1 Then
                    Dim condition As String = $"`{RepairLogTable.ColNames.DUT_SN}` = '{barcode}' order by id limit 1"
                    Dim logId As Integer = CInt(db.ExecuteScalar(db.CmdHelper.DbSearch(UtsDb.RemotePrivateDb, $"{RepairLogTable.ColNames.ID}", tbName, condition)))

                    condition = $"`{RepairRequestTable.ColNames.Barcode}` = '{barcode}'"
                    fileds.Clear()
                    fileds.Add($"{RepairRequestTable.ColNames.RepairProgress}", $"已维修")
                    fileds.Add($"{RepairRequestTable.ColNames.RepairResult}", $"{_RepairResult(CboRepairResult.Text)}")
                    fileds.Add($"{RepairRequestTable.ColNames.RepairLogID}", $"{logId}")
                    fileds.Add($"{RepairRequestTable.ColNames.Repairier}", $"{UserInfo.UserId}")
                    cmd = db.CmdHelper.DbUpdate(UtsDb.RemotePrivateDb, RepairRequestTable.TableName, fileds， condition)
                    db.ExecuteNonQuery(cmd)
                End If

                db.Close()
            End Using

            For i As Integer = 0 To ProductImgs.Count - 1
                ProductImgs(i).Image = Nothing
                ProductImgs(i).Control.Image = My.Resources.NoImg40_30
            Next

            lblPassFailDisplay.ForeColor = Color.Green
            lblPassFailDisplay.Text = "PASS"

            CboRepairScheme.AutoCompleteCustomSource.Add(CboRepairScheme.Text)

            TxtDevSn.SelectAll()
            TxtDevSn.Focus()
        Catch ex As Exception
            lblPassFailDisplay.ForeColor = Color.Red
            lblPassFailDisplay.Text = "FAIL"

            ApplicationLog.WriteErrorLog($"保存维修记录至云端错误，{ex.Message}")
            MsgBox($"保存维修记录至云端错误，{ex.Message}")
        End Try


    End Sub


    Public Class ProductRepairData
        ''' <summary>
        ''' 维修产品索引
        ''' </summary>
        ''' <returns></returns>
        Public Property ProductID As Integer

        ''' <summary>
        ''' 维修站位索引
        ''' </summary>
        ''' <returns></returns>
        Public Property StationID As Integer

        ''' <summary>
        ''' 内部订单索引
        ''' </summary>
        ''' <returns></returns>
        Public Property OrderID As Integer

        ''' <summary>
        ''' 绑定测试记录索引
        ''' </summary>
        ''' <returns></returns>
        Public Property TestLogID As Integer


        ''' <summary>
        ''' 产品条码
        ''' </summary>
        ''' <returns></returns>
        Public Property DUT_SN As String

        ''' <summary>
        ''' 测试流程
        ''' </summary>
        ''' <returns></returns>
        Public Property TestPlan As String

        ''' <summary>
        ''' 失败步骤
        ''' </summary>
        ''' <returns></returns>
        Public Property FailSteps As String

        ''' <summary>
        ''' 失败提示信息
        ''' </summary>
        ''' <returns></returns>
        Public Property FailMsg As String

        ''' <summary>
        ''' 错误代码
        ''' </summary>
        ''' <returns></returns>
        Public Property ErrCode As String

        ''' <summary>
        ''' 维修日期
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairDate As DateTime

        ''' <summary>
        ''' 维修类型
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairType As Integer

        ''' <summary>
        ''' 维修原因
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairReason As Integer

        ''' <summary>
        ''' 维修来源
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairSource As String

        ''' <summary>
        ''' 产品单号
        ''' </summary>
        ''' <returns></returns>
        Public Property DocuNumber As String

        ''' <summary>
        ''' 维修方案
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairComment As String

        ''' <summary>
        ''' 维修结果
        ''' </summary>
        ''' <returns></returns>
        Public Property RepairResult As Integer

        ''' <summary>
        ''' 维修产品图
        ''' </summary>
        ''' <returns></returns>
        Public Property ProductImages As List(Of String)

        Sub New()
            ProductImages = New List(Of String)
        End Sub


        Public Function ToDbFileds() As Dictionary(Of String, String)
            Dim dicFileds As New Dictionary(Of String, String)
            dicFileds.Add($"{RepairLogTable.ColNames.ProductID}", $"{ProductID}")
            dicFileds.Add($"{RepairLogTable.ColNames.StationID}", $"{StationID}")
            dicFileds.Add($"{RepairLogTable.ColNames.OrderID}", $"{OrderID}")
            dicFileds.Add($"{RepairLogTable.ColNames.TestLogID}", $"{TestLogID}")
            dicFileds.Add($"{RepairLogTable.ColNames.DUT_SN}", $"{DUT_SN}")
            dicFileds.Add($"{RepairLogTable.ColNames.TestPlan}", $"{TestPlan}")
            dicFileds.Add($"{RepairLogTable.ColNames.FailSteps}", $"{FailSteps}")
            dicFileds.Add($"{RepairLogTable.ColNames.FailMsg}", $"{FailMsg}")
            dicFileds.Add($"{RepairLogTable.ColNames.ErrCode}", $"{ErrCode}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairDate}", $"{RepairDate}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairType}", $"{RepairType}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairReason}", $"{RepairReason}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairSource}", $"{RepairSource}")
            dicFileds.Add($"{RepairLogTable.ColNames.DocuNumber}", $"{DocuNumber}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairComment}", $"{RepairComment}")
            dicFileds.Add($"{RepairLogTable.ColNames.RepairResult}", $"{RepairResult}")

            For i As Integer = 0 To ProductImages.Count - 1
                dicFileds.Add($"ProductImg{i + 1}", ProductImages(i))
            Next

            Return dicFileds
        End Function
    End Class




#End Region


#Region "绘制图像"
    Private Sub FrmMain_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
        If e.Control Then
            Select Case e.KeyCode
                Case Keys.C
                    CopyImage()
                Case Keys.D
                    DeleteImage()
                Case Keys.V
                    PasteImage()
            End Select
        End If
    End Sub

    Private Sub TsmiCopy_Click(sender As Object, e As EventArgs) Handles TsmiCopy.Click
        CopyImage()
    End Sub

    Private Sub TsmiPaste_Click(sender As Object, e As EventArgs) Handles TsmiPaste.Click
        PasteImage()
    End Sub

    Private Sub TsmiDelete_Click(sender As Object, e As EventArgs) Handles TsmiDelete.Click
        DeleteImage()
    End Sub

    Public Sub CopyImage()
        Console.WriteLine("Copy Data!")
        If ProductImgs(_imgIndex).Image Is Nothing Then Return
        Clipboard.SetDataObject(ProductImgs(_imgIndex).Image)
    End Sub

    Public Sub PasteImage()
        If Clipboard.ContainsImage Then
            Try
                ToolStrip2.Focus()

                ProductImgs(_imgIndex).Control.Image = Clipboard.GetImage

                ProductImgs(_imgIndex).Image = ProductImgs(_imgIndex).Control.Image
            Catch ex As Exception
                ApplicationLog.WriteErrorLog($"更新预览图失败！原因：{ex.Message}")
                MsgBox($"更新预览图失败！原因：{ex.Message}")
            End Try
        End If
    End Sub

    Public Sub DeleteImage()
        ProductImgs(_imgIndex).Image = Nothing

        ProductImgs(_imgIndex).Control.Image = My.Resources.NoImg40_30
    End Sub

    Public Sub ExecuteCmd(filePath As String)
        Dim proc As New Process

        With proc.StartInfo
            .FileName = filePath
        End With

        Try
            proc.Start()
        Catch ex As Exception
            ApplicationLog.WriteErrorLog($"启动程序[{filePath}]失败，原因：{ex.Message}")
            Console.WriteLine($"ExecuteCmd Error:{ex.Message}")
        End Try
    End Sub

    Private Sub CboRepairType_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CboRepairType.SelectedIndexChanged
        If CboRepairType.SelectedIndex = -1 Then Return
        If _RepairTypes.ContainsKey(CboRepairType.Text) Then
            CboRepairReason.Items.Clear()
            CboRepairReason.Items.AddRange(_RepairTypes(CboRepairType.Text).RepairReason.Keys.ToArray)
        End If

    End Sub

    Private _lastNode As TreeNode

    Private Sub TvwTestLog_NodeMouseClick(sender As Object, e As TreeNodeMouseClickEventArgs) Handles TvwTestLog.NodeMouseClick, TvwTestLog_Request.NodeMouseClick
        Console.WriteLine($"Level:{e.Node.Level},Index :{e.Node.Index}")

        If e.Node.Level <> 2 Then Return
        Dim tLog As BarcodeTestLog = CType(e.Node.Tag, BarcodeTestLog)

        Dim pid As Integer = tLog.ParentStationLog.ParentProductLog.ProjectIndex
        Dim sid As Integer = tLog.ParentStationLog.StationIndex
        Dim errCode As String = tLog.ErrorCode
        Dim failStep As String = tLog.Fileds("FailSteps")
        Dim testPlan As String = tLog.Fileds("TestPlan")
        Dim sn As String = tLog.Fileds("DUT_SN")

        If _lastNode IsNot Nothing Then
            _lastNode.BackColor = TvwTestLog.BackColor
        End If
        e.Node.BackColor = Color.SkyBlue
        _lastNode = e.Node

        Dim cmd As String
        Dim dtTable As DataTable
        Using db As New DbExecutor(UtsDb.RemoteDbType, UtsDb.RemoteConnString)
            db.Open()

            '更新ErrCode表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairLogTable.TableName, $"{RepairLogTable.ColNames.ErrCode} = '{errCode}' order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd)
            GrdErrCode.DataSource = dtTable
            GrdErrCode.DisplayRowNumber = True
            GrdErrCode.ExtendLastCol = True
            repairCheckRows.Clear()

            For i As Integer = 1 To GrdErrCode.Cols - 1
                repairCheckRows.Add(GrdErrCode.Cell(0, i).Text, "1")
            Next

            '更新错误步骤表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairLogTable.TableName, $"{RepairLogTable.ColNames.TestPlan} = '{testPlan}' and {RepairLogTable.ColNames.FailSteps} = '{failStep}' order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd)
            GrdTestPlan.DataSource = dtTable
            GrdTestPlan.ExtendLastCol = True
            GrdTestPlan.DisplayRowNumber = True

            '更新SN的维修记录
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, RepairLogTable.TableName, $"{RepairLogTable.ColNames.DUT_SN} = '{sn}' order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd)
            GrdSnRepair.DataSource = dtTable
            GrdSnRepair.ExtendLastCol = True
            GrdSnRepair.DisplayRowNumber = True

            Dim tableName As String = TestLogTable.TableName(pid, sid)
            '更新当前站位所有测试记录表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, tableName, "id > 0 order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd, False)
            GrdAllRecord.DataSource = dtTable
            GrdAllRecord.ExtendLastCol = True
            GrdAllRecord.DisplayRowNumber = True

            '更新当前站位Pass测试记录表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, tableName, $"{TestLogTable.ColNames.TestResult} = 1 order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd, False)
            GrdPassRecord.DataSource = dtTable
            GrdPassRecord.ExtendLastCol = True
            GrdPassRecord.DisplayRowNumber = True

            '更新当前站位Fail测试记录表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, tableName, $"{TestLogTable.ColNames.TestResult} = 0 order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd, False)
            GrdFailRecord.DataSource = dtTable
            GrdFailRecord.ExtendLastCol = True
            GrdFailRecord.DisplayRowNumber = True

            '更新当前站位对应SN测试记录表
            cmd = db.CmdHelper.DbSearchAll(UtsDb.RemotePrivateDb, tableName, $"{TestLogTable.ColNames.DUT_SN} = '{sn}' order by id desc limit 100")
            dtTable = db.ExecuteDataTable(cmd, False)
            GrdSnRecord.DataSource = dtTable
            GrdSnRecord.ExtendLastCol = True
            GrdSnRecord.DisplayRowNumber = True

            testCheckRows.Clear()
            For i As Integer = 1 To GrdSnRecord.Cols - 1
                testCheckRows.Add(GrdSnRecord.Cell(0, i).Text, "1")
            Next

            db.Close()
        End Using
    End Sub

    Dim frm As FrmImage
    Dim watch As New Stopwatch

    Private Sub ShowImage(index As Integer)
        If ProductImgs(index).Image Is Nothing Then Return

        If frm Is Nothing OrElse frm.Visible = False Then
            frm = New FrmImage
            frm.Location = New Point(Location.X + (Width - frm.Width) \ 2, Location.Y + (Height - frm.Height) \ 2)
            frm.StartPosition = FormStartPosition.Manual
            frm.TopMost = True
            frm.PictureBox1.Image = ProductImgs(index).Image
            frm.Show()
        Else
            frm.PictureBox1.Image = ProductImgs(index).Image
        End If
    End Sub

    Private Sub 完整图像ToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles 完整图像ToolStripMenuItem.Click
        ShowImage(_imgIndex)
    End Sub


    Dim repairCheckRows As New Dictionary(Of String, String)
    Dim testCheckRows As New Dictionary(Of String, String)

    Private Sub BtnCheckTest_Click(sender As Object, e As EventArgs) Handles BtnCheckTest.Click
        Dim frm As New FrmCheckLog
        frm.CheckRows = testCheckRows
        If frm.ShowDialog() <> DialogResult.OK Then Return
        Dim rows As Dictionary(Of String, String) = frm.CheckRows

        For i As Integer = 0 To frm.CheckRows.Count - 1
            If frm.CheckRows.Values(i) = "1" Then
                GrdAllRecord.Column(i + 1).Visible = True
                GrdAllRecord.Column(i + 1).Visible = True
                GrdAllRecord.Column(i + 1).Visible = True
                GrdAllRecord.Column(i + 1).Visible = True
            Else
                GrdAllRecord.Column(i + 1).Visible = False
                GrdAllRecord.Column(i + 1).Visible = False
                GrdAllRecord.Column(i + 1).Visible = False
                GrdAllRecord.Column(i + 1).Visible = False
            End If
        Next
    End Sub

    Private Sub BtnCheckRepair_Click(sender As Object, e As EventArgs) Handles BtnCheckRepair.Click
        Dim frm As New FrmCheckLog
        frm.CheckRows = repairCheckRows
        If frm.ShowDialog() <> DialogResult.OK Then Return
        Dim rows As Dictionary(Of String, String) = frm.CheckRows

        For i As Integer = 0 To frm.CheckRows.Count - 1
            If frm.CheckRows.Values(i) = "1" Then
                GrdTestPlan.Column(i + 1).Visible = True
                GrdErrCode.Column(i + 1).Visible = True
                GrdSnRepair.Column(i + 1).Visible = True
            Else
                GrdTestPlan.Column(i + 1).Visible = False
                GrdErrCode.Column(i + 1).Visible = False
                GrdSnRepair.Column(i + 1).Visible = False
            End If
        Next
    End Sub

    Private Sub FrmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        ApplicationLog.WriteInfoLog($"{Application.ProductName} {Application.ProductVersion} 运行程序关闭中。")


        ApplicationLog.WriteInfoLog($"运行程序已关闭。")
    End Sub

    '鼠标移动至控件即出现预览图
    'Private Sub TsBtnImg0_MouseHover(sender As Object, e As EventArgs) Handles TsBtnImg0.MouseHover, TsBtnImg1.MouseHover, TsBtnImg2.MouseHover, TsBtnImg3.MouseHover
    '    Dim tsBtn As ToolStripButton = CType(sender, ToolStripButton)
    '    ShowImage(CInt(tsBtn.Tag))
    'End Sub


    'Private Sub SplitContainer1_MouseLeave(sender As Object, e As EventArgs) Handles TsBtnImg0.MouseLeave, TsBtnImg1.MouseLeave， TsBtnImg2.MouseLeave， TsBtnImg3.MouseLeave
    '    If frm.Visible Then frm.Visible = False

    '    Console.WriteLine("Hide Image!")
    'End Sub
#End Region


End Class
