private async void PART_Stepper_ContinueNavigation(object sender, MaterialDesignExtensions.Controls.StepperNavigationEventArgs args)
        {
            int idx = 0;

            for (; idx < PART_Stepper.Controller.Steps.Length; ++idx)
            {
                if (args.CurrentStep == PART_Stepper.Controller.Steps[idx])
                {
                    break;      // 确定现在在哪个Step
                }
            }
            if (idx == 0)
            {
                // 发送申请
                ApplicationMaterialListViewModel selected = (ApplicationMaterialListViewModel)MaterialSelectListBox.SelectedItem;
                if (selected == null)
                {
                    MainWindow.SetSnackBarContentAndPopup("请选择要申请的物资");
                    args.Cancel = true;
                    return;
                }
                else if (QuantityInputBox.Value == null || QuantityInputBox.Value <= 0)
                {
                    MainWindow.SetSnackBarContentAndPopup("不合法的数目");
                    args.Cancel = true;
                    return;
                }
                else if (QuantityInputBox.Value > selected.Constraint)
                {
                    MainWindow.SetSnackBarContentAndPopup("超出数量限制");
                    args.Cancel = true;
                    return;
                }

                NewApplicationResponse response = await NetworkHelper.GetAsync(new NewApplicationRequest()
                {
                    MaterialId = selected.OriginItem.Id,
                    Quantity   = (int)QuantityInputBox.Value,
                    Address    = UserInfo.HomeAddress
                }).Progress(ParentWindow.PART_ProgressBar);

                ApplicationViewModel       = new ApplicationListViewModel(response.Item);
                ApplicationDetailViewModel = new ApplicationDetailViewModel(await NetworkHelper.GetAsync(new GetApplicationDetailRequest()
                {
                    ApplicationId = ApplicationViewModel.OriginalItem.ID
                }).Progress(ParentWindow.PART_ProgressBar));
                RefreshApplicationCardView();
            }
            else if (idx == 3)
            {
                // 确认
                await NetworkHelper.GetAsync(new ConfirmApplicationDoneRequest()
                {
                    ApplicationId = ApplicationViewModel.OriginalItem.ID
                });
            }
        }
        public NewApplicationResponse HandleNewApplicationRequest(NewApplicationRequest request)
        {
            // 指定SQL语句
            SqlCommand com = new SqlCommand(
                $"select MaterialId, MaterialName, MaterialQuantity " +
                $"from Materials " +
                $"where MaterialId={request.MaterialId}"
                , Connect.Connection);
            // 建立SqlDataAdapter和DataSet对象
            SqlDataAdapter dataAdapter = new SqlDataAdapter(com);
            DataSet        dataSet     = new DataSet();

            int n = dataAdapter.Fill(dataSet, "Materials");
            NewApplicationResponse ret;

            if (n != 0 && request.Quantity <= (int)dataSet.Tables[0].Rows[0]["MaterialQuantity"])
            {
                string materialName = dataSet.Tables[0].Rows[0]["MaterialName"].ToString();
                try
                {
                    SqlTransaction transaction = Connect.Connection.BeginTransaction();

                    com = new SqlCommand(
                        $"update Materials " +
                        $"set MaterialQuantity = MaterialQuantity - {request.Quantity} " +
                        $"where MaterialId={request.MaterialId}"
                        , Connect.Connection, transaction);

                    com.ExecuteNonQuery();

                    DateTime now = DateTime.Now;

                    com.CommandText = $"INSERT INTO Tranc (UserId, Address, MaterialId, MaterialQuantity, TransactionState, TransactionType, StartTime, AdminId) " +
                                      $"OUTPUT INSERTED.TransactionId values ({UserId}, '{request.Address}', {request.MaterialId}, {request.Quantity}, " +
                                      $"{(int)ApplicationState.Applying}, {(int)TransactionType.APPLICATION}, '{now}', -1)";

                    // https://stackoverflow.com/questions/18373461/execute-insert-command-and-return-inserted-id-in-sql
                    int modified = Convert.ToInt32(com.ExecuteScalar());

                    ret = new NewApplicationResponse()
                    {
                        Item = new GetApplicationListResponse.Item()
                        {
                            ID        = modified,
                            Name      = materialName,
                            Quantity  = request.Quantity,
                            State     = ApplicationState.Applying,
                            StartTime = now
                        }
                    };

                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    if (com.Transaction != null)
                    {
                        com.Transaction.Rollback();
                    }
                    throw ex;
                }
            }
            else
            {
                Console.WriteLine($"DEBUG: no enough material for {request.MaterialId} or material doesn't exist");
                ret = new NewApplicationResponse()
                {
                    Item = null
                };
            }

            return(ret);
        }