ソースを参照

添加项目文件。

luowen 4 年 前
コミット
a32c4a8fd9
100 ファイル変更7735 行追加0 行削除
  1. 55 0
      StaffPerformance.sln
  2. 3 0
      package-lock.json
  3. 12 0
      winForm.sp.wispro/App.config
  4. 22 0
      winForm.sp.wispro/Program.cs
  5. 36 0
      winForm.sp.wispro/Properties/AssemblyInfo.cs
  6. 63 0
      winForm.sp.wispro/Properties/Resources.Designer.cs
  7. 117 0
      winForm.sp.wispro/Properties/Resources.resx
  8. 26 0
      winForm.sp.wispro/Properties/Settings.Designer.cs
  9. 7 0
      winForm.sp.wispro/Properties/Settings.settings
  10. 65 0
      winForm.sp.wispro/frmExcelViewer.Designer.cs
  11. 49 0
      winForm.sp.wispro/frmExcelViewer.cs
  12. 120 0
      winForm.sp.wispro/frmExcelViewer.resx
  13. 88 0
      winForm.sp.wispro/frmMain.Designer.cs
  14. 90 0
      winForm.sp.wispro/frmMain.cs
  15. 120 0
      winForm.sp.wispro/frmMain.resx
  16. 156 0
      winForm.sp.wispro/frmMerageExcel.Designer.cs
  17. 74 0
      winForm.sp.wispro/frmMerageExcel.cs
  18. 120 0
      winForm.sp.wispro/frmMerageExcel.resx
  19. 4 0
      winForm.sp.wispro/packages.config
  20. 119 0
      winForm.sp.wispro/wispro.sp.winform.csproj
  21. 118 0
      wispro.sp.api/Controllers/AccountController.cs
  22. 156 0
      wispro.sp.api/Controllers/PerformanceItemController.cs
  23. 135 0
      wispro.sp.api/Controllers/StaffController.cs
  24. 72 0
      wispro.sp.api/Controllers/StaffGradeController.cs
  25. 35 0
      wispro.sp.api/Controllers/VerifyCoefficientController.cs
  26. 655 0
      wispro.sp.api/Migrations/20210910105657_spDB0910.Designer.cs
  27. 305 0
      wispro.sp.api/Migrations/20210910105657_spDB0910.cs
  28. 653 0
      wispro.sp.api/Migrations/spDbContextModelSnapshot.cs
  29. 67 0
      wispro.sp.api/Program.cs
  30. 30 0
      wispro.sp.api/Properties/launchSettings.json
  31. 100 0
      wispro.sp.api/Startup.cs
  32. 9 0
      wispro.sp.api/appsettings.Development.json
  33. 23 0
      wispro.sp.api/appsettings.json
  34. 350 0
      wispro.sp.api/spDbContext.cs
  35. 27 0
      wispro.sp.api/wispro.sp.api.csproj
  36. 24 0
      wispro.sp.data/ItemStaffMap.cs
  37. 18 0
      wispro.sp.data/PerformanceItemMap.cs
  38. 21 0
      wispro.sp.data/StaffGradeMap.cs
  39. 17 0
      wispro.sp.data/StaffMap.cs
  40. 28 0
      wispro.sp.data/VerifyCoeffientMap.cs
  41. 20 0
      wispro.sp.data/wispro.sp.datamap.csproj
  42. 15 0
      wispro.sp.share/ApiSaveResponse.cs
  43. 16 0
      wispro.sp.share/ListApiResponse.cs
  44. 22 0
      wispro.sp.share/QueryFilter.cs
  45. 18 0
      wispro.sp.share/webViewObject/loginDto.cs
  46. 18 0
      wispro.sp.share/webViewObject/userToken.cs
  47. 12 0
      wispro.sp.share/wispro.sp.share.csproj
  48. 504 0
      wispro.sp.utility/ExcelHelper.cs
  49. 346 0
      wispro.sp.utility/NPOIExcle.cs
  50. 12 0
      wispro.sp.utility/wispro.sp.utility.csproj
  51. 12 0
      wispro.sp.web/App.razor
  52. 63 0
      wispro.sp.web/Auth/JwtAuthenticationStateProvider.cs
  53. 101 0
      wispro.sp.web/AuthProvider.cs
  54. 9 0
      wispro.sp.web/Components/EditableLinkGroup.razor
  55. 21 0
      wispro.sp.web/Components/EditableLinkGroup.razor.cs
  56. 20 0
      wispro.sp.web/Components/EditableLinkGroup.razor.css
  57. 57 0
      wispro.sp.web/Components/PerformanceItemDescriptionItem.razor
  58. 80 0
      wispro.sp.web/Components/PerformanceItemDescriptionItem.razor.cs
  59. 71 0
      wispro.sp.web/Components/Radar.razor
  60. 52 0
      wispro.sp.web/Components/Radar.razor.css
  61. 52 0
      wispro.sp.web/Components/RightContent.razor
  62. 119 0
      wispro.sp.web/Components/RightContent.razor.cs
  63. 47 0
      wispro.sp.web/Components/UserGradeSelect.razor
  64. 49 0
      wispro.sp.web/Extensions/DateTimeExtension.cs
  65. 240 0
      wispro.sp.web/Layouts/BasicLayout.razor
  66. 20 0
      wispro.sp.web/Layouts/LoginLayout.razor
  67. 37 0
      wispro.sp.web/Layouts/LoginLayout.razor.cs
  68. 14 0
      wispro.sp.web/Models/ActivitiesType.cs
  69. 8 0
      wispro.sp.web/Models/ActivityGroup.cs
  70. 8 0
      wispro.sp.web/Models/ActivityProject.cs
  71. 8 0
      wispro.sp.web/Models/ActivityUser.cs
  72. 12 0
      wispro.sp.web/Models/AdvancedOperation.cs
  73. 9 0
      wispro.sp.web/Models/AdvancedProfileData.cs
  74. 12 0
      wispro.sp.web/Models/BasicGood.cs
  75. 8 0
      wispro.sp.web/Models/BasicProfileDataType.cs
  76. 12 0
      wispro.sp.web/Models/BasicProgress.cs
  77. 16 0
      wispro.sp.web/Models/ChartData.cs
  78. 8 0
      wispro.sp.web/Models/ChartDataItem.cs
  79. 45 0
      wispro.sp.web/Models/CurrentUser.cs
  80. 48 0
      wispro.sp.web/Models/FormModel.cs
  81. 17 0
      wispro.sp.web/Models/ListFormModel.cs
  82. 42 0
      wispro.sp.web/Models/ListItemDataType.cs
  83. 19 0
      wispro.sp.web/Models/LoginParamsType.cs
  84. 11 0
      wispro.sp.web/Models/NoticeItem.cs
  85. 19 0
      wispro.sp.web/Models/NoticeType.cs
  86. 9 0
      wispro.sp.web/Models/OfflineChartDataItem.cs
  87. 8 0
      wispro.sp.web/Models/OfflineDataItem.cs
  88. 85 0
      wispro.sp.web/Models/ProjectInfo.cs
  89. 9 0
      wispro.sp.web/Models/RadarDataItem.cs
  90. 11 0
      wispro.sp.web/Models/SearchDataItem.cs
  91. 105 0
      wispro.sp.web/Pages/CustomerList.razor
  92. 332 0
      wispro.sp.web/Pages/CustomerList.razor.cs
  93. 5 0
      wispro.sp.web/Pages/ItemHandler/PerformanceItemList.razor
  94. 12 0
      wispro.sp.web/Pages/ItemHandler/PerformanceItemList.razor.cs
  95. 62 0
      wispro.sp.web/Pages/LoginPages.razor
  96. 60 0
      wispro.sp.web/Pages/LoginPages.razor.cs
  97. 147 0
      wispro.sp.web/Pages/PerformanceList.razor
  98. 230 0
      wispro.sp.web/Pages/PerformanceList.razor.cs
  99. 122 0
      wispro.sp.web/Pages/Project/AssignPoint.razor
  100. 0 0
      wispro.sp.web/Pages/Project/AssignPoint.razor.cs

+ 55 - 0
StaffPerformance.sln

@@ -0,0 +1,55 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.31624.102
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.api", "wispro.sp.api\wispro.sp.api.csproj", "{86964765-C850-48E8-B11F-1AD8B74E0BAE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.winClient", "wispro.sp.winClient\wispro.sp.winClient.csproj", "{18A48BC9-D464-4FF2-8281-FE8E6C9F3DDE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.entity", "wospro.sp.entity\wispro.sp.entity.csproj", "{30097917-88C1-4070-ABD1-FBB60CE2771E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.utility", "wispro.sp.utility\wispro.sp.utility.csproj", "{2D297FAD-B8BD-407E-9A72-90B3F4768C48}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.share", "wispro.sp.share\wispro.sp.share.csproj", "{E4C01740-6419-4078-BEFB-2A563CBB9417}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "wispro.sp.web", "wispro.sp.web\wispro.sp.web.csproj", "{237D9F7B-801E-440F-BA1A-3B5F8468C14F}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{86964765-C850-48E8-B11F-1AD8B74E0BAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{86964765-C850-48E8-B11F-1AD8B74E0BAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{86964765-C850-48E8-B11F-1AD8B74E0BAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{86964765-C850-48E8-B11F-1AD8B74E0BAE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{18A48BC9-D464-4FF2-8281-FE8E6C9F3DDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{18A48BC9-D464-4FF2-8281-FE8E6C9F3DDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{18A48BC9-D464-4FF2-8281-FE8E6C9F3DDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{18A48BC9-D464-4FF2-8281-FE8E6C9F3DDE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{30097917-88C1-4070-ABD1-FBB60CE2771E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{30097917-88C1-4070-ABD1-FBB60CE2771E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{30097917-88C1-4070-ABD1-FBB60CE2771E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{30097917-88C1-4070-ABD1-FBB60CE2771E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2D297FAD-B8BD-407E-9A72-90B3F4768C48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2D297FAD-B8BD-407E-9A72-90B3F4768C48}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2D297FAD-B8BD-407E-9A72-90B3F4768C48}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2D297FAD-B8BD-407E-9A72-90B3F4768C48}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E4C01740-6419-4078-BEFB-2A563CBB9417}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E4C01740-6419-4078-BEFB-2A563CBB9417}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E4C01740-6419-4078-BEFB-2A563CBB9417}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E4C01740-6419-4078-BEFB-2A563CBB9417}.Release|Any CPU.Build.0 = Release|Any CPU
+		{237D9F7B-801E-440F-BA1A-3B5F8468C14F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{237D9F7B-801E-440F-BA1A-3B5F8468C14F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{237D9F7B-801E-440F-BA1A-3B5F8468C14F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{237D9F7B-801E-440F-BA1A-3B5F8468C14F}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {099AB5DA-7A4D-4738-8EBE-64E3C1B46D75}
+	EndGlobalSection
+EndGlobal

+ 3 - 0
package-lock.json

@@ -0,0 +1,3 @@
+{
+  "lockfileVersion": 1
+}

+ 12 - 0
winForm.sp.wispro/App.config

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
+    </startup>
+  <appSettings>
+    <add key="CalculatedFile" value ="21.01-21.06 工程师绩效报表-总表.xlsx"/>
+    <add key="DinashuRegularFile" value ="20210903-威世博常用绩效点数计算规则-v2-lcy.xls"/>
+    <add key="PersonListFile" value ="210730-威世博人员清单v1r01-xm"/>
+    
+  </appSettings>
+</configuration>

+ 22 - 0
winForm.sp.wispro/Program.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace wispro.sp.winform
+{
+    static class Program
+    {
+        /// <summary>
+        /// 应用程序的主入口点。
+        /// </summary>
+        [STAThread]
+        static void Main()
+        {
+            Application.EnableVisualStyles();
+            Application.SetCompatibleTextRenderingDefault(false);
+            Application.Run(new frmMain());
+        }
+    }
+}

+ 36 - 0
winForm.sp.wispro/Properties/AssemblyInfo.cs

@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的一般信息由以下
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("winForm.sp.wispro")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("winForm.sp.wispro")]
+[assembly: AssemblyCopyright("Copyright ©  2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 会使此程序集中的类型
+//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
+//请将此类型的 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
+[assembly: Guid("10f9117f-03c1-4623-b0b4-2fecc0e096f5")]
+
+// 程序集的版本信息由下列四个值组成: 
+//
+//      主版本
+//      次版本
+//      生成号
+//      修订号
+//
+//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
+//通过使用 "*",如下所示:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 63 - 0
winForm.sp.wispro/Properties/Resources.Designer.cs

@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace wispro.sp.winform.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   一个强类型的资源类,用于查找本地化的字符串等。
+    /// </summary>
+    // 此类是由 StronglyTypedResourceBuilder
+    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
+    // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
+    // (以 /str 作为命令选项),或重新生成 VS 项目。
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   返回此类使用的缓存的 ResourceManager 实例。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("wispro.sp.winform.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   重写当前线程的 CurrentUICulture 属性,对
+        ///   使用此强类型资源类的所有资源查找执行重写。
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
winForm.sp.wispro/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 26 - 0
winForm.sp.wispro/Properties/Settings.Designer.cs

@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     此代码由工具生成。
+//     运行时版本:4.0.30319.42000
+//
+//     对此文件的更改可能会导致不正确的行为,并且如果
+//     重新生成代码,这些更改将会丢失。
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace wispro.sp.winform.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.10.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
winForm.sp.wispro/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 65 - 0
winForm.sp.wispro/frmExcelViewer.Designer.cs

@@ -0,0 +1,65 @@
+
+namespace wispro.sp.winform
+{
+    partial class frmExcelViewer
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.dataGridView1 = new System.Windows.Forms.DataGridView();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
+            this.SuspendLayout();
+            // 
+            // dataGridView1
+            // 
+            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.dataGridView1.Location = new System.Drawing.Point(0, 0);
+            this.dataGridView1.Name = "dataGridView1";
+            this.dataGridView1.RowHeadersWidth = 62;
+            this.dataGridView1.RowTemplate.Height = 30;
+            this.dataGridView1.Size = new System.Drawing.Size(800, 450);
+            this.dataGridView1.TabIndex = 0;
+            this.dataGridView1.RowPostPaint += new System.Windows.Forms.DataGridViewRowPostPaintEventHandler(this.dataGridView1_RowPostPaint);
+            // 
+            // frmExcelViewer
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(800, 450);
+            this.Controls.Add(this.dataGridView1);
+            this.Name = "frmExcelViewer";
+            this.Text = "frmExcelViewer";
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.DataGridView dataGridView1;
+    }
+}

+ 49 - 0
winForm.sp.wispro/frmExcelViewer.cs

@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace wispro.sp.winform
+{
+    public partial class frmExcelViewer : Form
+    {
+        public frmExcelViewer()
+        {
+            InitializeComponent();
+        }
+
+        private DataTable _data;
+        public DataTable Data { 
+            get {
+                return _data;
+            }
+            set
+            {
+                _data = value ;
+
+                if(_data != null)
+                {
+                    
+                    dataGridView1.DataSource = _data;
+                    
+                }
+            }
+        }
+
+        private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
+        {
+            Rectangle rect = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y,
+            dataGridView1.RowHeadersWidth - 4, e.RowBounds.Height);
+            TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(),
+            dataGridView1.RowHeadersDefaultCellStyle.Font, rect,
+            dataGridView1.RowHeadersDefaultCellStyle.ForeColor,
+            TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
+        }
+
+    }
+}

+ 120 - 0
winForm.sp.wispro/frmExcelViewer.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 88 - 0
winForm.sp.wispro/frmMain.Designer.cs

@@ -0,0 +1,88 @@
+
+namespace wispro.sp.winform
+{
+    partial class frmMain
+    {
+        /// <summary>
+        /// 必需的设计器变量。
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// 清理所有正在使用的资源。
+        /// </summary>
+        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows 窗体设计器生成的代码
+
+        /// <summary>
+        /// 设计器支持所需的方法 - 不要修改
+        /// 使用代码编辑器修改此方法的内容。
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.btnMerageExcel = new System.Windows.Forms.Button();
+            this.btnInputdianshu = new System.Windows.Forms.Button();
+            this.btnCalPerformance = new System.Windows.Forms.Button();
+            this.SuspendLayout();
+            // 
+            // btnMerageExcel
+            // 
+            this.btnMerageExcel.Location = new System.Drawing.Point(62, 29);
+            this.btnMerageExcel.Name = "btnMerageExcel";
+            this.btnMerageExcel.Size = new System.Drawing.Size(220, 73);
+            this.btnMerageExcel.TabIndex = 0;
+            this.btnMerageExcel.Text = "合并反馈文档";
+            this.btnMerageExcel.UseVisualStyleBackColor = true;
+            this.btnMerageExcel.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // btnInputdianshu
+            // 
+            this.btnInputdianshu.Location = new System.Drawing.Point(334, 29);
+            this.btnInputdianshu.Name = "btnInputdianshu";
+            this.btnInputdianshu.Size = new System.Drawing.Size(226, 73);
+            this.btnInputdianshu.TabIndex = 1;
+            this.btnInputdianshu.Text = "输入基础点数";
+            this.btnInputdianshu.UseVisualStyleBackColor = true;
+            this.btnInputdianshu.Click += new System.EventHandler(this.button1_Click_1);
+            // 
+            // btnCalPerformance
+            // 
+            this.btnCalPerformance.Location = new System.Drawing.Point(608, 29);
+            this.btnCalPerformance.Name = "btnCalPerformance";
+            this.btnCalPerformance.Size = new System.Drawing.Size(226, 73);
+            this.btnCalPerformance.TabIndex = 1;
+            this.btnCalPerformance.Text = "计算绩效点数";
+            this.btnCalPerformance.UseVisualStyleBackColor = true;
+            this.btnCalPerformance.Click += new System.EventHandler(this.btnCalPerformance_Click);
+            // 
+            // frmMain
+            // 
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.ClientSize = new System.Drawing.Size(882, 144);
+            this.Controls.Add(this.btnCalPerformance);
+            this.Controls.Add(this.btnInputdianshu);
+            this.Controls.Add(this.btnMerageExcel);
+            this.Name = "frmMain";
+            this.Text = "威世博绩效点数计算工具";
+            this.ResumeLayout(false);
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Button btnMerageExcel;
+        private System.Windows.Forms.Button btnInputdianshu;
+        private System.Windows.Forms.Button btnCalPerformance;
+    }
+}
+

+ 90 - 0
winForm.sp.wispro/frmMain.cs

@@ -0,0 +1,90 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Configuration;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using wispro.sp.entity;
+using wispro.sp.utility;
+
+namespace wispro.sp.winform
+{
+    public partial class frmMain : Form
+    {
+        public frmMain()
+        {
+            InitializeComponent();
+        }
+
+        private void button1_Click(object sender, EventArgs e)
+        {
+            DateTime startTime = DateTime.Now;
+            frmMerageExcel frm = new frmMerageExcel();
+
+            if(frm.ShowDialog() == DialogResult.OK)
+            {
+                MessageBox.Show($"合并完成,合并后文件保存在:\r\n{frm.SaveFilePath}\r\n用时:{DateTime.Now - startTime }");
+            }
+
+        }
+
+        private void button1_Click_1(object sender, EventArgs e)
+        {
+            OpenFileDialog ofd = new OpenFileDialog()
+            {
+                Multiselect = false,
+                Filter = "*.xls|*.xlsx"
+            };
+
+            string strDinashuRegularFile = ConfigurationSettings.AppSettings["DinashuRegularFile"];
+            if (ofd.ShowDialog()== DialogResult.OK)
+            {
+                new ExcelHelper().FillDianShu(ofd.FileName, strDinashuRegularFile);
+            }
+
+
+            
+        }
+
+        private void btnCalPerformance_Click(object sender, EventArgs e)
+        {
+            DataTable dt = wispro.sp.utility.NPOIExcel.ExcelToDataTable(@"D:\users\luowen\Documents\工作文档\深圳威世博人力绩效\210730-威世博人员清单v1r01-xm.xls", true);
+
+            //List<Staff> retList = new List<Staff>();
+
+            //if (dt != null)
+            //{
+            //    foreach (DataRow row in dt.Rows)
+            //    {
+            //        retList.Add(new Staff()
+            //        {
+            //            Name = row["姓名"].ToString(),
+            //            Status = row["姓名"].ToString(),
+            //            isCalPerformsnce = (row["是否核算绩效"].ToString() == "是"),
+            //            StaffGrade = new StaffGrade() { Grade = row["工程师等级"].ToString(), GradeCoefficient = decimal.Parse(row["等级系数"].ToString()) },
+            //            Department = row["部门"].ToString(),
+            //            WorkPlace = row["工作地"].ToString(),
+            //            EntyDate = DateTime.Parse(row["入职时间"].ToString()),
+            //            Memo = row["备注"].ToString()
+
+            //        });
+            //    }
+            //}
+
+            //string str = Newtonsoft.Json.JsonConvert.SerializeObject(retList);
+            //using (var file = System.IO.File.CreateText("d:\\temp\\Staff.json")) {
+            //    file.Write(str);
+            //}
+
+            frmExcelViewer frm = new frmExcelViewer();
+            frm.Data = dt;
+            frm.ShowDialog();
+
+
+        }
+    }
+}

+ 120 - 0
winForm.sp.wispro/frmMain.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 156 - 0
winForm.sp.wispro/frmMerageExcel.Designer.cs

@@ -0,0 +1,156 @@
+
+namespace wispro.sp.winform
+{
+    partial class frmMerageExcel
+    {
+        /// <summary>
+        /// Required designer variable.
+        /// </summary>
+        private System.ComponentModel.IContainer components = null;
+
+        /// <summary>
+        /// Clean up any resources being used.
+        /// </summary>
+        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing && (components != null))
+            {
+                components.Dispose();
+            }
+            base.Dispose(disposing);
+        }
+
+        #region Windows Form Designer generated code
+
+        /// <summary>
+        /// Required method for Designer support - do not modify
+        /// the contents of this method with the code editor.
+        /// </summary>
+        private void InitializeComponent()
+        {
+            this.lblSaveFilePath = new System.Windows.Forms.Label();
+            this.txtSaveFilePath = new System.Windows.Forms.TextBox();
+            this.label1 = new System.Windows.Forms.Label();
+            this.btnSelectSavePath = new System.Windows.Forms.Button();
+            this.btnAdd = new System.Windows.Forms.Button();
+            this.btnBeginMerage = new System.Windows.Forms.Button();
+            this.btnCancel = new System.Windows.Forms.Button();
+            this.lstFiles = new System.Windows.Forms.CheckedListBox();
+            this.SuspendLayout();
+            // 
+            // lblSaveFilePath
+            // 
+            this.lblSaveFilePath.AutoSize = true;
+            this.lblSaveFilePath.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+            this.lblSaveFilePath.Location = new System.Drawing.Point(56, 64);
+            this.lblSaveFilePath.Name = "lblSaveFilePath";
+            this.lblSaveFilePath.Size = new System.Drawing.Size(208, 21);
+            this.lblSaveFilePath.TabIndex = 0;
+            this.lblSaveFilePath.Text = "合并文件保存路径:";
+            // 
+            // txtSaveFilePath
+            // 
+            this.txtSaveFilePath.Font = new System.Drawing.Font("宋体", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+            this.txtSaveFilePath.Location = new System.Drawing.Point(270, 55);
+            this.txtSaveFilePath.Name = "txtSaveFilePath";
+            this.txtSaveFilePath.Size = new System.Drawing.Size(698, 39);
+            this.txtSaveFilePath.TabIndex = 1;
+            // 
+            // label1
+            // 
+            this.label1.AutoSize = true;
+            this.label1.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+            this.label1.Location = new System.Drawing.Point(56, 131);
+            this.label1.Name = "label1";
+            this.label1.Size = new System.Drawing.Size(164, 21);
+            this.label1.TabIndex = 0;
+            this.label1.Text = "合共文件清单:";
+            this.label1.Click += new System.EventHandler(this.label1_Click);
+            // 
+            // btnSelectSavePath
+            // 
+            this.btnSelectSavePath.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
+            this.btnSelectSavePath.Location = new System.Drawing.Point(974, 53);
+            this.btnSelectSavePath.Name = "btnSelectSavePath";
+            this.btnSelectSavePath.Size = new System.Drawing.Size(123, 42);
+            this.btnSelectSavePath.TabIndex = 3;
+            this.btnSelectSavePath.Text = "选择";
+            this.btnSelectSavePath.UseVisualStyleBackColor = true;
+            this.btnSelectSavePath.Click += new System.EventHandler(this.btnSelectSavePath_Click);
+            // 
+            // btnAdd
+            // 
+            this.btnAdd.Location = new System.Drawing.Point(56, 567);
+            this.btnAdd.Name = "btnAdd";
+            this.btnAdd.Size = new System.Drawing.Size(158, 58);
+            this.btnAdd.TabIndex = 5;
+            this.btnAdd.Text = "添加文件";
+            this.btnAdd.UseVisualStyleBackColor = true;
+            this.btnAdd.Click += new System.EventHandler(this.btnAdd_Click);
+            // 
+            // btnBeginMerage
+            // 
+            this.btnBeginMerage.Location = new System.Drawing.Point(926, 567);
+            this.btnBeginMerage.Name = "btnBeginMerage";
+            this.btnBeginMerage.Size = new System.Drawing.Size(171, 58);
+            this.btnBeginMerage.TabIndex = 6;
+            this.btnBeginMerage.Text = "开始合并";
+            this.btnBeginMerage.UseVisualStyleBackColor = true;
+            this.btnBeginMerage.Click += new System.EventHandler(this.btnBeginMerage_Click);
+            // 
+            // btnCancel
+            // 
+            this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+            this.btnCancel.Location = new System.Drawing.Point(751, 567);
+            this.btnCancel.Name = "btnCancel";
+            this.btnCancel.Size = new System.Drawing.Size(155, 58);
+            this.btnCancel.TabIndex = 6;
+            this.btnCancel.Text = "取消";
+            this.btnCancel.UseVisualStyleBackColor = true;
+            this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
+            // 
+            // lstFiles
+            // 
+            this.lstFiles.FormattingEnabled = true;
+            this.lstFiles.Location = new System.Drawing.Point(60, 172);
+            this.lstFiles.Name = "lstFiles";
+            this.lstFiles.Size = new System.Drawing.Size(1037, 379);
+            this.lstFiles.TabIndex = 7;
+            // 
+            // frmMerageExcel
+            // 
+            this.AcceptButton = this.btnBeginMerage;
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F);
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+            this.CancelButton = this.btnCancel;
+            this.ClientSize = new System.Drawing.Size(1151, 676);
+            this.Controls.Add(this.lstFiles);
+            this.Controls.Add(this.btnCancel);
+            this.Controls.Add(this.btnBeginMerage);
+            this.Controls.Add(this.btnAdd);
+            this.Controls.Add(this.btnSelectSavePath);
+            this.Controls.Add(this.txtSaveFilePath);
+            this.Controls.Add(this.label1);
+            this.Controls.Add(this.lblSaveFilePath);
+            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+            this.Name = "frmMerageExcel";
+            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+            this.Text = "合并Excel文件";
+            this.ResumeLayout(false);
+            this.PerformLayout();
+
+        }
+
+        #endregion
+
+        private System.Windows.Forms.Label lblSaveFilePath;
+        private System.Windows.Forms.TextBox txtSaveFilePath;
+        private System.Windows.Forms.Label label1;
+        private System.Windows.Forms.Button btnSelectSavePath;
+        private System.Windows.Forms.Button btnAdd;
+        private System.Windows.Forms.Button btnBeginMerage;
+        private System.Windows.Forms.Button btnCancel;
+        private System.Windows.Forms.CheckedListBox lstFiles;
+    }
+}

+ 74 - 0
winForm.sp.wispro/frmMerageExcel.cs

@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace wispro.sp.winform
+{
+    public partial class frmMerageExcel : Form
+    {
+        public frmMerageExcel()
+        {
+            InitializeComponent();
+        }
+
+        private void label1_Click(object sender, EventArgs e)
+        {
+
+        }
+
+        private void btnSelectSavePath_Click(object sender, EventArgs e)
+        {
+            FolderBrowserDialog fbd = new FolderBrowserDialog();
+
+            if(fbd.ShowDialog()== DialogResult.OK)
+            {
+                txtSaveFilePath.Text = System.IO.Path.Combine(fbd.SelectedPath, $"{DateTime.Now.ToString("yyyyMMdd")}-{DateTime.Now.Month -1}月份绩效计算案件清单.xlsx");
+            }
+        }
+
+        private void btnAdd_Click(object sender, EventArgs e)
+        {
+            OpenFileDialog ofd = new OpenFileDialog()
+            {
+                Multiselect = true,
+                Filter= "Excel文件|*.xls;*.xlsx|全部文件|*.*"
+            };
+
+            if(ofd.ShowDialog() == DialogResult.OK)
+            {
+                lstFiles.Items.AddRange(ofd.FileNames);
+            }
+        }
+
+        public string SaveFilePath { get; set; }
+        private void btnBeginMerage_Click(object sender, EventArgs e)
+        {
+            if (!string.IsNullOrEmpty(txtSaveFilePath.Text) && lstFiles.Items.Count > 0){
+
+                string[] files = new string[lstFiles.Items.Count];
+                for(int i = 0; i < lstFiles.Items.Count; i++)
+                {
+                    files[i] = lstFiles.Items[i].ToString();
+                }
+
+                new wispro.sp.utility.ExcelHelper().MerageExcel(txtSaveFilePath.Text, files);
+                SaveFilePath = txtSaveFilePath.Text;
+            }
+
+            this.DialogResult = DialogResult.OK;
+            this.Close();
+        }
+
+        private void btnCancel_Click(object sender, EventArgs e)
+        {
+            this.DialogResult = DialogResult.Cancel;
+            this.Close();
+        }
+    }
+}

+ 120 - 0
winForm.sp.wispro/frmMerageExcel.resx

@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 4 - 0
winForm.sp.wispro/packages.config

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Newtonsoft.Json" version="13.0.1" targetFramework="net472" />
+</packages>

+ 119 - 0
winForm.sp.wispro/wispro.sp.winform.csproj

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{10F9117F-03C1-4623-B0B4-2FECC0E096F5}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>wispro.sp.winform</RootNamespace>
+    <AssemblyName>wispro.sp.winform</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+    <Deterministic>true</Deterministic>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject>wispro.sp.winform.Program</StartupObject>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+      <HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="frmExcelViewer.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="frmExcelViewer.Designer.cs">
+      <DependentUpon>frmExcelViewer.cs</DependentUpon>
+    </Compile>
+    <Compile Include="frmMain.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="frmMain.Designer.cs">
+      <DependentUpon>frmMain.cs</DependentUpon>
+    </Compile>
+    <Compile Include="frmMerageExcel.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="frmMerageExcel.Designer.cs">
+      <DependentUpon>frmMerageExcel.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <EmbeddedResource Include="frmExcelViewer.resx">
+      <DependentUpon>frmExcelViewer.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="frmMain.resx">
+      <DependentUpon>frmMain.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="frmMerageExcel.resx">
+      <DependentUpon>frmMerageExcel.cs</DependentUpon>
+    </EmbeddedResource>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+      <DesignTime>True</DesignTime>
+    </Compile>
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\wispro.sp.entity\wispro.sp.entity.csproj">
+      <Project>{fd17e62d-c5fa-4eb5-9de5-8a061afca858}</Project>
+      <Name>wispro.sp.entity</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\wispro.sp.utility\wispro.sp.utility.csproj">
+      <Project>{2e1f76da-44f6-4ff3-9a39-73c8e022fa1d}</Project>
+      <Name>wispro.sp.utility</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 118 - 0
wispro.sp.api/Controllers/AccountController.cs

@@ -0,0 +1,118 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+using wispro.sp.share.webViewObject;
+
+namespace wispro.sp.api.Controllers
+{
+    [Route("api/[controller]")]
+    [ApiController]
+    public class AccountController : ControllerBase
+    {
+        private static List<Staff> CacheList = new List<Staff>();
+        public IConfiguration Configuration { get; }
+
+        public AccountController(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+        
+        [HttpGet,HttpPost,Route("Login")]
+        public userToken Login(loginDto loginUser)
+        {
+            //添加验证代码
+            spDbContext dbContext = new spDbContext();
+            Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account == loginUser.Name && s.Password == loginUser.Password).FirstOrDefault();
+
+            if(staff != null)
+            {
+                return GetToken(staff);
+            }
+            else
+            {
+                return new userToken() { 
+                    StatusCode = System.Net.HttpStatusCode.NotFound,
+                    Name = null, 
+                    Token = null 
+                };
+            }
+            
+        }
+
+        [HttpGet,Route("GetUser")]
+        public userToken GetUser()
+        {
+            if (User.Identity.IsAuthenticated)//如果Token有效
+            {
+                var name = User.Claims.First(x => x.Type == ClaimTypes.Name).Value;//从Token中拿出用户ID
+                                                                                   //模拟获得Token
+                spDbContext dbContext = new spDbContext();
+                Staff staff = dbContext.Staffs.Where<Staff>(s => s.Account == name).FirstOrDefault();
+
+                if (staff != null)
+                {
+                    return GetToken(staff);
+                }
+                else
+                {
+                    return new userToken() {StatusCode=System.Net.HttpStatusCode.NotFound, Name = null, Token = null };
+                }
+            }
+            else
+            {
+                return new userToken() {StatusCode= System.Net.HttpStatusCode.NotFound, Name = null, Token = null };
+            }
+        }
+
+
+        private userToken GetToken(Staff staff)
+        {
+            var claims = new Claim[]
+            {
+                new Claim("Id",staff.Id.ToString()),
+                new Claim(ClaimTypes.Name,staff.Name),
+                new Claim(ClaimTypes.Email,(staff.Mail==null)?"":staff.Mail),
+                //new Claim(ClaimTypes.Role,"Admin"),
+            };
+
+
+            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:Key"]));
+            var credential = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
+            var expireTime = DateTime.Now.AddMinutes(2);
+            
+            var token = new JwtSecurityToken(
+                issuer: Configuration["jwt:Issuer"],
+                audience: Configuration["jwt:Audience"],
+                claims: claims,
+                notBefore: DateTime.Now,
+                expires: expireTime,                
+                signingCredentials: credential);
+
+            
+            string jwtToken = new JwtSecurityTokenHandler().WriteToken(token);
+
+            //建立UserToken物件後回傳client
+            userToken userToken = new userToken()
+            {
+                StatusCode = System.Net.HttpStatusCode.OK,
+                Name = staff.Name,
+                Token = jwtToken,
+                ExpireTime = expireTime
+            };
+
+            return userToken;
+
+        }
+    }
+    
+}

+ 156 - 0
wispro.sp.api/Controllers/PerformanceItemController.cs

@@ -0,0 +1,156 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+using wispro.sp.share;
+
+namespace wispro.sp.api.Controllers
+{
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    [Authorize]
+    public class PerformanceItemController : ControllerBase
+    {
+        spDbContext Context;
+
+        public PerformanceItemController(spDbContext context)
+        {
+            Context = context;
+        }
+        public ApiSaveResponse New(PerformanceItem item)
+        {
+            ApiSaveResponse ret = new ApiSaveResponse();
+            using (Context.Database.BeginTransaction())
+            {
+                try
+                {
+
+                    if (!string.IsNullOrEmpty(item.Customer.Name))
+                    {
+                        var temCustomer = Context.Customers.Where<Customer>(c => c.Name == item.Customer.Name).FirstOrDefault();
+
+                        if (temCustomer == null)
+                        {
+                            Context.Customers.Add(item.Customer);
+                            Context.SaveChanges();
+                        }
+                        else
+                        {
+                            item.Customer = temCustomer;
+                        }
+
+                        item.CustomerId = item.Customer.Id;
+                    }
+                    else
+                    {
+                        item.Customer = null;
+                    }
+
+                    List<PerformanceItem> items = Context.PerformanceItems.Where<PerformanceItem>(x =>
+                        x.CaseNo == item.CaseNo && x.DoItem == item.DoItem && x.DoItem != "提出报告").ToList();
+
+                    if (items.Count > 0)
+                    {
+                        ret.Success = false;
+                        ret.ErrorMessage = $"案件【{item.CaseNo}】处理事项【{item.DoItem }】已存在!";
+                    }
+                    else
+                    {
+                        Context.PerformanceItems.Add(item);
+                    }
+
+                    Context.SaveChanges();
+
+                    foreach(ItemStaff itemStaff in item.ItemStaffs)
+                    {
+                        itemStaff.ItemId = item.Id;
+
+                        if(itemStaff.DoPersonId ==0 && itemStaff.DoPerson != null)
+                        {
+                            var temStaff = Context.Staffs.FirstOrDefault<Staff>(s => s.Name == itemStaff.DoPerson.Name);
+
+                            if(temStaff != null)
+                            {
+                                itemStaff.DoPersonId = temStaff.Id;
+                                itemStaff.DoPerson = null;
+                            }
+                            else
+                            {
+                                Context.Staffs.Add(itemStaff.DoPerson);
+                                Context.SaveChanges();
+                                itemStaff.DoPersonId = itemStaff.DoPerson.Id;
+                            }
+                        }
+                    }
+
+                    Context.ItemStaffs.AddRange(item.ItemStaffs);
+
+                    Context.Database.CommitTransaction();
+                }
+                catch (Exception ex)
+                {
+                    ret.Success = false;
+                    ret.ErrorMessage = ex.Message;
+                    Context.Database.RollbackTransaction();
+                }
+            }
+            
+
+            return ret;
+        }
+
+        public ListApiResponse<PerformanceItem> Query(int pageIndex,int pageSize)
+        {
+            if (!User.Identity.IsAuthenticated)
+            {
+               
+            }
+
+            ListApiResponse<PerformanceItem> ret = new ListApiResponse<PerformanceItem>();
+            var results = Context.PerformanceItems
+                .Where<PerformanceItem>(s => s.ItemStaffs
+                    .Where<ItemStaff>(iStaff => iStaff.DoPerson.Name == User.Identity.Name).Count() > 0 && s.Month == 7 && s.Year == 2021);
+
+            ret.TotalCount = results.Count();
+
+            List<PerformanceItem> retList = results
+                .Include(pi=>pi.ItemStaffs).ThenInclude(iStaff=>iStaff.DoPerson)
+                .Include(pi=>pi.Reviewer)
+                .Include(pi=>pi.Customer)
+                .OrderByDescending(o=>o.Id)
+                .Skip<PerformanceItem>((pageIndex - 1) * pageSize).Take(pageSize).ToList<PerformanceItem>();
+
+            ret.Results = retList;
+
+            return ret;
+        }
+
+        public ListApiResponse<PerformanceItem> QueryFilter(QueryFilter queryFilter)
+        {
+
+            ListApiResponse<PerformanceItem> ret = new ListApiResponse<PerformanceItem>();
+            ret.TotalCount = Context.PerformanceItems.Count<PerformanceItem>();
+
+            List<PerformanceItem> retList = Context.PerformanceItems
+                //.Where<PerformanceItem>(s => s.ItemStaffs
+                //    .Where<ItemStaff>(iStaff => iStaff.DoPerson.Name == "李申").Count() > 0 && s.Month== 7 && s.Year == 2021)
+                .Include(pi => pi.ItemStaffs).ThenInclude(iStaff => iStaff.DoPerson)
+                .Include(pi => pi.Reviewer)
+                .Include(pi => pi.Customer)
+                .OrderByDescending(o => o.Id)
+                .Skip<PerformanceItem>((queryFilter.pageIndex - 1) * queryFilter.pageSize).Take(queryFilter.pageSize).ToList<PerformanceItem>();
+
+            //Context.PerformanceItems.Where<PerformanceItem>(p=>p.ItemStaffs.Where<ItemStaff>)
+            ret.Results = retList;
+
+            return ret;
+        }
+
+
+    }
+}

+ 135 - 0
wispro.sp.api/Controllers/StaffController.cs

@@ -0,0 +1,135 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using wispro.sp.entity;
+using wispro.sp.share;
+using System.Linq;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+
+namespace wispro.sp.api.Controllers
+{
+    //[Authorize]
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    public class StaffController : ControllerBase
+    {
+        private static List<Staff> CacheList = new List<Staff>();
+        spDbContext Context;
+
+        public StaffController(spDbContext context)
+        {
+            Context = context;
+            
+            //DataTable dt = wispro.sp.utility.NPOIExcel.ExcelToDataTable(@"D:\users\luowen\Documents\工作文档\深圳威世博人力绩效\210730-威世博人员清单v1r01-xm.xls", true);
+
+            //CacheList = new List<Staff>();
+
+            //if (dt != null)
+            //{
+            //    foreach (DataRow row in dt.Rows)
+            //    {
+            //        CacheList.Add(new Staff()
+            //        {
+            //            Name = row["姓名"].ToString(),
+            //            Status = row["岗位状态"].ToString(),
+            //            IsCalPerformsnce = (row["是否核算绩效"].ToString() == "是"),
+            //            StaffGrade = new StaffGrade() { Grade = row["工程师等级"].ToString(), Coefficient = double.Parse(row["等级系数"].ToString()) },
+            //            Department = row["部门"].ToString(),
+            //            WorkPlace = row["工作地"].ToString(),
+            //            EntyDate = DateTime.Parse(row["入职时间"].ToString()),
+            //            Memo = row["备注"].ToString()
+
+            //        });
+            //    }
+            //}
+        }
+        
+
+        public List<Staff> GetAll()
+        {
+            return Context.Staffs.ToList<Staff>();
+        }
+
+        
+        
+        public ListApiResponse<Staff> Query(int pageIndex,int pageSize)
+        {
+            ListApiResponse<Staff> ret = new ListApiResponse<Staff>();
+            ret.TotalCount = Context.Staffs.Count<Staff>();
+
+            List<Staff> retList = Context.Staffs.Skip<Staff>((pageIndex - 1) * pageSize).Take(pageSize).ToList<Staff>();
+
+            //for(int i = (pageIndex-1) * pageSize; i < pageIndex  * pageSize; i++)
+            //{
+            //    if (i < CacheList.Count)
+            //    {
+            //        retList.Add(CacheList[i]);
+            //    }
+            //}
+            ret.Results = retList;
+
+            return ret;
+        }
+
+        [HttpPost]
+        public ApiSaveResponse Save(Staff staff)
+        {
+            ApiSaveResponse ret = new ApiSaveResponse();
+            try
+            {
+                if (staff.Id == 0)
+                {
+                    
+                    List<Staff> grades = Context.Staffs.Where<Staff>(x => x.Name == staff.Name).ToList();
+
+                    if (grades.Count > 0)
+                    {
+                        ret.Success = false;
+                        ret.ErrorMessage = $"用户【{staff.Name}】已存在!";
+                    }
+                    else
+                    {
+                        Context.Staffs.Add(staff);
+                    }
+                }
+                else
+                {
+                    Staff editObject = Context.Staffs.Where<Staff>(x => x.Id == staff.Id).FirstOrDefault();
+
+                    if (editObject != null)
+                    {
+                        editObject.Name = staff.Name;
+                        editObject.StaffGradeId = staff.StaffGradeId;
+                        editObject.Account = staff.Account;
+                        editObject.Department = staff.Department;
+                        editObject.EntyDate = staff.EntyDate;
+                        editObject.IsCalPerformsnce = staff.IsCalPerformsnce;
+                        editObject.Memo = staff.Memo;
+                        editObject.Password = editObject.Password;
+                        editObject.Status = staff.Status;
+                        editObject.WorkPlace = staff.WorkPlace;
+                    }
+                    else
+                    {
+                        ret.Success = false;
+                        ret.ErrorMessage = $"编号为【{staff.Id}】的用户不存在!";
+                    }
+                    
+                }
+
+                Context.SaveChanges();
+
+                ret.Success = true;
+            }
+            catch (Exception ex)
+            {
+                ret.Success = false;
+                ret.ErrorMessage = ex.Message;
+            }
+
+            return ret;
+        }
+    }
+}

+ 72 - 0
wispro.sp.api/Controllers/StaffGradeController.cs

@@ -0,0 +1,72 @@
+using Microsoft.AspNetCore.Mvc;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using wispro.sp.entity;
+using wispro.sp.share;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+
+namespace wispro.sp.api.Controllers
+{
+    //[Authorize]
+    [Route("api/[controller]/[action]")]
+    [ApiController]
+    public class StaffGradeController : ControllerBase
+    {
+        spDbContext Context;
+
+        public StaffGradeController(spDbContext context)
+        {
+            Context = context;
+        }
+
+        
+        public List<StaffGrade> GetAll()
+        {
+            var result= Context.StaffGrades.Where<StaffGrade>(x=>x.Id >0);
+            return result.ToList<StaffGrade>();
+            
+        }
+
+        [HttpPost]
+        public ApiSaveResponse Save(StaffGrade staffGrade)
+        {
+            ApiSaveResponse ret = new ApiSaveResponse();
+            try
+            {
+                if (staffGrade.Id == 0)
+                {
+                    List<StaffGrade> grades = Context.StaffGrades.Where<StaffGrade>(x => x.Grade == staffGrade.Grade).ToList();
+
+                    if (grades.Count > 0)
+                    {
+                        ret.Success = false;
+                        ret.ErrorMessage = "该等级系数已设定!";
+                    }
+                    else
+                    {
+                        Context.StaffGrades.Add(staffGrade);
+                    }
+                }
+                else
+                {
+                    List<StaffGrade> grades = Context.StaffGrades.Where<StaffGrade>(x => x.Id == staffGrade.Id).ToList();
+                    grades[0].Grade = staffGrade.Grade;
+                    grades[0].Coefficient = staffGrade.Coefficient;
+                }
+
+                Context.SaveChanges();
+
+                ret.Success = true;
+            }
+            catch(Exception ex)
+            {
+                ret.Success = false;
+                ret.ErrorMessage = ex.Message;
+            }
+
+            return ret;
+        }
+    }
+}

+ 35 - 0
wispro.sp.api/Controllers/VerifyCoefficientController.cs

@@ -0,0 +1,35 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+
+namespace wispro.sp.api.Controllers
+{
+    //[Authorize]
+    [Route("api/[controller]")]
+    [ApiController]
+    public class VerifyCoefficientController : ControllerBase
+    {
+        spDbContext Context;
+
+        public VerifyCoefficientController(spDbContext context)
+        {
+            Context = context;
+        }
+
+
+        public List<VerifyCoefficient> GetAll()
+        {
+            var result = Context.VerifyCoefficients.Include(b=>b.DoPerson).Include(b=>b.Checker);
+                
+            return result.ToList<VerifyCoefficient>();
+
+        }
+    }
+}

+ 655 - 0
wispro.sp.api/Migrations/20210910105657_spDB0910.Designer.cs

@@ -0,0 +1,655 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using wispro.sp.api;
+
+namespace wispro.sp.api.Migrations
+{
+    [DbContext(typeof(spDbContext))]
+    [Migration("20210910105657_spDB0910")]
+    partial class spDB0910
+    {
+        protected override void BuildTargetModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("Relational:Collation", "Chinese_PRC_CI_AS")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128)
+                .HasAnnotation("ProductVersion", "5.0.9")
+                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.Property<int>("Id")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Address")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("ContactMan")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(200)
+                        .HasColumnType("nvarchar(200)");
+
+                    b.Property<string>("Phone")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<int?>("ResponseManId")
+                        .HasColumnType("int");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ResponseManId");
+
+                    b.ToTable("Customer");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.ItemStaff", b =>
+                {
+                    b.Property<int>("ItemId")
+                        .HasColumnType("int");
+
+                    b.Property<int>("DoPersonId")
+                        .HasColumnType("int");
+
+                    b.Property<double>("PerformancePoint")
+                        .HasColumnType("float");
+
+                    b.HasKey("ItemId", "DoPersonId");
+
+                    b.HasIndex("DoPersonId");
+
+                    b.ToTable("ItemStaff");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("AgentFeedbackMemo")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ApplicationName")
+                        .HasMaxLength(200)
+                        .HasColumnType("nvarchar(200)");
+
+                    b.Property<string>("ApplicationType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<decimal?>("BasePoint")
+                        .HasColumnType("numeric(18,2)");
+
+                    b.Property<string>("BusinessType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseCoefficient")
+                        .HasMaxLength(10)
+                        .HasColumnType("nvarchar(10)");
+
+                    b.Property<string>("CaseName")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("CaseNo")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseStage")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseState")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<int?>("CustomerId")
+                        .HasColumnType("int");
+
+                    b.Property<DateTime?>("CustomerLimitDate")
+                        .HasColumnType("date");
+
+                    b.Property<string>("DoItem")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("DoItemCoefficient")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("DoItemMemo")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("DoItemState")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<DateTime?>("EntrustingDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FinalizationDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FinishedDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FirstDraftDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("InternalDate")
+                        .HasColumnType("date");
+
+                    b.Property<int>("Month")
+                        .HasColumnType("int");
+
+                    b.Property<string>("OverDueMemo")
+                        .HasMaxLength(100)
+                        .HasColumnType("nvarchar(100)");
+
+                    b.Property<int?>("PreOastaffId")
+                        .HasColumnType("int")
+                        .HasColumnName("PreOAStaffId");
+
+                    b.Property<DateTime?>("ReturnDate")
+                        .HasColumnType("date");
+
+                    b.Property<int?>("ReviewerId")
+                        .HasColumnType("int");
+
+                    b.Property<int?>("StaffId")
+                        .HasColumnType("int");
+
+                    b.Property<int?>("Status")
+                        .HasColumnType("int")
+                        .HasColumnName("status");
+
+                    b.Property<int>("Year")
+                        .HasColumnType("int");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomerId");
+
+                    b.HasIndex("PreOastaffId");
+
+                    b.HasIndex("ReviewerId");
+
+                    b.HasIndex("StaffId");
+
+                    b.ToTable("PerformanceItem");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.Property<int>("Id")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Account")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Department")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<DateTime?>("EntyDate")
+                        .HasColumnType("date");
+
+                    b.Property<bool>("IsCalPerformsnce")
+                        .HasColumnType("bit")
+                        .HasColumnName("isCalPerformsnce");
+
+                    b.Property<string>("Memo")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Password")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<int>("StaffGradeId")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Status")
+                        .IsRequired()
+                        .HasMaxLength(25)
+                        .HasColumnType("nvarchar(25)");
+
+                    b.Property<string>("WorkPlace")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("StaffGradeId");
+
+                    b.ToTable("Staff");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.StaffGrade", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<double>("Coefficient")
+                        .HasColumnType("float");
+
+                    b.Property<string>("Grade")
+                        .IsRequired()
+                        .HasMaxLength(5)
+                        .HasColumnType("nchar(5)")
+                        .IsFixedLength(true);
+
+                    b.HasKey("Id");
+
+                    b.ToTable("StaffGrade");
+
+                    b.HasData(
+                        new
+                        {
+                            Id = 1,
+                            Coefficient = 1.2,
+                            Grade = "S级"
+                        },
+                        new
+                        {
+                            Id = 2,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A3级"
+                        },
+                        new
+                        {
+                            Id = 3,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A2级"
+                        },
+                        new
+                        {
+                            Id = 4,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A1级"
+                        },
+                        new
+                        {
+                            Id = 5,
+                            Coefficient = 1.0,
+                            Grade = "B3级"
+                        },
+                        new
+                        {
+                            Id = 6,
+                            Coefficient = 1.0,
+                            Grade = "B2级"
+                        },
+                        new
+                        {
+                            Id = 7,
+                            Coefficient = 0.90000000000000002,
+                            Grade = "B1级"
+                        },
+                        new
+                        {
+                            Id = 8,
+                            Coefficient = 0.90000000000000002,
+                            Grade = "C3级"
+                        },
+                        new
+                        {
+                            Id = 9,
+                            Coefficient = 0.69999999999999996,
+                            Grade = "C2级"
+                        },
+                        new
+                        {
+                            Id = 10,
+                            Coefficient = 0.69999999999999996,
+                            Grade = "C1级"
+                        },
+                        new
+                        {
+                            Id = 11,
+                            Coefficient = 0.59999999999999998,
+                            Grade = "D3级"
+                        },
+                        new
+                        {
+                            Id = 12,
+                            Coefficient = 0.59999999999999998,
+                            Grade = "D2级"
+                        },
+                        new
+                        {
+                            Id = 13,
+                            Coefficient = 0.5,
+                            Grade = "D1级"
+                        });
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.VerifyCoefficient", b =>
+                {
+                    b.Property<int>("CheckerId")
+                        .HasColumnType("int");
+
+                    b.Property<int>("DoPersonId")
+                        .HasColumnType("int");
+
+                    b.Property<double>("Coefficient")
+                        .HasColumnType("float");
+
+                    b.HasKey("CheckerId", "DoPersonId");
+
+                    b.HasIndex("DoPersonId");
+
+                    b.ToTable("VerifyCoefficient");
+
+                    b.HasData(
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        });
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Staff", "ResponseMan")
+                        .WithMany("Customers")
+                        .HasForeignKey("ResponseManId")
+                        .HasConstraintName("FK_Customer_Staff");
+
+                    b.Navigation("ResponseMan");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.ItemStaff", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Staff", "DoPerson")
+                        .WithMany("ItemStaffs")
+                        .HasForeignKey("DoPersonId")
+                        .HasConstraintName("FK_ItemStaff_Staff")
+                        .IsRequired();
+
+                    b.HasOne("wispro.sp.entity.PerformanceItem", "Item")
+                        .WithMany("ItemStaffs")
+                        .HasForeignKey("ItemId")
+                        .HasConstraintName("FK_ItemStaff_PerformanceItem")
+                        .IsRequired();
+
+                    b.Navigation("DoPerson");
+
+                    b.Navigation("Item");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Customer", "Customer")
+                        .WithMany("PerformanceItems")
+                        .HasForeignKey("CustomerId")
+                        .HasConstraintName("FK_PerformanceItem_Customer");
+
+                    b.HasOne("wispro.sp.entity.Staff", "PreOastaff")
+                        .WithMany()
+                        .HasForeignKey("PreOastaffId")
+                        .HasConstraintName("FK_PerformanceItem_Staff");
+
+                    b.HasOne("wispro.sp.entity.Staff", "Reviewer")
+                        .WithMany("ReviewerItems")
+                        .HasForeignKey("ReviewerId")
+                        .HasConstraintName("FK_PerformanceItem_Reviewer");
+
+                    b.HasOne("wispro.sp.entity.Staff", null)
+                        .WithMany("PerformanceItems")
+                        .HasForeignKey("StaffId");
+
+                    b.Navigation("Customer");
+
+                    b.Navigation("PreOastaff");
+
+                    b.Navigation("Reviewer");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.HasOne("wispro.sp.entity.StaffGrade", "StaffGrade")
+                        .WithMany("Staff")
+                        .HasForeignKey("StaffGradeId")
+                        .HasConstraintName("FK_Staff_StaffGrade")
+                        .IsRequired();
+
+                    b.Navigation("StaffGrade");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.VerifyCoefficient", b =>
+                {
+                    b.HasOne("wispro.sp.entity.StaffGrade", "Checker")
+                        .WithMany("VerifyCoefficientCheckers")
+                        .HasForeignKey("CheckerId")
+                        .HasConstraintName("FK_VerifyCoefficient_StaffGrade")
+                        .IsRequired();
+
+                    b.HasOne("wispro.sp.entity.StaffGrade", "DoPerson")
+                        .WithMany("VerifyCoefficientDoPeople")
+                        .HasForeignKey("DoPersonId")
+                        .HasConstraintName("FK_VerifyCoefficient_StaffGrade1")
+                        .IsRequired();
+
+                    b.Navigation("Checker");
+
+                    b.Navigation("DoPerson");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.Navigation("PerformanceItems");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.Navigation("ItemStaffs");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.Navigation("Customers");
+
+                    b.Navigation("ItemStaffs");
+
+                    b.Navigation("PerformanceItems");
+
+                    b.Navigation("ReviewerItems");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.StaffGrade", b =>
+                {
+                    b.Navigation("Staff");
+
+                    b.Navigation("VerifyCoefficientCheckers");
+
+                    b.Navigation("VerifyCoefficientDoPeople");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}

+ 305 - 0
wispro.sp.api/Migrations/20210910105657_spDB0910.cs

@@ -0,0 +1,305 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace wispro.sp.api.Migrations
+{
+    public partial class spDB0910 : Migration
+    {
+        protected override void Up(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.CreateTable(
+                name: "StaffGrade",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "int", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    Grade = table.Column<string>(type: "nchar(5)", fixedLength: true, maxLength: 5, nullable: false),
+                    Coefficient = table.Column<double>(type: "float", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_StaffGrade", x => x.Id);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "Staff",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "int", nullable: false),
+                    Account = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
+                    Password = table.Column<string>(type: "nvarchar(max)", nullable: false),
+                    Name = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: false),
+                    Status = table.Column<string>(type: "nvarchar(25)", maxLength: 25, nullable: false),
+                    isCalPerformsnce = table.Column<bool>(type: "bit", nullable: false),
+                    StaffGradeId = table.Column<int>(type: "int", nullable: false),
+                    Department = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    WorkPlace = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    EntyDate = table.Column<DateTime>(type: "date", nullable: true),
+                    Memo = table.Column<string>(type: "nvarchar(max)", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Staff", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_Staff_StaffGrade",
+                        column: x => x.StaffGradeId,
+                        principalTable: "StaffGrade",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "VerifyCoefficient",
+                columns: table => new
+                {
+                    CheckerId = table.Column<int>(type: "int", nullable: false),
+                    DoPersonId = table.Column<int>(type: "int", nullable: false),
+                    Coefficient = table.Column<double>(type: "float", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_VerifyCoefficient", x => new { x.CheckerId, x.DoPersonId });
+                    table.ForeignKey(
+                        name: "FK_VerifyCoefficient_StaffGrade",
+                        column: x => x.CheckerId,
+                        principalTable: "StaffGrade",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_VerifyCoefficient_StaffGrade1",
+                        column: x => x.DoPersonId,
+                        principalTable: "StaffGrade",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "Customer",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "int", nullable: false),
+                    Name = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: false),
+                    ContactMan = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    Address = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
+                    Phone = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    ResponseManId = table.Column<int>(type: "int", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_Customer", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_Customer_Staff",
+                        column: x => x.ResponseManId,
+                        principalTable: "Staff",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "PerformanceItem",
+                columns: table => new
+                {
+                    Id = table.Column<int>(type: "int", nullable: false)
+                        .Annotation("SqlServer:Identity", "1, 1"),
+                    Year = table.Column<int>(type: "int", nullable: false),
+                    Month = table.Column<int>(type: "int", nullable: false),
+                    CaseNo = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    ApplicationType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    BusinessType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    AgentFeedbackMemo = table.Column<string>(type: "nvarchar(max)", nullable: true),
+                    DoItem = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    CaseStage = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    CaseCoefficient = table.Column<string>(type: "nvarchar(10)", maxLength: 10, nullable: true),
+                    DoItemCoefficient = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    PreOAStaffId = table.Column<int>(type: "int", nullable: true),
+                    ReviewerId = table.Column<int>(type: "int", nullable: true),
+                    CustomerId = table.Column<int>(type: "int", nullable: true),
+                    ApplicationName = table.Column<string>(type: "nvarchar(200)", maxLength: 200, nullable: true),
+                    FinishedDate = table.Column<DateTime>(type: "date", nullable: true),
+                    FinalizationDate = table.Column<DateTime>(type: "date", nullable: true),
+                    ReturnDate = table.Column<DateTime>(type: "date", nullable: true),
+                    CaseType = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    CaseState = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    DoItemMemo = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
+                    DoItemState = table.Column<string>(type: "nvarchar(50)", maxLength: 50, nullable: true),
+                    CaseName = table.Column<string>(type: "nvarchar(500)", maxLength: 500, nullable: true),
+                    CustomerLimitDate = table.Column<DateTime>(type: "date", nullable: true),
+                    EntrustingDate = table.Column<DateTime>(type: "date", nullable: true),
+                    InternalDate = table.Column<DateTime>(type: "date", nullable: true),
+                    FirstDraftDate = table.Column<DateTime>(type: "date", nullable: true),
+                    OverDueMemo = table.Column<string>(type: "nvarchar(100)", maxLength: 100, nullable: true),
+                    BasePoint = table.Column<decimal>(type: "numeric(18,2)", nullable: true),
+                    status = table.Column<int>(type: "int", nullable: true),
+                    StaffId = table.Column<int>(type: "int", nullable: true)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_PerformanceItem", x => x.Id);
+                    table.ForeignKey(
+                        name: "FK_PerformanceItem_Customer",
+                        column: x => x.CustomerId,
+                        principalTable: "Customer",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_PerformanceItem_Reviewer",
+                        column: x => x.ReviewerId,
+                        principalTable: "Staff",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_PerformanceItem_Staff",
+                        column: x => x.PreOAStaffId,
+                        principalTable: "Staff",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_PerformanceItem_Staff_StaffId",
+                        column: x => x.StaffId,
+                        principalTable: "Staff",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.CreateTable(
+                name: "ItemStaff",
+                columns: table => new
+                {
+                    ItemId = table.Column<int>(type: "int", nullable: false),
+                    DoPersonId = table.Column<int>(type: "int", nullable: false),
+                    PerformancePoint = table.Column<double>(type: "float", nullable: false)
+                },
+                constraints: table =>
+                {
+                    table.PrimaryKey("PK_ItemStaff", x => new { x.ItemId, x.DoPersonId });
+                    table.ForeignKey(
+                        name: "FK_ItemStaff_PerformanceItem",
+                        column: x => x.ItemId,
+                        principalTable: "PerformanceItem",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                    table.ForeignKey(
+                        name: "FK_ItemStaff_Staff",
+                        column: x => x.DoPersonId,
+                        principalTable: "Staff",
+                        principalColumn: "Id",
+                        onDelete: ReferentialAction.Restrict);
+                });
+
+            migrationBuilder.InsertData(
+                table: "StaffGrade",
+                columns: new[] { "Id", "Coefficient", "Grade" },
+                values: new object[,]
+                {
+                    { 1, 1.2, "S级" },
+                    { 2, 1.1000000000000001, "A3级" },
+                    { 3, 1.1000000000000001, "A2级" },
+                    { 4, 1.1000000000000001, "A1级" },
+                    { 5, 1.0, "B3级" },
+                    { 6, 1.0, "B2级" },
+                    { 7, 0.90000000000000002, "B1级" },
+                    { 8, 0.90000000000000002, "C3级" },
+                    { 9, 0.69999999999999996, "C2级" },
+                    { 10, 0.69999999999999996, "C1级" },
+                    { 11, 0.59999999999999998, "D3级" },
+                    { 12, 0.59999999999999998, "D2级" },
+                    { 13, 0.5, "D1级" }
+                });
+
+            migrationBuilder.InsertData(
+                table: "VerifyCoefficient",
+                columns: new[] { "CheckerId", "DoPersonId", "Coefficient" },
+                values: new object[,]
+                {
+                    { 2, 5, 0.20000000000000001 },
+                    { 2, 13, 0.5 },
+                    { 4, 12, 0.40000000000000002 },
+                    { 3, 12, 0.40000000000000002 },
+                    { 2, 12, 0.40000000000000002 },
+                    { 4, 11, 0.40000000000000002 },
+                    { 3, 11, 0.40000000000000002 },
+                    { 2, 11, 0.40000000000000002 },
+                    { 4, 10, 0.29999999999999999 },
+                    { 3, 10, 0.29999999999999999 },
+                    { 2, 10, 0.29999999999999999 },
+                    { 4, 9, 0.29999999999999999 },
+                    { 3, 13, 0.5 },
+                    { 3, 9, 0.29999999999999999 },
+                    { 4, 8, 0.20000000000000001 },
+                    { 3, 8, 0.20000000000000001 },
+                    { 2, 8, 0.20000000000000001 },
+                    { 4, 7, 0.20000000000000001 },
+                    { 3, 7, 0.20000000000000001 },
+                    { 2, 7, 0.20000000000000001 },
+                    { 4, 6, 0.20000000000000001 },
+                    { 3, 6, 0.20000000000000001 },
+                    { 2, 6, 0.20000000000000001 },
+                    { 4, 5, 0.20000000000000001 },
+                    { 3, 5, 0.20000000000000001 },
+                    { 2, 9, 0.29999999999999999 },
+                    { 4, 13, 0.5 }
+                });
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Customer_ResponseManId",
+                table: "Customer",
+                column: "ResponseManId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_ItemStaff_DoPersonId",
+                table: "ItemStaff",
+                column: "DoPersonId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_PerformanceItem_CustomerId",
+                table: "PerformanceItem",
+                column: "CustomerId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_PerformanceItem_PreOAStaffId",
+                table: "PerformanceItem",
+                column: "PreOAStaffId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_PerformanceItem_ReviewerId",
+                table: "PerformanceItem",
+                column: "ReviewerId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_PerformanceItem_StaffId",
+                table: "PerformanceItem",
+                column: "StaffId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_Staff_StaffGradeId",
+                table: "Staff",
+                column: "StaffGradeId");
+
+            migrationBuilder.CreateIndex(
+                name: "IX_VerifyCoefficient_DoPersonId",
+                table: "VerifyCoefficient",
+                column: "DoPersonId");
+        }
+
+        protected override void Down(MigrationBuilder migrationBuilder)
+        {
+            migrationBuilder.DropTable(
+                name: "ItemStaff");
+
+            migrationBuilder.DropTable(
+                name: "VerifyCoefficient");
+
+            migrationBuilder.DropTable(
+                name: "PerformanceItem");
+
+            migrationBuilder.DropTable(
+                name: "Customer");
+
+            migrationBuilder.DropTable(
+                name: "Staff");
+
+            migrationBuilder.DropTable(
+                name: "StaffGrade");
+        }
+    }
+}

+ 653 - 0
wispro.sp.api/Migrations/spDbContextModelSnapshot.cs

@@ -0,0 +1,653 @@
+// <auto-generated />
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using wispro.sp.api;
+
+namespace wispro.sp.api.Migrations
+{
+    [DbContext(typeof(spDbContext))]
+    partial class spDbContextModelSnapshot : ModelSnapshot
+    {
+        protected override void BuildModel(ModelBuilder modelBuilder)
+        {
+#pragma warning disable 612, 618
+            modelBuilder
+                .HasAnnotation("Relational:Collation", "Chinese_PRC_CI_AS")
+                .HasAnnotation("Relational:MaxIdentifierLength", 128)
+                .HasAnnotation("ProductVersion", "5.0.9")
+                .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.Property<int>("Id")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Address")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("ContactMan")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(200)
+                        .HasColumnType("nvarchar(200)");
+
+                    b.Property<string>("Phone")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<int?>("ResponseManId")
+                        .HasColumnType("int");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("ResponseManId");
+
+                    b.ToTable("Customer");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.ItemStaff", b =>
+                {
+                    b.Property<int>("ItemId")
+                        .HasColumnType("int");
+
+                    b.Property<int>("DoPersonId")
+                        .HasColumnType("int");
+
+                    b.Property<double>("PerformancePoint")
+                        .HasColumnType("float");
+
+                    b.HasKey("ItemId", "DoPersonId");
+
+                    b.HasIndex("DoPersonId");
+
+                    b.ToTable("ItemStaff");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<string>("AgentFeedbackMemo")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("ApplicationName")
+                        .HasMaxLength(200)
+                        .HasColumnType("nvarchar(200)");
+
+                    b.Property<string>("ApplicationType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<decimal?>("BasePoint")
+                        .HasColumnType("numeric(18,2)");
+
+                    b.Property<string>("BusinessType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseCoefficient")
+                        .HasMaxLength(10)
+                        .HasColumnType("nvarchar(10)");
+
+                    b.Property<string>("CaseName")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("CaseNo")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseStage")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseState")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("CaseType")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<int?>("CustomerId")
+                        .HasColumnType("int");
+
+                    b.Property<DateTime?>("CustomerLimitDate")
+                        .HasColumnType("date");
+
+                    b.Property<string>("DoItem")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("DoItemCoefficient")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("DoItemMemo")
+                        .HasMaxLength(500)
+                        .HasColumnType("nvarchar(500)");
+
+                    b.Property<string>("DoItemState")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<DateTime?>("EntrustingDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FinalizationDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FinishedDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("FirstDraftDate")
+                        .HasColumnType("date");
+
+                    b.Property<DateTime?>("InternalDate")
+                        .HasColumnType("date");
+
+                    b.Property<int>("Month")
+                        .HasColumnType("int");
+
+                    b.Property<string>("OverDueMemo")
+                        .HasMaxLength(100)
+                        .HasColumnType("nvarchar(100)");
+
+                    b.Property<int?>("PreOastaffId")
+                        .HasColumnType("int")
+                        .HasColumnName("PreOAStaffId");
+
+                    b.Property<DateTime?>("ReturnDate")
+                        .HasColumnType("date");
+
+                    b.Property<int?>("ReviewerId")
+                        .HasColumnType("int");
+
+                    b.Property<int?>("StaffId")
+                        .HasColumnType("int");
+
+                    b.Property<int?>("Status")
+                        .HasColumnType("int")
+                        .HasColumnName("status");
+
+                    b.Property<int>("Year")
+                        .HasColumnType("int");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("CustomerId");
+
+                    b.HasIndex("PreOastaffId");
+
+                    b.HasIndex("ReviewerId");
+
+                    b.HasIndex("StaffId");
+
+                    b.ToTable("PerformanceItem");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.Property<int>("Id")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Account")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Department")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<DateTime?>("EntyDate")
+                        .HasColumnType("date");
+
+                    b.Property<bool>("IsCalPerformsnce")
+                        .HasColumnType("bit")
+                        .HasColumnName("isCalPerformsnce");
+
+                    b.Property<string>("Memo")
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<string>("Name")
+                        .IsRequired()
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.Property<string>("Password")
+                        .IsRequired()
+                        .HasColumnType("nvarchar(max)");
+
+                    b.Property<int>("StaffGradeId")
+                        .HasColumnType("int");
+
+                    b.Property<string>("Status")
+                        .IsRequired()
+                        .HasMaxLength(25)
+                        .HasColumnType("nvarchar(25)");
+
+                    b.Property<string>("WorkPlace")
+                        .HasMaxLength(50)
+                        .HasColumnType("nvarchar(50)");
+
+                    b.HasKey("Id");
+
+                    b.HasIndex("StaffGradeId");
+
+                    b.ToTable("Staff");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.StaffGrade", b =>
+                {
+                    b.Property<int>("Id")
+                        .ValueGeneratedOnAdd()
+                        .HasColumnType("int")
+                        .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+                    b.Property<double>("Coefficient")
+                        .HasColumnType("float");
+
+                    b.Property<string>("Grade")
+                        .IsRequired()
+                        .HasMaxLength(5)
+                        .HasColumnType("nchar(5)")
+                        .IsFixedLength(true);
+
+                    b.HasKey("Id");
+
+                    b.ToTable("StaffGrade");
+
+                    b.HasData(
+                        new
+                        {
+                            Id = 1,
+                            Coefficient = 1.2,
+                            Grade = "S级"
+                        },
+                        new
+                        {
+                            Id = 2,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A3级"
+                        },
+                        new
+                        {
+                            Id = 3,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A2级"
+                        },
+                        new
+                        {
+                            Id = 4,
+                            Coefficient = 1.1000000000000001,
+                            Grade = "A1级"
+                        },
+                        new
+                        {
+                            Id = 5,
+                            Coefficient = 1.0,
+                            Grade = "B3级"
+                        },
+                        new
+                        {
+                            Id = 6,
+                            Coefficient = 1.0,
+                            Grade = "B2级"
+                        },
+                        new
+                        {
+                            Id = 7,
+                            Coefficient = 0.90000000000000002,
+                            Grade = "B1级"
+                        },
+                        new
+                        {
+                            Id = 8,
+                            Coefficient = 0.90000000000000002,
+                            Grade = "C3级"
+                        },
+                        new
+                        {
+                            Id = 9,
+                            Coefficient = 0.69999999999999996,
+                            Grade = "C2级"
+                        },
+                        new
+                        {
+                            Id = 10,
+                            Coefficient = 0.69999999999999996,
+                            Grade = "C1级"
+                        },
+                        new
+                        {
+                            Id = 11,
+                            Coefficient = 0.59999999999999998,
+                            Grade = "D3级"
+                        },
+                        new
+                        {
+                            Id = 12,
+                            Coefficient = 0.59999999999999998,
+                            Grade = "D2级"
+                        },
+                        new
+                        {
+                            Id = 13,
+                            Coefficient = 0.5,
+                            Grade = "D1级"
+                        });
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.VerifyCoefficient", b =>
+                {
+                    b.Property<int>("CheckerId")
+                        .HasColumnType("int");
+
+                    b.Property<int>("DoPersonId")
+                        .HasColumnType("int");
+
+                    b.Property<double>("Coefficient")
+                        .HasColumnType("float");
+
+                    b.HasKey("CheckerId", "DoPersonId");
+
+                    b.HasIndex("DoPersonId");
+
+                    b.ToTable("VerifyCoefficient");
+
+                    b.HasData(
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 2,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 3,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 5,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 6,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 7,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 8,
+                            Coefficient = 0.20000000000000001
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 9,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 10,
+                            Coefficient = 0.29999999999999999
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 11,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 12,
+                            Coefficient = 0.40000000000000002
+                        },
+                        new
+                        {
+                            CheckerId = 4,
+                            DoPersonId = 13,
+                            Coefficient = 0.5
+                        });
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Staff", "ResponseMan")
+                        .WithMany("Customers")
+                        .HasForeignKey("ResponseManId")
+                        .HasConstraintName("FK_Customer_Staff");
+
+                    b.Navigation("ResponseMan");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.ItemStaff", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Staff", "DoPerson")
+                        .WithMany("ItemStaffs")
+                        .HasForeignKey("DoPersonId")
+                        .HasConstraintName("FK_ItemStaff_Staff")
+                        .IsRequired();
+
+                    b.HasOne("wispro.sp.entity.PerformanceItem", "Item")
+                        .WithMany("ItemStaffs")
+                        .HasForeignKey("ItemId")
+                        .HasConstraintName("FK_ItemStaff_PerformanceItem")
+                        .IsRequired();
+
+                    b.Navigation("DoPerson");
+
+                    b.Navigation("Item");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.HasOne("wispro.sp.entity.Customer", "Customer")
+                        .WithMany("PerformanceItems")
+                        .HasForeignKey("CustomerId")
+                        .HasConstraintName("FK_PerformanceItem_Customer");
+
+                    b.HasOne("wispro.sp.entity.Staff", "PreOastaff")
+                        .WithMany()
+                        .HasForeignKey("PreOastaffId")
+                        .HasConstraintName("FK_PerformanceItem_Staff");
+
+                    b.HasOne("wispro.sp.entity.Staff", "Reviewer")
+                        .WithMany("ReviewerItems")
+                        .HasForeignKey("ReviewerId")
+                        .HasConstraintName("FK_PerformanceItem_Reviewer");
+
+                    b.HasOne("wispro.sp.entity.Staff", null)
+                        .WithMany("PerformanceItems")
+                        .HasForeignKey("StaffId");
+
+                    b.Navigation("Customer");
+
+                    b.Navigation("PreOastaff");
+
+                    b.Navigation("Reviewer");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.HasOne("wispro.sp.entity.StaffGrade", "StaffGrade")
+                        .WithMany("Staff")
+                        .HasForeignKey("StaffGradeId")
+                        .HasConstraintName("FK_Staff_StaffGrade")
+                        .IsRequired();
+
+                    b.Navigation("StaffGrade");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.VerifyCoefficient", b =>
+                {
+                    b.HasOne("wispro.sp.entity.StaffGrade", "Checker")
+                        .WithMany("VerifyCoefficientCheckers")
+                        .HasForeignKey("CheckerId")
+                        .HasConstraintName("FK_VerifyCoefficient_StaffGrade")
+                        .IsRequired();
+
+                    b.HasOne("wispro.sp.entity.StaffGrade", "DoPerson")
+                        .WithMany("VerifyCoefficientDoPeople")
+                        .HasForeignKey("DoPersonId")
+                        .HasConstraintName("FK_VerifyCoefficient_StaffGrade1")
+                        .IsRequired();
+
+                    b.Navigation("Checker");
+
+                    b.Navigation("DoPerson");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Customer", b =>
+                {
+                    b.Navigation("PerformanceItems");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.PerformanceItem", b =>
+                {
+                    b.Navigation("ItemStaffs");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.Staff", b =>
+                {
+                    b.Navigation("Customers");
+
+                    b.Navigation("ItemStaffs");
+
+                    b.Navigation("PerformanceItems");
+
+                    b.Navigation("ReviewerItems");
+                });
+
+            modelBuilder.Entity("wispro.sp.entity.StaffGrade", b =>
+                {
+                    b.Navigation("Staff");
+
+                    b.Navigation("VerifyCoefficientCheckers");
+
+                    b.Navigation("VerifyCoefficientDoPeople");
+                });
+#pragma warning restore 612, 618
+        }
+    }
+}

+ 67 - 0
wispro.sp.api/Program.cs

@@ -0,0 +1,67 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using System;
+using System.Linq;
+
+namespace wispro.sp.api
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            //spDbContext context = new spDbContext();
+
+            ////判断是否有待迁移
+            //if (context.Database.GetPendingMigrations().Any())
+            //{
+            //    //Console.WriteLine("Migrating...");
+            //    ////执行迁移
+            //    //context.Database.Migrate();
+            //    //Console.WriteLine("Migrated");
+            //}
+
+            
+            var host = CreateHostBuilder(args).Build();
+
+            using (var serviceScope = host.Services.CreateScope())
+            {
+                var services = serviceScope.ServiceProvider;
+
+                try
+                {
+                    var context = services.GetRequiredService<spDbContext>();
+
+                    var result = context.Database.EnsureCreated();
+
+                    if (result)
+                    {
+                        System.Diagnostics.Debug.Write("数据库创建成功!");
+                    }
+                    else
+                    {
+                        System.Diagnostics.Debug.Write("数据库创建失败!");
+                    }
+                    
+                }
+                catch (Exception ex)
+                {
+                    //var logger = services.GetRequiredService<ILogger<Program>>();
+                    //logger.LogError(ex, "An error occurred.");
+                }
+            }
+
+            host.Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+
+        
+    }
+}

+ 30 - 0
wispro.sp.api/Properties/launchSettings.json

@@ -0,0 +1,30 @@
+{
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:39476",
+      "sslPort": 44359
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "api/Staff/getAll",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "wispro.sp.api": {
+      "commandName": "Project",
+      "launchBrowser": true,
+      "launchUrl": "api/Staff/getAll",
+      "applicationUrl": "https://localhost:5001;http://localhost:5000",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 100 - 0
wispro.sp.api/Startup.cs

@@ -0,0 +1,100 @@
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.Text;
+
+namespace wispro.sp.api
+{
+    public class Startup
+    {
+        readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+            services.AddCors(options =>
+            {
+                options.AddPolicy(MyAllowSpecificOrigins,
+                builder =>
+                {
+                    builder.AllowAnyOrigin()
+                           .AllowAnyMethod()
+                           .AllowAnyHeader();
+                });
+            });
+
+            
+            //services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
+            //    .AddJwtBearer(options =>
+            //    {
+            //        options.TokenValidationParameters = new TokenValidationParameters
+            //        {
+            //            ValidateIssuer = true,//是否验证Issuer
+            //            ValidateAudience = true,//是否验证Audience
+            //            ValidateLifetime = true,//是否验证失效时间
+            //            ValidateIssuerSigningKey = true,//是否验证SecurityKey
+            //            ValidAudience = Configuration["jwt:Audience"],//Audience
+            //            ValidIssuer = Configuration["jwt:Issuer"],//Issuer,这两项和签发jwt的设置一致
+            //            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:Key"]))//拿到SecurityKey
+            //        };
+            //    });
+
+            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(option =>
+            {
+                option.TokenValidationParameters = new TokenValidationParameters
+                {
+                    ValidateIssuer = false,
+                    ValidateAudience = false,
+                    ValidateLifetime = true,
+                    ValidateIssuerSigningKey = true,
+                    ValidIssuer = Configuration["jwt:Issuer"],
+                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["jwt:Key"])),
+                    ClockSkew = TimeSpan.Zero
+                };
+            });
+
+            services.AddControllers().AddNewtonsoftJson(o=>o.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
+            services.AddDbContext<spDbContext>(optionsAction =>
+                optionsAction.UseSqlServer(Configuration.GetConnectionString("DefaultConnect"))
+            );
+            
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseCors(MyAllowSpecificOrigins);
+
+            app.UseHttpsRedirection();
+
+            app.UseRouting();
+
+            app.UseAuthentication();
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllers();
+            });
+
+            
+        }
+    }
+}

+ 9 - 0
wispro.sp.api/appsettings.Development.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  }
+}

+ 23 - 0
wispro.sp.api/appsettings.json

@@ -0,0 +1,23 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  },
+  "AllowedHosts": "*",
+  "ConnectionStrings": {
+    "DefaultConnect": "Data Source=(local);Initial Catalog=spDB;User ID=sa;Password=Lqftiu807005"
+  },
+
+
+  "ValidAudience": "StaffPerformance",
+  "ValidIssuer": "http://localhost:39476",
+
+  "jwt": {
+    "Key": "fef3d2e1Edwfw43312321edszaSd",
+    "Audience": "StaffPerformance",
+    "Issuer": "http://localhost:39476"
+  }
+}

+ 350 - 0
wispro.sp.api/spDbContext.cs

@@ -0,0 +1,350 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using System.Configuration;
+using wispro.sp.entity;
+
+
+namespace wispro.sp.api
+{
+    public partial class spDbContext : DbContext
+    {
+        public spDbContext()
+        {
+        }
+
+        public spDbContext(DbContextOptions<spDbContext> options)
+            : base(options)
+        {
+        }
+
+        public virtual DbSet<Customer> Customers { get; set; }
+        public virtual DbSet<ItemStaff> ItemStaffs { get; set; }
+        public virtual DbSet<PerformanceItem> PerformanceItems { get; set; }
+        public virtual DbSet<StaffGrade> StaffGrades { get; set; }
+        public virtual DbSet<VerifyCoefficient> VerifyCoefficients { get; set; }
+        public virtual DbSet<Staff> Staffs { get; set; }
+
+        public virtual DbSet<Message> Messages { get; set; }
+
+        public virtual DbSet<MessageReadRecord> MessageReadRecords { get;set;}
+
+        public virtual DbSet<MessagePerformanceItem> MessagePerformanceItems { get; set; }
+
+        public virtual DbSet<AttachFile> AttachFiles { get; set; }
+
+        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
+        {
+            if (!optionsBuilder.IsConfigured)
+            {
+                optionsBuilder.UseSqlServer("Data Source=(local);Initial Catalog=spDB;User ID=sa;Password=Lqftiu807005");// Configuration.GetConnectionString("DefaultConnect"));
+                //ConfigurationManager.AppSettings["ValidAudience"]
+            }
+        }
+
+        protected override void OnModelCreating(ModelBuilder modelBuilder)
+        {
+
+            modelBuilder.Entity<Customer>(entity =>
+            {
+                entity.ToTable("Customer");
+
+                entity.Property(e => e.Address).HasMaxLength(500);
+
+                entity.Property(e => e.ContactMan).HasMaxLength(50);
+
+                entity.Property(e => e.Name)
+                    .IsRequired()
+                    .HasMaxLength(200);
+
+                entity.Property(e => e.Phone).HasMaxLength(50);
+
+                entity.HasOne(d => d.ResponseMan)
+                    .WithMany(p => p.Customers)
+                    .HasForeignKey(d => d.ResponseManId)
+                    .HasConstraintName("FK_Customer_Staff");
+            });
+
+            modelBuilder.Entity<ItemStaff>(entity =>
+            {
+                entity.HasKey(e => new { e.ItemId, e.DoPersonId });
+
+                entity.ToTable("ItemStaff");
+
+                entity.Property(e => e.PerformancePoint);//.HasColumnType("numeric(18, 2)");
+
+                entity.HasOne(d => d.DoPerson)
+                    .WithMany(p => p.ItemStaffs)
+                    .HasForeignKey(d => d.DoPersonId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_ItemStaff_Staff");
+
+                entity.HasOne(d => d.Item)
+                    .WithMany(p => p.ItemStaffs)
+                    .HasForeignKey(d => d.ItemId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_ItemStaff_PerformanceItem");
+            });
+
+            modelBuilder.Entity<PerformanceItem>(entity =>
+            {
+                entity.ToTable("PerformanceItem");
+
+                entity.Property(e => e.ApplicationName).HasMaxLength(200);
+
+                entity.Property(e => e.ApplicationType).HasMaxLength(50);
+
+                entity.Property(e => e.BasePoint).HasColumnType("numeric(18, 2)");
+
+                entity.Property(e => e.BusinessType).HasMaxLength(50);
+
+                entity.Property(e => e.CaseCoefficient).HasMaxLength(10);
+
+                entity.Property(e => e.CaseName).HasMaxLength(500);
+
+                entity.Property(e => e.CaseNo).HasMaxLength(50);
+
+                entity.Property(e => e.CaseStage).HasMaxLength(50);
+
+                entity.Property(e => e.CaseState).HasMaxLength(50);
+
+                entity.Property(e => e.CaseType).HasMaxLength(50);
+
+                entity.Property(e => e.EntrustingDate).HasColumnType("date");
+
+                entity.Property(e => e.CustomerLimitDate).HasColumnType("date");
+
+                entity.Property(e => e.DoItem).HasMaxLength(50);
+
+                entity.Property(e => e.DoItemCoefficient).HasMaxLength(50);
+
+                entity.Property(e => e.DoItemMemo).HasMaxLength(500);
+
+                entity.Property(e => e.DoItemState).HasMaxLength(50);
+
+                entity.Property(e => e.FinalizationDate).HasColumnType("date");
+
+                entity.Property(e => e.FinishedDate).HasColumnType("date");
+
+                entity.Property(e => e.FirstDraftDate).HasColumnType("date");
+
+                entity.Property(e => e.InternalDate).HasColumnType("date");
+
+                entity.Property(e => e.OverDueMemo).HasMaxLength(100);
+
+                entity.Property(e => e.PreOastaffId).HasColumnName("PreOAStaffId");
+
+                entity.Property(e => e.ReturnDate).HasColumnType("date");
+
+                entity.Property(e => e.Status).HasColumnName("status");
+
+                entity.HasOne(d => d.Customer)
+                    .WithMany(p => p.PerformanceItems)
+                    .HasForeignKey(d => d.CustomerId)
+                    .HasConstraintName("FK_PerformanceItem_Customer");
+
+                entity.HasOne(d => d.PreOastaff)
+                    .WithMany()
+                    .HasForeignKey(d => d.PreOastaffId)
+                    .HasConstraintName("FK_PerformanceItem_Staff");
+
+                entity.HasOne(d => d.Reviewer)
+                    .WithMany(p => p.ReviewerItems)
+                    .HasForeignKey(d => d.ReviewerId)
+                    .HasConstraintName("FK_PerformanceItem_Reviewer");
+            });
+
+            modelBuilder.Entity<StaffGrade>(entity =>
+            {
+                entity.ToTable("StaffGrade");
+
+                entity.Property(e => e.Coefficient);//.HasColumnType("numeric(18, 2)");
+
+                entity.Property(e => e.Grade)
+                    .IsRequired()
+                    .HasMaxLength(5)
+                    .IsFixedLength(true);
+            });
+
+            modelBuilder.Entity<VerifyCoefficient>(entity =>
+            {
+                entity.HasKey(e => new { e.CheckerId, e.DoPersonId });
+
+                entity.ToTable("VerifyCoefficient");
+
+                entity.Property(e => e.Coefficient);//.HasColumnType("numeric(18, 2)");
+
+                entity.HasOne(d => d.Checker)
+                    .WithMany(p => p.VerifyCoefficientCheckers)
+                    .HasForeignKey(d => d.CheckerId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_VerifyCoefficient_StaffGrade");
+
+                entity.HasOne(d => d.DoPerson)
+                    .WithMany(p => p.VerifyCoefficientDoPeople)
+                    .HasForeignKey(d => d.DoPersonId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_VerifyCoefficient_StaffGrade1");
+            });
+
+            modelBuilder.Entity<Staff>(entity =>
+            {
+                entity.ToTable("Staff");
+
+                //entity.Property(e => e.Id).ValueGeneratedNever();
+
+                entity.Property(e => e.Account)
+                    .IsRequired()
+                    .HasMaxLength(50);
+
+                entity.Property(e => e.Department).HasMaxLength(50);
+
+                entity.Property(e => e.EntyDate).HasColumnType("date");
+
+                entity.Property(e => e.IsCalPerformsnce).HasColumnName("isCalPerformsnce");
+
+                entity.Property(e => e.Name)
+                    .IsRequired()
+                    .HasMaxLength(50);
+
+                entity.Property(e => e.Password).IsRequired();
+
+                entity.Property(e => e.Status)
+                    .IsRequired()
+                    .HasMaxLength(25);
+
+                entity.Property(e => e.WorkPlace).HasMaxLength(50);
+
+                entity.HasOne(d => d.StaffGrade)
+                    .WithMany(p => p.Staff)
+                    .HasForeignKey(d => d.StaffGradeId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_Staff_StaffGrade");
+            });
+
+            modelBuilder.Entity<Message>(entity =>
+            {
+                //entity.HasKey(e => e.Id);
+
+                entity.ToTable("Message");
+
+                entity.Property(e => e.Type);
+                entity.Property(e => e.MessageInfo).HasMaxLength(500);
+
+                entity.HasOne(d => d.From)
+                    .WithMany()
+                    .HasForeignKey(d => d.FromId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_From_Staff");
+
+            });
+            
+
+            modelBuilder.Entity<MessageReadRecord>(entity =>
+            {
+                entity.HasKey(e => new { e.MessageId,e.StaffId});
+
+                entity.ToTable("MessageReadRecord");
+
+                entity.Property(e => e.isReaded);
+
+                entity.HasOne(d => d.Staff)
+                    .WithMany()
+                    .HasForeignKey(d => d.StaffId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_MessageReadRecord_Staff");
+
+                entity.HasOne(d => d.Message)
+                    .WithMany()
+                    .HasForeignKey(d => d.MessageId)
+                    .OnDelete(DeleteBehavior.ClientSetNull)
+                    .HasConstraintName("FK_MessageReadRecord_Message");
+
+            });
+
+            modelBuilder.Entity<MessagePerformanceItem>( entity =>
+            {
+                entity.HasKey(e=> new { e.ItemId,e.MessageId});
+
+                entity.HasOne(d => d.Message)
+                    .WithMany(m => m.RelatedItem)
+                    .HasForeignKey(d => d.MessageId)
+                    .HasConstraintName("FK_MessagePerformanceItem_Message");
+
+                entity.HasOne(d => d.Item )
+                    .WithMany()
+                    .HasForeignKey(d => d.ItemId)
+                    .HasConstraintName("FK_MessagePerformanceItem_Item");
+            });
+
+            modelBuilder.Entity<AttachFile>(entity =>
+            {
+
+                entity.ToTable("AttachFile");
+
+                entity.Property(e=>e.Name).HasMaxLength(200);
+                entity.Property(e => e.SavePath).HasMaxLength(200);
+
+                entity.HasOne(d => d.UploadUser)
+                    .WithMany()
+                    .HasForeignKey(d => d.UploadUserId)
+                    .HasConstraintName("FK_AttachFile_UpdateUser");
+            });
+
+            modelBuilder.Entity<StaffGrade>().HasData(
+                new StaffGrade[]
+                {
+                    new StaffGrade() {Id=1, Grade = "S级", Coefficient = 1.2},
+                    new StaffGrade() {Id=2, Grade = "A3级", Coefficient = 1.1},
+                    new StaffGrade() {Id =3, Grade = "A2级", Coefficient = 1.1},
+                    new StaffGrade() {Id=4, Grade = "A1级", Coefficient = 1.1},
+                    new StaffGrade() {Id=5, Grade = "B3级", Coefficient = 1.0},
+                    new StaffGrade() {Id=6, Grade = "B2级", Coefficient = 1.0},
+                    new StaffGrade() {Id=7, Grade = "B1级", Coefficient = 0.9},
+                    new StaffGrade() {Id=8, Grade = "C3级", Coefficient = 0.9},
+                    new StaffGrade() {Id=9, Grade = "C2级", Coefficient = 0.7},
+                    new StaffGrade() {Id= 10, Grade = "C1级", Coefficient = 0.7},
+                    new StaffGrade() {Id=11, Grade = "D3级", Coefficient = 0.6},
+                    new StaffGrade() {Id=12, Grade = "D2级", Coefficient = 0.6},
+                    new StaffGrade() {Id=13, Grade = "D1级", Coefficient = 0.5}
+                });
+
+            modelBuilder.Entity<VerifyCoefficient>().HasData(
+                new VerifyCoefficient[]
+                {
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =5, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =6, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =7, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =8, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =9, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =10, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =11, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =12, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 2, DoPersonId =13, Coefficient = 0.5},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =5, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =6, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =7, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =8, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =9, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =10, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =11, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =12, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 3, DoPersonId =13, Coefficient = 0.5},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =5, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =6, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =7, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =8, Coefficient = 0.2},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =9, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =10, Coefficient = 0.3},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =11, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =12, Coefficient = 0.4},
+                    new VerifyCoefficient() { CheckerId  = 4, DoPersonId =13, Coefficient = 0.5},
+                }
+                );
+
+
+            OnModelCreatingPartial(modelBuilder);
+        }
+
+        partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
+    }
+}

+ 27 - 0
wispro.sp.api/wispro.sp.api.csproj

@@ -0,0 +1,27 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+    <Platforms>AnyCPU;x64;x86</Platforms>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.18" />
+    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.10" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.9">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\wispro.sp.share\wispro.sp.share.csproj" />
+    <ProjectReference Include="..\wispro.sp.utility\wispro.sp.utility.csproj" />
+    <ProjectReference Include="..\wospro.sp.entity\wispro.sp.entity.csproj" />
+  </ItemGroup>
+
+  <ProjectExtensions><VisualStudio><UserProperties appsettings_1json__JsonSchema="" /></VisualStudio></ProjectExtensions>
+
+
+</Project>

+ 24 - 0
wispro.sp.data/ItemStaffMap.cs

@@ -0,0 +1,24 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+
+namespace wispro.sp.datamap
+{
+    public class ItemStaffMap : IEntityTypeConfiguration<ItemStaff>
+    {
+        public void Configure(EntityTypeBuilder<ItemStaff> builder)
+        {
+            //builder.HasNoKey();
+            //builder.HasKey(o=> new {o.DoPersonId,o.ItemId });
+            //builder.HasOne(o => o.DoPerson).WithMany().HasForeignKey("DoPersonId");
+            //builder.HasOne(o => o.Item).WithMany(x=>x.DoPersons).HasForeignKey("ItemId");
+        }
+
+    }
+
+}

+ 18 - 0
wispro.sp.data/PerformanceItemMap.cs

@@ -0,0 +1,18 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using wispro.sp.entity;
+
+namespace wispro.sp.datamap
+{
+    public class PerformanceItemMap : IEntityTypeConfiguration<PerformanceItem>
+    {
+        public void Configure(EntityTypeBuilder<PerformanceItem> builder)
+        {
+            builder.HasKey(o => o.Id);
+            builder.HasOne(o => o.PreOAStaff).WithMany().HasForeignKey("PreOAStaffId");
+            //builder.HasMany(o => o.DoPersons).WithOne(t => t.Item).IsRequired();
+            
+        }
+
+    }
+}

+ 21 - 0
wispro.sp.data/StaffGradeMap.cs

@@ -0,0 +1,21 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using wispro.sp.entity;
+
+namespace wispro.sp.datamap
+{
+    public class StaffGradeMap: IEntityTypeConfiguration<StaffGrade>
+    {
+        public void Configure(EntityTypeBuilder<StaffGrade> b)
+        {
+            //b.HasKey(o => o.Id);
+            b.Property(e => e.Coefficient).HasColumnType("decimal(2, 1)");
+
+            b.Property(e => e.Grade)
+                .IsRequired()
+                .HasMaxLength(5)
+                .IsFixedLength(true);
+        }
+        
+    }
+}

+ 17 - 0
wispro.sp.data/StaffMap.cs

@@ -0,0 +1,17 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using wispro.sp.entity;
+
+namespace wispro.sp.datamap
+{
+    public class StaffMap : IEntityTypeConfiguration<Staff>
+    {
+        public void Configure(EntityTypeBuilder<Staff> builder)
+        {
+            builder.HasKey(o => o.Id);
+            //builder.HasOne(o => o.StaffGrade).WithMany(o => o.Staffs).HasForeignKey("StaffGradeId");
+        }
+
+    }
+    
+}

+ 28 - 0
wispro.sp.data/VerifyCoeffientMap.cs

@@ -0,0 +1,28 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using wispro.sp.entity;
+
+namespace wispro.sp.datamap
+{
+    public class VerifyCoefficientMap : IEntityTypeConfiguration<VerifyCoefficient>
+    {
+        public void Configure(EntityTypeBuilder<VerifyCoefficient> builder)
+        {
+            builder.HasKey(o => new { o.CheckerId, o.DoPersonId });
+
+            builder.ToTable("VerifyCoefficient");
+
+            builder.Property(e => e.Coefficient).HasColumnType("decimal(18, 0)");
+
+            builder.HasOne(d => d.Checker)
+                .WithMany()
+                .HasForeignKey(d => d.CheckerId);
+
+            builder.HasOne(d => d.DoPerson)
+                .WithMany(p => p.VerifyCoefficientDoPeople)
+                .HasForeignKey(d => d.CheckerId);
+        }
+        
+    }
+    
+}

+ 20 - 0
wispro.sp.data/wispro.sp.datamap.csproj

@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.9" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
+    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.9">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\wospro.sp.entity\wispro.sp.entity.csproj" />
+  </ItemGroup>
+
+</Project>

+ 15 - 0
wispro.sp.share/ApiSaveResponse.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.share
+{
+    public class ApiSaveResponse
+    {
+        public bool Success { get; set; }
+
+        public string ErrorMessage { get; set; }
+    }
+}

+ 16 - 0
wispro.sp.share/ListApiResponse.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+
+namespace wispro.sp.share
+{
+    public class  ListApiResponse<T>
+    {
+        public List<T> Results { get; set; }
+
+        public int TotalCount { get; set; }
+    }
+}

+ 22 - 0
wispro.sp.share/QueryFilter.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.share
+{
+    public class QueryFilter
+    {
+        public int pageIndex { get; set; }
+        public int pageSize { get; set; }
+
+        public string PersonName { get; set; }
+
+        public int? Year { get; set; }
+
+        public int? Month { get; set; }
+
+        
+    }
+}

+ 18 - 0
wispro.sp.share/webViewObject/loginDto.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.share.webViewObject
+{
+    public class loginDto
+    {
+        [Required(ErrorMessage = "请填写Email")]
+        public string Name { get; set; }
+
+        [Required(ErrorMessage = "请填写Password")]
+        public string Password { get; set; }
+    }
+}

+ 18 - 0
wispro.sp.share/webViewObject/userToken.cs

@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.share.webViewObject
+{
+    public class userToken
+    {
+        public HttpStatusCode StatusCode { get; set; }
+        public string Name { get; set; }
+        public string Token { get; set; }
+        
+        public DateTime ExpireTime { get; set; }
+    }
+}

+ 12 - 0
wispro.sp.share/wispro.sp.share.csproj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+    <Platforms>AnyCPU;x64;x86</Platforms>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\wospro.sp.entity\wispro.sp.entity.csproj" />
+  </ItemGroup>
+
+</Project>

+ 504 - 0
wispro.sp.utility/ExcelHelper.cs

@@ -0,0 +1,504 @@
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Configuration;
+
+namespace wispro.sp.utility
+{
+    public class ExcelHelper
+    {
+
+        //string[] temList = new string[] {"PACN1917256",
+        //                                    "PAUS2010223",
+        //                                    "PAUS1914936",
+        //                                    "PACN1815861",
+        //                                    "PACN1913445",
+        //                                    "PACN1816576",
+        //                                    "PACN2113860",
+        //                                    "PACN1812755-结案",
+        //                                    "PACN2015701",
+        //                                    "PCTCN1815005",
+        //                                    "PACN1913883-加快",
+        //                                    "PACN1915086-加快",
+        //                                    "PACN1810141",
+        //                                    "PACN1815247",
+        //                                    "PACN1812737",
+        //                                    "PACN1813923",
+        //                                    "PACN1912513",
+        //                                    "PACN1912504",
+        //                                    "PAEPO2112337",
+        //                                    "PAUS2111949",
+        //                                    "PATW2111951",
+        //                                    "PAEPO2111950",
+        //                                    "PAEPO2111788",
+        //                                    "PAEPO2013035",
+        //                                    "PAEPO1918035",
+        //                                    "PAEPO1813034",
+        //                                    "PAGB1711461" };
+
+        public DataTable MerageExcel(string desFileName,string[] excelFiles)
+        {
+            DataTable retDt = null;
+            foreach(string strFileName in excelFiles)
+            {
+                if (System.IO.File.Exists(strFileName))
+                {
+                    if (retDt == null)
+                    {
+                        retDt = NPOIExcel.ExcelToDataTable(strFileName, true,true);
+
+                        DataTable temdt = new DataTable();
+                        foreach(DataColumn col in retDt.Columns)
+                        {
+                            
+                            DataColumn temCol = new DataColumn();
+                            temCol.ColumnName = col.ColumnName;
+                            temCol.DataType = col.DataType;
+                            temCol.Caption = col.Caption;
+                            
+                            temdt.Columns.Add(temCol);
+                        }
+
+                        MerageDataTable(temdt, retDt);
+
+                        retDt = temdt;
+                    }
+                    else
+                    {
+                        DataTable dt = NPOIExcel.ExcelToDataTable(strFileName, true, true);
+                        MerageDataTable(retDt, dt);
+
+                    }
+                }
+                else
+                {
+                    throw new ApplicationException($"文件不存在:{strFileName}");
+                }
+            }
+
+            string strCalculatedFile = ConfigurationSettings.AppSettings["CalculatedFile"];// "21.01-21.06 工程师绩效报表-总表.xlsx";
+            DataTable CalculatedTable = NPOIExcel.ExcelToDataTable(strCalculatedFile, true);
+
+            #region  删除空行
+            List<DataRow> delRows = new List<DataRow>();
+            System.Collections.Hashtable temHash = new System.Collections.Hashtable();
+            foreach (DataRow row in retDt.Rows)
+            {
+                if ((row[0] == null || row[0].ToString() == "") && (row[1] == null || row[1].ToString() == "") && (row[2] == null || row[2].ToString() == ""))
+                {
+                    delRows.Add(row);
+                }
+                else
+                {
+                    #region 添加我方案号和处理事项相同的项目到hashTable
+                    string strKey = $"{row["我方文号"].ToString()}-{row["处理事项"].ToString()}";
+                    if(temHash.Contains(strKey))
+                    {
+                        List<DataRow> List = (List<DataRow>)temHash[strKey];
+                        List.Add(row);
+                    }
+                    else
+                    {
+                        List<DataRow> List = new List<DataRow>();
+                        List.Add(row);
+                        temHash.Add(strKey, List);
+                    }
+                    #endregion
+                    #region 处理事项为技术确认直接删除
+                    try
+                    {
+                        if (row["处理事项"].ToString().Trim() == "技术确认")
+                        {
+                            delRows.Add(row);
+                        }
+                    }
+                    catch { }
+                    #endregion
+                    #region 已核算绩效标记
+                    string strTem = isCalculatedData(row, CalculatedTable);
+
+                    if(strTem != "")
+                    {
+                        if (!retDt.Columns.Contains("核查数据反馈"))
+                        {
+                            retDt.Columns.Add("核查数据反馈");
+                        }
+
+                        row["核查数据反馈"] = strTem;
+                    }
+                    #endregion
+                    #region 处理君龙处理人
+                    row["处理人"] = FormatStaffName(row["处理人"].ToString());
+                    #endregion
+                    #region 处理人和核稿人相同时,删除核稿人
+                    if (row["处理人"].ToString() == row["核稿人"].ToString())
+                    {
+                        row["核稿人"] = "";
+                    }
+                    #endregion
+                    #region 严重超期降系数处理,如果代理人没有填写客观原因才降系数,如果没有客户期限,期限为内部期限,如果没有内部期限,期限为委托日期+30天
+                    try
+                    {
+                        if (row["处理事项"].ToString() == "新申请")
+                        {
+                            DateTime dt1 = DateTime.MinValue;
+                            if (!string.IsNullOrEmpty(row["返稿日"].ToString()))
+                            {
+                                try
+                                {
+                                    dt1 = DateTime.Parse(row["返稿日"].ToString());
+                                }
+                                catch
+                                {
+                                    dt1 = DateTime.Parse("1899-12-30").AddDays(double.Parse(row["返稿日"].ToString()));
+                                    row["返稿日"] = dt1;
+                                }
+
+                            }
+
+                            DateTime dt2 = DateTime.MinValue;
+                            if (!string.IsNullOrEmpty(row["客户期限"].ToString()))
+                            {
+                                try
+                                {
+                                    dt2 = DateTime.Parse(row["客户期限"].ToString());
+                                }
+                                catch
+                                {
+                                    dt2 = DateTime.Parse("1899-12-30").AddDays(double.Parse(row["客户期限"].ToString()));
+                                    row["客户期限"] = dt2;
+                                }
+
+                            }
+                            else
+                            {
+                                if (!string.IsNullOrEmpty(row["内部期限"].ToString()))
+                                {
+
+                                    try
+                                    {
+                                        dt2 = DateTime.Parse(row["内部期限"].ToString());
+                                    }
+                                    catch
+                                    {
+                                        dt2 = DateTime.Parse("1899-12-30").AddDays(double.Parse(row["内部期限"].ToString()));
+                                        row["内部期限"] = dt2;
+                                    }
+                                }
+                                else
+                                {
+                                    if (!string.IsNullOrEmpty(row["委案日期"].ToString()))
+                                    {
+
+                                        try
+                                        {
+                                            dt2 = DateTime.Parse(row["委案日期"].ToString()).AddDays(30);
+                                        }
+                                        catch
+                                        {
+                                            dt2 = DateTime.Parse("1899-12-30").AddDays(double.Parse(row["内部期限"].ToString())).AddDays(30);
+                                            row["内部期限"] = dt2.AddDays(-30);
+                                        }
+                                    }
+                                }
+                            }
+
+                            string strReason = row["备注(发文严重超期是否属客观原因,若为否,请填写原因)"].ToString();
+
+                            if ((dt1 - dt2).TotalDays > 30 && !string.IsNullOrEmpty(strReason))
+                            {
+                                if (!retDt.Columns.Contains("是否降系数"))
+                                {
+                                    retDt.Columns.Add("是否降系数");
+                                }
+
+                                switch (row["案件系数"].ToString())
+                                {
+                                    case "S":
+                                        row["案件系数"] = "A";
+                                        row["是否降系数"] = $"严重超期降系数【超期:{(dt1 - dt2).TotalDays}】 S-A";
+                                        break;
+                                    case "A":
+                                        row["案件系数"] = "B";
+                                        row["是否降系数"] = $"严重超期降系数【超期:{(dt1 - dt2).TotalDays}】 A-B";
+                                        break;
+                                    case "B":
+                                        row["案件系数"] = "C";
+                                        row["是否降系数"] = $"严重超期降系数【超期:{(dt1 - dt2).TotalDays}】 B-C";
+                                        break;
+                                    case "C":
+                                        row["案件系数"] = "D";
+                                        row["是否降系数"] = $"严重超期降系数【超期:{(dt1 - dt2).TotalDays}】 C-D";
+                                        break;
+                                }
+
+                            }
+                        }
+                    }
+                    catch { }
+                    #endregion 
+                }
+            }
+
+            #region 删除我方文号和处理事项相同,比较少处理人的记录
+            foreach (string strKey in temHash.Keys)
+            {
+                List<DataRow> rows = (List<DataRow>)temHash[strKey];
+                if(rows.Count > 1)
+                {
+                    DataRow retRow = null;
+                    List<string> clrList = null;
+                    foreach(DataRow row in rows)
+                    {
+                        if (retRow == null)
+                        {
+                            retRow = row;
+                            clrList = row["处理人"].ToString().Split(new char[] { ',', ',', '、' }).ToList<string>();
+                        }
+                        else
+                        {
+                            List<string> temClrList = row["处理人"].ToString().Split(new char[] { ',', ',', '、' }).ToList<string>();
+                            if(temClrList.Count > clrList.Count)
+                            {
+                                delRows.Add(retRow);
+                                retRow = row;
+                                clrList = temClrList;
+                            }
+                            else
+                            {
+                                delRows.Add(row);
+                            }
+                        }
+                    }
+                }
+            }
+            #endregion
+
+            foreach(DataRow row in delRows)
+            {
+                retDt.Rows.Remove(row);
+            }
+            #endregion
+            CalculatedTable.Dispose();
+
+            NPOIExcel.DataTableToExcel(retDt ,desFileName);
+            return retDt;
+        }
+
+        private void MerageDataTable(DataTable retDt, DataTable dt)
+        {
+            int iRow = 0;
+            foreach (DataRow row in dt.Rows)
+            {
+                iRow++;
+                
+                //判断是否有相同的记录,我方文号+处理事项+处理人相同
+                DataRow oldRow = isExists(row, retDt);
+                if (oldRow == null)
+                {
+                    DataRow newRow = retDt.NewRow();
+
+                    foreach (DataColumn col in dt.Columns)
+                    {
+                        if (retDt.Columns.Contains(col.ColumnName))
+                        {
+                            newRow[col.ColumnName] = row[col.ColumnName];
+                        }
+                    }
+
+                    retDt.Rows.Add(newRow);
+                }
+                else
+                {
+                    foreach (DataColumn col in dt.Columns)
+                    {
+                        if (retDt.Columns.Contains(col.ColumnName))
+                        {
+                            if (string.IsNullOrEmpty(oldRow[col.ColumnName].ToString())
+                                && !string.IsNullOrEmpty(row[col.ColumnName].ToString()))
+                            {
+                                oldRow[col.ColumnName] = row[col.ColumnName];
+                            }
+
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// 处理君龙处理人
+        /// </summary>
+        /// <param name="strName"></param>
+        /// <returns></returns>
+        private string FormatStaffName(string strName)
+        {
+            if (string.IsNullOrEmpty(strName))
+            {
+                return strName;
+            }
+
+            string strReturn = "";
+            string[] Names = strName.Trim().Split(new char[] { ',' });
+
+            foreach(string name in Names)
+            {
+                
+                strReturn = string.IsNullOrEmpty(strReturn) ? name.Replace("-君龙", "") : $"{strReturn},{name.Replace("-君龙", "")}";
+            }
+
+            return strReturn;
+        }
+
+        private DataRow isExists(DataRow row,DataTable dt)
+        {
+
+            //DataRow[] temRows = dt.Select($"我方文号='{row["我方文号"].ToString()}' and 处理事项='{row["处理事项"].ToString()}' and 处理人='{row["处理人"].ToString()}'");
+            //if (temRows.Length > 0)
+            //{
+            //    return temRows[0];
+            //}
+            //else
+            //{
+            //    return null;
+            //}
+
+
+            foreach (DataRow temRow in dt.Rows)
+            {
+                if(row["我方文号"].ToString() == temRow["我方文号"].ToString() &&
+                    row["处理事项"].ToString() == temRow["处理事项"].ToString() &&
+                    row["处理人"].ToString() == temRow["处理人"].ToString())
+                {
+                    System.Diagnostics.Debug.WriteLine(string.Format("{0} 重复项目", row["我方文号"].ToString()));
+
+                    return temRow;
+
+                    
+                }
+            }
+
+            return null;
+        }
+
+        private string isCalculatedData(DataRow row ,DataTable CalculatedTable)
+        {
+            foreach (DataRow temRow in CalculatedTable.Rows)
+            {
+                if (row["我方文号"].ToString() == temRow["我方文号"].ToString() &&
+                    row["处理事项"].ToString() == temRow["处理事项"].ToString() )
+                {
+                    if(row["处理事项"].ToString() == "处理审查意见")
+                    {
+                        if ( row["案件阶段"].ToString() == temRow["案件阶段"].ToString())
+                            return temRow["绩效核算月份"].ToString() + "已核算绩效!";
+                    }
+                    else
+                    {
+                        return temRow["绩效核算月份"].ToString() + "已核算绩效!";
+                    }
+                    
+                }
+            }
+
+            return "";
+        }
+        
+        /// <summary>
+        /// 填充点数
+        /// </summary>
+        /// <param name="strPath">总表文件路径</param>
+        /// <param name="dianshuFilePath">点数规则文件路径</param>
+        public void FillDianShu(string strPath,string dianshuFilePath)
+        {
+            DataTable dsTable = NPOIExcel.ExcelToDataTable(dianshuFilePath,true);
+
+            //DataRow[] Rows = dsTable.Select("1=1", "转换条件");
+
+            DataTable dt = NPOIExcel.ExcelToDataTable(strPath, true);
+
+            for(int iRow = dsTable.Rows.Count-1;iRow>=0;iRow--)
+            //foreach(DataRow row in dsTable.Rows)
+            {
+                
+                DataRow row = dsTable.Rows[iRow];
+
+
+                if (!string.IsNullOrEmpty(row["转换条件"].ToString().Trim()))
+                {
+                    try
+                    {
+                        DataRow[] temRows = dt.Select(row["转换条件"].ToString().Trim());
+
+                        foreach (DataRow dataRow in temRows)
+                        {
+                            dataRow["基本点数"] = double.Parse(row["点数"].ToString());
+                        }
+                    }
+                    catch(Exception ex)
+                    {
+                        System.Diagnostics.Debug.WriteLine(ex.ToString());
+                    }
+                }
+            }
+           
+
+            #region 翻译按字数计算
+            DataRow[] fyList = dt.Select("处理事项='翻译'");
+            foreach (DataRow dataRow in fyList)
+            {
+                string strBZ = dataRow["备注(填表注意事项)"].ToString();
+                System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("(\\d{1,})字");
+                System.Text.RegularExpressions.Match m = r.Match(strBZ);
+                
+
+                if (m.Success)
+                {
+                    double iChar = double.Parse(m.Groups[1].Value);
+
+                    if (strBZ.Contains("中-英"))
+                    {
+                        double ds = (iChar*0.16)/1000.00;
+                        dataRow["基本点数"] = ds.ToString();
+                    }
+                    else
+                    {
+                        if (strBZ.Contains("中-德") || strBZ.Contains("德-中"))
+                        {
+                            double ds = (iChar * 0.18) / 1000.00;
+                            dataRow["基本点数"] = ds.ToString();
+                        }
+                        else
+                        {
+                            if (strBZ.Contains("英-中"))
+                            {
+                                double ds = (iChar * 0.1) / 1000.00;
+                                dataRow["基本点数"] = ds.ToString();
+                            }
+                        }
+                    }
+                }
+                else
+                {
+
+                }
+            }
+            #endregion
+
+            #region 已算绩效,基本点数为0
+            DataRow[] ysjxList = dt.Select("备注(填表注意事项)='已算绩效' or 备注(填表注意事项)='绩效已算' or 备注(填表注意事项)='已计算' or 备注(填表注意事项)='绩效已核算'  or 核查数据反馈 like '已核算绩效'");
+            foreach (DataRow dataRow in ysjxList)
+            {
+                dataRow["基本点数"] = "0";
+            }
+            #endregion
+
+            NPOIExcel.DataTableToExcel(dt, strPath);
+        }
+
+    }
+}

+ 346 - 0
wispro.sp.utility/NPOIExcle.cs

@@ -0,0 +1,346 @@
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using NPOI.XSSF.UserModel;
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace wispro.sp.utility
+{
+    public class NPOIExcel
+    {
+        /// <summary>
+        /// 将excel导入到datatable
+        /// </summary>
+        /// <param name="filePath">excel路径</param>
+        /// <param name="isColumnName">第一行是否是列名</param>
+        /// <param name="IgnoreZeroHightRow">是否忽略隐藏行</param>
+        /// <returns>返回datatable</returns>
+        public static DataTable ExcelToDataTable(string filePath, bool isColumnName,bool IgnoreZeroHightRow = false)
+        {
+            DataTable dataTable = null;
+            FileStream fs = null;
+            DataColumn column = null;
+            DataRow dataRow = null;
+            IWorkbook workbook = null;
+            ISheet sheet = null;
+            IRow row = null;
+            ICell cell = null;
+            int startRow = 0;
+            try
+            {
+                using (fs = File.OpenRead(filePath))
+                {
+                    // 2007版本
+                    if (filePath.IndexOf(".xlsx") > 0)
+                        workbook = new XSSFWorkbook(fs);
+                    // 2003版本
+                    else if (filePath.IndexOf(".xls") > 0)
+                        workbook = new HSSFWorkbook(fs);
+
+                    if (workbook != null)
+                    {
+                        sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
+                        dataTable = new DataTable();
+                        if (sheet != null)
+                        {
+                            int rowCount = sheet.LastRowNum;//总行数
+                            if (rowCount > 0)
+                            {
+                                IRow firstRow = sheet.GetRow(0);//第一行
+                                int cellCount = firstRow.LastCellNum;//列数
+
+                                //构建datatable的列
+                                if (isColumnName)
+                                {
+                                    startRow = 1;//如果第一行是列名,则从第二行开始读取
+                                    for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
+                                    {
+                                        cell = firstRow.GetCell(i);
+                                        if (cell != null)
+                                        {
+                                            if (cell.StringCellValue != null)
+                                            {
+                                                column = new DataColumn(cell.StringCellValue);
+                                                dataTable.Columns.Add(column);
+                                            }
+                                        }
+                                    }
+                                }
+                                else
+                                {
+                                    for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
+                                    {
+                                        column = new DataColumn("column" + (i + 1));
+                                        dataTable.Columns.Add(column);
+                                    }
+                                }
+
+                                //填充行
+                                for (int i = startRow; i <= rowCount; ++i)
+                                {
+                                    row = sheet.GetRow(i);
+
+                                    if (row != null && IgnoreZeroHightRow && row.ZeroHeight)
+                                    {
+                                        System.Diagnostics.Debug.WriteLine (string.Format("[{0}]隐藏行:{1}", filePath, i));
+                                        continue;
+                                        
+                                    }
+
+                                    
+                                    if (row == null || row.Cells.Count ==0) continue;
+
+                                    dataRow = dataTable.NewRow();
+                                    for (int j = row.FirstCellNum; j < cellCount; ++j)
+                                    {
+                                        cell = row.GetCell(j);
+                                        if (cell == null)
+                                        {
+                                            dataRow[j] = "";
+                                        }
+                                        else
+                                        {
+                                            //CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
+                                            switch (cell.CellType)
+                                            {
+                                                case CellType.Blank:
+                                                    dataRow[j] = "";
+                                                    break;
+                                                case CellType.Numeric:
+                                                    short format = cell.CellStyle.DataFormat;
+                                                    //对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
+                                                    if (format == 14 || format == 31 || format == 57 || format == 58 || format == 177 || format == 176)
+                                                        try
+                                                        {
+                                                            dataRow[j] = cell.DateCellValue;
+                                                        }
+                                                        catch
+                                                        {
+                                                            //dataRow[j] = null;
+                                                        }
+                                                    else
+                                                        dataRow[j] = cell.NumericCellValue;
+                                                    break;
+                                                case CellType.String:
+                                                    dataRow[j] = cell.StringCellValue;
+                                                    
+                                                    break;
+                                            }
+                                        }
+                                    }
+                                    dataTable.Rows.Add(dataRow);
+                                }
+                            }
+                        }
+                    }
+                }
+                return dataTable;
+            }
+            catch (Exception ex)
+            {
+                if (fs != null)
+                {
+                    fs.Close();
+                }
+                return null;
+            }
+        }
+
+        public static DataTable ExcelToDataTable(string v)
+        {
+            return ExcelToDataTable(v, false, true);
+        }
+
+        /// <summary>
+        /// 写入excel
+        /// </summary>
+        /// <param name="dt">datatable</param>
+        /// <param name="strFile">strFile</param>
+        /// <returns></returns>
+        public static bool DataTableToExcel(DataTable dt, string strFile)
+        {
+            bool result = false;
+            IWorkbook workbook = null;
+            FileStream fs = null;
+            IRow row = null;
+            ISheet sheet = null;
+            ICell cell = null;
+            try
+            {
+                if (dt != null && dt.Rows.Count > 0)
+                {
+                    workbook = new XSSFWorkbook();
+                    sheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表
+                    int rowCount = dt.Rows.Count;//行数
+                    int columnCount = dt.Columns.Count;//列数
+
+                    //设置列头
+                    row = sheet.CreateRow(0);//excel第一行设为列头
+                    for (int c = 0; c < columnCount; c++)
+                    {
+                        cell = row.CreateCell(c);
+                        cell.SetCellValue(dt.Columns[c].ColumnName);
+                    }
+
+                    //设置每行每列的单元格,
+                    for (int i = 0; i < rowCount; i++)
+                    {
+                        row = sheet.CreateRow(i + 1);
+                        for (int j = 0; j < columnCount; j++)
+                        {
+                            cell = row.CreateCell(j);//excel第二行开始写入数据
+                            cell.SetCellValue(dt.Rows[i][j].ToString());
+                        }
+                    }
+                    using (fs = File.OpenWrite(strFile))
+                    {
+                        workbook.Write(fs);//向打开的这个xls文件中写入数据
+                        result = true;
+                    }
+                }
+                return result;
+            }
+            catch (Exception ex)
+            {
+                if (fs != null)
+                {
+                    fs.Close();
+                }
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Excel导入成Datable
+        /// </summary>
+        /// <param name="file">导入路径(包含文件名与扩展名)</param>
+        /// <returns></returns>
+        public static DataTable ExcelToTable(string file)
+        {
+            DataTable dt = new DataTable();
+            IWorkbook workbook;
+            string fileExt = Path.GetExtension(file).ToLower();
+            using (FileStream fs = new FileStream(file, FileMode.Open, FileAccess.Read))
+            {
+                //XSSFWorkbook 适用XLSX格式,HSSFWorkbook 适用XLS格式
+                if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(fs); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(fs); } else { workbook = null; }
+                if (workbook == null) { return null; }
+                ISheet sheet = workbook.GetSheetAt(0);
+
+                //表头  
+                IRow header = sheet.GetRow(sheet.FirstRowNum);
+                List<int> columns = new List<int>();
+                for (int i = 0; i < header.LastCellNum; i++)
+                {
+                    object obj = GetValueType(header.GetCell(i));
+                    if (obj == null || obj.ToString() == string.Empty)
+                    {
+                        dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
+                    }
+                    else
+                        dt.Columns.Add(new DataColumn(obj.ToString()));
+                    columns.Add(i);
+                }
+                //数据  
+                for (int i = sheet.FirstRowNum + 1; i <= sheet.LastRowNum; i++)
+                {
+                    DataRow dr = dt.NewRow();
+                    bool hasValue = false;
+                    foreach (int j in columns)
+                    {
+                        dr[j] = GetValueType(sheet.GetRow(i).GetCell(j));
+                        if (dr[j] != null && dr[j].ToString() != string.Empty)
+                        {
+                            hasValue = true;
+                        }
+                    }
+                    if (hasValue)
+                    {
+                        dt.Rows.Add(dr);
+                    }
+                }
+            }
+            return dt;
+        }
+
+        /// <summary>
+        /// Datable导出成Excel
+        /// </summary>
+        /// <param name="dt"></param>
+        /// <param name="file">导出路径(包括文件名与扩展名)</param>
+        public static void TableToExcel(DataTable dt, string file)
+        {
+            IWorkbook workbook;
+            string fileExt = Path.GetExtension(file).ToLower();
+            if (fileExt == ".xlsx") { workbook = new XSSFWorkbook(); } else if (fileExt == ".xls") { workbook = new HSSFWorkbook(); } else { workbook = null; }
+            if (workbook == null) { return; }
+            ISheet sheet = string.IsNullOrEmpty(dt.TableName) ? workbook.CreateSheet("Sheet1") : workbook.CreateSheet(dt.TableName);
+
+            //表头  
+            IRow row = sheet.CreateRow(0);
+            for (int i = 0; i < dt.Columns.Count; i++)
+            {
+                ICell cell = row.CreateCell(i);
+                cell.SetCellValue(dt.Columns[i].ColumnName);
+            }
+
+            //数据  
+            for (int i = 0; i < dt.Rows.Count; i++)
+            {
+                IRow row1 = sheet.CreateRow(i + 1);
+                for (int j = 0; j < dt.Columns.Count; j++)
+                {
+                    ICell cell = row1.CreateCell(j);
+                    cell.SetCellValue(dt.Rows[i][j].ToString());
+                }
+            }
+
+            //转为字节数组  
+            MemoryStream stream = new MemoryStream();
+            workbook.Write(stream);
+            var buf = stream.ToArray();
+
+            //保存为Excel文件  
+            using (FileStream fs = new FileStream(file, FileMode.Create, FileAccess.Write))
+            {
+                fs.Write(buf, 0, buf.Length);
+                fs.Flush();
+            }
+        }
+
+        /// <summary>
+        /// 获取单元格类型
+        /// </summary>
+        /// <param name="cell"></param>
+        /// <returns></returns>
+        private static object GetValueType(ICell cell)
+        {
+            if (cell == null)
+                return null;
+            switch (cell.CellType)
+            {
+                case CellType.Blank: //BLANK:  
+                    return null;
+                case CellType.Boolean: //BOOLEAN:  
+                    return cell.BooleanCellValue;
+                case CellType.Numeric: //NUMERIC:  
+                    return cell.NumericCellValue;
+                case CellType.String: //STRING:  
+                    return cell.StringCellValue;
+                case CellType.Error: //ERROR:  
+                    return cell.ErrorCellValue;
+                case CellType.Formula: //FORMULA:  
+                default:
+                    return "=" + cell.CellFormula;
+
+            }
+        }
+
+    }
+}
+

+ 12 - 0
wispro.sp.utility/wispro.sp.utility.csproj

@@ -0,0 +1,12 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+    <Platforms>AnyCPU;x64;x86</Platforms>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="NPOI" Version="2.5.4" />
+  </ItemGroup>
+
+</Project>

+ 12 - 0
wispro.sp.web/App.razor

@@ -0,0 +1,12 @@
+<Router AppAssembly="@typeof(Program).Assembly">
+    <Found Context="routeData">
+        <RouteView RouteData="@routeData" DefaultLayout="@typeof(BasicLayout)" />
+    </Found>
+    <NotFound>
+        <LayoutView Layout="@typeof(BasicLayout)">
+            <p>Sorry, there's nothing at this address.</p>
+        </LayoutView>
+    </NotFound>
+</Router>
+<AntContainer />
+    

+ 63 - 0
wispro.sp.web/Auth/JwtAuthenticationStateProvider.cs

@@ -0,0 +1,63 @@
+using Microsoft.AspNetCore.Components.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Blazored.LocalStorage;
+using System.Security.Claims;
+using System.Net.Http;
+
+using wispro.sp.web.Utils;
+
+namespace wispro.sp.web.Auth
+{
+    public class JwtAuthenticationStateProvider : AuthenticationStateProvider
+    {
+        private readonly ILocalStorageService localStorageService;
+        private readonly HttpClient httpClient;
+
+        private AuthenticationState anonymous;
+
+        public JwtAuthenticationStateProvider(ILocalStorageService localStorageService, HttpClient httpClient)
+        {
+            anonymous = new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity()));
+            this.localStorageService = localStorageService;
+            this.httpClient = httpClient;
+        }
+
+        public override async Task<AuthenticationState> GetAuthenticationStateAsync()
+        {
+            //確認localstorage裡面是否有token
+            string tokenInLocalStorage = await localStorageService.GetItemAsStringAsync("authToken");
+            if (string.IsNullOrEmpty(tokenInLocalStorage))
+            {
+                //沒有的話,回傳匿名使用者
+                return null;
+            }
+
+            
+            //將token取出轉為claim
+            var claims = JwtParser.ParseClaimsFromJwt(tokenInLocalStorage);
+
+            //在每次request的header中帶入bearer token
+            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", tokenInLocalStorage);
+
+            //回傳帶有user claim的AuthenticationState物件
+            return new AuthenticationState(new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt")));
+        }
+
+        public void NotifyUserAuthentication(string token)
+        {
+            var claims = JwtParser.ParseClaimsFromJwt(token);
+            var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "jwt"));
+            var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
+            NotifyAuthenticationStateChanged(authState);
+        }
+
+        public void NotifyUserLogOut()
+        {
+            var authState = Task.FromResult(anonymous);
+            NotifyAuthenticationStateChanged(authState);
+        }
+    }
+}

+ 101 - 0
wispro.sp.web/AuthProvider.cs

@@ -0,0 +1,101 @@
+using Blazored.LocalStorage;
+using Microsoft.AspNetCore.Components.Authorization;
+using System;
+using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Http.Json;
+using System.Security.Claims;
+using System.Threading.Tasks;
+using wispro.sp.share.webViewObject;
+using wispro.sp.web.Utils;
+
+namespace wispro.sp.web
+{
+    //AuthProvider.cs
+    public class AuthProvider : AuthenticationStateProvider
+    {
+        private readonly HttpClient HttpClient;
+        private readonly ILocalStorageService localStorageService;
+        public string UserName { get; set; }
+
+        public AuthProvider(ILocalStorageService localStorageService, HttpClient httpClient)
+        {
+            this.localStorageService = localStorageService;
+            HttpClient = httpClient;
+        }
+
+        public async override Task<AuthenticationState> GetAuthenticationStateAsync()
+        {
+            //var token = await localStorageService.GetItemAsync<string>("authToken");
+            //var userName = await localStorageService.GetItemAsync<string>("authUserName");
+
+            userToken result = new userToken();
+
+            //if (string.IsNullOrEmpty(token))
+            //{
+            //    //这里获得用户登录状态
+            result = await HttpClient.GetFromJsonAsync<userToken>($"http://localhost:39476/api/account/GetUser");
+            //}
+            //else
+            //{
+            //    result.Name = userName;
+            //    result.Token = token;
+            //}
+
+
+            if (result?.Name == null)
+            {
+                MarkUserAsLoggedOut();
+                return new AuthenticationState(new ClaimsPrincipal());
+            }
+            else
+            {
+                var claims = new List<Claim>();
+                claims.Add(new Claim(ClaimTypes.Name, result.Name));
+                var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "apiauth"));
+                return new AuthenticationState(authenticatedUser);
+            }
+        }
+
+        /// <summary>
+        /// 标记授权
+        /// </summary>
+        /// <param name="loginModel"></param>
+        /// <returns></returns>
+        public async void MarkUserAsAuthenticated(userToken userDto)
+        {
+            HttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", userDto.Token);
+            UserName = userDto.Name;
+
+            var claims = JwtParser.ParseClaimsFromJwt(userDto.Token);
+            //JwtSecurityTokenHandler jwtSecurityTokenHandler = new JwtSecurityTokenHandler();
+            //JwtSecurityToken token = jwtSecurityTokenHandler.ReadJwtToken(userDto.Token);
+
+            var authenticatedUser = new ClaimsPrincipal(new ClaimsIdentity(claims, "apiauth"));
+            var authState = Task.FromResult(new AuthenticationState(authenticatedUser));
+            NotifyAuthenticationStateChanged(authState);
+
+            ////可以将Token存储在本地存储中,实现页面刷新无需登录
+            await localStorageService.SetItemAsync<string>("authToken", userDto.Token);
+            await localStorageService.SetItemAsync<string>("authUserName", userDto.Name);
+        }
+
+        /// <summary>
+        /// 标记注销
+        /// </summary>
+        public async void MarkUserAsLoggedOut()
+        {
+            await localStorageService.RemoveItemAsync("authToken");
+            await localStorageService.RemoveItemAsync("authUserName");
+            HttpClient.DefaultRequestHeaders.Authorization = null;
+            UserName = null;
+
+            var anonymousUser = new ClaimsPrincipal(new ClaimsIdentity());
+            var authState = Task.FromResult(new AuthenticationState(anonymousUser));
+            NotifyAuthenticationStateChanged(authState);
+        }
+    }
+}

+ 9 - 0
wispro.sp.web/Components/EditableLinkGroup.razor

@@ -0,0 +1,9 @@
+<div class="linkGroup">
+    @foreach (var link in Links)
+    {
+<a href="@link.Href">@link.Title</a>}
+
+    <Button Size="small" Type="primary" Ghost>
+        <Icon Type="plus" /> Add
+    </Button>
+</div>

+ 21 - 0
wispro.sp.web/Components/EditableLinkGroup.razor.cs

@@ -0,0 +1,21 @@
+using Microsoft.AspNetCore.Components;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Components
+{
+
+    public class EditableLink
+    {
+        public string Title { get; set; }
+        public string Href { get; set; }
+        public string Id { get; set; }
+    }
+
+    public partial class EditableLinkGroup
+    {
+        [Parameter] public EditableLink[] Links { get; set; }
+    }
+}

+ 20 - 0
wispro.sp.web/Components/EditableLinkGroup.razor.css

@@ -0,0 +1,20 @@
+/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
+/* stylelint-disable no-duplicate-selectors */
+/* stylelint-disable */
+/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */
+.linkGroup {
+    padding: 20px 0 8px 24px;
+    font-size: 0;
+}
+
+    .linkGroup > a {
+        display: inline-block;
+        width: 25%;
+        margin-bottom: 13px;
+        color: rgba(0, 0, 0, 0.85);
+        font-size: 14px;
+    }
+
+        .linkGroup > a:hover {
+            color: #1890ff;
+        }

+ 57 - 0
wispro.sp.web/Components/PerformanceItemDescriptionItem.razor

@@ -0,0 +1,57 @@
+<ListItem>
+    <Card Title=@(EditingItem.CaseNo) Style="width: 100%">
+        <Extra>
+            <Space>
+                <SpaceItem>
+                    绩效特殊字段:
+                    <Select DataSource="@_Reasons"
+                            @bind-Value="@EditingItem.AgentFeedbackMemo"
+                            LabelName="@nameof(Reason.Name)"
+                            ValueName="@nameof(Reason.Value)"
+                            Placeholder="请选项一项反馈"
+                            DefaultActiveFirstItem="false"
+                            EnableSearch
+                            Style="width:200px;">
+                    </Select>
+                </SpaceItem>
+                <SpaceItem>
+                    <Button Type="primary" Icon="plus" OnClick="OnsubShensu" Style="float:right" Size="small">提出申诉</Button>
+                </SpaceItem>
+                @if ((!EditingItem.CaseNo.Contains("CN") || EditingItem.CaseNo.Contains("WO")) && EditingItem.DoItem =="新申请") { 
+                <SpaceItem>
+                    <Button Type="primary" Icon="plus" OnClick="OnSWJXType" Style="float:right"  Size="small">涉外绩效按字数计算</Button>
+                </SpaceItem>
+                }
+            </Space>
+        </Extra>
+        <Body>
+            <Descriptions Bordered Size="@DescriptionsSize.Small">
+                <DescriptionsItem Title="处理事项">@EditingItem.DoItem</DescriptionsItem>
+                <DescriptionsItem Title="处理人">
+                    @if (EditingItem.ItemStaffs != null)
+                    {
+                        foreach (ItemStaff itemStaff in EditingItem.ItemStaffs)
+                        {
+                            <span>@(itemStaff.DoPerson.Name)&nbsp;</span>
+                        }
+                    }
+                </DescriptionsItem>
+                <DescriptionsItem Title="核稿人">@(EditingItem.Reviewer ==null?"": EditingItem.Reviewer.Name)</DescriptionsItem>
+                <DescriptionsItem Title="完成时间">@(EditingItem.FinishedDate.HasValue? EditingItem.FinishedDate.Value.ToString("yyyy-MM-dd"):"")</DescriptionsItem>
+                <DescriptionsItem Title="案件系数">@EditingItem.CaseCoefficient</DescriptionsItem>
+                <DescriptionsItem Title="处理事项系数">@EditingItem.DoItemCoefficient</DescriptionsItem>
+                <DescriptionsItem Title="返稿日">@(EditingItem.ReturnDate .HasValue? EditingItem.ReturnDate.Value.ToString("yyyy-MM-dd"):"")</DescriptionsItem>
+                <DescriptionsItem Title="客户期限">@(EditingItem.CustomerLimitDate .HasValue? EditingItem.CustomerLimitDate.Value.ToString("yyyy-MM-dd"):"")</DescriptionsItem>
+                <DescriptionsItem Title="初稿日">@(EditingItem.FirstDraftDate .HasValue? EditingItem.FirstDraftDate.Value.ToString("yyyy-MM-dd"):"")</DescriptionsItem>
+                <DescriptionsItem Title="内部期限">@(EditingItem.InternalDate .HasValue? EditingItem.InternalDate.Value.ToString("yyyy-MM-dd"):"")</DescriptionsItem>
+                <DescriptionsItem Title="案件阶段">@EditingItem.CaseStage</DescriptionsItem>
+                <DescriptionsItem Title="案件名称" Span="2">@EditingItem.CaseName</DescriptionsItem>
+                <DescriptionsItem Title="案件状态">@EditingItem.CaseState</DescriptionsItem>
+
+                <DescriptionsItem Title="申请人" Span="3">@EditingItem.ApplicationName</DescriptionsItem>
+                <DescriptionsItem Title="备注" Span="3">@EditingItem.CaseMemo</DescriptionsItem>
+
+            </Descriptions>
+        </Body>
+    </Card>
+</ListItem>

+ 80 - 0
wispro.sp.web/Components/PerformanceItemDescriptionItem.razor.cs

@@ -0,0 +1,80 @@
+using AntDesign;
+using AntDesign.ProLayout;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Web;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+
+namespace wispro.sp.web.Components
+{
+    public partial class PerformanceItemDescriptionItem
+    {
+        [Parameter]
+        public PerformanceItem EditingItem { get; set; }
+
+        [Parameter]
+        public EventCallback<PerformanceItem> OnSubmitShenSu { get; set; }
+
+        [Parameter]
+        public EventCallback<PerformanceItem> OnSWJXSF { get; set; }
+
+        class Reason
+        {
+            public string Value { get; set; }
+            public string Name { get; set; }
+        }
+
+        List<Reason> _Reasons = new List<Reason>()
+        {
+            new Reason(){Name="PCT首次英文案",Value="PCT首次英文案"},
+            new Reason(){Name="我方转格式、复核",Value="我方转格式、复核"},
+            new Reason(){Name="台湾案转大陆案",Value="台湾案转大陆案"},
+            new Reason(){Name="大陆案转台湾案",Value="大陆案转台湾案"},
+            new Reason(){Name="同套大陆+台湾",Value="同套大陆+台湾"},
+            new Reason(){Name="不请款",Value="不请款"},
+            new Reason(){Name="撤回后重新递交",Value="撤回后重新递交"},
+            new Reason(){Name="发文后客户取消申请",Value="发文后客户取消申请"},
+            new Reason(){Name="发文后客户原因取消申请,系统结案",Value="发文后客户原因取消申请,系统结案"},
+            new Reason(){Name="改权",Value="改权"},
+            new Reason(){Name="改权+改说明书",Value="改权+改说明书"},
+            new Reason(){Name="客户不进行答辩",Value="客户不进行答辩"},
+            new Reason(){Name="客户提供答辩点,撰写英文报导函",Value="客户提供答辩点,撰写英文报导函"},
+            new Reason(){Name="客户未提供答辩点,撰写英文报导函",Value="客户未提供答辩点,撰写英文报导函辩"},
+            new Reason(){Name="内-外",Value="内-外"},
+            new Reason(){Name="外-内",Value="外-内"},
+            new Reason(){Name="外-内首次申请",Value="外-内首次申请"},
+            new Reason(){Name="请款",Value="请款"},
+            new Reason(){Name="涉外OA不答辩,发报导函结案",Value="涉外OA不答辩,发报导函结案"},
+            new Reason(){Name="涉外实质改权",Value="涉外实质改权"},
+            new Reason(){Name="首次中文案",Value="首次中文案"},
+            new Reason(){Name="我方转格式、复核",Value="我方转格式、复核"},
+            new Reason(){Name="外所/他人首次转入OA",Value="外所/他人首次转入OA"},
+            new Reason(){Name="我方代交",Value="我方代交"},
+            new Reason(){Name="转格式",Value="转格式"},
+            new Reason(){Name="撰写中客户取消申请",Value="撰写中客户取消申请"}
+
+
+        };
+
+        private void OnsubShensu()
+        {
+            if (OnSubmitShenSu.HasDelegate)
+            {
+                OnSubmitShenSu.InvokeAsync(EditingItem);
+            }
+        }
+
+        private void OnSWJXType()
+        {
+            if (OnSWJXSF.HasDelegate)
+            {
+                OnSWJXSF.InvokeAsync(EditingItem);
+            }
+        }
+
+        
+    }
+}

+ 71 - 0
wispro.sp.web/Components/Radar.razor

@@ -0,0 +1,71 @@
+@using wispro.sp.web.Services 
+
+<AntDesign.Charts.Radar @ref="_chart" TItem="RadarDataItem" Config="_chartConfig"/>
+
+@if (HasLegend)
+{
+    <Row Class="legend">
+        <AntDesign.Col>
+            <div class="legendItem">
+                <p>
+                    <span class="dot" style="background-color: #aaa"></span>
+                    <span></span>
+                </p>
+                <h6></h6>
+            </div>
+        </AntDesign.Col>
+    </Row>
+}
+
+@inject IChartService ChartService
+@code
+{ 
+    [Parameter] 
+    public bool HasLegend { get; set; } = false;
+
+    [Parameter] 
+    public int Height { get; set; } = 343;
+
+    private IChartComponent _chart;
+
+    private readonly RadarConfig _chartConfig = new RadarConfig
+    {
+        Height = 400,
+        ForceFit = true,
+        AngleField = "label",
+        RadiusField = "value",
+        SeriesField = "name",
+        RadiusAxis = new ValueAxis
+        {
+            Grid = new BaseAxisGrid
+            {
+                Line = new BaseAxisGridLine
+                {
+                    Type = "line"
+                }
+            }
+        },
+        Area = new RadarViewConfigArea
+        {
+            Visible = false
+        },
+        Point = new RadarViewConfigPoint
+        {
+            Visible = true
+        },
+        Legend = new Legend
+        {
+            Visible = true,
+            Position = "bottom-center"
+        },
+
+
+    };
+
+    protected override async System.Threading.Tasks.Task OnInitializedAsync()
+    {
+        await base.OnInitializedAsync();
+        var data = await ChartService.GetRadarDataAsync();
+        await _chart.ChangeData(data);
+    }
+}

+ 52 - 0
wispro.sp.web/Components/Radar.razor.css

@@ -0,0 +1,52 @@
+/* stylelint-disable at-rule-empty-line-before,at-rule-name-space-after,at-rule-no-unknown */
+/* stylelint-disable no-duplicate-selectors */
+/* stylelint-disable */
+/* stylelint-disable declaration-bang-space-before,no-duplicate-selectors,string-no-newline */
+.radar .legend {
+    margin-top: 16px;
+}
+
+    .radar .legend .legendItem {
+        position: relative;
+        color: rgba(0, 0, 0, 0.45);
+        line-height: 22px;
+        text-align: center;
+        cursor: pointer;
+    }
+
+        .radar .legend .legendItem p {
+            margin: 0;
+        }
+
+        .radar .legend .legendItem h6 {
+            margin-top: 4px;
+            margin-bottom: 0;
+            padding-left: 16px;
+            color: rgba(0, 0, 0, 0.85);
+            font-size: 24px;
+            line-height: 32px;
+        }
+
+        .radar .legend .legendItem::after {
+            position: absolute;
+            top: 8px;
+            right: 0;
+            width: 1px;
+            height: 40px;
+            background-color: #f0f0f0;
+            content: '';
+        }
+
+    .radar .legend > :last-child .legendItem::after {
+        display: none;
+    }
+
+    .radar .legend .dot {
+        position: relative;
+        top: -1px;
+        display: inline-block;
+        width: 6px;
+        height: 6px;
+        margin-right: 6px;
+        border-radius: 6px;
+    }

+ 52 - 0
wispro.sp.web/Components/RightContent.razor

@@ -0,0 +1,52 @@
+@namespace wispro.sp.web.Components
+@inherits AntDomComponentBase
+
+<Space Class="@ClassMapper.Class" Size="@("24")">
+    <SpaceItem>
+        <HeaderSearch Class="action search"
+                      Placeholder="Site Search"
+                      DefaultValue="umi ui"
+                      Options="DefaultOptions" />
+    </SpaceItem>
+    <SpaceItem>
+        <AntDesign.Tooltip Title="@("Help")" Placement="@PlacementType.Bottom">
+            <Unbound>
+                <span @ref="@context.Current" class="action">
+                    <Icon Type="question-circle" Theme="outline" />
+                </span>
+            </Unbound>
+        </AntDesign.Tooltip>
+    </SpaceItem>
+    <SpaceItem>
+        <NoticeIcon ClearText="清空"
+                    ViewMoreText="更多..."
+                    Count="_count"
+                    OnClear="HandleClear"
+                    OnViewMore="HandleViewMore">
+            <NoticeList TabKey="notification"
+                        Title="通知"
+                        EmptyText="你已查看所有通知"
+                        ShowViewMore
+                        Data="_notifications" />
+            <NoticeList TabKey="message"
+                        Title="处理事项"
+                        EmptyText="你没有需要处理的新事项"
+                        ShowViewMore
+                        Data="_messages" />
+            @*<NoticeList TabKey="event"
+                        Title="Upcoming"
+                        EmptyText="You have completed all to do"
+                        ShowViewMore
+                        Data="_events" />*@
+        </NoticeIcon>
+    </SpaceItem>
+    <SpaceItem>
+        <AvatarDropdown Name="@_currentUser.Name"
+                        Avatar="@_currentUser.Avatar"
+                        MenuItems="@AvatarMenuItems"
+                        OnItemSelected="HandleSelectUser" />
+    </SpaceItem>
+    <SpaceItem>
+        @*<SelectLang OnItemSelected="HandleSelectLang" />*@
+    </SpaceItem>
+</Space>

+ 119 - 0
wispro.sp.web/Components/RightContent.razor.cs

@@ -0,0 +1,119 @@
+using wispro.sp.web.Models;
+using wispro.sp.web.Services;
+using AntDesign.ProLayout;
+using Microsoft.AspNetCore.Components;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using AntDesign;
+using Microsoft.AspNetCore.Components.Authorization;
+using wispro.sp.web.Auth;
+
+namespace wispro.sp.web.Components
+{
+    public partial class RightContent
+    {
+        private CurrentUser _currentUser = new CurrentUser();
+        private NoticeIconData[] _notifications = { };
+        private NoticeIconData[] _messages = { };
+        private NoticeIconData[] _events = { };
+        private int _count = 0;
+
+        private List<AutoCompleteDataItem<string>> DefaultOptions { get; set; } = new List<AutoCompleteDataItem<string>>
+        {
+            new AutoCompleteDataItem<string>
+            {
+                Label = "umi ui",
+                Value = "umi ui"
+            },
+            new AutoCompleteDataItem<string>
+            {
+                Label = "Pro Table",
+                Value = "Pro Table"
+            },
+            new AutoCompleteDataItem<string>
+            {
+                Label = "Pro Layout",
+                Value = "Pro Layout"
+            }
+        };
+
+        public AvatarMenuItem[] AvatarMenuItems { get; set; } = new AvatarMenuItem[]
+        {
+            new() { Key = "center", IconType = "user", Option = "个人中心"},
+            new() { Key = "setting", IconType = "setting", Option = "个人设置"},
+            new() { IsDivider = true },
+            new() { Key = "logout", IconType = "logout", Option = "退出登录"}
+        };
+
+        [Inject] protected NavigationManager NavigationManager { get; set; }
+
+        [Inject] protected IUserService UserService { get; set; }
+        [Inject] protected IProjectService ProjectService { get; set; }
+        [Inject] protected MessageService MessageService { get; set; }
+
+        [Inject] protected IAuthService authorProvider { get; set; }
+
+        protected override async System.Threading.Tasks.Task OnInitializedAsync()
+        {
+            await base.OnInitializedAsync();
+            SetClassMap();
+            _currentUser = UserService.CurrentUser;
+            var notices = await ProjectService.GetNoticesAsync();
+            _notifications = notices.Where(x => x.Type == "notification").Cast<NoticeIconData>().ToArray();
+            _messages = notices.Where(x => x.Type == "message").Cast<NoticeIconData>().ToArray();
+            _events = notices.Where(x => x.Type == "event").Cast<NoticeIconData>().ToArray();
+            _count = notices.Length;
+        }
+
+        protected void SetClassMap()
+        {
+            ClassMapper
+                .Clear()
+                .Add("right");
+        }
+
+        public void HandleSelectUser(MenuItem item)
+        {
+            switch (item.Key)
+            {
+                case "center":
+                    NavigationManager.NavigateTo("/account/center");
+                    break;
+                case "setting":
+                    NavigationManager.NavigateTo("/account/settings");
+                    break;
+                case "logout":
+                    authorProvider.LogoutAsync();
+                    //NavigationManager.NavigateTo("/LoginPages");
+                    break;
+            }
+        }
+
+        public void HandleSelectLang(MenuItem item)
+        {
+        }
+
+        public async System.Threading.Tasks.Task HandleClear(string key)
+        {
+            switch (key)
+            {
+                case "notification":
+                    _notifications = new NoticeIconData[] { };
+                    break;
+                case "message":
+                    _messages = new NoticeIconData[] { };
+                    break;
+                case "event":
+                    _events = new NoticeIconData[] { };
+                    break;
+            }
+            await MessageService.Success($"清空了{key}");
+        }
+
+        public async System.Threading.Tasks.Task HandleViewMore(string key)
+        {
+            await MessageService.Info("Click on view more");
+        }
+    }
+}

+ 47 - 0
wispro.sp.web/Components/UserGradeSelect.razor

@@ -0,0 +1,47 @@
+@inject StaffGradeService _staffGradeService;
+
+<Select DataSource="@_StaffGrades"
+        @bind-Value="@_StaffGradeId"
+        LabelName="@nameof(wispro.sp.entity.StaffGrade.Grade)"
+        ValueName="@nameof(wispro.sp.entity.StaffGrade.Id)"
+        Style="width: 200px"
+        Placeholder="选择一个代理人等级"
+        IgnoreItemChanges="false"
+        AllowClear>
+</Select>
+
+@code {
+    private List<StaffGrade> _StaffGrades;
+    private int _StaffGradeId;
+    private StaffGrade _SelectedItem;
+
+    [Parameter]
+    public int StaffGradeId 
+    {
+        get { return _StaffGradeId; }
+        set {
+            if (_StaffGradeId == value) return;
+
+            _StaffGradeId = value;
+            StaffGradeIdChanged.InvokeAsync(_StaffGradeId);
+        }
+    }
+
+
+    [Parameter]
+    public EventCallback<int> StaffGradeIdChanged { get; set; }
+
+    protected override async System.Threading.Tasks.Task OnInitializedAsync()
+    {
+        base.OnInitialized();
+
+        _StaffGrades =await _staffGradeService.GetAll();
+    }
+
+    private void OnSelectedItemChangedHandler(StaffGrade value)
+    {
+        _SelectedItem = value;
+        StaffGradeIdChanged.InvokeAsync(_SelectedItem.Id);
+    }
+
+}

+ 49 - 0
wispro.sp.web/Extensions/DateTimeExtension.cs

@@ -0,0 +1,49 @@
+using System;
+
+namespace wispro.sp.web {
+  public static class DateTimeExtension {
+    private const int Second = 1;
+    private const int Minute = 60 * Second;
+    private const int Hour = 60 * Minute;
+    private const int Day = 24 * Hour;
+    private const int Month = 30 * Day;
+
+    // todo: Need to be localized
+    public static string ToFriendlyDisplay(this DateTime dateTime) {
+      var ts = DateTime.Now - dateTime;
+      var delta = ts.TotalSeconds;
+      if (delta < 0) {
+        return "not yet";
+      }
+      if (delta < 1 * Minute) {
+        return ts.Seconds == 1 ? "1 second ago" : ts.Seconds + " seconds ago";
+      }
+      if (delta < 2 * Minute) {
+        return "1 minute ago";
+      }
+      if (delta < 45 * Minute) {
+        return ts.Minutes + "minute";
+      }
+      if (delta < 90 * Minute) {
+        return "1 hour ago";
+      }
+      if (delta < 24 * Hour) {
+        return ts.Hours + " hours ago";
+      }
+      if (delta < 48 * Hour) {
+        return "yesterday";
+      }
+      if (delta < 30 * Day) {
+        return ts.Days + " days ago";
+      }
+      if (delta < 12 * Month) {
+        var months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));
+        return months <= 1 ? "A month ago" : months + " months ago";
+      }
+      else {
+        var years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));
+        return years <= 1 ? "a year ago" : years + " years ago";
+      }
+    }
+  }
+}

+ 240 - 0
wispro.sp.web/Layouts/BasicLayout.razor

@@ -0,0 +1,240 @@
+@namespace wispro.sp.web
+@inherits LayoutComponentBase
+@using Microsoft.AspNetCore.Components.Authorization
+
+<CascadingAuthenticationState>
+    <AuthorizeView>
+        <Authorized>
+            <AntDesign.ProLayout.BasicLayout Logo="@("images/小美logo-64-64.png")"
+                                             MenuData="_menuData" Theme="MenuTheme.Light" Layout="AntDesign.ProLayout.Layout.Mix">
+
+                <RightContentRender>
+                    <wispro.sp.web.Components.RightContent />
+                </RightContentRender>
+                <ChildContent>
+                    @Body
+                </ChildContent>
+                <FooterRender>
+                    <FooterView Copyright="2021 小美知识产权集团" Links="Links"></FooterView>
+                </FooterRender>
+            </AntDesign.ProLayout.BasicLayout>
+        </Authorized>
+        <NotAuthorized>
+            <wispro.sp.web.Pages.LoginPages />
+        </NotAuthorized>
+    </AuthorizeView>
+</CascadingAuthenticationState>
+@code
+{
+
+    RenderFragment sub1Title =
+    @<Template>
+        <Icon Type="user" Theme="outline"></Icon>
+        我的配置
+        <Icon Type="down" />
+    </Template>;
+
+    private readonly MenuDataItem[] _menuData =
+    {
+        new MenuDataItem
+        {
+            Path = "/Home",
+            Name = "首页",
+            Key = "index",
+            Icon = "home",
+        },
+        new MenuDataItem
+        {
+            Path = "/StartPerformanceCalculation",
+            Name = "开启绩效计算",
+            Key = "startCal",
+            Icon = "play-circle",
+        },
+        //new MenuDataItem
+        //{
+        //    Path = "/PerformanceList",
+        //    Name = "我的绩效",
+        //    Key = "PerformanceList",
+        //    Icon = "ordered-list",
+        //},
+        new MenuDataItem
+        {
+            Name="申请案处理界面",
+            Key="appManager",
+            Icon ="setting",
+            Children= new MenuDataItem[]
+            {
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "案件确认",
+                    Key = "app_confirm"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "案件系数申诉审核",
+                    Key = "app_xishu_confirm"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "处理事项系数申诉审核",
+                    Key = "app_doItemxishu_confirm"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "处理人错误申诉审核",
+                    Key = "app_doperson_confirm"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "审核人错误申诉审核",
+                    Key = "app_doperson_confirm"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "验证超期说明审核",
+                    Key = "app_doperson_confirm1"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "案件分配比例申诉审核",
+                    Key = "app_doperson_confirm4"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "案件缺漏提报审核",
+                    Key = "app_doperson_confirm2"
+                },
+                new MenuDataItem
+                {
+                    Path="/PerformanceList",
+                    Name = "涉外新申请算法确认",
+                    Key = "app_doperson_confirm3"
+                }
+            }
+        },
+        new MenuDataItem
+        {
+            Name = "专案处理界面",
+            Key = "staffManager",
+            Icon = "setting",
+            Children= new MenuDataItem[]
+            {
+                new MenuDataItem
+                {
+                    Path ="/Project/ReadMessage",
+                    Name ="专案点数分配系统通知",
+                    Key= "project_readMsg",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/Project/AssignPoint/1",
+                    Name ="分配专案点数",
+                    Key= "project_assignpoint",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/Project/ReadAssignPointMsg",
+                    Name ="专案点数分配通知阅读",
+                    Key= "ReadAssignPointMsg",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/Project/ConfirmProjectPoint",
+                    Name ="代理人确认",
+                    Key= "project_point_confirm",
+                    Icon = ""
+                }
+
+            }
+        },
+        new MenuDataItem
+        {
+            Name = "基本资料管理",
+            Key = "baseResource",
+            Icon = "setting",
+            Children= new MenuDataItem[]
+            {
+                new MenuDataItem
+                {
+                    Path ="/StaffList",
+                    Name ="账号管理",
+                    Key= "staff",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/StaffGrade",
+                    Name ="代理人系数设定",
+                    Key= "sg",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/VerifyCeofficient",
+                    Name ="核稿系数设定",
+                    Key="vc",
+                    Icon = ""
+                }
+                ,
+                new MenuDataItem
+                {
+                    Path ="/VerifyCeofficient",
+                    Name ="案件难度系数设定",
+                    Key="vc",
+                    Icon = ""
+                },
+                new MenuDataItem
+                {
+                    Path ="/CustomerList",
+                    Name ="客户信息管理",
+                    Key="customer",
+                    Icon = ""
+                }
+
+            }
+        }
+    };
+
+    public LinkItem[] Links { get; set; } =
+    {
+        new LinkItem
+        {
+            Key = "威世博官网",
+            Title = "深圳威世博",
+            Href = "https://www.weishibo.cn/",
+            BlankTarget = true,
+        },
+        new LinkItem
+        {
+            Key = "patentics",
+            Title = "Patentics数据库",
+            Href = "https://www.patentics.com/",
+            BlankTarget = true,
+        },
+        new LinkItem
+        {
+            Key = "合享数据库",
+            Title = "合享数据库",
+            Href = "https://www.incopat.com/intelLib/node/initIntelligentLib",
+            BlankTarget = true,
+        },
+        new LinkItem
+        {
+            Key = "zhihuiya",
+            Title = "智慧芽数据库",
+            Href = "https://account.zhihuiya.com/",
+            BlankTarget = true,
+        }
+    };
+}

+ 20 - 0
wispro.sp.web/Layouts/LoginLayout.razor

@@ -0,0 +1,20 @@
+@inherits LayoutComponentBase
+
+<AntDesign.Layout Style="@Style" Class="site-layout-background-img">
+    <Content Style="padding: 24px;min-height: 280px;">
+        @Body
+    </Content>
+    <Footer Style="text-align: center;height:50px;"> ©2021 Created by 小米知识产权</Footer>
+</AntDesign.Layout>
+
+<style>
+    .site-layout-background-img {
+        background-image: url(images/bg1.jpg);
+        background-attachment: fixed;
+        background-repeat: no-repeat;
+        background-size: cover;
+        background-position: center;
+    }
+
+    
+</style>

+ 37 - 0
wispro.sp.web/Layouts/LoginLayout.razor.cs

@@ -0,0 +1,37 @@
+using Microsoft.AspNetCore.Components;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Layouts
+{
+    public partial class LoginLayout
+    {
+        [Parameter]
+        public string Style { get; set; } = "min-height:100vh;";
+
+        protected override void OnInitialized()
+        {
+            base.OnInitialized();
+        }
+        EventCallback _layoutStyleCallBack = EventCallback.Empty;
+        EventCallback LayoutStyleCallBack
+        {
+            get
+            {
+                if (_layoutStyleCallBack.Equals(EventCallback.Empty))
+                    _layoutStyleCallBack = EventCallback.Factory.Create(this, SetStyle);
+                return _layoutStyleCallBack;
+            }
+        }
+
+        public void SetStyle(object style)
+        {
+            if (style != null)
+            {
+                Style = style.ToString();
+            }
+        }
+    }
+}

+ 14 - 0
wispro.sp.web/Models/ActivitiesType.cs

@@ -0,0 +1,14 @@
+using System;
+
+namespace wispro.sp.web.Models
+{
+    public class ActivitiesType
+    {
+        public string Id { get; set; }
+        public DateTime UpdatedAt { get; set; }
+        public ActivityUser User { get; set; }
+        public ActivityGroup Group { get; set; }
+        public ActivityProject Project { get; set; }
+        public string Template { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/ActivityGroup.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class ActivityGroup
+    {
+        public string Name { get; set; }
+        public string Link { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/ActivityProject.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class ActivityProject
+    {
+        public string Name { get; set; }
+        public string Link { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/ActivityUser.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class ActivityUser
+    {
+        public string Name { get; set; }
+        public string Avatar { get; set; }
+    }
+}

+ 12 - 0
wispro.sp.web/Models/AdvancedOperation.cs

@@ -0,0 +1,12 @@
+namespace wispro.sp.web.Models
+{
+    public class AdvancedOperation
+    {
+        public string Key { get; set; }
+        public string Type { get; set; }
+        public string Name { get; set; }
+        public string Status { get; set; }
+        public string UpdatedAt { get; set; }
+        public string Memo { get; set; }
+    }
+}

+ 9 - 0
wispro.sp.web/Models/AdvancedProfileData.cs

@@ -0,0 +1,9 @@
+namespace wispro.sp.web.Models
+{
+    public class AdvancedProfileData
+    {
+        public AdvancedOperation[] AdvancedOperation1 { get; set; }
+        public AdvancedOperation[] AdvancedOperation2 { get; set; }
+        public AdvancedOperation[] AdvancedOperation3 { get; set; }
+    }
+}

+ 12 - 0
wispro.sp.web/Models/BasicGood.cs

@@ -0,0 +1,12 @@
+namespace wispro.sp.web.Models
+{
+    public class BasicGood
+    {
+        public string Id { get; set; }
+        public string Name { get; set; }
+        public string Barcode { get; set; }
+        public string Price { get; set; }
+        public string Num { get; set; }
+        public string Amount { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/BasicProfileDataType.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class BasicProfileDataType
+    {
+        public BasicGood[] BasicGoods { get; set; }
+        public BasicProgress[] BasicProgress { get; set; }
+    }
+}

+ 12 - 0
wispro.sp.web/Models/BasicProgress.cs

@@ -0,0 +1,12 @@
+namespace wispro.sp.web.Models
+{
+    public class BasicProgress
+    {
+        public string Key { get; set; }
+        public string Time { get; set; }
+        public string Rate { get; set; }
+        public string Status { get; set; }
+        public string Operator { get; set; }
+        public string Cost { get; set; }
+    }
+}

+ 16 - 0
wispro.sp.web/Models/ChartData.cs

@@ -0,0 +1,16 @@
+namespace wispro.sp.web.Models
+{
+    public class ChartData
+    {
+        public ChartDataItem[] VisitData { get; set; }
+        public ChartDataItem[] VisitData2 { get; set; }
+        public ChartDataItem[] SalesData { get; set; }
+        public SearchDataItem[] SearchData { get; set; }
+        public OfflineDataItem[] OfflineData { get; set; }
+        public OfflineChartDataItem[] OfflineChartData { get; set; }
+        public ChartDataItem[] SalesTypeData { get; set; }
+        public ChartDataItem[] SalesTypeDataOnline { get; set; }
+        public ChartDataItem[] SalesTypeDataOffline { get; set; }
+        public RadarDataItem[] RadarData { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/ChartDataItem.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class ChartDataItem
+    {
+        public string X { get; set; }
+        public int Y { get; set; }
+    }
+}

+ 45 - 0
wispro.sp.web/Models/CurrentUser.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Models
+{
+    public class TagType
+    {
+        public string Key { get; set; }
+        public string Label { get; set; }
+    }
+
+    public class GeographicType
+    {
+        public TagType Province { get; set; }
+        public TagType City { get; set; }
+    }
+
+    public class CurrentUser
+    {
+        public string Name { get; set; }
+        public string Avatar { get; set; }
+        public string Userid { get; set; }
+        public NoticeType[] Notice { get; set; } = { };
+        public string Email { get; set; }
+        public string Signature { get; set; }
+        public string Title { get; set; }
+        public string Group { get; set; }
+        public TagType[] Tags { get; set; } = { };
+        public int NotifyCount { get; set; }
+        public int UnreadCount { get; set; }
+        public string Country { get; set; }
+        public GeographicType Geographic { get; set; }
+        public string Address { get; set; }
+        public string Phone { get; set; }
+    }
+
+    public class UserLiteItem
+    {
+        public string Avater { get; set; }
+        public string Title { get; set; }
+        public string Description { get; set; }
+    }
+}

+ 48 - 0
wispro.sp.web/Models/FormModel.cs

@@ -0,0 +1,48 @@
+using System;
+
+namespace wispro.sp.web.Models
+{
+    public class StepFormModel
+    {
+        public string ReceiverAccountType { get; set; } = "ant-design@alipay.com";
+        public string ReceiverAccount { get; set; } = "test@example.com";
+        public string ReceiverName { get; set; } = "Alex";
+        public string PayAccount { get; set; }
+        public string Password { get; set; } = "500";
+        public string Amount { get; set; } = "12345678";
+    }
+
+    public class AdvancedFormModel
+    {
+        public string Name { get; set; }
+        public string Url { get; set; }
+        public string Owner { get; set; }
+        public string Approver { get; set; }
+        public DateTime?[] DateRange { get; set; }
+        public string Type { get; set; }
+        public string Name2 { get; set; }
+        public string Url2 { get; set; }
+        public string Owner2 { get; set; }
+        public string Approver2 { get; set; }
+        public DateTime? DateRange2 { get; set; }
+        public string Type2 { get; set; }
+    }
+
+    public class BasicFormModel
+    {
+        public string Title { get; set; }
+        public string Client { get; set; }
+        public string Invites { get; set; }
+        public int Disclosure { get; set; }
+        public int Weight { get; set; }
+        public string Standard { get; set; }
+        public string Goal { get; set; }
+        public DateTime?[] DateRange { get; set; }
+    }
+
+    public class Owner
+    {
+        public string Id { get; set; }
+        public string Name { get; set; }
+    }
+}

+ 17 - 0
wispro.sp.web/Models/ListFormModel.cs

@@ -0,0 +1,17 @@
+namespace wispro.sp.web.Models
+{
+    public class ListFormModel
+    {
+        public string Owner { get; set; } = "wzj";
+
+        public string ActiveUser { get; set; }
+
+        public string Satisfaction { get; set; }
+    }
+
+    public class BasicListFormModel
+    {
+        public string Status { get; set; } = "all";
+        public string SearchKeyword { get; set; }
+    }
+}

+ 42 - 0
wispro.sp.web/Models/ListItemDataType.cs

@@ -0,0 +1,42 @@
+using System;
+using System.Text.Json.Serialization;
+using wispro.sp.web.Utils;
+
+namespace wispro.sp.web.Models
+{
+    public class Member
+    {
+        public string Avatar { get; set; }
+        public string Name { get; set; }
+        public string Id { get; set; }
+    }
+
+    public class ListItemDataType
+    {
+        public string Id { get; set; }
+        public string Owner { get; set; }
+        public string Title { get; set; }
+        public string Avatar { get; set; }
+        public string Cover { get; set; }
+        public string Status { get; set; }
+        public int Percent { get; set; }
+        public string Logo { get; set; }
+        public string Href { get; set; }
+        public string Body { get; set; }
+        public string SubDescription { get; set; }
+        public string Description { get; set; }
+        public int ActiveUser { get; set; }
+        public int NewUser { get; set; }
+        public int Star { get; set; }
+        public int Like { get; set; }
+        public int Message { get; set; }
+        public string Content { get; set; }
+        public Member[] Members { get; set; }
+
+        [JsonConverter(typeof(LongToDateTimeConverter))]
+        public DateTime UpdatedAt { get; set; }
+
+        [JsonConverter(typeof(LongToDateTimeConverter))]
+        public DateTime CreatedAt { get; set; }
+    }
+}

+ 19 - 0
wispro.sp.web/Models/LoginParamsType.cs

@@ -0,0 +1,19 @@
+using System.ComponentModel.DataAnnotations;
+
+namespace wispro.sp.web.Models
+{
+    public class LoginParamsType
+    {
+        [Required] public string UserName { get; set; }
+
+        [Required] public string Password { get; set; }
+
+        public string Mobile { get; set; }
+
+        public string Captcha { get; set; }
+
+        public string LoginType { get; set; }
+
+        public bool AutoLogin { get; set; }
+    }
+}

+ 11 - 0
wispro.sp.web/Models/NoticeItem.cs

@@ -0,0 +1,11 @@
+using AntDesign.ProLayout;
+
+namespace wispro.sp.web.Models
+{
+    public class NoticeItem : NoticeIconData
+    {
+        public string Id { get; set; }
+        public string Type { get; set; }
+        public string Status { get; set; }
+    }
+}

+ 19 - 0
wispro.sp.web/Models/NoticeType.cs

@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Models
+{
+    public class NoticeType
+    {
+        public string Id { get; set; }
+        public string Title { get; set; }
+        public string Logo { get; set; }
+        public string Description { get; set; }
+        public string UpdatedAt { get; set; }
+        public string Member { get; set; }
+        public string Href { get; set; }
+        public string MemberLink { get; set; }
+    }
+}

+ 9 - 0
wispro.sp.web/Models/OfflineChartDataItem.cs

@@ -0,0 +1,9 @@
+namespace wispro.sp.web.Models
+{
+    public class OfflineChartDataItem
+    {
+        public long X { get; set; }
+        public int Y1 { get; set; }
+        public int Y2 { get; set; }
+    }
+}

+ 8 - 0
wispro.sp.web/Models/OfflineDataItem.cs

@@ -0,0 +1,8 @@
+namespace wispro.sp.web.Models
+{
+    public class OfflineDataItem
+    {
+        public string Name { get; set; }
+        public float Cvr { get; set; }
+    }
+}

+ 85 - 0
wispro.sp.web/Models/ProjectInfo.cs

@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Models
+{
+    public class ProjectInfo
+    {
+        public string CaseNo { get; set; }
+        public string CaseName { get; set; }
+
+        public string DoItem { get; set; }
+
+        public string ResponseMan { get; set; }
+
+        public List<string> DoPerson { get; set; }
+    }
+
+    public class ProjectPoint
+    {
+        public string person { get; set; }
+
+        public string doItem { get; set; }
+
+        public string DoItemCoefficient { get; set; }
+
+        public double Point { get; set; }
+    }
+
+    public class Task
+    {
+        public int Id { get; set; }
+        public string Name { get; set; }
+
+        public string ResponseMan { get; set; }
+
+        public string UIUrl { get; set; }
+
+        public List<TaskHandleInfo> Handles { get; set; }
+
+        public string Type { get; set; }
+
+        public DateTime? LimiteDate { get; set; }
+
+        public ProjectInfo ProjectInfo { get; set; }
+
+        public string State { get; set; }
+
+        public DateTime? FinishedTime { get; set; }
+
+        public DateTime CreateTime { get; set; } = DateTime.Now;
+    }
+
+    public class TaskHandleInfo
+    {
+        public string Name { get; set; }
+
+        public string UIUrl { get; set; }
+    }
+
+    public class ProjectMessage
+    {
+        public string From { get; set; }
+
+        public List<MsgReadInfo> To { get; set; }
+
+        public string MessageInfo { get; set; }
+
+        public List<Task> Tasks { get; set; }
+
+        public string Type { get; set; }
+
+        //public List<ProjectInfo> ProjectInfos { get; set; }
+    }
+
+    public class MsgReadInfo
+    {
+        public string Reciever { get; set; }
+
+        public bool isReaded { get; set; }
+
+        public DateTime? ReadTime { get; set; }
+    }
+}

+ 9 - 0
wispro.sp.web/Models/RadarDataItem.cs

@@ -0,0 +1,9 @@
+namespace wispro.sp.web.Models
+{
+    public class RadarDataItem
+    {
+        public string Name { get; set; }
+        public string Label { get; set; }
+        public int Value { get; set; }
+    }
+}

+ 11 - 0
wispro.sp.web/Models/SearchDataItem.cs

@@ -0,0 +1,11 @@
+namespace wispro.sp.web.Models
+{
+    public class SearchDataItem
+    {
+        public int Index { get; set; }
+        public string Keywod { get; set; }
+        public int Count { get; set; }
+        public int Range { get; set; }
+        public int Status { get; set; }
+    }
+}

+ 105 - 0
wispro.sp.web/Pages/CustomerList.razor

@@ -0,0 +1,105 @@
+@page  "/CustomerList"
+
+@inject HttpClient Http
+@using AntDesign.TableModels
+@inject MessageService _message
+@using System.ComponentModel
+@using wispro.sp.share
+@attribute [Authorize]
+
+<PageContainer>
+    <Breadcrumb>
+        <Breadcrumb>
+            <BreadcrumbItem>
+                <a href="/Home"><Icon Type="home"></Icon></a>
+            </BreadcrumbItem>
+            <BreadcrumbItem>
+                <Icon Type="setting"></Icon><span>基本信息管理</span>
+            </BreadcrumbItem>
+            <BreadcrumbItem>
+                <Icon Type="user"></Icon><span>客户管理</span>
+            </BreadcrumbItem>
+        </Breadcrumb>
+    </Breadcrumb>
+    <Content>
+        <Button Type="primary" Icon="plus" OnClick="AddNew" Style="float:right">添加</Button>
+    </Content>
+    <ChildContent>
+        @if (_Customers == null)
+        {
+            <center><Spin /></center>
+        }
+        else
+        {
+
+            <AntDesign.Table @ref="table"
+                             TItem="wispro.sp.entity.Customer"
+                             Loading="_loading"
+                             DataSource="@_Customers"
+                             Total="_total"
+                             @bind-SelectedRows="selectedRows"
+                             OnRow="OnRow"
+                             Bordered=@true
+                             Size=@TableSize.Middle>
+                <ChildContent>
+                    <Selection Key="@(context.Id.ToString())" />
+                    <AntDesign.Column Title="公司名称" @bind-Field="@context.Name" Sortable Filterable />
+                    <AntDesign.Column Title="地址" @bind-Field="@context.Address" Sortable Filterable />
+                    <AntDesign.Column Title="联系人" @bind-Field="@context.ContactMan" Sortable Filterable />
+                    <AntDesign.Column Title="电话" @bind-Field="@context.Phone" Sortable Filterable />
+                    @*<AntDesign.Column Title="负责人" @bind-Field="@context.ResponseMan.Name" Sortable Filterable />*@
+
+                    <ActionColumn>
+                        <Space>
+                            <SpaceItem><Button Danger OnClick="()=>Edit(context.Id)">编辑</Button></SpaceItem>
+                        </Space>
+                    </ActionColumn>
+                </ChildContent>
+
+            </AntDesign.Table>
+
+        }
+
+    </ChildContent>
+</PageContainer>
+
+
+<Modal Title="修改"
+       Visible="@_visible"
+       OnOk="@HandleOk"
+       OnCancel="@HandleCancel">
+
+    <Form Model="Editing" LabelColSpan="6"
+          WrapperColSpan="16">
+
+        <FormItem Label="公司名称">
+            <Input @bind-Value="@context.Name" />
+        </FormItem>
+
+        <FormItem Label="联系地址">
+            <Input @bind-Value="@context.Address" />
+        </FormItem>
+
+        <FormItem Label="电话">
+            <Input @bind-Value="@context.Phone" />
+        </FormItem>
+
+        <FormItem Label="联系人">
+            <Input @bind-Value="@context.ContactMan" />
+        </FormItem>
+
+        <FormItem Label="负责人">
+            @if (context.ResponseMan == null)
+            {
+                context.ResponseMan = new Staff();
+            }
+            <Input @bind-Value="@context.ResponseMan.Name" />
+        </FormItem>
+
+    </Form>
+
+</Modal>
+
+
+
+

+ 332 - 0
wispro.sp.web/Pages/CustomerList.razor.cs

@@ -0,0 +1,332 @@
+using AntDesign;
+using AntDesign.TableModels;
+using Microsoft.AspNetCore.Components.Web;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Pages
+{
+    public partial class CustomerList
+    {
+        private List<entity.Customer> _Customers =new List<entity.Customer>()
+            {
+                new entity.Customer()
+                {
+                    Id=1,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address="广东省东莞市长安镇乌沙海滨路18号",
+                    Phone="4001-666-888",
+                    ContactMan="刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+},
+                new entity.Customer()
+                {
+                    Id = 2,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 3,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 4,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 5,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 6,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 7,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 8,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 9,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 10,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 11,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 12,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 13,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 14,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 15,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 16,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 17,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                   ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                },
+                new entity.Customer()
+                {
+                    Id = 18,
+                    Name = "OPPO广东移动通信有限公司",
+                    Address = "广东省东莞市长安镇乌沙海滨路18号",
+                    Phone = "4001-666-888",
+                    ContactMan = "刘波",
+                    ResponseMan= new entity.Staff(){Name ="钟子敏",Id =1},
+                    ResponseManId= 1
+                }
+            };
+
+        IEnumerable<entity.Customer> selectedRows;
+        ITable table;
+
+        int _pageIndex = 1;
+        int _pageSize = 10;
+        int _total = 0;
+        bool _loading = false;
+
+        entity.Customer Editing = null;
+        bool _visible = false;
+        bool _isAdd = false;
+
+
+
+        protected override void OnInitialized()
+        {
+
+            _loading = true;
+
+            //await System.Threading.Thread.Sleep();
+            //List<wispro.sp.entity.StaffGrade> data = await Http.GetFromJsonAsync<List<wispro.sp.entity.StaffGrade>>($"http://localhost:39476/api/StaffGrade/GetAll");
+
+            _loading = false;
+            _total = _Customers.Count;
+
+        }
+
+        private void HandlePageChange(PaginationEventArgs args)
+        {
+            if (_pageIndex != args.Page)
+            {
+                _pageIndex = args.Page;
+            }
+
+            if (_pageSize != args.PageSize)
+            {
+                _pageSize = args.PageSize;
+            }
+        }
+
+
+        Dictionary<string, object> OnRow(RowData<entity.Customer> row)
+        {
+            Dictionary<string, object> ret = new Dictionary<string, object>();
+
+            ret.Add("id", row.Data.Id);
+            ret.Add("onclick", ((Action)delegate
+            {
+            //_message.Info($"row {row.Data.Grade} was clicked");
+        }));
+
+
+            return ret;
+        }
+
+        public void RemoveSelection(int id)
+        {
+            //var selected = selectedRows.Where(x => x.Id != id);
+            //selectedRows = selected;
+        }
+
+        private void Delete(int id)
+        {
+            var DelCustumer = _Customers.Where(x => x.Id == id).FirstOrDefault<entity.Customer>();
+
+            if (DelCustumer != null)
+            {
+                Editing = DelCustumer;
+                _isAdd = false;
+                _visible = true;
+            }
+            else
+            {
+
+            }
+            _total = _Customers.Count;
+        }
+
+        private void Edit(int id)
+        {
+            Editing = _Customers.Where(x => x.Id == id).FirstOrDefault<entity.Customer>();
+
+            if (Editing != null)
+            {
+                _isAdd = false;
+                _visible = true;
+            }
+            else
+            {
+
+            }
+            _total = _Customers.Count;
+        }
+
+        private void AddNew()
+        {
+            Editing = new entity.Customer();
+            //_isAdd = true;
+            _visible = true;
+        }
+
+        private async Task HandleOk(MouseEventArgs e)
+        {
+
+            //var data = await Http.PostAsJsonAsync<wispro.sp.entity.StaffGrade>($"http://localhost:39476/api/StaffGrade/Save", EditingStaff);
+
+            //if (data.IsSuccessStatusCode)
+            //{
+            //    ApiSaveResponse result = await data.Content.ReadFromJsonAsync<ApiSaveResponse>();
+            //    await Task.Delay(1000);
+
+            //    if (result.Success)
+            //    {
+            //        await _message.Success("数据已保存!");
+            //    }
+            //    else
+            //    {
+            //        await _message.Error($"{result.ErrorMessage}");
+            //    }
+
+            //}
+            //else
+            //{
+            //    await _message.Error($"请求发生错误 {data.StatusCode}");
+            //}
+
+            _visible = false;
+        }
+
+        private void HandleCancel(MouseEventArgs e)
+        {
+            Console.WriteLine(e);
+            _visible = false;
+        }
+    }
+}

+ 5 - 0
wispro.sp.web/Pages/ItemHandler/PerformanceItemList.razor

@@ -0,0 +1,5 @@
+@page "/PerformanceItemList"
+
+<h3>PerformanceItemList</h3>
+
+

+ 12 - 0
wispro.sp.web/Pages/ItemHandler/PerformanceItemList.razor.cs

@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace wispro.sp.web.Pages.ItemHandler
+{
+    public partial class PerformanceItemList
+    {
+
+    }
+}

+ 62 - 0
wispro.sp.web/Pages/LoginPages.razor

@@ -0,0 +1,62 @@
+@page "/"
+@layout Layouts.LoginLayout
+
+<div class="login-NavLogin">
+    <div style="padding:30px">
+        <Card Bordered="true" Title=@("用户登录") Style="width:400px" Hoverable="true">
+            <Body>
+                <Form Model="@model" OnFinish="OnLogin">
+                    <FormItem>
+                        <Space Direction="DirectionVHType.Vertical" Style="width:100%">
+                            <SpaceItem>
+                                <AntDesign.Input Placeholder="请输入用户名" Size="@InputSize.Large" @bind-Value="context.Name">
+                                    <Prefix><Icon Type="user"></Icon></Prefix>
+                                </AntDesign.Input>
+                                <br/>
+                            </SpaceItem>
+                            <SpaceItem>
+                                <AntDesign.Input Placeholder="请输入密码" Size="@InputSize.Large" @bind-Value="context.Password" type="password">
+                                    <Prefix><Icon Type="lock"></Icon></Prefix>
+                                </AntDesign.Input>
+                            </SpaceItem>
+                        </Space>
+                    </FormItem>
+                    <Space Direction="DirectionVHType.Vertical" Style="width:100%">
+                        <SpaceItem>
+                            <Spin Spinning="isLoading">
+                                <Button Type="primary" HtmlType="submit" Class="submit" Size="large" Block>登&nbsp;录</Button>
+                            </Spin>
+                        </SpaceItem>
+                        <SpaceItem>
+                            <div class="other">
+                                <a style="float: right;">
+                                    忘记密码
+                                </a>
+                            </div>
+                        </SpaceItem>
+                    </Space>
+                </Form>
+            </Body>
+        </Card>
+    </div>
+</div>
+
+
+<style>
+    .login-NavLogin {
+        position: absolute;
+        left: 50%;
+        top: 40%;
+        transform: translate(-50%, -50%);
+    }
+
+    body {
+        background-image: url(images/bg1.jpg);
+        background-attachment: fixed;
+        background-repeat: no-repeat;
+        background-size: cover;
+        background-position: center;
+    }
+</style>
+
+

+ 60 - 0
wispro.sp.web/Pages/LoginPages.razor.cs

@@ -0,0 +1,60 @@
+using AntDesign;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Authorization;
+using System.Net.Http;
+using System.Net.Http.Json;
+using wispro.sp.share.webViewObject;
+using wispro.sp.web.Services;
+using System.IdentityModel.Tokens.Jwt;
+using Microsoft.IdentityModel.Tokens;
+using System.Linq;
+using System.Security.Claims;
+using Blazored.LocalStorage;
+
+namespace wispro.sp.web.Pages
+{
+    public partial class LoginPages
+    {
+        [Inject] public HttpClient Http { get; set; }
+        [Inject] public MessageService MsgSvr { get; set; }
+        //[Inject] public AuthenticationStateProvider AuthProvider { get; set; }
+        [Inject] public IUserService _UserService { get; set; }
+        [Inject] public IAuthService authService { get; set; }
+
+        [Inject] public NavigationManager navigation { get; set; }
+
+        loginDto model = new loginDto();
+        bool isLoading;
+
+        async void OnLogin()
+        {
+            isLoading = true;
+
+            //var httpResponse = await Http.PostAsJsonAsync<loginDto>($"http://localhost:39476/api/account/Login", model);
+            //userToken result = await httpResponse.Content.ReadFromJsonAsync<userToken>();
+            bool result = await authService.LoginAsync(model);
+
+            if (result)
+            {
+                navigation.NavigateTo("/Home");
+            }
+            else
+            {
+                _ = MsgSvr.Error($"用户名或密码错误");
+                //await js.InvokeVoidAsync("alert", "登入失敗");
+            }
+
+            //if (string.IsNullOrWhiteSpace(result?.Token) == false)
+            //{
+            //    _ = MsgSvr.Success($"登录成功");
+            //    //((AuthProvider)AuthProvider).MarkUserAsAuthenticated(result);
+            //}
+            //else
+            //{
+            //    _ = MsgSvr.Error($"用户名或密码错误");
+            //}
+            isLoading = false;
+            //await InvokeAsync(StateHasChanged);
+        }
+    }
+}

+ 147 - 0
wispro.sp.web/Pages/PerformanceList.razor

@@ -0,0 +1,147 @@
+@page "/PerformanceList"
+@using wispro.sp.web.Components
+
+<PageContainer>
+    <Breadcrumb>
+        <Breadcrumb>
+            <BreadcrumbItem>
+                <a href="/Home"><Icon Type="home"></Icon></a>
+            </BreadcrumbItem>
+            <BreadcrumbItem>
+                <Icon Type="setting"></Icon><span>我的绩效清单</span>
+            </BreadcrumbItem>
+
+        </Breadcrumb>
+    </Breadcrumb>
+    <Content>
+        @*<Button Type="primary" Icon="plus" OnClick="AddNew" Style="float:right">添加</Button>*@
+    </Content>
+    <ChildContent>
+        <Pagination @bind-Current="@_pageIndex" @bind-Total="@_total" ShowSizeChanger OnChange="OnChange" />
+        @if (_Datas == null)
+        {
+            <center><Spin /></center>
+        }
+        else
+        {
+
+            <AntList TItem="PerformanceItem"
+                     DataSource="@_Datas"
+                     Class="activitiesList"
+                     Size="large"
+                     ItemLayout="ListItemLayout.Horizontal">
+                <PerformanceItemDescriptionItem EditingItem="context" OnSubmitShenSu="OnsubShensu" OnSWJXSF="OnJXCal"></PerformanceItemDescriptionItem>
+            </AntList>
+            @*<Pagination @bind-Current="_pageIndex"  @bind-Total="@_total"  ShowSizeChanger  OnChange="OnChange"/>*@
+        }
+    </ChildContent>
+</PageContainer>
+
+<Modal Title="涉外新申请算法备注" Visible="_ShowJXModal"
+       OnOk="@HandleOk1"
+       OnCancel="@HandleCancel1"
+       MaskClosable="false"
+       Width="600">
+    <Card Style="width:100%" Bordered>
+        <div>
+            <Row>
+                <AntDesign.Col Span="4"><b>我方文号:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@EditingItem.CaseNo</AntDesign.Col>
+                <AntDesign.Col Span="4"><b>处理事项:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@EditingItem.DoItem</AntDesign.Col>
+            </Row>
+            <Row><AntDesign.Col Span="24">&nbsp;</AntDesign.Col></Row>
+            <Row>
+                <AntDesign.Col Span="4"><b>案件名称:</b></AntDesign.Col>
+                <AntDesign.Col Span="20">@EditingItem.CaseName</AntDesign.Col>
+
+            </Row>
+        </div>
+    </Card>
+    <br />
+    <Form Model="_calType" LabelColSpan="6" WrapperColSpan="16">
+        <FormItem Label="绩效计算方式">
+            <RadioGroup @bind-Value="@context.Type">
+                <Radio  Value="@("按照字数计算绩效")">按照字数计算绩效</Radio>
+                <Radio  Value="@("按照件数计算绩效")">按照件数计算绩效</Radio>
+            </RadioGroup>
+        </FormItem>
+        <FormItem Label="请谁确认">
+            <Select DataSource="@Reviewers"
+                    @bind-Value="@context.ReviewerId"
+                    LabelName="@nameof(Staff.Name)"
+                    ValueName="@nameof(Staff.Id)"
+                    Placeholder="请选择确认人"
+                    Style="width: 100%"
+                    AllowClear
+                    DefaultActiveFirstItem="false"
+                    EnableSearch>
+            </Select>
+        </FormItem>
+        <FormItem Label="字数">
+            <AntDesign.InputNumber @bind-Value="context.wordCount" Min="1"></AntDesign.InputNumber>
+        </FormItem>
+    </Form>
+</Modal>
+
+<Modal Title="申诉窗口" Visible="@_visible"
+       OnOk="@HandleOk"
+       OnCancel="@HandleCancel"
+       MaskClosable ="false"
+       Width="600">
+    <Card Style="width:100%" Bordered>
+        <div>
+            <Row>
+                <AntDesign.Col Span="4"><b>我方文号:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@EditingItem.CaseNo</AntDesign.Col>
+                <AntDesign.Col Span="4"><b>处理事项:</b></AntDesign.Col>
+                <AntDesign.Col Span="8">@EditingItem.DoItem</AntDesign.Col>
+            </Row>
+            <Row><AntDesign.Col Span="24">&nbsp;</AntDesign.Col></Row>
+            <Row>
+                <AntDesign.Col Span="4"><b>案件名称:</b></AntDesign.Col>
+                <AntDesign.Col Span="20">@EditingItem.CaseName</AntDesign.Col>
+
+            </Row>
+        </div>
+    </Card>
+    <br />
+    <Form Model="_shenshou" LabelColSpan="6" WrapperColSpan="16">
+        <FormItem Label="类型">
+            <Select DataSource="@AvatarMenuItems"
+                    @bind-Value="@context.Type"
+                    LabelName="@nameof(AvatarMenuItem.Option)"
+                    ValueName="@nameof(AvatarMenuItem.Key)"
+                    Placeholder="请选择申诉类型"
+                    Style="width:100%"
+                    AllowClear
+                    DefaultActiveFirstItem="false"
+                    EnableSearch>
+            </Select>
+        </FormItem>
+        <FormItem Label="向谁申诉">
+            <Select DataSource="@Reviewers"
+                    @bind-Value="@context.ReviewerId"
+                    LabelName="@nameof(Staff.Name)"
+                    ValueName="@nameof(Staff.Id)"
+                    Placeholder="请选择审核人"
+                    Style="width: 100%"
+                    AllowClear
+                    DefaultActiveFirstItem="false"
+                    EnableSearch>
+            </Select>
+        </FormItem>
+        <FormItem Label="申诉理由">
+            <TextArea @bind-Value="@context.Reason" Rows="6" Style="width: 100%" />
+        </FormItem>
+        <FormItem Label="附件">
+            <Upload @attributes="attrs"
+                    FileList="fileList"
+                    OnChange="HandleChange">
+                <Button Icon="upload"><span>添加附件</span></Button>
+            </Upload>
+        </FormItem>
+    </Form>
+
+</Modal>
+

+ 230 - 0
wispro.sp.web/Pages/PerformanceList.razor.cs

@@ -0,0 +1,230 @@
+using AntDesign;
+using AntDesign.ProLayout;
+using Microsoft.AspNetCore.Components;
+using Microsoft.AspNetCore.Components.Web;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using wispro.sp.entity;
+using wispro.sp.web.Services;
+
+
+namespace wispro.sp.web.Pages
+{
+    public partial class PerformanceList
+    {
+
+        private List<PerformanceItem> _Datas;
+        IEnumerable<PerformanceItem> selectedItems;
+
+        int _pageIndex = 1;
+        int _pageSize = 10;
+        int _total = 0;
+        bool _loading = false;
+        PerformanceItem EditingItem = null;
+        bool _visible = false;
+        bool _isAdd = false;
+
+        [Inject] public PerformanceItemServices _ItemService { get; set; }
+        [Inject] public MessageService _message { get; set; }
+        [Inject] protected NavigationManager NavigationManager { get; set; }
+
+        
+
+        public void HandleSelectUser(MenuItem item)
+        {
+            switch (item.Key)
+            {
+                case "reviewer":
+                    //NavigationManager.NavigateTo("/account/center");
+                    break;
+                case "doPerson":
+                    //NavigationManager.NavigateTo("/account/settings");
+                    break;
+                case "caseCoe":
+                    //authorProvider.LogoutAsync();
+                    //NavigationManager.NavigateTo("/LoginPages");
+                    break;
+                case "itemCoe":
+                    //authorProvider.LogoutAsync();
+                    //NavigationManager.NavigateTo("/LoginPages");
+                    break;
+                case "milPerson":
+                    //authorProvider.LogoutAsync();
+                    //NavigationManager.NavigateTo("/LoginPages");
+                    break;
+            }
+        }
+        protected async override Task OnInitializedAsync()
+        {
+
+            _loading = true;
+
+            var data = await _ItemService.GetItems(_pageIndex, _pageSize);
+
+            
+            _Datas = data.Results;
+            _total = data.TotalCount;
+            _loading = false;
+        }
+
+        
+        private void OnsubShensu(PerformanceItem Item)
+        {
+            EditingItem = Item;
+            _visible = true;
+            //return new EventCallback();
+        }
+
+        bool _ShowJXModal = false;
+        private void OnJXCal(PerformanceItem Item)
+        {
+            EditingItem = Item;
+            _ShowJXModal = true;
+        }
+
+        #region 申诉窗口事件
+        private void HandleOk(MouseEventArgs e)
+        {
+            Console.WriteLine(e);
+            _visible = false;
+        }
+
+        private void HandleCancel(MouseEventArgs e)
+        {
+            Console.WriteLine(e);
+            _visible = false;
+        }
+        #endregion
+
+        #region 绩效计算窗口事件
+        private void HandleOk1(MouseEventArgs e)
+        {
+            Console.WriteLine(e);
+            _ShowJXModal = false;
+        }
+
+        private void HandleCancel1(MouseEventArgs e)
+        {
+            Console.WriteLine(e);
+            _ShowJXModal = false;
+        }
+        #endregion
+
+        public AvatarMenuItem[] AvatarMenuItems { get; set; } = new AvatarMenuItem[]
+        {
+            new() { Key = "reviewer", IconType = "user", Option = "核稿人申诉"},
+            new() { Key = "doPerson", IconType = "user", Option = "处理人申诉"},
+            new() { Key = "caseCoe", IconType = "logout", Option = "案件系数申诉"},
+            new() { Key = "itemCoe", IconType = "logout", Option = "处理事项系数申诉"},
+            new() { Key = "milPerson", IconType = "logout", Option = "多人处理分配比率申诉"},
+            new() { Key = "logout", IconType = "logout", Option = "严重超期说明"},
+            new() { Key = "logout", IconType = "logout", Option = "涉外新申请绩效计算备注"}
+        };
+        #region 文件上传控件设定
+        List<UploadFileItem> fileList = new List<UploadFileItem>
+            {
+                new UploadFileItem
+                {
+                    Id = "1",
+                    FileName = "客户往来邮件1.jpg",
+                    Url = "#",
+                    State = UploadState.Success
+                },
+                new UploadFileItem
+                {
+                    Id = "2",
+                    FileName = "与客户微信聊天图片.jpg",
+                    Url = "#",
+                    State = UploadState.Success
+                },
+                new UploadFileItem
+                {
+                    Id = "3",
+                    FileName = "附件.docx",
+                    Url = "#",
+                    State = UploadState.Success
+                }
+            };
+
+        Dictionary<string, object> attrs = new Dictionary<string, object>
+        {
+            {"Action", "#" },
+            {"Name", "files" },
+            {"Multiple", true }
+        };
+
+        void HandleChange(UploadInfo fileinfo)
+        {
+            //if (fileList.Count > 5)
+            //{
+            //    fileList.RemoveRange(0, fileList.Count - 2);
+            //}
+            //fileList.Where(file => file.State == UploadState.Success && !string.IsNullOrWhiteSpace(file.Response)).ForEach(file => {
+            //    var result = file.GetResponse<ResponseModel>();
+            //    file.Url = result.url;
+            //});
+        }
+
+        public class ResponseModel
+        {
+            public string name { get; set; }
+
+            public string status { get; set; }
+
+            public string url { get; set; }
+
+            public string thumbUrl { get; set; }
+        }
+        #endregion
+
+        class shenshou
+        {
+            public string Type { get; set; }
+
+            public int ReviewerId { get; set; }
+            public string Reason { get; set; }
+
+            public List<UploadFileItem> Files { get; set; }
+        }
+
+        class CalType
+        {
+            public string Type { get; set; } = "按照字数计算绩效";
+
+            public int ReviewerId { get; set; }
+
+            public int wordCount { get; set; }
+        }
+
+        CalType _calType = new CalType();
+        shenshou _shenshou = new shenshou();
+        List<Staff> Reviewers = new List<Staff>()
+        {
+            new Staff(){Id =1,Name ="钟子敏"},
+            new Staff(){Id =1,Name ="邢丽霞"},
+            new Staff(){Id =1,Name ="李丽"},
+            new Staff(){Id =1,Name ="贾凤涛"},
+        };
+
+        private async Task OnChange(PaginationEventArgs args)
+        {
+            if (_pageIndex != args.Page || _pageSize != args.PageSize)
+            {
+                _pageIndex = args.Page;
+                _pageSize = args.PageSize;
+
+                _loading = true;
+                _Datas = null;
+                var data = await _ItemService.GetItems(_pageIndex, _pageSize);
+                //var  data = response.GetAwaiter().GetResult();
+
+                _Datas = data.Results;
+                _total = data.TotalCount;
+                _loading = false;
+            }
+        }
+
+    }
+}

+ 122 - 0
wispro.sp.web/Pages/Project/AssignPoint.razor

@@ -0,0 +1,122 @@
+@page "/Project/AssignPoint/{id}"
+
+<PageContainer>
+    <Breadcrumb>
+        <Breadcrumb>
+            <BreadcrumbItem>
+                <a href="/Home"><Icon Type="home"></Icon></a>
+            </BreadcrumbItem>
+            <BreadcrumbItem>
+                <span>项目</span>
+            </BreadcrumbItem>
+            <BreadcrumbItem>
+                <span>分配项目点数</span>
+            </BreadcrumbItem>
+        </Breadcrumb>
+    </Breadcrumb>
+    <Content></Content>
+    <ChildContent>
+        <Card>
+            <Card>
+                <div>
+                    <Row>
+                        <AntDesign.Col Span="4"><b>我方文号:</b></AntDesign.Col>
+                        <AntDesign.Col Span="8">@task.ProjectInfo.CaseNo</AntDesign.Col>
+                        <AntDesign.Col Span="4"><b>处理事项:</b></AntDesign.Col>
+                        <AntDesign.Col Span="8">@task.ProjectInfo.DoItem</AntDesign.Col>
+                    </Row>
+                    <Row><AntDesign.Col Span="24">&nbsp;</AntDesign.Col></Row>
+                    <Row>
+                        <AntDesign.Col Span="4"><b>案件名称:</b></AntDesign.Col>
+                        <AntDesign.Col Span="16">@task.ProjectInfo.CaseName</AntDesign.Col>
+                        <AntDesign.Col Span="4"><Button Type="primary" Icon="plus" OnClick="AddNew" Style="float:right">添加</Button></AntDesign.Col>
+                    </Row>
+                </div>
+            </Card>
+            <Card>
+                <AntDesign.Table TItem="wispro.sp.web.Models.ProjectPoint"
+                                 DataSource="projectPoints"
+                                 Bordered=@true
+                                 Size=@TableSize.Small>
+                    <ChildContent Context="pp">
+                        <AntDesign.Column Title="处理事项" @bind-Field="@pp.doItem" Sortable Filterable />
+                        <AntDesign.Column Title="难度系数" @bind-Field="@pp.DoItemCoefficient" Sortable Filterable />
+                        <AntDesign.Column Title="处理人" @bind-Field="@pp.person" Sortable Filterable />
+                        <AntDesign.Column Title="分配点数"  @bind-Field="@pp.Point" TData="double">
+                            @if (editId == pp.person)
+                            {
+                                <Input Type="text" @bind-Value="pp.Point" OnBlur="stopEdit" AutoFocus />
+                            }
+                            else
+                            {
+                                <div class="editable-cell-value-wrap" style="padding-right:10px" @onclick="()=>startEdit(pp.person)">
+                                    @pp.Point
+                                </div>
+                            }
+                        </AntDesign.Column>
+                        <ActionColumn>
+                            <Space>
+                                <SpaceItem><Button Danger OnClick="()=>Delete(pp.person)">删除</Button></SpaceItem>
+                            </Space>
+                        </ActionColumn>
+                    </ChildContent>
+
+                </AntDesign.Table>
+            </Card>
+            
+            <Card>
+                <Space Style="float:right">
+                    <SpaceItem><Button Type="primary" Icon="save" OnClick="OnSave" Style="float:right">保存</Button></SpaceItem>
+                    <SpaceItem><Button Icon="cancel" OnClick="OnCancel" Style="float:right">取消</Button></SpaceItem>
+                </Space>
+            </Card>
+        </Card>
+        
+    </ChildContent>
+</PageContainer>
+
+
+<Modal  Title="分配点数"
+       Visible="@_visible"
+       OnOk="@HandleOk"
+       OnCancel="@HandleCancel" 
+       MaskClosable="false"
+       DestroyOnClose="true"
+       @ref="model">
+    <Form Model="addDoItem" LabelColSpan="6"
+          WrapperColSpan="16">
+        <FormItem Label="处理事项">
+            <Input @bind-Value="@context.Name" />
+        </FormItem>
+        <FormItem Label="难度系数">
+            <Input @bind-Value="@context.nanduxishu" />
+        </FormItem>
+        <AntDesign.Table 
+                         TItem="ProjectPoint"
+                         DataSource="addDoItem.AddprojectPoints"
+                         Bordered=@true
+                         Size=@TableSize.Small>
+            <ChildContent Context="pp">
+                <AntDesign.Column Title="处理人" @bind-Field="@pp.person" Sortable Filterable />
+                <AntDesign.Column Width="30%" Title="分配点数" TData="double">
+                    @if (editId == pp.person)
+                    {
+                        <Input Type="text" @bind-Value="pp.Point" OnBlur="stopEdit" AutoFocus />
+                    }
+                    else
+                    {
+                        <div class="editable-cell-value-wrap" style="padding-right:10px" @onclick="()=>startEdit(pp.person)">
+                            @pp.Point  
+                        </div>
+                    }
+                </AntDesign.Column>
+                <ActionColumn>
+                    <Space>
+                        <SpaceItem><Button Danger OnClick="()=>Delete(pp.person)">删除</Button></SpaceItem>
+                    </Space>
+                </ActionColumn>
+            </ChildContent>
+
+        </AntDesign.Table>
+    </Form>
+</Modal>

+ 0 - 0
wispro.sp.web/Pages/Project/AssignPoint.razor.cs


この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません