Переглянути джерело

feat: 调整发货单选择合同的界面和逻辑

JaneDoe 3 місяців тому
батько
коміт
a5ed1fef41

+ 17 - 6
UniformMaterialManagementSystem/Entities/DeliveryReceipt.cs

@@ -24,12 +24,6 @@ namespace UniformMaterialManagementSystem.Entities
 
         public double ContractQty { get; set; } = 0!;
 
-        [NotMapped]
-        public double InspQty { get; set; }
-
-        [NotMapped]
-        public double RemainQty { get; set; }
-
         public DateTime ContractSigningDate { get; set; } = default!;
 
         public string ProductName { get; set; } = null!;
@@ -65,14 +59,31 @@ namespace UniformMaterialManagementSystem.Entities
 
         public byte[]? Licence { get; set; } = null!;
 
+        //[NotMapped]
+        //public double InspQty { get; set; }
+
+        [NotMapped]
+        public double RemainQty { get; set; }
+
         [NotMapped]
         public bool IsNewRow { get; set; } = true;
 
         [NotMapped]
         public bool IsReported { get; set; } = false;
 
+        [NotMapped]
+        public int WorkYear { get; set; }
+
         // 发货、接收和使用使用同一张表,明细也用同一张表,三个模块分别控制不同的必录项
         public ObservableCollection<DeliveryReceiptDetail> DeliveryReceiptDetails { get; set; } = [];
 
+        public DeliveryReceipt()
+        {
+            var loginUser = App.CurrentUser;
+            if(loginUser != null)
+            {
+                WorkYear = loginUser.WorkYear;
+            }
+        }
     }
 }

+ 2 - 0
UniformMaterialManagementSystem/Entities/DeliveryReceiptDetail.cs

@@ -25,6 +25,8 @@ namespace UniformMaterialManagementSystem.Entities
 
         public string? UseStatus { get; set; }
 
+        public string? ShipNote { get; set; }
+
         [NotMapped]
         public bool IsNewRow { get; set; } = true;
     }

+ 1217 - 0
UniformMaterialManagementSystem/Migrations/20240808074740_add_DeliReceDetail.Designer.cs

@@ -0,0 +1,1217 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using UniformMaterialManagementSystem.Data;
+
+#nullable disable
+
+namespace UniformMaterialManagementSystem.Migrations
+{
+    [DbContext(typeof(SqliteContext))]
+    [Migration("20240808074740_add_DeliReceDetail")]
+    partial class add_DeliReceDetail
+    {
+        /// <inheritdoc />
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder.HasAnnotation("ProductVersion", "7.0.20");
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Company", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Address")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Category")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Code")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Manager")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ShortName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("SystemCode")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("Companies");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Contract", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<byte[]>("ApplyAttachment")
+                        .HasColumnType("BLOB");
+
+                    b.Property<byte[]>("Attachment")
+                        .HasColumnType("BLOB");
+
+                    b.Property<bool>("ChangedStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<Guid>("CompanyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ContractNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("EditDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("EditUser")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("ExportStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<Guid>("PurchaseCompanyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("SigningDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Telephone")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("Year")
+                        .HasColumnType("INTEGER");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("CompanyGuid");
+
+                    b.HasIndex("PurchaseCompanyGuid");
+
+                    b.ToTable("Contracts");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.ContractDetail", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("ContractGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("ContractQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<DateTime>("DeliveryTime")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("InspectStatus")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("InspectedQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<Guid>("MaterialGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("ReduceQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<double>("ShippedQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<bool>("ShippedStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<double>("UnitPrice")
+                        .HasColumnType("REAL");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("ContractGuid");
+
+                    b.HasIndex("MaterialGuid");
+
+                    b.ToTable("ContractDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.DeliveryReceipt", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyNo")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("BatchNo")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("CompanyName")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("ContractGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ContractNo")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("ContractQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<DateTime>("ContractSigningDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<byte[]>("Licence")
+                        .HasColumnType("BLOB");
+
+                    b.Property<string>("ProductName")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("PurchaseCompanyName")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ReceivedCompanyName")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime?>("ReceivedDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ReceivedMan")
+                        .HasColumnType("TEXT");
+
+                    b.Property<int?>("ReceivedPackets")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<double?>("ReceivedQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("ReceivedStatus")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ReceivedTel")
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("ShippedDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ShippedMan")
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("ShippedPackets")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<double>("ShippedQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("ShippedTel")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("DeliveryReceipts");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.DeliveryReceiptDetail", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("DeliveryReceiptGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("PacketNo")
+                        .IsRequired()
+                        .HasColumnType("TEXT");
+
+                    b.Property<double?>("ReceiveQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("ShipNote")
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("ShippedQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<double?>("UseQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("UseStatus")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("DeliveryReceiptGuid");
+
+                    b.ToTable("DeliveryReceiptDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.FactoryLicense", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApproveUser")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("AuditUser")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Department")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("EditUser")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("FactoryDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("FactoryQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<Guid>("InspectApplyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("LicenseListNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("LicenseNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("SignDate")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("InspectApplyGuid");
+
+                    b.ToTable("FactoryLicenses");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApply", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyDescription")
+                        .HasMaxLength(1000)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime?>("ApplyReceiveDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyUser")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("BatchNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Company")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("CompanyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("EndProductDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("InspCategory")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("InspDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("InspQuantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<byte[]>("InspReport")
+                        .HasColumnType("BLOB");
+
+                    b.Property<string>("InspReportNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("LicenseStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<Guid>("MaterialGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ProductName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("ReportStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<bool>("SampleStatus")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<DateTime>("StartProductDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("Year")
+                        .HasColumnType("INTEGER");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("CompanyGuid");
+
+                    b.HasIndex("MaterialGuid");
+
+                    b.ToTable("InspectApplies");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApplyContractDetail", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("ApplyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("ContractDetailGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ContractNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("InspectQty")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("PurchaseCompany")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("PurchaseCompanyShortName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("SigningDate")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("UnInspectQty")
+                        .HasColumnType("REAL");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("ApplyGuid");
+
+                    b.ToTable("InspectApplyContractDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApplyDetail", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("ApplyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ApplyNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("PacketNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("Quantity")
+                        .HasColumnType("REAL");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("ApplyGuid");
+
+                    b.ToTable("InspectApplyDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionOrganization", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Address")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Contacts")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("OrderNo")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Telephone")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("InspectionOrganizations");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionReport", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Conclusion")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ConclusionDesc")
+                        .IsRequired()
+                        .HasMaxLength(1000)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Department")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("EditUser")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("InspectApplyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsSample")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("ReportBasis")
+                        .IsRequired()
+                        .HasMaxLength(200)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ReportDesc")
+                        .IsRequired()
+                        .HasMaxLength(1000)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ReportNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("ReportTime")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("InspectApplyGuid");
+
+                    b.ToTable("InspectionReports");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionReportDetail", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("InspectionReportGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Inspector")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("JobCategory")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("SupervisionUnit")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("InspectionReportGuid");
+
+                    b.ToTable("InspectionReportDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Material", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("CategoryCode")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("MeasureUnit")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("NormName")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Specification")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("VarietyCode")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("Materials");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.MenuItem", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Icon")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<bool>("IsVisible")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("OrderIndex")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<Guid?>("ParentGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Path")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("ParentGuid");
+
+                    b.ToTable("MenuItems");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Role", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Description")
+                        .IsRequired()
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("Roles");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.RoleMenuItem", b =>
+                {
+                    b.Property<Guid>("MenuItemGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("RoleGuid")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("MenuItemGuid", "RoleGuid");
+
+                    b.HasIndex("RoleGuid");
+
+                    b.ToTable("RoleMenuItems");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.SampleRegistration", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("BatchNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Department")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("EditTime")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("EditUser")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("InspectApplyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("InspectionOrganization")
+                        .IsRequired()
+                        .HasMaxLength(500)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("PacketNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("ProductDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ProductUsers")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<double>("Quantity")
+                        .HasColumnType("REAL");
+
+                    b.Property<string>("SampleNo")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("SingleIndexItem")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Telephone")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("TestingItem")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("InspectApplyGuid");
+
+                    b.ToTable("SampleRegistrations");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.SerialNumber", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("CompanyCode")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("CompanyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("InspCategory")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("MaxNumber")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("SupervisionUnitGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<int>("Year")
+                        .HasColumnType("INTEGER");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("SerialNumbers");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.SupervisionUnit", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Note")
+                        .HasMaxLength(100)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("ShortName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.ToTable("SupervisionUnits");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.User", b =>
+                {
+                    b.Property<Guid>("Guid")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid?>("CompanyGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("CompanyName")
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("IdNumber")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<bool>("IsEnabled")
+                        .HasColumnType("INTEGER");
+
+                    b.Property<string>("LoginName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Password")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<DateTime>("RegisterDate")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("Salt")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("SupervisionUnitGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<string>("UserName")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("Guid");
+
+                    b.HasIndex("CompanyGuid");
+
+                    b.HasIndex("SupervisionUnitGuid");
+
+                    b.ToTable("Users");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.UserRole", b =>
+                {
+                    b.Property<Guid>("RoleGuid")
+                        .HasColumnType("TEXT");
+
+                    b.Property<Guid>("UserGuid")
+                        .HasColumnType("TEXT");
+
+                    b.HasKey("RoleGuid", "UserGuid");
+
+                    b.HasIndex("UserGuid");
+
+                    b.ToTable("UserRoles");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Contract", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Company", "Company")
+                        .WithMany()
+                        .HasForeignKey("CompanyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Company", "PurchaseCompany")
+                        .WithMany()
+                        .HasForeignKey("PurchaseCompanyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("Company");
+
+                    b.Navigation("PurchaseCompany");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.ContractDetail", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Contract", "Contract")
+                        .WithMany("ContractDetails")
+                        .HasForeignKey("ContractGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Material", "Material")
+                        .WithMany()
+                        .HasForeignKey("MaterialGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("Contract");
+
+                    b.Navigation("Material");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.DeliveryReceiptDetail", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.DeliveryReceipt", null)
+                        .WithMany("DeliveryReceiptDetails")
+                        .HasForeignKey("DeliveryReceiptGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.FactoryLicense", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectApply", "InspectApply")
+                        .WithMany()
+                        .HasForeignKey("InspectApplyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectApply");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApply", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Company", "MaterialCompany")
+                        .WithMany()
+                        .HasForeignKey("CompanyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Material", "Material")
+                        .WithMany()
+                        .HasForeignKey("MaterialGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("Material");
+
+                    b.Navigation("MaterialCompany");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApplyContractDetail", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectApply", "InspectApply")
+                        .WithMany("InspectApplyContractDetails")
+                        .HasForeignKey("ApplyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectApply");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApplyDetail", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectApply", "InspectApply")
+                        .WithMany("InspectApplyDetails")
+                        .HasForeignKey("ApplyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectApply");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionReport", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectApply", "InspectApply")
+                        .WithMany()
+                        .HasForeignKey("InspectApplyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectApply");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionReportDetail", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectionReport", "InspectionReport")
+                        .WithMany("InspectionReportDetails")
+                        .HasForeignKey("InspectionReportGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectionReport");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.MenuItem", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.MenuItem", "Parent")
+                        .WithMany("Children")
+                        .HasForeignKey("ParentGuid")
+                        .OnDelete(DeleteBehavior.Restrict);
+
+                    b.Navigation("Parent");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.RoleMenuItem", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.MenuItem", "MenuItem")
+                        .WithMany("MenuRoles")
+                        .HasForeignKey("MenuItemGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Role", "Role")
+                        .WithMany("RoleMenus")
+                        .HasForeignKey("RoleGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("MenuItem");
+
+                    b.Navigation("Role");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.SampleRegistration", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.InspectApply", "InspectApply")
+                        .WithMany()
+                        .HasForeignKey("InspectApplyGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("InspectApply");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.User", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Company", "Company")
+                        .WithMany()
+                        .HasForeignKey("CompanyGuid");
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.SupervisionUnit", "SupervisionUnit")
+                        .WithMany()
+                        .HasForeignKey("SupervisionUnitGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("Company");
+
+                    b.Navigation("SupervisionUnit");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.UserRole", b =>
+                {
+                    b.HasOne("UniformMaterialManagementSystem.Entities.Role", "Role")
+                        .WithMany("UserRoles")
+                        .HasForeignKey("RoleGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.HasOne("UniformMaterialManagementSystem.Entities.User", "User")
+                        .WithMany("UserRoles")
+                        .HasForeignKey("UserGuid")
+                        .OnDelete(DeleteBehavior.Cascade)
+                        .IsRequired();
+
+                    b.Navigation("Role");
+
+                    b.Navigation("User");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Contract", b =>
+                {
+                    b.Navigation("ContractDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.DeliveryReceipt", b =>
+                {
+                    b.Navigation("DeliveryReceiptDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectApply", b =>
+                {
+                    b.Navigation("InspectApplyContractDetails");
+
+                    b.Navigation("InspectApplyDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.InspectionReport", b =>
+                {
+                    b.Navigation("InspectionReportDetails");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.MenuItem", b =>
+                {
+                    b.Navigation("Children");
+
+                    b.Navigation("MenuRoles");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.Role", b =>
+                {
+                    b.Navigation("RoleMenus");
+
+                    b.Navigation("UserRoles");
+                });
+
+            modelBuilder.Entity("UniformMaterialManagementSystem.Entities.User", b =>
+                {
+                    b.Navigation("UserRoles");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}

+ 28 - 0
UniformMaterialManagementSystem/Migrations/20240808074740_add_DeliReceDetail.cs

@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace UniformMaterialManagementSystem.Migrations
+{
+    /// <inheritdoc />
+    public partial class add_DeliReceDetail : Migration
+    {
+        /// <inheritdoc />
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.AddColumn<string>(
+                name: "ShipNote",
+                table: "DeliveryReceiptDetails",
+                type: "TEXT",
+                nullable: true);
+        }
+
+        /// <inheritdoc />
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropColumn(
+                name: "ShipNote",
+                table: "DeliveryReceiptDetails");
+        }
+    }
+}

+ 3 - 0
UniformMaterialManagementSystem/Migrations/SqliteContextModelSnapshot.cs

@@ -271,6 +271,9 @@ namespace UniformMaterialManagementSystem.Migrations
                     b.Property<double?>("ReceiveQuantity")
                         .HasColumnType("REAL");
 
+                    b.Property<string>("ShipNote")
+                        .HasColumnType("TEXT");
+
                     b.Property<double>("ShippedQuantity")
                         .HasColumnType("REAL");
 

+ 71 - 111
UniformMaterialManagementSystem/ViewModels/DeliveryReceiptViewModel.cs

@@ -20,6 +20,7 @@ using UniformMaterialManagementSystem.Entities;
 using UniformMaterialManagementSystem.Services;
 using UniformMaterialManagementSystem.Utils;
 using UniformMaterialManagementSystem.Views;
+using Material = UniformMaterialManagementSystem.Entities.Material;
 
 namespace UniformMaterialManagementSystem.ViewModels
 {
@@ -30,15 +31,6 @@ namespace UniformMaterialManagementSystem.ViewModels
         [ObservableProperty]
         private List<string> _inspectApplyNos = new List<string>();
 
-        //[ObservableProperty]
-        //private List<string> _companyNames = new List<string>();
-
-        //[ObservableProperty]
-        //private List<string> _productNames = new List<string>();
-
-        //[ObservableProperty]
-        //private ObservableCollection<InspectApplyContractDetail> _inspectApplyContracts = new ObservableCollection<InspectApplyContractDetail>();
-
         [ObservableProperty]
         private ObservableCollection<DeliveryReceipt> _deliveryReceipts = new ObservableCollection<DeliveryReceipt>();
 
@@ -48,17 +40,17 @@ namespace UniformMaterialManagementSystem.ViewModels
         [ObservableProperty]
         private DeliveryReceipt? _currDeliveryReceipt = null;
 
-        //[ObservableProperty]
-        //private double _inspQty = 0;
+        #endregion
 
-        //[ObservableProperty]
-        //private double _remainQty = 0;
+        private Contract _selectedContract = null!;
 
-        #endregion
+        private ContractDetail _selectedContractDetail = null!;
 
-        private InspectApply _selectedApply = null!;
+        private Material _selectedMaterial = null!;
 
-        private InspectApplyContractDetail _selectedContractDetail = null!;
+        //private InspectApply _selectedApply = null!;
+
+        private bool _isExcute = true;
 
         private IDataBaseService<DeliveryReceipt> _service;
 
@@ -66,90 +58,50 @@ namespace UniformMaterialManagementSystem.ViewModels
         {
             _service = service;
 
-            // 只获取发货数据,接收、使用数据不关心
+            // 只获取发货数据,不关心接收、使用数据
             // 已复核的发货单才允许录入使用数据,使用数据必录许可证。
             LoadData();
         }
 
-        //[RelayCommand]
-        //public void Query(AutoCompleteBox autoListBoxNo)
-        //{
-        //    //object[]? values = parameters as object[];
-        //    //if (values == null || values.Length != 2) { return; }
-        //    //AutoCompleteBox? autoListBoxNo = values[0] as AutoCompleteBox;
-        //    //AutoCompleteBox? autoListBoxMate = values[1] as AutoCompleteBox;
-        //    //if (autoListBoxNo == null || autoListBoxMate == null) { return; }
-
-        //    //// 根据 申请编号 和 材料名称 查询数据:为空获取全部数据
-        //    //string? applyNo = autoListBoxNo.Text;
-        //    //string? mateName = autoListBoxMate.Text;
-        //    //string predicate = string.Empty;
-        //    //if (!string.IsNullOrEmpty(applyNo))
-        //    //{
-        //    //    predicate = $"x => x.ApplyNo.Equals({applyNo})";
-        //    //}
-        //    //if(!string.IsNullOrEmpty(mateName))
-        //    //{
-        //    //    predicate = predicate.Length == 0 ? $"x => x.ApplyNo.Equals({applyNo})" : predicate + "and x => x.ApplyNo.Equals({applyNo})";
-        //    //}
-
-        //    // 根据选择的 检验申请编号 获取合同数据
-        //    if (autoListBoxNo == null) { return; }
-        //    //string? applyNo = autoListBoxNo.Text; // Text 属性更新不及时,SelectedItem更新及时
-        //    string? applyNo = autoListBoxNo.SelectedItem == null ? string.Empty : autoListBoxNo.SelectedItem.ToString();
-        //    IQueryable<InspectApplyContractDetail>? contracts = null;
-        //    if (!string.IsNullOrEmpty(applyNo))
-        //    {
-        //        // todo 会不会出现当前合同对应多个检验申请
-        //        contracts = App.Current.Services.GetService<IDataBaseService<InspectApplyContractDetail>>()?.Query(x => x.ApplyNo.Equals(applyNo)).OrderBy(x => x.ContractNo);
-        //    }
-        //    else
-        //    {
-        //        // 没有设置值则获取全部合同明细
-        //        contracts = App.Current.Services.GetService<IDataBaseService<InspectApplyContractDetail>>()?.Query().OrderBy(x => x.ContractNo);
-        //    }
-
-        //    if (contracts == null || !contracts.Any())
-        //    {
-        //        MessageBox.Show("获取合同数据失败!");
-        //        return;
-        //    }
-        //    InspectApplyContracts = new ObservableCollection<InspectApplyContractDetail>(contracts);
-        //}
-
-        // CallMethod 可以传递事件参数,但没办法屏蔽事件
+        // CallMethodAction 不需要注册命令,可以传递事件参数。参数列表必须与事件自带的参数列表保持一致
         public void DeliverySelectionChanged(object sender, SelectionChangedEventArgs args)
         {
+            // 手动屏蔽本事件
+            if (!_isExcute) { return; }
+
             DataGrid? fdgDelivery = sender as DataGrid;
             if (fdgDelivery == null) { return; }
 
+            // 暂时屏蔽行切换事件
+            _isExcute = false;
 
             // 离开行之前,判断当前行是否未保存
             if (args.RemovedItems.Count > 0)
             {
                 DeliveryReceipt? leavingDelivery = args.RemovedItems[0] as DeliveryReceipt;
                 if (leavingDelivery == null) { return; }
+                // 手动切换为切换前的行(为了主表编辑界面的值不切换)
+                fdgDelivery.SelectedItem = leavingDelivery;
+
+                // 判断当前行是否新增行或已修改
                 bool isChanged = IsChanged(leavingDelivery);
                 if (isChanged)
                 {
                     // 询问是否切换
                     MessageBoxResult res = MessageBox.Show("当前行已修改,切换行会丢失已修改的数据,是否确认切换行?", "询问", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
-                    // 不切换:需要重新赋值
+                    // 不切换:重新赋值为切换前的行
                     if (res != MessageBoxResult.Yes)
                     {
                         // 取消切换行:当前行不变
-                        fdgDelivery.SelectionChanged -= DeliverySelectionChanged;
-
-                        fdgDelivery.SelectedItem = leavingDelivery; // 值已经更新为切换后的行,所以需要重新赋值为旧行
+                        fdgDelivery.SelectedItem = leavingDelivery; // 重新赋值为旧行; CurrDeliveryReceipt 通过绑定自动更新
+                        fdgDelivery.Items.Refresh(); // 必须刷新界面
                         // 直接赋值会循环调用本事件,CurrDeliveryReceipt 双向绑定也会循环调用
-                        CurrDeliveryReceipt = leavingDelivery; // 值仍为旧行? CurrDeliveryReceipt 双向绑定?
 
-                        fdgDelivery.SelectionChanged += DeliverySelectionChanged;
-
-                        DeliveryDetails = leavingDelivery.DeliveryReceiptDetails; // 值仍为旧行明细
+                        // 取消屏蔽后返回
+                        _isExcute = true;
                         return;
                     }
-                    // 切换:继续执行,到 展示新行数据的部分
+                    // 切换:则展示新行数据
                 }
             }
 
@@ -158,10 +110,12 @@ namespace UniformMaterialManagementSystem.ViewModels
             {
                 DeliveryReceipt? newDelivery = args.AddedItems[0] as DeliveryReceipt;
                 if (newDelivery == null) { return; }
-                //fdgDelivery.SelectedItem = newDelivery; // 二者相等? 已经是 SelectionChanged,所以相等?
-                //CurrDeliveryReceipt = newDelivery; // 相等?
-                //DeliveryDetails = newDelivery.DeliveryReceiptDetails; // 相等?
+                fdgDelivery.SelectedItem = newDelivery; // 刚刚为了界面数据赋值,所以这里需要设置为切换后的行
+                //fdgDelivery.Items.Refresh(); // 不必刷新前台界面
             }
+
+            // 取消屏蔽行切换
+            _isExcute = true;
         }
 
         [RelayCommand]
@@ -177,41 +131,40 @@ namespace UniformMaterialManagementSystem.ViewModels
 
             // 若没有选择(取消 or 直接关闭对话框),则直接返回
             SelectApplyContractDialogViewModel? dialogVM = dialog.DataContext as SelectApplyContractDialogViewModel;
-            if (dialogVM?.SelectedApply == null || dialogVM.SelectedContract == null) { return; }
-            _selectedApply = dialogVM.SelectedApply;
-            _selectedContractDetail = dialogVM.SelectedContract;
+            if (dialogVM == null || dialogVM.SelectedContract == null || dialogVM.SelectedContractDetail == null || dialogVM.SelectedMaterial == null) { return; }
+            _selectedContract = dialogVM.SelectedContract;
+            _selectedContractDetail = dialogVM.SelectedContractDetail;
+            _selectedMaterial = dialogVM.SelectedMaterial;
 
             // 获取当前合同信息的已发运数量
-            string applyNo = _selectedApply.ApplyNo;
-            string contractNo = _selectedContractDetail.ContractNo;
-            double hasShippedQty = (double)DeliveryReceipts.Where(x => x.ApplyNo.Equals(applyNo) && x.ContractNo.Equals(contractNo)).Select(x => x.ShippedQty).Sum();
+            string contractNo = _selectedContract.ContractNo;
+            double hasShippedQty = (double)DeliveryReceipts.Where(x => x.ContractNo.Equals(contractNo)).Select(x => x.ShippedQty).Sum();
 
             // 新增发货单
             CurrDeliveryReceipt = new DeliveryReceipt();
             DeliveryReceipts.Add(CurrDeliveryReceipt);
-            // 检验申请编号
-            CurrDeliveryReceipt.ApplyNo = _selectedApply.ApplyNo;
-            // 产品名称
-            CurrDeliveryReceipt.ProductName = _selectedApply.ProductName;
-            // todo 只能选择当前生产企业的合同?
+
+            // 产品名称:选择的材料名称
+            CurrDeliveryReceipt.ProductName = _selectedMaterial.Name;
+            // todo 当前角色的生产企业:只有材料生产企业的用户有发货单的权限,成品企业是接收单和使用单
             // 生产企业
-            CurrDeliveryReceipt.CompanyName = _selectedApply.Company;
+            CurrDeliveryReceipt.CompanyName = App.CurrentUser!.CompanyName!;
             // 合同编号
             CurrDeliveryReceipt.ContractNo = contractNo;
             // 采购机构
-            CurrDeliveryReceipt.PurchaseCompanyName = _selectedContractDetail.PurchaseCompany;
-            // 合同数量
-            CurrDeliveryReceipt.ContractQty = _selectedContractDetail.InspectQty;
+            CurrDeliveryReceipt.PurchaseCompanyName = _selectedContract.PurchaseCompany.Name;
+            // 合同数量:明细的数量
+            CurrDeliveryReceipt.ContractQty = _selectedContractDetail.ContractQty;
             // 合同时间
-            CurrDeliveryReceipt.ContractSigningDate = Convert.ToDateTime(_selectedContractDetail.SigningDate);
-            // 检验合格数量:检验申请主表-报检数量
-            CurrDeliveryReceipt.InspQty = _selectedApply.InspQuantity;
+            CurrDeliveryReceipt.ContractSigningDate = _selectedContract.SigningDate.Date;
+            // 检验合格数量:检验申请主表-报检数量 todo 不用显示
+            //CurrDeliveryReceipt.InspQty = inspApply.InspQuantity;
             // 可发运数量:检验申请主表-报检数量 - 已发运数量
-            CurrDeliveryReceipt.RemainQty = CurrDeliveryReceipt.InspQty - hasShippedQty;
+            //CurrDeliveryReceipt.RemainQty = CurrDeliveryReceipt.InspQty - hasShippedQty;
             // 接收单位:等于合同-采购机构
-            CurrDeliveryReceipt.ReceivedCompanyName = _selectedContractDetail.PurchaseCompany;
-            // 批次号
-            CurrDeliveryReceipt.BatchNo = _selectedApply.BatchNo;
+            CurrDeliveryReceipt.ReceivedCompanyName = _selectedContract.PurchaseCompany.Name;
+            // 批次号:根据上传的 Excel
+            //CurrDeliveryReceipt.BatchNo = inspApply.BatchNo;
             // 发运时间:默认当前日期
             CurrDeliveryReceipt.ShippedDate = DateTime.Now.Date;
             // 发运承办人:默认当前用户的姓名
@@ -226,10 +179,6 @@ namespace UniformMaterialManagementSystem.ViewModels
         [RelayCommand]
         public void DeleteDelivery(DataGrid fdgDelivery)
         {
-            var selected = fdgDelivery.SelectedItem;
-            var curr = CurrDeliveryReceipt;
-            var details = DeliveryDetails;
-
             // 没有选中行直接删除
             if (CurrDeliveryReceipt == null)
             {
@@ -247,8 +196,10 @@ namespace UniformMaterialManagementSystem.ViewModels
             // 新增行直接删除
             if (CurrDeliveryReceipt.IsNewRow)
             {
+                // todo 直接删除会切换行
+                _isExcute = false;
                 DeliveryReceipts.Remove(CurrDeliveryReceipt);
-                CurrDeliveryReceipt = null;
+                //CurrDeliveryReceipt = null;
                 return;
             }
 
@@ -286,6 +237,13 @@ namespace UniformMaterialManagementSystem.ViewModels
             if (CurrDeliveryReceipt == null) { return; }
             if (CurrDeliveryReceipt.IsReported) { return; }
 
+            // 判断必录项
+            if (CurrDeliveryReceipt.BatchNo == null || string.IsNullOrEmpty(CurrDeliveryReceipt.BatchNo))
+            {
+                MessageBox.Show("请上传发货明细后保存");
+                return;
+            }
+
             // todo 清空日期选择框,但 发运日期 并不会清空
             // 检查发运时间是否已录入
             if (CurrDeliveryReceipt.ShippedDate == null)
@@ -353,6 +311,8 @@ namespace UniformMaterialManagementSystem.ViewModels
             }
         }
 
+        // todo 子表发运数据列变化后实时更新发运数量的值
+        // todo 新增和删除行的时候 / 行切换的时候,自动汇总发运包数的值
         [RelayCommand]
         public void DetailSelectionChanged()
         {
@@ -605,22 +565,22 @@ namespace UniformMaterialManagementSystem.ViewModels
             foreach (var delivery in DeliveryReceipts)
             {
                 // 检验合格数量:检验申请主表-报检数量
-                string applyNo = delivery.ApplyNo;
-                InspectApply? apply = App.Current.Services.GetService<IDataBaseService<InspectApply>>()?.Query(x => x.ApplyNo.Equals(applyNo)).FirstOrDefault();
-                if (apply == null) { continue; }
-                delivery.InspQty = apply.InspQuantity;
+                //string applyNo = delivery.ApplyNo;
+                //InspectApply? apply = App.Current.Services.GetService<IDataBaseService<InspectApply>>()?.Query(x => x.ApplyNo.Equals(applyNo)).FirstOrDefault();
+                //if (apply == null) { continue; }
+                //delivery.InspQty = apply.InspQuantity;
 
                 // 可发运数量:检验申请主表-报检数量 - 已发运数量
-                string contractNo = delivery.ContractNo;
-                double hasShippedQty = (double)DeliveryReceipts.Where(x => x.ApplyNo.Equals(applyNo) && x.ContractNo.Equals(contractNo)).Select(x => x.ShippedQty).Sum();
-                delivery.RemainQty = delivery.InspQty - hasShippedQty;
+                //string contractNo = delivery.ContractNo;
+                //double hasShippedQty = (double)DeliveryReceipts.Where(x => x.ApplyNo.Equals(applyNo) && x.ContractNo.Equals(contractNo)).Select(x => x.ShippedQty).Sum();
+                //delivery.RemainQty = delivery.InspQty - hasShippedQty;
 
                 // 是否为新行:否
                 delivery.IsNewRow = false;
 
                 // 子表明细行
                 var details = delivery.DeliveryReceiptDetails.OrderBy(x => x.PacketNo).ToArray();
-                foreach(var dtl in details)
+                foreach (var dtl in details)
                 {
                     dtl.IsNewRow = false;
                 }

+ 242 - 53
UniformMaterialManagementSystem/ViewModels/SelectApplyContractDialogViewModel.cs

@@ -1,110 +1,276 @@
 using System;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
+using System.Diagnostics.Contracts;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows;
 using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Media;
 using CommunityToolkit.Mvvm.ComponentModel;
 using CommunityToolkit.Mvvm.Input;
 using Microsoft.EntityFrameworkCore;
 using Microsoft.Extensions.DependencyInjection;
+using UniformMaterialManagementSystem.Custom;
 using UniformMaterialManagementSystem.Entities;
 using UniformMaterialManagementSystem.Services;
+using Contract = UniformMaterialManagementSystem.Entities.Contract;
 
 namespace UniformMaterialManagementSystem.ViewModels
 {
     public partial class SelectApplyContractDialogViewModel : ObservableObject
     {
+        #region 数据绑定字段
 
+        [ObservableProperty]
+        private List<string> _materialNames = new List<string>();
+
+        [ObservableProperty]
+        private string _selectedMaterialName = string.Empty;
+
+        [ObservableProperty]
+        private ObservableCollection<Material> _materials = new ObservableCollection<Material>();
 
         [ObservableProperty]
-        private ObservableCollection<InspectApply> _inspectApplies = new ObservableCollection<InspectApply>();
+        private Material? _selectedMaterial;
 
         [ObservableProperty]
-        private ObservableCollection<InspectApplyContractDetail> _inspectApplyContracts = new ObservableCollection<InspectApplyContractDetail>();
+        private ObservableCollection<Contract> _contracts = new ObservableCollection<Contract>();
 
-        public delegate void GetRetuenData(InspectApply inspectApply, InspectApplyContractDetail inspectApplyContractDetail);
-        public GetRetuenData getRetuenData = null!;
+        [ObservableProperty]
+        private ObservableCollection<ContractDetail> _contractDetails = new ObservableCollection<ContractDetail>();
 
+        [ObservableProperty]
+        private Contract? _selectedContract;
 
-        internal InspectApply? SelectedApply = null;
+        [ObservableProperty]
+        private ContractDetail? _selectedContractDetail;
 
-        internal InspectApplyContractDetail? SelectedContract = null;
+        #endregion
 
         public SelectApplyContractDialogViewModel()
         {
-            // 获取检验申请编号数据源
-            var inspectApplies = App.Current.Services.GetService<IDataBaseService<InspectApply>>()?.Query().Include(x => x.InspectApplyContractDetails);
-            if (inspectApplies == null || !inspectApplies.Any())
+            // 获取产品名称数据源
+            var materials = App.Current.Services.GetService<IDataBaseService<Material>>()?.Query(x => x.IsEnabled);
+            if (materials != null && materials.Any())
             {
-                MessageBox.Show("获取检验申请数据失败!");
-                return;
+                MaterialNames = materials.Select(x => x.Name).ToList();
+                Materials = new ObservableCollection<Material>(materials);
+            }
+            else
+            {
+                MessageBox.Show("获取产品名称失败!");
             }
-            InspectApplies = new ObservableCollection<InspectApply>(inspectApplies);
-
         }
 
         [RelayCommand]
-        public void Loaded(DataGrid fdgContract)
+        public void Loaded(DataGrid fdgContractDetail)
         {
             // todo 当窗口 SizeChanged 重新计算列宽
             // todo 没有减去 FilterDataGrid 右侧竖向条的宽度,暂时不研究
+            // 看下 fdg 的 VisualTree,能找到就找,找不到就删掉 ScrolView?
             // 根据当前窗口的宽度计算列宽
-            //double actualWidth = fdgContract.ActualWidth;
-            //double colWidth = actualWidth / 6;
-            //foreach (var col in fdgContract.Columns)
+            double fdgWidth0 = fdgContractDetail.Width; // NaN
+            double fdgWidth = fdgContractDetail.ActualWidth; // 1424
+            double rowHeaderWidth1 = fdgContractDetail.RowHeaderWidth; // 30
+            double rowHeaderWidth2 = fdgContractDetail.RowHeaderActualWidth; // 30
+            double avgColWidth0 = -1;
+            ScrollViewer? scrollViewer = FindVisualChild<ScrollViewer>(fdgContractDetail);
+            if (scrollViewer != null)
+            {
+                double width0 = scrollViewer.Width; // NaN
+                double width1 = scrollViewer.ActualWidth; // 1422
+                //double width2 = scrollViewer.ViewportWidth; // 1407 // SizeChanged 后 ViewportWidth 比 ActualWidth 少了22,ViewportWidth 更小了
+                //double width1 = scrollViewer.ScrollInfo.ActualWidth; // 访问限制
+
+                var scrollBar0 = FindVisualChild<ScrollBar>(fdgContractDetail); // null
+                var scrollBar = FindVisualChild<ScrollBar>(scrollViewer); // 能获取到
+
+                double barWidth0 = scrollBar.ActualWidth; // 0
+                double barWidth1 = scrollBar.Width; // 17
+
+                double colsWidth = fdgWidth - rowHeaderWidth1 - barWidth1; // 1377
+                //double colsWidth0 = width1 - rowHeaderWidth1; // col 会宽一点点,所以必须计算Bar的Width
+                avgColWidth0 = colsWidth / 9; // 153
+            }
+
+
+            foreach (var col in fdgContractDetail.Columns)
+            {
+                if (col.Header.Equals("材料名称"))
+                {
+                    col.Width = 2 * avgColWidth0;
+                }
+                else
+                {
+                    col.Width = avgColWidth0;
+                }
+            }
+        }
+
+
+        [RelayCommand]
+        public void DialogSizeChanged(DataGrid fdgContractDetail)
+        {
+            // todo 如果 width 小于 700,返回。设置了 MinWidth 后列标题不会被遮挡,但窗口依然可以变窄
+            // 如果太窄,列标题被盖住,即使拉宽了也不显示列标题了
+            // todo 下午来了换个问题写,然后整理下笔记,明天再研究
+
+            double fdgWidth0 = fdgContractDetail.Width; // NaN
+            double fdgWidth = fdgContractDetail.ActualWidth; // 1424
+            double rowHeaderWidth1 = fdgContractDetail.RowHeaderWidth; // 30
+            double rowHeaderWidth2 = fdgContractDetail.RowHeaderActualWidth; // 30
+            double avgColWidth0 = -1;
+            ScrollViewer? scrollViewer = FindVisualChild<ScrollViewer>(fdgContractDetail);
+            if (scrollViewer != null)
+            {
+                double width0 = scrollViewer.Width; // NaN
+                double width1 = scrollViewer.ActualWidth; // 1422
+                double width2 = scrollViewer.ViewportWidth; // 1407
+
+                var scrollBar0 = FindVisualChild<ScrollBar>(fdgContractDetail); // null
+                var scrollBar = FindVisualChild<ScrollBar>(scrollViewer); // 能获取到
+
+                double barWidth0 = scrollBar.ActualWidth; // 0
+                double barWidth1 = scrollBar.Width; // 17
+
+                double colsWidth = fdgWidth - rowHeaderWidth1 - barWidth1; // 1377
+                double colsWidth0 = width1 - rowHeaderWidth1;
+                avgColWidth0 = colsWidth / 9; // 153
+            }
+
+
+            foreach (var col in fdgContractDetail.Columns)
+            {
+                if (col.Header.Equals("材料名称"))
+                {
+                    col.Width = 2 * avgColWidth0;
+                }
+                else
+                {
+                    col.Width = avgColWidth0;
+                }
+            }
+        }
+
+        [RelayCommand]
+        public void Query(AutoCompleteBox autoListBoxMate)
+        {
+            if (autoListBoxMate == null) { return; }
+
+            // 清空已选择的合同
+            SelectedContract = null;
+            SelectedContractDetail = null;
+
+            // 编辑 autoCompleteBox 的显示文本,不会修改 SelectedItem,用选择项即可
+            if (SelectedMaterial == null)
+            {
+                MessageBox.Show("请先选择材料!");
+                return;
+            }
+
+            //if (SelectedMaterialName == null || string.IsNullOrEmpty(SelectedMaterialName))
             //{
-            //    if (col.Header.Equals("采购机构"))
-            //    {
-            //        col.Width = 2 * colWidth;
-            //    }
-            //    else
-            //    {
-            //        col.Width = colWidth;
-            //    }
+            //    MessageBox.Show("请先选择材料!");
+            //    return;
             //}
+            //string? materialName = autoListBoxMate.Text; // Text 属性更新不及时,SelectedItem更新及时
+            //string? materialName = autoListBoxMate.SelectedItem.ToString();
+
+            // 获取全部合同数据
+            List<Contract>? mateContracts = new List<Contract>();
+
+            // todo 根据当前角色,筛选全部 / 当前生产企业的合同
+            var contracts = App.Current.Services.GetService<IDataBaseService<Contract>>()?.Query().Include(x => x.Company).Include(x => x.PurchaseCompany).Include(x => x.ContractDetails);
+            if (contracts == null || !contracts.Any())
+            {
+                MessageBox.Show("获取合同数据失败!");
+                return;
+            }
+
+            foreach (var contract in contracts)
+            {
+                var details = contract.ContractDetails;
+                var count = details.Where(x => x.MaterialGuid.Equals(SelectedMaterial.Guid)).Count();
+                if (count > 0)
+                {
+                    mateContracts.Add(contract);
+                    continue;
+                }
+            }
+
+            // 获取所有的合同明细
+            var contractDetails = App.Current.Services.GetService<IDataBaseService<ContractDetail>>()?.Query().Include(x => x.Material).Include(x => x.Contract);
+            if (contractDetails == null || !contractDetails.Any())
+            {
+                MessageBox.Show("获取合同数据失败!");
+                return;
+            }
+
+            // 根据选择的 产品名称 获取合同数据
+            foreach (var detail in contractDetails)
+            {
+                // todo 明细表 Material 字段为空,怎么 Include ?
+                if (detail.Material.Name.Equals(SelectedMaterialName))
+                {
+                    mateContracts.Add(detail.Contract);
+                }
+            }
+
+            if (mateContracts.Count == 0)
+            {
+                MessageBox.Show("该材料没有对应的合同数据!");
+                return;
+            }
+            Contracts = new ObservableCollection<Contract>(mateContracts);
         }
 
         [RelayCommand]
-        public void ApplySelectionChanged(DataGrid fdgApply)
+        public void SelectionChanged()
         {
-            // 获取当前行的合同信息
-            InspectApply? currApply = fdgApply.SelectedItem as InspectApply;
-            if (currApply == null) { return; }
-
-            InspectApplyContracts.Clear();
-            // !不能直接赋值,否则清空后会把 currApply 的明细也清空
-            //InspectApplyContracts = currApply.InspectApplyContractDetails; 
-            InspectApplyContracts = new ObservableCollection<InspectApplyContractDetail>(currApply.InspectApplyContractDetails);
+            if (SelectedMaterial == null) { return; }
+            if (SelectedContract == null) { return; }
+
+            // 筛选合同明细
+            var details = App.Current.Services.GetService<IDataBaseService<ContractDetail>>()?.Query(x => x.ContractGuid.Equals(SelectedContract.Guid) && x.MaterialGuid.Equals(SelectedMaterial.Guid));
+            if (details == null)
+            {
+                MessageBox.Show("获取合同明细失败");
+                return;
+            }
+            ContractDetails = new ObservableCollection<ContractDetail>(details);
         }
 
         [RelayCommand]
-        public void Confirm(object parameters)
+        public void Confirm(Window window)
         {
-            // 获取控件
-            object[]? values = parameters as object[];
-            if (values == null || values.Length != 3) { return; }
-            DataGrid? fdgApply = values[0] as DataGrid;
-            DataGrid? fdgContract = values[1] as DataGrid;
-            Window? window = values[2] as Window;
-            if (fdgApply == null || fdgContract == null || window == null) { return; }
-
-            // 检查是否勾选且只勾选一行
-            var selectedApply = fdgApply.SelectedItem as InspectApply;
-            var selectedContract = fdgContract.SelectedItem as InspectApplyContractDetail;
-            if (selectedApply == null || selectedContract == null)
-            {
-                MessageBox.Show("请选择一条检验申请和一条合同信息!");
+            // 不需要传递控件,因为有字段绑定
+
+            // 检查是否勾选行
+            if (SelectedContract == null)
+            {
+                MessageBox.Show("请选择合同!");
                 return;
             }
 
-            // 传递参数到父窗体
-            //getRetuenData(selectedApply, selectedContract);
-            this.SelectedApply = selectedApply;
-            this.SelectedContract = selectedContract;
+            // 如果选择了合同主表且子表只有一行明细,自动勾选明细
+            if (SelectedContractDetail == null)
+            {
+                if (ContractDetails.Count == 1)
+                {
+                    SelectedContractDetail = ContractDetails[0];
+                }
+                else
+                {
+                    MessageBox.Show("请选择合同明细!");
+                    return;
+                }
+            }
 
+            // 传递参数到父窗体:通过字段
+            // 关闭选择窗口
             window.Close();
         }
 
@@ -113,5 +279,28 @@ namespace UniformMaterialManagementSystem.ViewModels
         {
             window.Close();
         }
+
+        /// <summary>
+        /// 获取 VisualTree 指定类型的子元素
+        /// </summary>
+        private T? FindVisualChild<T>(DependencyObject obj) where T : DependencyObject // Visual 继承自 DependencyObject
+        {
+            T? child = default(T);
+            int num = VisualTreeHelper.GetChildrenCount(obj);
+            for (int i = 0; i < num; i++)
+            {
+                DependencyObject dObj = VisualTreeHelper.GetChild(obj, i);
+                child = dObj as T;
+                if (child != null)
+                {
+                    break;
+                }
+                else
+                {
+                    child = FindVisualChild<T>(dObj);
+                }
+            }
+            return child;
+        }
     }
 }

+ 51 - 47
UniformMaterialManagementSystem/Views/DeliveryReceiptControl.xaml

@@ -83,16 +83,16 @@
 
         <!-- 行标题样式 -->
         <Style x:Key="CustomRowHeaderStyle" TargetType="DataGridRowHeader">
-            <!-- 模板里面放 Label 控件,文本内容绑定 DataGridRow 的标题(行号) -->
+            <!-- 通过 Template 设置行号、居中、边框 -->
             <Setter Property="Template">
                 <Setter.Value>
                     <ControlTemplate TargetType="DataGridRowHeader">
-                        <!-- 宽度跟行高相同 -->
+                        <!-- 在这里设置 Width 会受到 DataGrid.RowHeaderWidth 的限制,显示不全 -->
                         <Label Width="30"
                                Background="White"
                                BorderBrush="Black"
                                BorderThickness="0 0 1 1"
-                               Content="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
+                               Content="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=DataGridRow}}"
                                HorizontalContentAlignment="Center" />
                     </ControlTemplate>
                 </Setter.Value>
@@ -153,7 +153,7 @@
             <Setter Property="VerticalAlignment" Value="Center" />
             <Setter Property="TextAlignment" Value="Center" />
         </Style>
-        
+
         <!-- 文本列编辑状态居左 -->
         <Style x:Key="TextColumnEditingStyle" TargetType="TextBox">
             <Setter Property="HorizontalContentAlignment" Value="Left" />
@@ -246,7 +246,7 @@
                         Tag="{x:Static utils:RegularFontUtil.Save_32}"
                         Template="{StaticResource CustomToolBarButtomTemplate}"
                         Command="{Binding SaveCommand}" />
-                
+
                 <!--<WrapPanel Orientation="Horizontal">
                     <StackPanel Orientation="Horizontal">
                         <TextBlock Text="检验申请编号:" 
@@ -282,10 +282,9 @@
             </ToolBar>
         </Border>
 
-        <!-- 发货单主表:主表不允许编辑,只能选择一行后编辑信息 -->
-        <!-- todo 控件的高度为空,不能这么绑定:
-                  MaxHeight="{Binding Path=Width,ElementName=dataGridDeliveryDetail}"
-              行标题:RowHeaderStyle="{StaticResource CustomRowHeaderStyle}" -->
+        <!-- 发货单主表:主表不允许编辑,只能选择一行后在下方编辑界面编辑 -->
+        <!-- 正常显示行标题:ShowRowsCount="True" 
+                            RowHeaderWidth="30"-->
         <fdg:FilterDataGrid x:Name="fdgDelivery"
                             Grid.Row="1" 
                             Grid.Column="0"
@@ -294,10 +293,12 @@
                             Background="White"
                             AutoGenerateColumns="False"
                             CanUserAddRows="False"
-                            behavoirs:DataGridBehavior.RowNumbers="True"
+                            CanUserResizeRows="False"
                             SelectionMode="Single"
                             SelectionUnit="FullRow"
                             HeadersVisibility="All"
+                            ShowRowsCount="True"
+                            RowHeaderWidth="30"
                             ColumnHeaderStyle="{StaticResource CustomColumnHeaderStyle}"
                             RowHeaderStyle="{StaticResource CustomRowHeaderStyle}"
                             RowStyle="{StaticResource CustomRowStyle}"
@@ -311,26 +312,21 @@
             <b:Interaction.Triggers>
                 <!-- 选择行切换事件 -->
                 <b:EventTrigger EventName="SelectionChanged">
-                    <!-- 绑定命令 -->
-                    <!--<b:InvokeCommandAction Command="{Binding DeliverySelectionChangedCommand}"
-                                           CommandParameter="{Binding ElementName=fdgDelivery}" />-->
-
                     <!-- 调用方法:传递事件参数 -->
-                    <!-- TargetObject="{Binding }" 表示目标对象是当前的数据上下文,事件被触发时调用数据上下文的指定方法;指定的方法不需要绑定命令,参数必须与事件的参数一致 -->
-                    <!--<b:CallMethodAction TargetObject="{Binding }" 
-                                        MethodName="DeliverySelectionChanged" />-->
+                    <!-- TargetObject="{Binding }" 表示目标对象是当前的数据上下文 -->
+                    <b:CallMethodAction TargetObject="{Binding }" 
+                                        MethodName="DeliverySelectionChanged" />
 
                 </b:EventTrigger>
             </b:Interaction.Triggers>
 
             <!-- todo 为什么只能设置为绝对宽度,比例宽度列标题不显示? -->
-            <!-- todo 检查下数据库字段,添加检验申请和合同编号字段等 -->
             <!-- 数据结构 -->
             <fdg:FilterDataGrid.Columns>
-                <fdg:FilterDataGridTextColumn Header="检验申请编号" Width="300"
+                <!--<fdg:FilterDataGridTextColumn Header="检验申请编号" Width="300"
                                               IsColumnFiltered="True"
                                               ElementStyle="{StaticResource TextColumnElementStyle}"
-                                              Binding="{Binding ApplyNo}" />
+                                              Binding="{Binding ApplyNo}" />-->
                 <fdg:FilterDataGridTextColumn Header="合同编号" Width="200"
                                               IsColumnFiltered="True"
                                               ElementStyle="{StaticResource TextColumnElementStyle}"
@@ -481,11 +477,10 @@
                             <Label Content="{Binding CurrDeliveryReceipt.ContractSigningDate, StringFormat='yyyy:MM:dd'}"
                                    Style="{StaticResource CustomLabelStyle}" />
                         </StackPanel>
-                        <!-- 检验合格数量、剩余数量 -->
-                        <StackPanel Orientation="Horizontal">
+                        <!-- 检验合格数量、剩余数量:非保存列 -->
+                        <!--<StackPanel Orientation="Horizontal">
                             <TextBlock Text="检验合格数量:"
                                        Style="{StaticResource CustomTextBlockStyle}" />
-                            <!-- 非保存列;重复设置 Width、TextAligment 属性,直接设置的值覆盖 Style 的值 -->
                             <TextBlock Text="{Binding CurrDeliveryReceipt.InspQty}" 
                                        Width="50"
                                        Foreground="Red"
@@ -498,7 +493,7 @@
                                        Foreground="Red"
                                        TextAlignment="Left"
                                        Style="{StaticResource CustomTextBlockStyle}" />
-                        </StackPanel>
+                        </StackPanel>-->
 
                     </WrapPanel>
                 </Grid>
@@ -609,7 +604,7 @@
                         Tag="{x:Static utils:RegularFontUtil.Delete_32}"
                         Template="{StaticResource CustomToolBarButtomTemplate}"
                         Command="{Binding DeleteDetailCommand}"
-                        CommandParameter="{Binding ElementName=dataGridDeliveryDetail}" />
+                        CommandParameter="{Binding ElementName=fdgDeliveryDetail}" />
                 <Separator />
                 <!-- Arrow_Turn_Right_48 -->
                 <Button Content="导入"
@@ -624,20 +619,25 @@
         </Border>
 
         <!-- todo 没有行的时候左边不显示行标题,必须有行之后才会出现行标题,列宽会变化 -->
-        <!-- todo 底部显示合计行?不用筛选,排序即可 -->
-        <fdg:FilterDataGrid x:Name="dataGridDeliveryDetail"
-                  Grid.Row="4" 
-                  Grid.Column="1" 
-                  Background="White"
-                  AutoGenerateColumns="False"
-                  CanUserAddRows="False"
-                  SelectionMode="Single"
-                  SelectionUnit="FullRow"
-                  ColumnHeaderStyle="{StaticResource CustomColumnHeaderStyle}"
-                  RowHeaderStyle="{StaticResource CustomRowHeaderStyle}"
-                  RowStyle="{StaticResource CustomRowStyle}"
-                  CellStyle="{StaticResource CustomCellStyle}"
-                  ItemsSource="{Binding CurrDeliveryReceipt.DeliveryReceiptDetails, Mode=TwoWay}">
+        <!-- todo 当按比例设置标题宽度时,单元格的竖向边框会部分消失 -->
+        <fdg:FilterDataGrid x:Name="fdgDeliveryDetail"
+                            Grid.Row="4" 
+                            Grid.Column="1" 
+                            Background="White"
+                            AutoGenerateColumns="False"
+                            CanUserAddRows="False"
+                            CanUserResizeRows="False"
+                            SelectionMode="Single"
+                            SelectionUnit="FullRow"
+                            HeadersVisibility="All"
+                            GridLinesVisibility="All"
+                            ShowRowsCount="True"
+                            RowHeaderWidth="30"
+                            ColumnHeaderStyle="{StaticResource CustomColumnHeaderStyle}"
+                            RowHeaderStyle="{StaticResource CustomRowHeaderStyle}"
+                            RowStyle="{StaticResource CustomRowStyle}"
+                            CellStyle="{StaticResource CustomCellStyle}"
+                            ItemsSource="{Binding CurrDeliveryReceipt.DeliveryReceiptDetails, Mode=TwoWay}">
 
             <!-- DataGrid 事件 -->
             <b:Interaction.Triggers>
@@ -647,21 +647,25 @@
                 </b:EventTrigger>
 
             </b:Interaction.Triggers>
-            
+
             <!-- 数据结构 -->
             <fdg:FilterDataGrid.Columns>
                 <!--<DataGridTextColumn Header="序号" Width="*" />-->
-                <fdg:FilterDataGridCheckBoxColumn Header="  " Width="50"
+                <fdg:FilterDataGridCheckBoxColumn Header="  " Width="30"
                                                   ElementStyle="{StaticResource CheckBoxColumnElementStyle}"
                                                   EditingElementStyle="{StaticResource CheckBoxColumnElementStyle}" />
                 <fdg:FilterDataGridTextColumn Header="材料包号" Width="*"
-                                    ElementStyle="{StaticResource TextColumnElementStyle}"
-                                    EditingElementStyle="{StaticResource TextColumnEditingStyle}"
-                                    Binding="{Binding PacketNo, UpdateSourceTrigger=PropertyChanged}" />
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              EditingElementStyle="{StaticResource TextColumnEditingStyle}"
+                                              Binding="{Binding PacketNo, UpdateSourceTrigger=PropertyChanged}" />
                 <fdg:FilterDataGridTextColumn Header="发运数量" Width="*"
-                                    ElementStyle="{StaticResource TextColumnElementStyle}"
-                                    EditingElementStyle="{StaticResource TextColumnEditingStyle}"
-                                    Binding="{Binding ShippedQuantity, UpdateSourceTrigger=PropertyChanged}" />
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              EditingElementStyle="{StaticResource TextColumnEditingStyle}"
+                                              Binding="{Binding ShippedQuantity, UpdateSourceTrigger=PropertyChanged}" />
+                <fdg:FilterDataGridTextColumn Header="备注" Width="*"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              EditingElementStyle="{StaticResource TextColumnEditingStyle}"
+                                              Binding="{Binding ShipNote, UpdateSourceTrigger=PropertyChanged}" />
             </fdg:FilterDataGrid.Columns>
         </fdg:FilterDataGrid>
     </Grid>

+ 1 - 96
UniformMaterialManagementSystem/Views/DeliveryReceiptControl.xaml.cs

@@ -33,12 +33,8 @@ namespace UniformMaterialManagementSystem.Views
             this.DataContext = App.Current.Services.GetService<DeliveryReceiptViewModel>();
 
             // 注册控件事件
-            // this.dataGridApply.LoadingRow += DataGrid_LoadingRow;
-            // this.dataGridContract.LoadingRow += DataGrid_LoadingRow;
             this.fdgDelivery.LoadingRow += DataGrid_LoadingRow;
-            this.dataGridDeliveryDetail.LoadingRow += DataGrid_LoadingRow;
-
-            this.fdgDelivery.SelectionChanged += fdgDelivery_SelectionChanged;
+            this.fdgDeliveryDetail.LoadingRow += DataGrid_LoadingRow;
         }
 
         private void DataGrid_LoadingRow(object? sender, DataGridRowEventArgs e)
@@ -46,96 +42,5 @@ namespace UniformMaterialManagementSystem.Views
             // 设置行标题:行索引+1
             e.Row.Header = e.Row.GetIndex() + 1;
         }
-
-        private void fdgDelivery_SelectionChanged(object sender, SelectionChangedEventArgs e)
-        {
-            DataGrid? fdgDelivery = sender as DataGrid;
-            if (fdgDelivery == null) { return; }
-
-            // 暂时屏蔽行切换事件
-            fdgDelivery.SelectionChanged -= fdgDelivery_SelectionChanged;
-
-            // 离开行之前,判断当前行是否未保存
-            if (e.RemovedItems.Count > 0)
-            {
-                DeliveryReceipt? leavingDelivery = e.RemovedItems[0] as DeliveryReceipt;
-                if (leavingDelivery == null) { return; }
-                // 手动切换为切换前的行(为了主表详情界面的值不切换)
-                fdgDelivery.SelectedItem = leavingDelivery;
-
-                // 判断当前行是否已修改
-                bool isChanged = IsChanged(leavingDelivery);
-                if (isChanged)
-                {
-                    // 询问是否切换
-                    MessageBoxResult res = MessageBox.Show("当前行已修改,切换行会丢失已修改的数据,是否确认切换行?", "询问", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
-                    // 不切换:需要重新赋值
-                    if (res != MessageBoxResult.Yes)
-                    {
-                        // 取消切换行:当前行不变
-                        fdgDelivery.SelectedItem = leavingDelivery; // 需要重新赋值为旧行;CurrDeliveryReceipt 通过绑定自动更新
-                        fdgDelivery.Items.Refresh(); // 必须刷新界面
-
-                        fdgDelivery.SelectionChanged += fdgDelivery_SelectionChanged;
-                        return;
-                    }
-                    // 切换:继续执行,到 展示新行数据的部分
-                }
-            }
-
-            // 进入新的行时,界面展示新行数据
-            if (e.AddedItems.Count > 0)
-            {
-                DeliveryReceipt? newDelivery = e.AddedItems[0] as DeliveryReceipt;
-                if (newDelivery == null) { return; }
-                fdgDelivery.SelectedItem = newDelivery ?? null; // 手动切换为null,所以需要重新赋值
-                                                                //fdgDelivery.Items.Refresh(); // 不取消切换不用刷新?
-
-                // 根据当前行设置子表明细
-                this.dataGridDeliveryDetail.ItemsSource = newDelivery.DeliveryReceiptDetails;
-            }
-
-            
-
-            // 重新响应事件
-            fdgDelivery.SelectionChanged += fdgDelivery_SelectionChanged;
-        }
-        /// <summary>
-        /// 判断行是否已修改
-        /// </summary>
-        private bool IsChanged(DeliveryReceipt deliveryReceipt)
-        {
-            // 新增行直接返回 true
-            if (deliveryReceipt.IsNewRow)
-            {
-                return true;
-            }
-
-            // 已保存的行检查数据库状态
-            var state = App.Current.Services.GetService<IDataBaseService<DeliveryReceipt>>()?.Entry(deliveryReceipt);
-            if (state != EntityState.Unchanged)
-            {
-                return true;
-            }
-
-            // 检查子表行
-            foreach (var detail in deliveryReceipt.DeliveryReceiptDetails)
-            {
-                if (detail.IsNewRow)
-                {
-                    return true;
-                }
-
-                var detailState = App.Current.Services.GetService<IDataBaseService<DeliveryReceiptDetail>>()?.Entry(detail);
-                if (detailState != EntityState.Unchanged)
-                {
-                    return true;
-                }
-
-                // todo 如果子表删除了几行是什么情况?
-            }
-
-            return false;
-        }
     }
 }

+ 158 - 54
UniformMaterialManagementSystem/Views/SelectApplyContractDialog.xaml

@@ -9,6 +9,7 @@
              xmlns:behavoirs="clr-namespace:UniformMaterialManagementSystem.Behaviors"
              xmlns:converters="clr-namespace:UniformMaterialManagementSystem.Converters"
              xmlns:fdg="http://FilterDataGrid.Control.com/2024"
+             xmlns:custom="clr-namespace:UniformMaterialManagementSystem.Custom"
              mc:Ignorable="d" 
              d:DesignHeight="450" d:DesignWidth="800">
 
@@ -89,10 +90,10 @@
                     <ControlTemplate TargetType="DataGridRowHeader">
                         <!-- 宽度跟行高相同 -->
                         <Label Width="30"
-                        Background="White"
-                        BorderBrush="Black"
-                        BorderThickness="0 0 1 1"
-                        Content="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
+                               Background="White"
+                               BorderBrush="Black"
+                               BorderThickness="0 0 1 1"
+                               Content="{Binding Path=Header, RelativeSource={RelativeSource AncestorType=DataGridRow}}" 
                         HorizontalContentAlignment="Center" />
                     </ControlTemplate>
                 </Setter.Value>
@@ -158,12 +159,21 @@
             <Setter Property="HorizontalAlignment" Value="Center" />
             <Setter Property="VerticalAlignment" Value="Center" />
         </Style>
+        
+        <!-- TextBlock 样式 -->
+        <Style x:Key="CustomTextBlockStyle" TargetType="TextBlock">
+            <Setter Property="Width" Value="auto" />
+            <Setter Property="FontSize" Value="14" />
+            <Setter Property="VerticalAlignment" Value="Center" />
+            <Setter Property="TextAlignment" Value="Right" />
+            <Setter Property="Margin" Value="3 0 3 0" />
+        </Style>
 
         <!-- 转换器 -->
         <converters:MultiParamConverter x:Key="MultiParamConverter" />
     </UserControl.Resources>
-
-    <Grid>
+    
+    <Grid MinWidth="700">
         <Grid.RowDefinitions>
             <RowDefinition Height="auto" />
             <RowDefinition Height="*" />
@@ -171,36 +181,64 @@
             <RowDefinition Height="*" />
         </Grid.RowDefinitions>
 
+        <!-- 当前弹出窗口大小变化事件 -->
+        <b:Interaction.Triggers>
+            <b:EventTrigger EventName="SizeChanged">
+                <b:InvokeCommandAction Command="{Binding DialogSizeChangedCommand}"
+                                       CommandParameter="{Binding ElementName=fdgContractDetail}" />
+            </b:EventTrigger>
+        </b:Interaction.Triggers>
+
         <!-- 工具栏 -->
         <Border Grid.Row="0"
                 BorderBrush="Gray"
                 BorderThickness="1">
             <ToolBar Background="White"
                      ToolBarTray.IsLocked="True">
+                <StackPanel Orientation="Horizontal">
+                    <TextBlock Text="产品名称:" 
+                               Style="{StaticResource CustomTextBlockStyle}"  />
+                    <custom:AutoCompleteBox x:Name="autoListBoxMate"
+                                            Background="White"
+                                            Width="300"
+                                            FontSize="14"
+                                            Margin="0 3 0 3"
+                                            ItemsSource="{Binding Materials}"
+                                            DisplayMemberPath="Name"
+                                            SelectedItem="{Binding SelectedMaterial, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
+                </StackPanel>
+                <Button Content="查询"
+                        Margin="5 0 5 0"
+                        Tag="{x:Static utils:RegularFontUtil.Search_32}"
+                        Template="{StaticResource CustomToolBarButtomTemplate}"
+                        Command="{Binding QueryCommand}"
+                        CommandParameter="{Binding ElementName=autoListBoxMate}">
+                </Button>
+                <Separator />
                 <Button Content="确认选择"
                         Tag="{x:Static utils:RegularFontUtil.Checkmark_32}"
                         Template="{StaticResource CustomToolBarButtomTemplate}"
-                        Command="{Binding ConfirmCommand}">
-                    <Button.CommandParameter>
+                        Command="{Binding ConfirmCommand}"
+                        CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
+                    <!--<Button.CommandParameter>
                         <MultiBinding Converter="{StaticResource MultiParamConverter}">
-                            <Binding ElementName="fdgApply" />
-                            <Binding ElementName="fdgContract" />
+                            <Binding ElementName="autoListBoxMate" />
                             <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}" />
                         </MultiBinding>
-                    </Button.CommandParameter>
+                    </Button.CommandParameter>-->
                 </Button>
                 <Button Content="取消"
                         Tag="{x:Static utils:RegularFontUtil.Dismiss_32}"
                         Template="{StaticResource CustomToolBarButtomTemplate}"
                         Command="{Binding CancelCommand}"
-                        CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
+                        CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" />
 
             </ToolBar>
         </Border>
 
         <!-- todo 不显示行号 -->
         <!-- 检验申请列表 -->
-        <fdg:FilterDataGrid x:Name="fdgApply"
+        <!--<fdg:FilterDataGrid x:Name="fdgApply"
                             Grid.Row="1"
                             FilterLanguage="SimplifiedChinese"
                             Background="White"
@@ -217,16 +255,13 @@
                             IsReadOnly="True"
                             ItemsSource="{Binding InspectApplies, Mode=TwoWay}">
 
-            <!-- DataGrid 事件 -->
             <b:Interaction.Triggers>
-                <!-- 选择行切换事件 -->
                 <b:EventTrigger EventName="SelectionChanged">
                     <b:InvokeCommandAction Command="{Binding ApplySelectionChangedCommand}"
                                            CommandParameter="{Binding ElementName=fdgApply}" />
                 </b:EventTrigger>
             </b:Interaction.Triggers>
 
-            <!-- 数据结构 -->
             <fdg:FilterDataGrid.Columns>
                 <fdg:FilterDataGridTextColumn Header="检验申请编号" Width="300"
                                               IsColumnFiltered="True"
@@ -279,21 +314,83 @@
                 <fdg:FilterDataGridTextColumn Header="申请检验准备情况说明" Width="300"
                                                IsColumnFiltered="True"
                                     Binding="{Binding ApplyDescription}">
-                    <!-- 文本默认不换行,但多行文本依然会自动加宽行高,设置行样式之后行高固定 -->
-                    <!--<DataGridTextColumn.ElementStyle>
-                        <Style>
-                            <Setter Property="TextBlock.TextWrapping" Value="NoWrap" />
-                        </Style>
-                    </DataGridTextColumn.ElementStyle>-->
                 </fdg:FilterDataGridTextColumn>
             </fdg:FilterDataGrid.Columns>
-        </fdg:FilterDataGrid>
+        </fdg:FilterDataGrid>-->
+        
+        <!-- 合同 -->
+        <fdg:FilterDataGrid x:Name="fdgContract"
+                            Grid.Row="1"
+                            FilterLanguage="SimplifiedChinese"
+                            Background="White"
+                            AutoGenerateColumns="False"
+                            CanUserAddRows="False"
+                            behavoirs:DataGridBehavior.RowNumbers="True"
+                            SelectionMode="Single"
+                            SelectionUnit="FullRow"
+                            HeadersVisibility="All"
+                            ShowRowsCount="True"
+                            RowHeaderWidth="30"
+                            ColumnHeaderStyle="{StaticResource CustomColumnHeaderStyle}"
+                            RowHeaderStyle="{StaticResource CustomRowHeaderStyle}"
+                            RowStyle="{StaticResource CustomRowStyle}"
+                            CellStyle="{StaticResource CustomCellStyle}"
+                            IsReadOnly="True"
+                            ItemsSource="{Binding Contracts, Mode=TwoWay}"
+                            SelectedItem="{Binding SelectedContract, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
+
+            <!-- DataGrid 事件 -->
+            <b:Interaction.Triggers>
+                <!-- 行切换事件 -->
+                <b:EventTrigger EventName="SelectionChanged">
+                    <b:InvokeCommandAction Command="{Binding SelectionChangedCommand}"
+                                           CommandParameter="{Binding ElementName=fdgContract}" />
+                </b:EventTrigger>
+            </b:Interaction.Triggers>
 
+            <!-- todo 手动设置列宽? -->
+            <!-- 数据结构 -->
+            <fdg:FilterDataGrid.Columns>
+                <fdg:FilterDataGridTextColumn Header="材料企业名称" Width="300"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding Company.Name}" />
+                <fdg:FilterDataGridTextColumn Header="成品企业名称" Width="300"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding PurchaseCompany.Name}" />
+                <fdg:FilterDataGridTextColumn Header="合同编号" Width="200"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding ContractNo}" />
+                <fdg:FilterDataGridTextColumn Header="合同签订时间" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding SigningDate, StringFormat='yyyy/MM/dd'}" />
+                <fdg:FilterDataGridTextColumn Header="填报人" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding EditUser}" />
+                <fdg:FilterDataGridTextColumn Header="填报时间" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding EditDate, StringFormat='yyyy/MM/dd'}" />
+                <fdg:FilterDataGridTextColumn Header="联系电话" Width="200"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding Telephone}" />
+                <fdg:FilterDataGridCheckBoxColumn Header="导出状态" Width="100"
+                                                  IsColumnFiltered="True"
+                                                  ElementStyle="{StaticResource CheckBoxColumnElementStyle}"
+                                                  Binding="{Binding ExportStatus}"/>
+            </fdg:FilterDataGrid.Columns>
+        </fdg:FilterDataGrid>
+        
         <!-- 水平拖动分割线 -->
         <GridSplitter Grid.Row="2" Height="5"  HorizontalAlignment="Stretch" />
 
         <!-- 合同明细 -->
-        <fdg:FilterDataGrid x:Name="fdgContract"
+        <fdg:FilterDataGrid x:Name="fdgContractDetail"
                             Grid.Row="3"
                             FilterLanguage="SimplifiedChinese"
                             Background="White"
@@ -303,52 +400,59 @@
                             SelectionMode="Single"
                             SelectionUnit="FullRow"
                             HeadersVisibility="All"
+                            ShowRowsCount="True"
+                            RowHeaderWidth="30"
                             ColumnHeaderStyle="{StaticResource CustomColumnHeaderStyle}"
                             RowHeaderStyle="{StaticResource CustomRowHeaderStyle}"
                             RowStyle="{StaticResource CustomRowStyle}"
                             CellStyle="{StaticResource CustomCellStyle}"
                             IsReadOnly="True"
-                            ItemsSource="{Binding InspectApplyContracts, Mode=TwoWay}">
+                            ItemsSource="{Binding ContractDetails, Mode=TwoWay}"
+                            SelectedItem="{Binding SelectedContractDetail, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
 
             <!-- DataGrid 事件 -->
             <b:Interaction.Triggers>
                 <!-- 加载事件:设置列宽 -->
                 <b:EventTrigger EventName="Loaded">
                     <b:InvokeCommandAction Command="{Binding LoadedCommand}"
-                                           CommandParameter="{Binding ElementName=fdgContract}" />
+                                           CommandParameter="{Binding ElementName=fdgContractDetail}" />
                 </b:EventTrigger>
-
-                <!-- 选择行切换事件 -->
-                <!--<b:EventTrigger EventName="SelectionChanged">
-                    <b:InvokeCommandAction Command="{Binding ContractSelectionChangedCommand}"
-                                           CommandParameter="{Binding ElementName=fdgContract}" />
-                </b:EventTrigger>-->
             </b:Interaction.Triggers>
 
-            <!-- todo 手动设置列宽? -->
             <!-- 数据结构 -->
             <fdg:FilterDataGrid.Columns>
-                <fdg:FilterDataGridTextColumn Header="合同编号" Width="200"
-                                                  IsColumnFiltered="True"
-                                                  ElementStyle="{StaticResource TextColumnElementStyle}"
-                                                  Binding="{Binding ContractNo}" />
-                <fdg:FilterDataGridTextColumn Header="采购机构" Width="200"
-                                                  IsColumnFiltered="True"
-                                                  ElementStyle="{StaticResource TextColumnElementStyle}"
-                                                  Binding="{Binding PurchaseCompany}" />
-                <!-- todo 是 string 类型的列? -->
-                <fdg:FilterDataGridTextColumn Header="合同签订时间" Width="200"
-                                                  IsColumnFiltered="True"
-                                                  ElementStyle="{StaticResource TextColumnElementStyle}"
-                                                  Binding="{Binding SigningDate, StringFormat='yyyy/MM/dd'}" />
-                <fdg:FilterDataGridTextColumn Header="合同数量" Width="200"
-                                                  IsColumnFiltered="True"
-                                                  ElementStyle="{StaticResource TextColumnElementStyle}"
-                                                  Binding="{Binding InspectQty}" />
-                <fdg:FilterDataGridTextColumn Header="可报检数量" Width="200"
-                                                  IsColumnFiltered="True"
-                                                  ElementStyle="{StaticResource TextColumnElementStyle}"
-                                                  Binding="{Binding UnInspectQty}" />
+                <fdg:FilterDataGridTextColumn Header="材料名称" Width="300"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding Material.Name}" />
+                <fdg:FilterDataGridTextColumn Header="成交数量" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding ContractQty}" />
+                <fdg:FilterDataGridTextColumn Header="计量单位" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding Material.MeasureUnit}" />
+                <fdg:FilterDataGridTextColumn Header="发货时间" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding DeliveryTime, StringFormat='yyyy/MM/dd'}" />
+                <fdg:FilterDataGridTextColumn Header="单价" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding UnitPrice}" />
+                <fdg:FilterDataGridTextColumn Header="已报检数量" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding InspectedQty}" />
+                <fdg:FilterDataGridTextColumn Header="已发货数量" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding ShippedQuantity}" />
+                <fdg:FilterDataGridTextColumn Header="报检状态" Width="100"
+                                              IsColumnFiltered="True"
+                                              ElementStyle="{StaticResource TextColumnElementStyle}"
+                                              Binding="{Binding InspectStatus}"/>
             </fdg:FilterDataGrid.Columns>
         </fdg:FilterDataGrid>
     </Grid>

+ 9 - 0
UniformMaterialManagementSystem/Views/SelectApplyContractDialog.xaml.cs

@@ -28,6 +28,15 @@ namespace UniformMaterialManagementSystem.Views
 
             // 绑定 ViewModel 
             this.DataContext = App.Current.Services.GetService<SelectApplyContractDialogViewModel>();
+            
+            // 注册控件事件
+            this.fdgContract.LoadingRow += DataGrid_LoadingRow;
+        }
+
+        private void DataGrid_LoadingRow(object? sender, DataGridRowEventArgs e)
+        {
+            // 设置行号
+            e.Row.Header = e.Row.GetIndex() + 1;
         }
     }
 }