Explorar el Código

Merge branch 'develop' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop

zhouj1203@hotmail.com hace 6 años
padre
commit
cb7b9de818
Se han modificado 77 ficheros con 38780 adiciones y 488 borrados
  1. 0 1
      TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs
  2. 2 2
      TEAMModelOS.SDK/Helper/Common/StringHelper/HtmlHelper.cs
  3. 2 0
      TEAMModelOS.SDK/TEAMModelOS.SDK.csproj
  4. 2 2
      TEAMModelOS.Service/Evaluation/Implements/HtmlAnalyzeService.cs
  5. 182 3
      TEAMModelOS.Test.OfficeDoc/Program.cs
  6. 8 1
      TEAMModelOS.sln
  7. 1 0
      TEAMModelOS/ClientApp/assets/icon/no_data.svg
  8. 8 10
      TEAMModelOS/ClientApp/common/loading.vue
  9. 147 0
      TEAMModelOS/ClientApp/components/evaluation/SyllabusTree.vue
  10. 5 0
      TEAMModelOS/ClientApp/router/routes.js
  11. 32 0
      TEAMModelOS/ClientApp/view/evaluation/index/CreateCompose.css
  12. 212 0
      TEAMModelOS/ClientApp/view/evaluation/index/CreateCompose.vue
  13. 6 0
      TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.css
  14. 7 11
      TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.vue
  15. 254 0
      TEAMModelOS/ClientApp/view/evaluation/index/CreateNewChild.vue
  16. 1 1
      TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.css
  17. 2 2
      TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.vue
  18. 25 2
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.css
  19. 115 58
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.vue
  20. 0 336
      TEAMModelOS/ClientApp/view/evaluation/index/ExercisesListTree.vue
  21. 106 6
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.css
  22. 229 18
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.vue
  23. 9 9
      TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.vue
  24. 182 24
      TEAMModelOS/ClientApp/view/evaluation/index/index.vue
  25. 168 0
      TEAMModelOS/ClientApp/view/evaluation/index/list.json
  26. 1 1
      TEAMModelOS/ClientApp/view/evaluation/types/BaseJudge.vue
  27. 1 0
      TEAMModelOS/ClientApp/view/syllabus/index/Syllabus.vue
  28. 1 1
      TEAMModelOS/Views/Shared/_Layout.cshtml
  29. 30 0
      TeamModelOS.OfficeDoc.Test/App_Start/BundleConfig.cs
  30. 13 0
      TeamModelOS.OfficeDoc.Test/App_Start/FilterConfig.cs
  31. 23 0
      TeamModelOS.OfficeDoc.Test/App_Start/RouteConfig.cs
  32. 24 0
      TeamModelOS.OfficeDoc.Test/Content/Site.css
  33. 587 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.css
  34. 1 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.css.map
  35. 6 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.min.css
  36. 1 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.min.css.map
  37. 6834 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap.css
  38. 1 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap.css.map
  39. 6 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap.min.css
  40. 1 0
      TeamModelOS.OfficeDoc.Test/Content/bootstrap.min.css.map
  41. 30 0
      TeamModelOS.OfficeDoc.Test/Controllers/HomeController.cs
  42. 1 0
      TeamModelOS.OfficeDoc.Test/Global.asax
  43. 21 0
      TeamModelOS.OfficeDoc.Test/Global.asax.cs
  44. 35 0
      TeamModelOS.OfficeDoc.Test/Properties/AssemblyInfo.cs
  45. 2580 0
      TeamModelOS.OfficeDoc.Test/Scripts/bootstrap.js
  46. 6 0
      TeamModelOS.OfficeDoc.Test/Scripts/bootstrap.min.js
  47. 2670 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.intellisense.js
  48. 10364 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.js
  49. 2 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.min.js
  50. 1 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.min.map
  51. 8269 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.js
  52. 2 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.min.js
  53. 1 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.min.map
  54. 1288 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate-vsdoc.js
  55. 1601 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.js
  56. 4 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.min.js
  57. 432 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.unobtrusive.js
  58. 5 0
      TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.unobtrusive.min.js
  59. 1406 0
      TeamModelOS.OfficeDoc.Test/Scripts/modernizr-2.8.3.js
  60. 240 0
      TeamModelOS.OfficeDoc.Test/TeamModelOS.OfficeDoc.Test.csproj
  61. 7 0
      TeamModelOS.OfficeDoc.Test/Views/Home/About.cshtml
  62. 17 0
      TeamModelOS.OfficeDoc.Test/Views/Home/Contact.cshtml
  63. 31 0
      TeamModelOS.OfficeDoc.Test/Views/Home/Index.cshtml
  64. 14 0
      TeamModelOS.OfficeDoc.Test/Views/Shared/Error.cshtml
  65. 43 0
      TeamModelOS.OfficeDoc.Test/Views/Shared/_Layout.cshtml
  66. 43 0
      TeamModelOS.OfficeDoc.Test/Views/Web.config
  67. 3 0
      TeamModelOS.OfficeDoc.Test/Views/_ViewStart.cshtml
  68. 30 0
      TeamModelOS.OfficeDoc.Test/Web.Debug.config
  69. 31 0
      TeamModelOS.OfficeDoc.Test/Web.Release.config
  70. 55 0
      TeamModelOS.OfficeDoc.Test/Web.config
  71. BIN
      TeamModelOS.OfficeDoc.Test/favicon.ico
  72. BIN
      TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.eot
  73. 288 0
      TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.svg
  74. BIN
      TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.ttf
  75. BIN
      TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.woff
  76. BIN
      TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.woff2
  77. 25 0
      TeamModelOS.OfficeDoc.Test/packages.config

+ 0 - 1
TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs

@@ -78,7 +78,6 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth
             //自定义授权
             services.AddAuthorization(auth =>
             {
-                auth.AddPolicy("Admin", policy => policy.RequireRole("Admin,Root,SchoolAdmin,Teacher").Build());
                 auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                     .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                     .RequireAuthenticatedUser()

+ 2 - 2
TEAMModelOS.SDK/Helper/Common/StringHelper/HtmlHelper.cs

@@ -47,7 +47,7 @@ namespace TEAMModelOS.SDK.Helper.Common.StringHelper
         }
 
         /// <summary>
-        /// 从html获取文本及img的url  去掉其他标签的干扰。以获取更准确的sha1校验值
+        /// 从html获取文本及img的url  去掉其他标签的干扰,空格。以获取更准确的sha1校验值
         /// </summary>
         /// <param name="html"></param>
         /// <returns></returns>
@@ -56,7 +56,7 @@ namespace TEAMModelOS.SDK.Helper.Common.StringHelper
             HtmlDocument doc = new HtmlDocument();
             doc.LoadHtml(html);
             List<string> urls = GetHtmlImageUrlList(html);
-            StringBuilder builder = new StringBuilder(doc.DocumentNode.InnerText);
+            StringBuilder builder = new StringBuilder(doc.DocumentNode.InnerText.Replace("&nbsp;", ""));
             if (urls.IsNotEmpty())
             {
                 foreach (string url in urls)

+ 2 - 0
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -2,6 +2,8 @@
 
   <PropertyGroup>
     <TargetFramework>netcoreapp2.2</TargetFramework>
+    <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
+    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 2
TEAMModelOS.Service/Evaluation/Implements/HtmlAnalyzeService.cs

@@ -134,7 +134,7 @@ namespace TEAMModelOS.Service.Evaluation.Implements
                 string RegexStr = ComposeStart + "([\\s\\S]*?)" + ComposeEnd;
                 Match mt = Regex.Match(html, RegexStr);
                 exercise.Question= HtmlHelper.DoUselessTag(mt.Value.Replace(ComposeStart,"").Replace(ComposeEnd,""));
-                string testinfo = Regex.Replace(html, RegexStr, "").Replace(ComposeTag,"【");
+                string testinfo = Regex.Replace(html, RegexStr, "").Replace(ComposeTag,CompleteStart);
                 //获取综合题的材料加每个小题的sha1Code
                 string testQs= HtmlHelper.DoTextImg(exercise.Question);
                 List<ExerciseDto> dtos =  AnalyzeWordAsync(testinfo, Lang);
@@ -287,7 +287,7 @@ namespace TEAMModelOS.Service.Evaluation.Implements
                     {
                         nbsp += "&nbsp;";
                     }
-                    ReplaceDto replaceDto = new ReplaceDto { oldstr = "【" + an + "】", newstr = "<underline data=\"" + index + "\"><u>" + nbsp + "</u></underline>" };
+                    ReplaceDto replaceDto = new ReplaceDto { oldstr = CompleteStart + an + CompleteEnd, newstr = "<underline data=\"" + index + "\"><u>" + nbsp + "</u></underline>" };
                     replaces.Add(replaceDto);
                     ans.Add(an);
                     m = m.NextMatch();

+ 182 - 3
TEAMModelOS.Test.OfficeDoc/Program.cs

@@ -19,15 +19,194 @@ namespace TEAMModelOS.Test.OfficeDoc
 {
     class Program
     {
+        /// <summary>
+
+        /// 对数组进行组合操作,选取selectCount个元素进行组合
+
+        /// </summary>
+
+        /// <param name="lsArray">即将进行组合操作的数组</param>
+
+        /// <param name="selectCount">选取的元素的个数</param>
+
+        static void C(List<string> lsArray, int selectCount)
+
+        {
+
+            int totolcount = lsArray.Count;
+
+            int[] currectselect = new int[selectCount];
+
+            int last = selectCount - 1;
+
+
+
+            for (int i = 0; i < selectCount; i++)
+
+            {
+
+                currectselect[i] = i;
+
+            }
+
+
+
+            while (true)
+
+            {
+
+                for (int i = 0; i < selectCount; i++)
+
+                {
+
+                    Console.Write(" {0} ", lsArray[currectselect[i]]);
+
+                }
+
+                Console.WriteLine();
+
+
+
+                if (currectselect[last] < totolcount - 1)
+
+                {
+
+                    currectselect[last]++;
+
+                }
+
+                else
+
+                {
+
+                    int pos = last;
+
+                    while (pos > 0 && currectselect[pos - 1] == currectselect[pos] - 1)
+
+                    {
+
+                        pos--;
+
+                    }
+
+                    if (pos == 0) return;
+
+                    currectselect[pos - 1]++;
+
+                    for (int i = pos; i < selectCount; i++)
+
+                    {
+
+                        currectselect[i] = currectselect[i - 1] + 1;
+
+                    }
+
+                }
+
+            }
+
+        }
+
+
+
+        /// <summary>
+
+        /// 对数组进行全排列
+
+        /// </summary>
+
+        /// <param name="lsArray">要进行全排列的数组</param>
+
+        /// <param name="begin">进行全排列的开始下标</param>
+
+        /// <param name="end">进行全排列的结束下标</param>
+
+        static void A(List<string> lsArray, int begin, int end)
+
+        {
+
+            if (begin == end)
+
+            {
+
+                for (int i = 0; i <= end; i++)
+
+                    Console.Write(" {0} ", lsArray[i]);
+
+                Console.WriteLine();
+
+            }
+
+            for (int i = begin; i <= end; i++)
+
+            {
+
+                Swap(lsArray, begin, i);
+
+                A(lsArray, begin + 1, end);
+
+                Swap(lsArray, begin, i);
+
+            }
+
+        }
+
+
+
+        /// <summary>
+
+        /// 交换数组中的下标为x,y的值
+
+        /// </summary>
+
+        /// <param name="lsArray">该数组</param>
+
+        /// <param name="x"></param>
+
+        /// <param name="y"></param>
+
+        static void Swap(List<string> lsArray, int x, int y)
+
+        {
+
+            string t = lsArray[x];
+
+            lsArray[x] = lsArray[y];
+
+            lsArray[y] = t;
+
+        }
+
         static void Main(string[] args)
         {
-            string wordPathStr = @"E:\document\题目模板.docx";
-            string s = HttpHelper.HttpGet("https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelos/common/20190620/index_143520-2550.html");
+            List<string> list = new List<string>();
+
+            for (int i = 0; i < 6; i++)
+
+            {
+
+                list.Add(i.ToString());
+
+            }
+
+
+
+            //C(list, 4);
+
+            Console.WriteLine("---------------------");
+
+            A(list, 0, 4);
+          
+            
+            
+            // wordPathStr = @"E:\document\题目模板.docx";
+            //string s = HttpHelper.HttpGet("https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelos/common/20190620/index_143520-2550.html");
 
             //for (int i = 0; i < 1000; i++) {
             //    Console.WriteLine(DateTime.Now.ToString("yyyyMMddHHmmssfffffff"));
             //}
-            ConvertDocxToHtml(wordPathStr);
+            //ConvertDocxToHtml(wordPathStr);
             //byte[] byteArray = File.ReadAllBytes(wordPathStr);
             //using (WordprocessingDocument doc = WordprocessingDocument.Open(wordPathStr, true))
             //{

+ 8 - 1
TEAMModelOS.sln

@@ -25,7 +25,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Test.CosmosDB",
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TeamModelOS.Test.JsonPath", "TeamModelOS.Test.JsonPath\TeamModelOS.Test.JsonPath.csproj", "{519FE59A-2D7B-407C-952B-4F497B8BA07E}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelOS.Test.OfficeDoc", "TEAMModelOS.Test.OfficeDoc\TEAMModelOS.Test.OfficeDoc.csproj", "{98D55090-23B0-4362-872D-A184D95085C6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Test.OfficeDoc", "TEAMModelOS.Test.OfficeDoc\TEAMModelOS.Test.OfficeDoc.csproj", "{98D55090-23B0-4362-872D-A184D95085C6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeamModelOS.OfficeDoc.Test", "TeamModelOS.OfficeDoc.Test\TeamModelOS.OfficeDoc.Test.csproj", "{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -61,6 +63,10 @@ Global
 		{98D55090-23B0-4362-872D-A184D95085C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{98D55090-23B0-4362-872D-A184D95085C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{98D55090-23B0-4362-872D-A184D95085C6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -73,6 +79,7 @@ Global
 		{72CA120D-2C8E-433C-93EC-2E84FC6EFF8E} = {CFBC5D78-72A7-4330-B779-F6826194F48A}
 		{519FE59A-2D7B-407C-952B-4F497B8BA07E} = {CFBC5D78-72A7-4330-B779-F6826194F48A}
 		{98D55090-23B0-4362-872D-A184D95085C6} = {CFBC5D78-72A7-4330-B779-F6826194F48A}
+		{E5E2E853-AAE9-45D8-A59B-BC054434F9AD} = {CFBC5D78-72A7-4330-B779-F6826194F48A}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {5C55F286-63D0-4235-BDE0-D7AD32B0EDEB}

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TEAMModelOS/ClientApp/assets/icon/no_data.svg


+ 8 - 10
TEAMModelOS/ClientApp/common/loading.vue

@@ -1,17 +1,19 @@
 <template>
   <div class="loading-container">
-    <div id="loadingBox"></div>
+    <div id="loadingBox" :style="{'margin-top':top+'px','border-width': borderWidth + 'px'}"></div>
   </div>
 </template>
 
 <script>
     export default {
     name: "loadingBox",
+    props: ["top","borderColor","color","borderWidth"],
     data() {
       return {
       }
     },
     created() {
+      //console.log(this.top);
     },
     methods: {
       
@@ -20,25 +22,21 @@
 </script>
 <style>
   .loading-container {
-    position:relative;
+    position:absolute;
     width:100%;
     height:100%;
-    background:#3cefff;
     display:flex;
     flex-direction:row;
     justify-content:center;
-    align-items:center;
   }
 
   #loadingBox {
-    position:absolute;
-    top:500px;
-    left:46%;
-    border: 6px solid hsla(185, 100%, 62%, 0.2);
+    margin-top:200px;
+    border: 3px solid hsla(185, 100%, 62%, 0.2);
     border-top-color: #4c9cff;
     border-radius: 50%;
-    width: 60px;
-    height: 60px;
+    width: 40px;
+    height: 40px;
     animation: spin .7s linear infinite;
   }
 

+ 147 - 0
TEAMModelOS/ClientApp/components/evaluation/SyllabusTree.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="tree-main">
+    <Tree :data="treeData" :render="renderContent" ref="tree" show-checkbox empty-text="暂无课纲内容"></Tree>
+  </div>
+</template>
+<script>
+  export default {
+    props: ["treeDatas"],
+    data() {
+      return {
+        treeData: []
+      };
+    },
+    created() {
+      this.treeData = this.treeDatas;
+    },
+
+    //监听树形数据源变化
+    watch: {
+      treeDatas: {
+        handler(newValue) {
+          this.treeData = newValue;
+        },
+        deep: true
+      }
+    },
+    methods: {
+      //自定义渲染树形工具
+       renderContent(h, { root, node, data }) {
+        return h(
+          "span",
+          {
+            domProps: {
+              className: "singleClass"
+            },
+            on: {
+              click: () => {
+                this.titleClick(root, node, data, event);
+              },
+            }
+          },
+          [
+            h("span", [
+              h("span", {
+                domProps: {
+                  className: "syllabus-name"
+                },
+              }, data.title)
+            ])
+          ]
+        );
+      },
+      // 标题点击收缩展开
+      titleClick(root, node, data, event) {
+        data.expand = !data.expand;
+      },
+      // 根目录点击事件
+      rootClick(data) {
+        data.expand = !data.expand;
+      }
+    },
+  };
+</script>
+<style scoped>
+  .tree-main {
+    margin-left: 5%;
+    width: 90%;
+  }
+
+  .ivu-tree .ivu-tree-arrow {
+    width: 2%;
+  }
+
+  .ivu-input-wrapper {
+    width: 80% !important;
+  }
+
+  .modelRow {
+    margin: 20px;
+    font-size: 14px;
+  }
+
+  .animated {
+    animation-duration: 0.5s;
+  }
+
+  @-webkit-keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0,-10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  @keyframes slideInDown {
+    from {
+      -webkit-transform: translate3d(0, -10%, 0);
+      transform: translate3d(0, -10%, 0) !important;
+      visibility: visible;
+    }
+
+    to {
+      -webkit-transform: translate3d(0, 0%, 0);
+      transform: translate3d(0, 0%, 0);
+    }
+  }
+
+  .slideInDown {
+    -webkit-animation-name: slideInDown;
+    animation-name: slideInDown;
+  }
+  .tree-main /deep/ .singleClass {
+     margin:0;
+  }
+
+
+  .tree-main /deep/ .singleClass .syllabus-name{
+    width:100px;    
+    overflow: hidden;    
+    text-overflow:ellipsis;    
+    white-space: nowrap;
+    display:inline-block;
+    vertical-align:middle;
+  }
+  .tree-main /deep/ .ivu-tree-empty{
+    width:100%;
+    height:60px;
+    line-height:60px;
+    text-align:center;
+    font-size:14px;
+  }
+
+  .btn-addClass {
+    width: 16%;
+    padding: 10px 6px !important;
+  }
+
+  .ivu-tabs-nav-scroll {
+    display: flex;
+    justify-content: center;
+  }
+</style>

+ 5 - 0
TEAMModelOS/ClientApp/router/routes.js

@@ -69,6 +69,11 @@ export const routes = [
         name: 'testPaperList',
         component: resolve => require(['@/view/evaluation/index/TestPaperList.vue'], resolve), //路由懒加载
       },
+      {
+        path: '/createCompose',
+        name: 'createCompose',
+        component: resolve => require(['@/view/evaluation/index/CreateCompose.vue'], resolve), //路由懒加载
+      },
 
     ]
   }

+ 32 - 0
TEAMModelOS/ClientApp/view/evaluation/index/CreateCompose.css

@@ -0,0 +1,32 @@
+.children-list {
+    width:100%;
+    height:auto;
+    padding:20px;
+
+}
+
+    .children-list .child-Index {
+        font-size:16px;
+        margin:10px;
+    }
+
+    .children-list .child-item {
+        font-size: 16px;
+        margin-top: 20px;
+    }
+
+        .children-list .child-item  .item-content {
+            display: inline-block;
+        }
+
+        .children-list .child-item .item-question {
+            font-size:18px;
+            
+        }
+        .children-list .child-item .item-option {
+            margin:10px;
+        }
+        
+        .children-list .child-item .item-answer {
+            margin:10px 0;
+        }

+ 212 - 0
TEAMModelOS/ClientApp/view/evaluation/index/CreateCompose.vue

@@ -0,0 +1,212 @@
+<template>
+  <div class="ev-container">
+    <span class="ev-title"><Icon type="ios-paper" />{{isEdit?'编辑习题':'新建综合题'}}</span>
+    <Divider />
+
+
+    <div class="exersices-analysis">
+      <IconText :text="'综合题题干'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:15px;"></IconText>
+      <div>
+        <div ref="stemEditor" style="text-align:left"></div>
+      </div>
+    </div>
+
+    <Button type="info" @click="handleAddChild" style="margin:20px 0">添加小题</Button>
+
+    <div class="children-list">
+      <div class="child-item" v-for="(item,index) in children">
+        <div class="item-question">
+          <p>{{index+1}} : <span class="item-content" v-html="item.question"></span></p>
+        </div>
+
+        <div v-for="(option,optionIndex) in item.option" class="item-option">
+          <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span class="item-content" v-html="option.value"></span></p>
+        </div>
+
+        <div class="item-answer">
+          <span style="color:#01b4ef">【答案】:</span>
+          <span v-html="item.answer[0] || item.answer" v-if="item.type == 'Subjective'"></span>
+          <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'Complete'" v-html="answer"></span>
+          <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
+        </div>
+        <div class="item-explain">
+          <span style="color:#01b4ef">【解析】:</span>
+          <span class="item-content" v-html="item.explain"></span>
+        </div>
+      </div>
+      <div>
+      </div>
+    </div>
+
+
+    <Modal v-model="addChildModal"
+           v-if="addChildModal"
+           title="新增小题"
+           width="1000px"
+           style="z-index:99999"
+           :loading="loading">
+      <CreateNewChild ref="newChild" :isChildEdit="isChildEdit"></CreateNewChild>
+      <div slot="footer">
+        <Button type="text" size="large" @click="addChildModal=false">取消</Button>
+        <Button type="primary" size="large" @click="getChildContent">确定</Button>
+      </div>
+    </Modal>
+
+
+
+
+
+    <div class="save-wrap display-flex">
+      <Button type="success" @click="getContent(exersicesType)">保存</Button>
+      <Button type="success" @click="reloadCreate" style="margin-left:10px" v-show="isEdit">新增习题</Button>
+      <Button type="success" @click="resetEditor" style="margin-left:10px">题库</Button>
+    </div>
+  </div>
+</template>
+<script>
+  import "videojs-contrib-hls.js/src/videojs.hlsjs"
+  import IconText from '@/components/evaluation/IconText.vue'
+  import CreateNewChild from '@/view/evaluation/index/CreateNewChild.vue'
+  import E from 'wangeditor'
+  //默认创建题目模板
+  const defaultExercise = {
+    question: "",
+    option: [],
+    children: [],
+    difficulty: "",
+    answer: [],
+    explain: "",
+    type: ""
+  }
+  export default {
+    components: {
+      IconText, CreateNewChild
+    },
+    data() {
+      return {
+        isEdit: false,
+        isChildEdit:false,
+        addChildModal: false,
+        collapseIndex:"0",
+        children:[],
+        loading:true,
+        editInfo: {},
+        exersicesType: 'Single',
+        exersicesDiff: "0",
+        analysisContent: "",
+        stemContent: "",
+        analysisEditor: null,
+        videoHtml: ""
+      }
+    },
+    created() {
+      let editItem = this.$route.params.item; //编辑题目
+      if (editItem) {
+        this.editInfo = editItem;
+        console.log(editItem);
+      }
+    },
+    methods: {
+      getContent: function (type) {
+        let exerciseItem = Object.assign({}, defaultExercise);
+
+
+        //判断获取的数据是否有空数据以及是否为空字符串
+        if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(exerciseItem.explain)) {
+          this.$router.push({
+            name: 'exercisesList',
+            params: {
+              exerciseItem: exerciseItem,
+            }
+          })
+        } else {
+          alert("请将题目填写完整!");
+        }
+
+        console.log(exerciseItem);
+
+      },
+
+      //调用子组件的获取内容方法获取子题的内容
+      getChildContent() {
+        this.$refs.newChild.getContent(this.$refs.newChild._data.exersicesType);
+        if (this.$refs.newChild._data.isCreateFinish) {
+          this.addChildModal = false;
+          this.children.push(this.$refs.newChild._data.exerciseItem)
+        }
+        
+      },
+
+      handleAddChild() {
+        this.addChildModal = true;
+        this.isChildEdit = false;
+      },
+
+      
+      //提取富文本内容中的文本
+      getSimpleText(html) {
+        if (html) {
+          var msg = html.replace(/<(?!img|video).*?>/g, '');//执行替换成空字符
+          return msg.replace(/&nbsp;/ig, "");
+        }
+      },
+      //排除对象空属性
+      checkContent(Obj) {
+        let flag = true;
+        for (let key in Obj) {
+          if (!Obj[key]) {
+            flag = false;
+          }
+        }
+        return flag;
+      },
+
+      //重置编辑器
+      resetEditor() {
+        this.$router.push({
+            name: 'exercisesList'
+          })
+      },
+
+      reloadCreate() {
+        location.reload()
+      }
+
+    },
+    mounted() {
+      let stemEditor = new E(this.$refs.stemEditor)
+      stemEditor.customConfig.onchange = (html) => {
+        this.stemContent = html
+      },
+      stemEditor.customConfig.uploadImgServer = '/api/file/uploadWangEditor'
+      stemEditor.customConfig.showLinkImg = false;
+      stemEditor.customConfig.uploadFileName = 'files'
+      stemEditor.create();
+      this.stemEditor = stemEditor;
+
+      let editItem = this.$route.params.item; //编辑题目
+      if (editItem) {
+        this.isEdit = true;
+        this.editInfo = editItem;
+        this.children = editItem.children;
+        this.exersicesDiff = editItem.difficulty || 0;
+        this.exersicesType = editItem.type;
+        this.stemContent = editItem.question;
+
+        this.stemEditor.txt.html(editItem.question);
+        //this.optionsContent = editItem.options;
+        //this.analysisContent = editItem.explain;
+        //this.analysisEditor.txt.html(editItem.explain);
+        //重新渲染题目难度
+        //let diffDom = document.getElementsByClassName('exersices-attr-diff')[0].getElementsByClassName('ivu-radio-wrapper')[editItem.difficulty];
+        //let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'];
+        //diffDom.style.background = colorArr[editItem.difficulty];
+        //diffDom.style.color = "#fff";
+      }
+
+    }
+  }
+</script>
+<style src="../index/CreateExercises.css" scoped></style>
+<style src="../index/CreateCompose.css" scoped></style>
+

+ 6 - 0
TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.css

@@ -6,6 +6,7 @@
 
     .ev-container .w-e-text-container {
         height:180px !important;
+        z-index:0 !important;
     }
 
     .ev-container .ev-title {
@@ -26,6 +27,7 @@
         display: flex;
         flex-direction: row;
         align-items: center;
+        justify-content:space-between;
     }
 
 .exersices-attr {
@@ -86,6 +88,10 @@ exersices-attr-diff {
     height:40px;
     line-height:30px;
     font-size:14px;
+    z-index:1;
+}
+.ev-container .w-e-toolbar .w-e-menu {
+    z-index: 1 !important;
 }
 
 

+ 7 - 11
TEAMModelOS/ClientApp/view/evaluation/index/CreateExercises.vue

@@ -11,6 +11,7 @@
           <Radio label="Judge" :disabled="isEdit">判断</Radio>
           <Radio label="Complete" :disabled="isEdit">填空</Radio>
           <Radio label="Subjective" :disabled="isEdit">问答</Radio>
+          <Radio label="Compose" :disabled="isEdit">综合</Radio>
         </RadioGroup>
       </div>
       <div class="exersices-attr-diff my-radio-style">
@@ -73,7 +74,7 @@
       return {
         isEdit: false,
         editInfo: {},
-        exersicesType: 'single',
+        exersicesType: 'Single',
         exersicesDiff: "0",
         analysisContent: "",
         stemContent: "",
@@ -172,6 +173,10 @@
       typeChange(val) {
         if (this.isEdit) {
           this.$Message.warning("暂不支持更换题型!");
+        } else if (val == 'Compose') {
+          this.$router.push({
+            name: 'createCompose'
+          })
         } else {
           this.exersicesType = val;
           this.analysisEditor.txt.clear();
@@ -219,15 +224,6 @@
         location.reload()
       },
 
-      insertAfter(newElement, targetElement) { // newElement是要追加的元素 targetElement 是指定元素的位置
-        var parent = targetElement.parentNode; // 找到指定元素的父节点
-        if (parent.lastChild == targetElement) { // 判断指定元素的是否是节点中的最后一个位置 如果是的话就直接使用appendChild方法
-          parent.appendChild(newElement, targetElement);
-        } else {
-          parent.insertBefore(newElement, targetElement.nextSibling);
-        };
-      },
-
       //文件上传成功回调
       handleSuccess(res, file) {
         this.videoHtml = "<br><iframe src='https://teammodelstorage.blob.core.chinacloudapi.cn/wechatfilescontainer/wechatfilescontainer/HilearningMobile_function_10.mp4' frameborder='0' allowfullscreen='true'></iframe><br>";
@@ -252,7 +248,7 @@
       if (editItem) {
         this.isEdit = true;
         this.editInfo = editItem;
-        this.exersicesDiff = editItem.difficulty;
+        this.exersicesDiff = editItem.difficulty || 0;
         this.exersicesType = editItem.type;
         this.stemContent = editItem.question;
         this.optionsContent = editItem.options;

+ 254 - 0
TEAMModelOS/ClientApp/view/evaluation/index/CreateNewChild.vue

@@ -0,0 +1,254 @@
+<template>
+  <div class="ev-container" style="padding:30px 0">
+    <div class="exersices-attr display-flex">
+      <div class="exersices-attr-type my-radio-style">
+        <IconText :text="'选择题型'" :color="'green'" :icon="'md-apps'"></IconText>
+        <RadioGroup v-model="exersicesType" type="button" @on-change="typeChange">
+          <Radio label="Single" :disabled="isEdit">单选</Radio>
+          <Radio label="Multiple" :disabled="isEdit">多选</Radio>
+          <Radio label="Judge" :disabled="isEdit">判断</Radio>
+          <Radio label="Complete" :disabled="isEdit">填空</Radio>
+          <Radio label="Subjective" :disabled="isEdit">问答</Radio>
+        </RadioGroup>
+      </div>
+      <div class="exersices-attr-diff my-radio-style">
+        <IconText :text="'题目难度'" :color="'red'" :icon="'md-pulse'"></IconText>
+        <RadioGroup v-model="exersicesDiff" type="button">
+          <Radio label="0" @click.native="diffChange($event,'0')">容易</Radio>
+          <Radio label="1" @click.native="diffChange($event,'1')">较易</Radio>
+          <Radio label="2" @click.native="diffChange($event,'2')">一般</Radio>
+          <Radio label="3" @click.native="diffChange($event,'3')">较难</Radio>
+          <Radio label="4" @click.native="diffChange($event,'4')">困难</Radio>
+        </RadioGroup>
+      </div>
+    </div>
+
+    <BaseSingle v-if="exersicesType=='Single'" ref="single" :editInfo="editInfo"></BaseSingle>
+    <BaseMultiple v-else-if="exersicesType=='Multiple'" ref="multiple" :editInfo="editInfo"></BaseMultiple>
+    <BaseJudge v-else-if="exersicesType=='Judge'" ref="judge" :editInfo="editInfo"></BaseJudge>
+    <BaseCompletion v-else-if="exersicesType=='Complete'" ref="complete" :editInfo="editInfo"></BaseCompletion>
+    <BaseSubjective v-else-if="exersicesType=='Subjective'" ref="subjective" :editInfo="editInfo"></BaseSubjective>
+
+    <div class="exersices-analysis">
+      <IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:15px;"></IconText>
+      <Upload action="/api/file/uploadWangEditor" name="files" :show-upload-list="false" :on-success="handleSuccess">
+        <Button icon="ios-cloud-upload-outline" class="btn-upload" type="primary">上传文件</Button>
+      </Upload>
+      <div>
+        <div ref="analysisEditor" style="text-align:left"></div>
+      </div>
+    </div>
+    <div class="save-wrap display-flex">
+      <!--<Button type="success" @click="getContent(exersicesType)">保存</Button>
+      <Button type="success" @click="reloadCreate" style="margin-left:10px" v-show="isEdit">新增习题</Button>
+      <Button type="success" @click="resetEditor" style="margin-left:10px">题库</Button>-->
+    </div>
+  </div>
+</template>
+<script>
+  import "videojs-contrib-hls.js/src/videojs.hlsjs"
+  import IconText from '@/components/evaluation/IconText.vue'
+  import BaseSingle from '@/view/evaluation/types/BaseSingle.vue'
+  import BaseMultiple from '@/view/evaluation/types/BaseMultiple.vue'
+  import BaseCompletion from '@/view/evaluation/types/BaseCompletion.vue'
+  import BaseJudge from '@/view/evaluation/types/BaseJudge.vue'
+  import BaseSubjective from '@/view/evaluation/types/BaseSubjective.vue'
+  import E from 'wangeditor'
+  //默认创建题目模板
+  const defaultExercise = {
+    question: "",
+    option: [],
+    difficulty: "",
+    answer: [],
+    explain: "",
+    type: ""
+  }
+  export default {
+    components: {
+      IconText, BaseSingle, BaseJudge, BaseMultiple, BaseCompletion, BaseSubjective
+    },
+    props: ['isChildEdit'],
+    data() {
+      return {
+        isEdit: false,
+        exerciseItem: {},
+        editInfo: {},
+        children:[],
+        exersicesType: 'Single',
+        exersicesDiff: "0",
+        analysisContent: "",
+        stemContent: "",
+        analysisEditor: null,
+        videoHtml: "",
+        isCreateFinish:false
+      }
+    },
+    created() {
+      //let editItem = this.$route.params.item; //编辑题目
+      //if (editItem) {
+      //  this.editInfo = editItem;
+      //  console.log(editItem);
+      //}
+    },
+    methods: {
+      getContent: function (type) {
+        let exerciseItem = Object.assign({}, defaultExercise);
+        switch (type) {
+          case "Single":
+            exerciseItem.question = this.$refs.single._data.stemContent;
+            exerciseItem.option = this.$refs.single._data.optionsContent.length == this.$refs.single._data.options.length ? this.$refs.single._data.optionsContent : null;
+            exerciseItem.type = this.exersicesType;
+            exerciseItem.difficulty = this.exersicesDiff;
+            exerciseItem.explain = this.analysisContent;
+            exerciseItem.answer = [String.fromCharCode(64 + parseInt(this.$refs.single._data.trueIndex + 1))];
+            break;
+          case "Multiple":
+            exerciseItem.question = this.$refs.multiple._data.stemContent;
+            exerciseItem.option = this.$refs.multiple._data.optionsContent.length == this.$refs.multiple._data.options.length ? this.$refs.multiple._data.optionsContent : null;
+            exerciseItem.type = this.exersicesType;
+            exerciseItem.difficulty = this.exersicesDiff;
+            exerciseItem.explain = this.analysisContent;
+            exerciseItem.answer = this.$refs.multiple._data.transferArr;
+            break;
+          case "Judge":
+            exerciseItem.question = this.$refs.judge._data.stemContent;
+            exerciseItem.option = [];
+            exerciseItem.type = this.exersicesType;
+            exerciseItem.difficulty = this.exersicesDiff;
+            exerciseItem.explain = this.analysisContent;
+            exerciseItem.answer = this.$refs.judge._data.trueAnswer;
+            break;
+          case "Complete":
+            exerciseItem.question = this.$refs.complete._data.stemContent;
+            exerciseItem.option = [];
+            exerciseItem.type = this.exersicesType;
+            exerciseItem.difficulty = this.exersicesDiff;
+            exerciseItem.explain = this.analysisContent;
+            exerciseItem.answer = this.$refs.complete._data.optionsContent.map(item => item.value);
+            break;
+          case "Subjective":
+            exerciseItem.question = this.$refs.subjective._data.stemContent;
+            exerciseItem.option = [];
+            exerciseItem.type = this.exersicesType;
+            exerciseItem.difficulty = this.exersicesDiff;
+            exerciseItem.explain = this.analysisContent;
+            exerciseItem.answer = this.$refs.subjective._data.answerContent;
+            break;
+        }
+
+        //判断获取的数据是否有空数据以及是否为空字符串
+        if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(exerciseItem.explain)) {
+          //this.$router.push({
+          //  name: 'exercisesList',
+          //  params: {
+          //    exerciseItem: exerciseItem,
+          //  }
+          //})
+          this.exerciseItem = exerciseItem;
+          this.isCreateFinish = true;
+        } else {
+          this.$Message.warning("请将题目填写完整!");
+        }
+
+        console.log(exerciseItem);
+
+      },
+
+      //题目类型转换
+      typeChange(val) {
+        if (this.isEdit) {
+          this.$Message.warning("暂不支持更换题型!");
+        } else if (val == 'Compose') {
+          this.$router.push({
+            name: 'createCompose'
+          })
+        } else {
+          this.exersicesType = val;
+          this.analysisEditor.txt.clear();
+        }
+      },
+
+      //难度与背景颜色切换
+      diffChange(e, type) {
+        this.exersicesDiff = type;
+        e.preventDefault();
+        let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'];
+        let ac = document.getElementsByClassName('exersices-attr-diff')[0].children[1].children;
+        for (let i = 0; i < ac.length; i++) {
+          ac[i].style.background = "#fff";
+          ac[i].style.color = "#515a6e";
+        }
+        e.target.style.background = colorArr[type];
+        e.target.style.color = "#fff";
+      },
+
+      //提取富文本内容中的文本
+      getSimpleText(html) {
+        var msg = html.replace(/<(?!img|video).*?>/g, '');//执行替换成空字符
+        return msg.replace(/&nbsp;/ig, "");
+      },
+      //排除对象空属性
+      checkContent(Obj) {
+        let flag = true;
+        for (let key in Obj) {
+          if (!Obj[key]) {
+            flag = false;
+          }
+        }
+        return flag;
+      },
+
+      //重置编辑器
+      resetEditor() {
+        this.$router.push({
+            name: 'exercisesList'
+          })
+      },
+
+      reloadCreate() {
+        location.reload()
+      },
+
+      //文件上传成功回调
+      handleSuccess(res, file) {
+        this.videoHtml = "<br><iframe src='https://teammodelstorage.blob.core.chinacloudapi.cn/wechatfilescontainer/wechatfilescontainer/HilearningMobile_function_10.mp4' frameborder='0' allowfullscreen='true'></iframe><br>";
+        this.analysisContent = this.analysisContent + this.videoHtml;
+        this.analysisEditor.txt.append(this.videoHtml);
+        console.log(this.analysisContent);
+      },
+
+    },
+    mounted() {
+      let analysisEditor = new E(this.$refs.analysisEditor)
+      analysisEditor.customConfig.onchange = (html) => {
+        this.analysisContent = html
+      },
+      analysisEditor.customConfig.uploadImgServer = '/api/file/uploadWangEditor'
+      analysisEditor.customConfig.showLinkImg = false;
+      analysisEditor.customConfig.uploadFileName = 'files'
+      analysisEditor.create();
+      this.analysisEditor = analysisEditor;
+
+      //let editItem = this.$route.params.item; //编辑题目
+      //if (editItem) {
+      //  this.isEdit = this.isChildEdit;
+      //  this.editInfo = editItem;
+      //  this.exersicesDiff = editItem.difficulty || 0;
+      //  this.exersicesType = editItem.type;
+      //  this.stemContent = editItem.question;
+      //  this.optionsContent = editItem.options;
+      //  this.analysisContent = editItem.explain;
+      //  this.analysisEditor.txt.html(editItem.explain);
+      //  //重新渲染题目难度
+      //  let diffDom = document.getElementsByClassName('exersices-attr-diff')[0].getElementsByClassName('ivu-radio-wrapper')[editItem.difficulty];
+      //  let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'];
+      //  diffDom.style.background = colorArr[editItem.difficulty];
+      //  diffDom.style.color = "#fff";
+      //}
+
+    }
+  }
+</script>
+<style src="../index/CreateExercises.css" scoped>
+  /*@import"../index/CreateExercises.css";*/
+</style>

+ 1 - 1
TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.css

@@ -57,7 +57,7 @@
     /*color: white;*/
     box-shadow: none !important;
     font-weight: 600;
-    
+    border: 1px solid #2d8cf0;
 }
 .test-scene .ivu-radio-group-button .ivu-radio-wrapper-checked {
     color: green;

+ 2 - 2
TEAMModelOS/ClientApp/view/evaluation/index/CreateTest.vue

@@ -16,7 +16,7 @@
         </div>
         <div class="exersices-attr-diff my-radio-style test-type">
           <IconText :text="'测试类型'" :color="'red'" :icon="'ios-settings'"></IconText>
-          <RadioGroup v-model="testBasicAttr.testTpye" type="button">
+          <RadioGroup v-model="testBasicAttr.testType" type="button">
             <Radio label="formal">正式成绩</Radio>
             <Radio label="practice">练习成绩</Radio>
             <Radio label="statistics">统计(问卷)</Radio>
@@ -385,7 +385,7 @@
         exersicesDiff:'',
         testBasicAttr: {
           testScene: 'simulation',
-          testTpye: 'formal',
+          testType: 'formal',
           testTarget: 'class',
           testMode: 'auto'
         },

+ 25 - 2
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.css

@@ -1,5 +1,6 @@
 .ev-list-container {
     user-select:none !important;
+    position:relative;
 }
     .ev-list-container .ev-header {
         background:#fff;
@@ -25,6 +26,18 @@
         margin:15px 0;
     }
 
+.no-data-text {
+    width: 100%;
+    padding:30px;
+    background: #fff;
+    display:flex;
+    flex-direction:column;
+    justify-content:center;
+    align-items:center;
+    margin-top:10px;
+    font-size:16px;
+}
+
 .ev-list-operation {
     position:relative;
     width: 100%;
@@ -167,6 +180,7 @@
             background: none;
         }
 .content-wrap {
+    position:relative;
     width:100%;
     height:auto;
     display:flex;
@@ -243,7 +257,7 @@
     display: inline-block;
     cursor:pointer;
     margin-top:12px;
-    font-size:16px;
+    font-size:14px;
 }
 
 .exercise-item .item-answer-item {
@@ -272,7 +286,7 @@
     display: table;
     margin-top: 10px;
     cursor: pointer;
-    font-size: 16px;
+    font-size: 14px;
 }
 
 .exercise-item .item-explain-item {
@@ -332,6 +346,15 @@
 
     .exercise-item .item-tools-tool .item-bind-point {
         color:rgb(128, 128, 128);
+        margin-left:5px;
+    }
+
+    .exercise-item .item-tools-tool .ivu-tag {
+        margin-top:-2px;
+    }
+    
+    .exercise-item .item-tools-tool .ivu-tag-border{
+        line-height:22px;
     }
 
 

+ 115 - 58
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesList.vue

@@ -1,6 +1,5 @@
 <template>
   <div class="ev-list-container">
-    <Loading v-show="importLoading"></Loading>
 
     <div class="ev-header">
       <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
@@ -56,7 +55,7 @@
       </span>
       <div class="operation-cart">
         <Poptip trigger="hover" title="我的试题篮" placement="bottom">
-          <Badge :count="basketCount" show-zero>
+          <Badge :count="basketCount" show-zero type="success">
             <img src="../../../assets/icon/icon_cart.png" />
           </Badge>
           <div class="basket-content" slot="content">
@@ -97,65 +96,101 @@
               <p @click="handleSubmitPaper">进入组卷中心</p>
             </div>
           </div>
-
         </Poptip>
       </div>
     </div>
+    <!-- 筛选部分结束 -->
+
+
     <!-- 题目列表部分 -->
-    <div v-if="list.length == 0">暂无数据</div>
+    <div v-if="list.length == 0" class="no-data-text">
+      <img src="../../../assets/icon/no_data.svg" width="120"/>
+      <span style="margin-top:15px;color:#808080">暂无数据</span>
+    </div>
     <div class="content-wrap" v-else>
+      <Loading v-show="importLoading"></Loading>
+
       <div class="exercise-item" v-for="(item,index) of list">
-        <div>
+        <!-- 题目难度类型以及绑定知识点 -->
+        <div class="item-types">
           <span class="item-difficulty" :style="{backgroundColor:diffColors[item.difficulty || 3]}">{{exersicesDiff[item.difficulty || 3]}}</span>
           <span class="item-type">{{exersicesType[item.type]}}</span>
           <span class="item-relevant-points">
             <span class="item-tools-bind">
               <span class="item-tools-tool">
-                <span class="item-bind-point">已关联知识点:</span>
-                <span class="item-bind-point">字音辨析</span>
-                <span class="item-bind-point">字音辨析</span>
-                <span class="item-bind-point">字音辨析</span>
-                <span class="item-bind-point">字音辨析</span>
+                <span class="item-bind-point">已关联知识点:</span>
+                <span class="item-bind-point" v-for="concept in item.concept" v-show="item.concept"><Tag color="success">{{concept.name}}</Tag></span>
+                <span class="item-bind-point"  v-show="!item.concept">暂未关联</span>
                 <Icon type="md-link" size="20" />
-                <span @click="handleBindPoint">绑定知识点</span>
+                <span @click="handleBindPoint(item.concept || [])">绑定知识点</span>
               </span>
             </span>
           </span>
         </div>
+        <!-- 题干部分 --> 
         <div class="item-question">
           <p>{{index+1}} : <span v-html="item.question"></span></p>
         </div>
+        <!-- 选项部分 -->
         <div v-for="(option,optionIndex) in item.option">
           <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
         </div>
-        <div class="item-answer">
+
+        <!-- 如果是组合题 -->
+        <div v-for="(childQuestion,childIndex) in item.children" v-if="item.children.length">
+          <div class="item-question">
+            <p>{{childIndex+1}} : <span v-html="childQuestion.question"></span></p>
+          </div>
+          <div v-for="(childOption,childOptionIndex) in childQuestion.option">
+            <p>{{String.fromCharCode(64 + parseInt(childOptionIndex+1))}} : <span v-html="childOption.value"></span></p>
+          </div>
+          <div class="item-answer" v-show="isShowAnswer">
+            <span style="color:#01b4ef">【答案】:</span>
+            <span v-html="childQuestion.answer[0] || childQuestion.answer" v-if="childQuestion.type == 'Subjective'"></span>
+            <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else-if="childQuestion.type == 'Complete'" v-html="answer"></span>
+            <span :class="[ childQuestion.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in childQuestion.answer" v-else>{{answer}}</span>
+          </div>
+          <div class="item-explain" v-show="isShowAnswer">
+            <span style="color:#01b4ef">【解析】:</span>
+            <span v-html="childQuestion.explain"></span>
+          </div>
+        </div>
+        <!-- 组合题结束 -->
+        <!-- 答案展示部分 -->
+        <div class="item-answer" v-show="item.type != 'Compose'">
           <span class="answer-title-line"></span>
           <span class="answer-title" @click="showAnswer($event,'answer')">答案:点击展开答案详情</span>
           <div class="item-answer-details">
             <span v-html="item.answer" v-if="item.type == 'Subjective'"></span>
             <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'Complete'" v-html="answer"></span>
             <span :class="[ item.type == 'Complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
-
           </div>
         </div>
-        <div class="item-explain">
+        <!-- 解析部分 -->
+        <div class="item-explain" v-show="item.type != 'Compose'">
           <span class="explain-title-line"></span>
           <span class="explain-title" @click="showAnswer($event,'explain')">解析:点击展开解析详情</span>
           <div class="item-explain-details">
             <span v-html="item.explain"></span>
           </div>
         </div>
+        <!-- 底部题目操作栏 -->
         <div class="item-tools">
-
           <span class="item-tools-info">来源:浙江省温州市2019年中考数学试卷</span>
           <span class="item-tools-info">使用次数:98 次</span>
-          <span class="item-tools-info" style="border:0">更新时间:2019-07-01</span>
-
-          <Button type="info" @click="handleChoose(item)">{{basketList.all.indexOf(item) > -1 ? '已选入' : '选题'}}</Button>
+          <span class="item-tools-info" style="border:0" >更新时间:2019-07-01</span>
+          <Button type="info" @click="handleChoose(item)">{{basketList.all.indexOf(item) > -1 ? '已选入' : '选题'}} </Button>
           <Button type="primary" @click="handleEdit(item)" style="margin-right:10px">编辑题目</Button>
+          <Button type="primary" @click= 'flag=!flag' style="margin-right:10px">加入</Button>
+          <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
+            <!--<p class="circle" v-show="flag"> </p>-->
+            <Button type="info" v-show="flag">点我</Button>
+          </transition>
         </div>
       </div>
     </div>
+
+    <!-- 底部分页区域 -->
     <Page :total="totalNum"
           show-sizer
           @on-page-size-change="pageSizeChange"
@@ -164,7 +199,7 @@
     <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
     <Button type="success" @click="backToPaper" style="margin:10px;">试卷</Button>
 
-    <!-- 绑定知识点弹窗 Transfer -->
+    <!-- 绑定知识点弹窗开始 -->
     <Modal v-model="bindPointModal"
            title="绑定知识点"
            width="500"
@@ -176,20 +211,20 @@
         <Input search placeholder="搜索知识点..." v-model="searchWord" @on-change="filterChange" />
         <Tabs v-model="tabSelectVal">
           <TabPane label="校本知识点" name="school">
-            <Tree :data="knowPointList" ref="pointTree" :render="renderContent" @on-check-change="pointTreeCheck" check-strictly></Tree>
+            <Tree :data="knowPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
           </TabPane>
           <TabPane label="标准知识点" name="all">
-            <Tree :data="allPointList" ref="pointTree" :render="renderContent" @on-check-change="pointTreeCheck" check-strictly></Tree>
+            <Tree :data="allPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
           </TabPane>
         </Tabs>
         <Spin fix v-show="pointListLoading"></Spin>
       </div>
-
       <div class="selected-point-list">
         <p class="bind-title">已选知识点<span style="font-weight:500;font-size:12px"> (最多绑定5个知识点,颜色代表不同来源)</span><span class="btn-clear" @click="handleClearChecked">清空</span></p>
         <span class="checked-point" :style="{background:item.origin=='school'?'#10abe7':'#12b9ab'}" v-for="item in checkedPointList">{{item.name}}<Icon type="md-close" color="#fff" style="margin-left:5px;cursor:pointer" @click="deleteCheckedPoint(item)" /></span>
       </div>
     </Modal>
+    <!-- 绑定知识点弹窗结束 -->
   </div>
 </template>
 <script>
@@ -205,6 +240,7 @@ import { setTimeout } from 'core-js';
     data() {
       return {
         list: [],
+        flag:false,
         searchWord: '',
         basketCount: 0,
         basketList: {
@@ -257,6 +293,22 @@ import { setTimeout } from 'core-js';
     },
     methods: {
 
+      beforeEnter(el){
+          el.style.transform = "translate(0, 0)"
+      },
+      enter(el, done){
+          // el.offsetWidth 强制html渲染动画
+          // el.offsetWidth 这句话如何不写就不会有动画效果直接渲染的
+          el.offsetWidth;
+          el.style.transform = "translate(150px, -250px)";
+          el.style.transition = "all 1s ease";
+          console.log(done);
+          done()
+      },
+      afterEnter(el){
+          this.flag = !this.flag
+      },
+
       //根据题库加载题目
       filterOriginChange(origin) {
         console.log(origin);
@@ -330,6 +382,8 @@ import { setTimeout } from 'core-js';
 
       //编辑习题
       handleEdit(item) {
+        item.options = item.option;
+        item.difficulty = item.difficulty || 2;
         this.$router.push({
             name: 'createExercises',
             params:{
@@ -353,22 +407,23 @@ import { setTimeout } from 'core-js';
 
       //从试题篮删除题型
       handleBasketDelete(type) {
+        let arr = JSON.parse(JSON.stringify(this.basketList.all))
         this.$Modal.confirm({
           title: '删除题型',
           content: '<p>确认删除该题型吗?</p>',
           okText:"确认",
           cancelText:"取消",
           onOk: () => {
-            this.basketList.all.forEach((item,index) => {
-              if (item.type == type) {
+            for (let i = 0; i < arr.length; i++) {
+              let shaCodeArr = this.basketList.all.map(item => item.shaCode);
+              let index = shaCodeArr.indexOf(arr[i].shaCode);
+              if (arr[i].type == type && index > -1) {
                 this.basketList.all.splice(index, 1);
               }
-            })
-            //console.log(this.basketList[type]);
+            }
             this.basketList[type] = [];
             this.basketCount = this.basketList.all.length;
             this.$Message.success("删除成功!");
-
           }
         });
 
@@ -385,10 +440,11 @@ import { setTimeout } from 'core-js';
       },
 
       //绑定知识点操作
-      handleBindPoint() {
+      handleBindPoint(concepts) {
         this.bindPointModal = true;
-        this.checkedPointList = [];
+        this.checkedPointList = concepts;
         this.knowPointList = this.schoolPointList;
+        console.log(concepts);
       },
 
       //获取标准知识块数据
@@ -406,19 +462,6 @@ import { setTimeout } from 'core-js';
         })
       },
 
-      //获取标准知识点仓库数据
-      getAllPoints() {
-         let data = {
-          pointParams: {
-              SubjectCode: "Subject_Chinese",
-              PartitionKey: "zh-CN",
-            }
-        }
-        this.$api.FindKnowledgePointByDict(data).then(res => {
-          this.pointListLoading = false;
-        })
-      },
-
        //获取学校知识块仓库数据
       getSchoolPoints() {
         let data = {
@@ -445,16 +488,16 @@ import { setTimeout } from 'core-js';
       },
 
       //知识点绑定选中事件
-      pointTreeCheck(val, data) {
-        let points = val.filter(item => item.children.length == 0);
-        if (points.length > 5) {
-          this.checkedPointList = points.slice(0, 5);
-          this.$Message.warning("最多绑定5个知识点!");
-        } else {
-          this.checkedPointList = points;
-        }
-        console.log(val, data);
-      },
+      //pointTreeCheck(val, data) {
+      //  let points = val.filter(item => item.children.length == 0);
+      //  if (points.length > 5) {
+      //    this.checkedPointList = points.slice(0, 5);
+      //    this.$Message.warning("最多绑定5个知识点!");
+      //  } else {
+      //    this.checkedPointList = points;
+      //  }
+      //  console.log(val, data);
+      //},
 
       //知识点树形结构渲染
        renderContent(h, { root, node, data }) {
@@ -485,7 +528,7 @@ import { setTimeout } from 'core-js';
               h("span", data.name),
               h('span',{
                 domProps: {
-                  className: this.checkedPointList.indexOf(data) > -1 ? "point-checkbox point-checked" : "point-checkbox point-unchecked"
+                  className: this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) > -1 ? "point-checkbox point-checked" : "point-checkbox point-unchecked"
                 },
                 style: {
                   display: data.children && data.children.length > 0
@@ -494,15 +537,19 @@ import { setTimeout } from 'core-js';
                 },
                 on: {
                   click: () => {
-                    if (this.checkedPointList.indexOf(data) == -1) {
+                    let conceptData = {};
+                    if (this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) == -1) {
                       if (this.checkedPointList.length < 5) {
-                        data.origin = this.tabSelectVal;
-                        this.checkedPointList.push(data);
+                        conceptData.origin = this.tabSelectVal;
+                        conceptData.knowledgeId = data.knowledgeId || data.rowKey;
+                        conceptData.name = data.name;
+                        conceptData.subjectCode = data.subjectCode;
+                        this.checkedPointList.push(conceptData);
                       } else {
                         this.$Message.warning("最多绑定5个知识点!");
                       }
                     } else {
-                      this.checkedPointList.splice(this.checkedPointList.indexOf(data), 1);
+                      this.checkedPointList.splice(this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey), 1);
                     }
 
                     console.log(this.checkedPointList);
@@ -566,7 +613,7 @@ import { setTimeout } from 'core-js';
     mounted() {
         this.getStandardList();
         this.getSchoolPoints();
-        this.getAllPoints();
+        //this.getAllPoints();
     },
     computed: {
       headers(){
@@ -581,6 +628,16 @@ import { setTimeout } from 'core-js';
 @import "../index/ExercisesList.css";
 </style>
 
+<style>
+  .circle {
+    border: solid 1px red;
+    background-color: red;
+    border-radius: 50%;
+    width: 50px;
+    height: 50px;
+  }
+</style>
+
 <!--<style src="../index/ExercisesList.css" scoped></style>-->
 <!--<style>
     .content-wrap .exercise-item p {

+ 0 - 336
TEAMModelOS/ClientApp/view/evaluation/index/ExercisesListTree.vue

@@ -1,336 +0,0 @@
-<template>
-  <div class="ev-list-container">
-    <div class="ev-header">
-      <Icon type="md-bookmarks" size="30" color="rgb(16, 171, 231)" />
-      <span class="ev-title">我的题库</span>
-      <span class="ev-length">共 {{list.length}} 道题</span>
-    </div>
-    <!-- 筛选部分 -->
-    <div class="filter-wrap">
-      <div class="filter-item">
-        <span class="filter-title">题型:</span>
-        <RadioGroup v-model="filterType" type="button" @on-change="filterTypeChange">
-          <Radio label="all">全部</Radio>
-          <Radio label="single">单选</Radio>
-          <Radio label="multiple">多选</Radio>
-          <Radio label="judge">判断</Radio>
-          <Radio label="complete">填空</Radio>
-          <Radio label="subjective">问答</Radio>
-        </RadioGroup>
-      </div>
-      <div class="filter-item">
-        <span class="filter-title">难度:</span>
-        <RadioGroup v-model="filterDiff" type="button" @on-change="filterDiffChange">
-          <Radio label="all">全部</Radio>
-          <Radio label="0">容易</Radio>
-          <Radio label="1">较易</Radio>
-          <Radio label="2">一般</Radio>
-          <Radio label="3">较难</Radio>
-          <Radio label="4">困难</Radio>
-        </RadioGroup>
-      </div>
-      <div class="filter-item">
-        <span class="filter-title">排序:</span>
-        <RadioGroup v-model="filterSort" type="button" @on-change="filterSortChange">
-          <Radio label="0">新增时间<Icon type="md-arrow-round-down" /></Radio>
-          <Radio label="1">使用次数<Icon type="md-arrow-round-down" /></Radio>
-        </RadioGroup>
-      </div>
-    </div>
-    <!-- 题目列表部分 -->
-    <div v-if="list.length == 0">暂无数据</div>
-    <div class="content-wrap" v-else>
-      <div class="exercise-item" v-for="(item,index) of list">
-        <span class="item-difficulty" :style="{backgroundColor:diffColors[item.difficulty]}">{{exersicesDiff[item.difficulty]}}</span>
-        <span class="item-type">{{exersicesType[item.type]}}</span>
-        <div class="item-question">
-          <p>{{index+1}} : <span v-html="item.question"></span></p>
-        </div>
-        <div v-for="(option,optionIndex) in item.options">
-          <p>{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : <span v-html="option.value"></span></p>
-        </div>
-        <div class="item-answer">
-          <span class="answer-title-line"></span>
-          <span class="answer-title" @click="showAnswer($event,'answer')">答案:点击展开答案详情</span>
-          <div class="item-answer-details">
-            <span v-html="item.answer" v-if="item.type == 'subjective'"></span>
-            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else-if="item.type == 'complete'" v-html="answer"></span>
-            <span :class="[ item.type == 'complete' ? 'item-answer-item':'']" v-for="answer in item.answer" v-else>{{answer}}</span>
-
-          </div>
-        </div>
-        <div class="item-explain">
-          <span class="explain-title-line"></span>
-          <span class="explain-title" @click="showAnswer($event,'explain')">解析:点击展开解析详情</span>
-          <div class="item-explain-details">
-            <span v-html="item.explain"></span>
-          </div>
-        </div>
-        <div class="item-tools">
-          <Button type="primary" @click="handleEdit(item)">编辑题目</Button>
-          <Button type="info">选题</Button>
-          <span class="item-tools-bind">
-            <span class="item-tools-tool" @click="handleBindPoint"><Icon type="ios-link" />绑定知识点</span>
-            <span class="item-tools-tool"><Icon type="ios-link" />绑定科目</span>
-            <span class="item-tools-tool"><Icon type="ios-link" />绑定课纲</span>
-          </span>
-        </div>
-      </div>
-    </div>
-    <Page :total="totalNum"
-          show-sizer
-          @on-page-size-change="pageSizeChange"
-          @on-change="pageChange"
-          :page-size-opts="[5,10,15,20]" />
-    <Button type="success" @click="backToAdd" style="margin:10px;">返回</Button>
-
-    <!-- 绑定知识点弹窗 Transfer -->
-    <Modal v-model="bindPointModal"
-           title="绑定知识点"
-           width="600"
-           class-name="transferModal"
-           @on-ok="handleTransferBlock"
-           @on-cancel="">
-      <Transfer :data="data3"
-                :target-keys="targetKeys"
-                :list-style="listStyle"
-                :render-format="renderTransfer"
-                :operations="['撤回知识库','绑定知识点']"
-                filter-placeholder="请输入搜索内容"
-                :titles="[transferStatus?'校本知识点':'标准知识点', '已选知识点']"
-                not-found-text="列表为空"
-                filterable
-                :filter-method="filterMethod"
-                @on-change="handleChangeTransfer">
-        <div :style="{float: 'right', margin: '5px'}">
-          <Button size="small" type="primary" @click="changePointData(!transferStatus)" class="transferBtn">{{ transferStatus ? '从标准库添加': "从私有库添加"}}</Button>
-          <Button size="small" @click="reloadPointData(transferStatus)">刷新</Button>
-        </div>
-      </Transfer>
-    </Modal>
-  </div>
-</template>
-<script>
-  import IconText from '@/components/evaluation/IconText.vue'
-  import questions from './list.json'
-import { setTimeout } from 'core-js';
-  export default {
-    components: {
-      IconText
-    },
-    data() {
-      return {
-        list: [],
-        schoolInfo: {},
-        bindPointModal: false,
-        exersicesType: {
-          single: "单选",
-          multiple: "多选",
-          judge: "判断",
-          complete: "填空",
-          subjective:"问答"
-        },
-        exersicesDiff: ["容易", "较易", "一般", "较难", "困难"],
-        diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
-        filterType:"all",
-        filterDiff:"all",
-        filterSort: "0",
-        pageSize: 5,
-        pageNum: 1,
-        totalNum: 100,
-        allList: questions.list,
-        knowPointList: [],
-        checkedPointList: [],
-        data3: [],
-        allPointList: [],
-        schoolAllPoint:[],
-        targetKeys: [],
-        targetList:[],
-        listStyle: {
-          width: '220px',
-          height: '420px'
-        },
-        transferStatus:true,
-      }
-    },
-    created() {
-      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
-      this.list = questions.list;
-      this.totalNum = questions.list.length;
-      if (this.$route.params.exerciseItem) {
-        this.list.unshift(this.$route.params.exerciseItem);
-      }
-      //获取学校与标准的知识点源
-        this.getSchoolPoints();
-        this.getAllPoints();
-    },
-    methods: {
-      //获取标准知识点仓库数据
-      getAllPoints() {
-         let data = {
-          pointParams: {
-              SubjectCode: "Subject_Chinese",
-              PartitionKey: "zh-CN",
-            }
-        }
-        this.$api.FindKnowledgePointByDict(data).then(res => {
-          this.allPointList = res.result.data;
-        })
-      },
-
-      //获取学校知识点仓库数据
-      getSchoolPoints() {
-         let data = {
-              SubjectCode: "Subject_Chinese",
-              PartitionKey: "zh-CN",
-              SchoolCode: this.schoolInfo.claim[0].claimCode,
-              Status:1
-        }
-        this.$api.FindSchoolPointByDict(data).then(res => {
-          this.schoolAllPoint = res.result.data;
-        })
-      },
-
-      //筛选题型
-      filterTypeChange(val) {
-        if (val == "all") {
-          this.list = questions.list;
-        } else {
-          this.list = questions.list.filter(item => item.type == val);
-        }
-      },
-
-      //筛选难度
-      filterDiffChange(val) {
-         if (val == "all") {
-          this.list = questions.list;
-         } else {
-           this.list = questions.list.filter(item => item.difficulty == val);
-        }
-      },
-
-      //排序条件更换
-      filterSortChange(val) {
-        console.log(val);
-      },
-
-      //展开与收起答案
-      showAnswer(e, type) {
-        let el = e.currentTarget;
-        let isShow = e.currentTarget.nextElementSibling.style.display||"none";
-        setTimeout(function () {
-          if (type == "explain") {
-            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
-            el.innerHTML = isShow == "none" ? "解析:点击收起解析详情" : "解析:点击展开解析详情";
-          } else {
-            el.nextElementSibling.style.display = isShow == "none" ? "block" : "none";
-            el.innerHTML = isShow == "none" ? "答案:点击收起答案详情" : "答案:点击展开答案详情";
-          }
-
-        },100)
-      },
-
-      //返回新建习题
-      backToAdd() {
-        this.$router.push({
-            path: '/createExercises',//或者路径跳转path: '/addCreditCards',
-          })
-      },
-
-      //切换页码
-      pageChange(page) {
-        let start = this.pageSize * (page - 1);
-        let end = this.pageSize * page;
-        let list = questions.list;
-        this.list = list.slice(start, end);
-        window.scroll(0, 0);
-      },
-
-      //切换分页Size
-      pageSizeChange(val) {
-        this.pageSize = val;
-        this.pageChange(1);
-      },
-
-      //编辑习题
-      handleEdit(item) {
-        this.$router.push({
-            name: 'createExercises',
-            params:{
-              item: item,
-            }
-          })
-      },
-
-      //绑定知识点操作
-      handleBindPoint() {
-        this.data3 = this.getPointList(this.transferStatus);
-        this.targetKeys = [];
-        this.bindPointModal = true;
-
-      },
-
-     //获取transfer的知识点数据源
-      getPointList(status) {
-        let mockData = [];
-        let list = status ? this.schoolAllPoint : this.allPointList;
-        for (let i = 0; i < list.length; i++) {
-          mockData.push({
-            id: i,
-            key: i.toString(),
-            label: i.toString(),
-            name: list[i].name,
-            termNum: i + 5,
-            blockId: i + 1,
-            description: list[i].name
-          });
-        }
-        return mockData;
-      },
-
-      //transfer 处理
-      handleChangeTransfer(newTargetKeys) {
-        this.targetKeys = newTargetKeys;
-        let targetList = [];
-        let list = this.transferStatus ? this.schoolAllPoint : this.allPointList;
-        newTargetKeys.forEach(item => {
-          targetList.push(list[item]);
-        })
-        this.targetList = targetList;
-      },
-
-      ////transfer 处理
-      renderTransfer(item) {
-        return item.name;
-      },
-      //重置数据
-      reloadPointData(status) {
-        this.data3 = this.getPointList(status);
-        this.targetKeys = [];
-      },
-      //切换数据源
-      changePointData(status) {
-        this.data3 = this.getPointList(status);
-        this.transferStatus = status;
-      },
-      //transfer Input 筛选数据
-      filterMethod(data, query) {
-        let val = data.name;
-        return val.toUpperCase().indexOf(query.toUpperCase()) > -1;
-      },
-
-
-      //确认编辑知识块
-      handleTransferBlock() {
-        console.log(this.targetList);
-      },
-
-    },
-    mounted() {
-     
-    }
-  }
-</script>
-<style scoped>
-  @import"../index/ExercisesList.css";
-</style>

+ 106 - 6
TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.css

@@ -34,11 +34,13 @@
         font-size: 20px;
         font-weight: bold;
         vertical-align: middle;
+        text-align:center
     }
     .paper-container .paper-subTitle {
         font-size: 16px;
         font-weight: bold;
         margin: 15px;
+        text-align:center;
         vertical-align: middle;
     }
     .paper-container .paper-info {
@@ -86,11 +88,15 @@
         border: 1px solid rgba(1,1,1,0);
     }
 
+        .paper-content .exercise-item .item-concept {
+            margin-top:10px;
+        }
+
         .paper-content .exercise-item .item-tools {
             position: absolute;
             right: -2px;
             top: -30px;
-            width:419px;
+            width:539px;
             height: 30px;
             margin:0;
             padding:0;
@@ -131,11 +137,10 @@
     .paper-content  .exercise-item:hover {
         box-shadow: none !important;
         border-color:#cfcfcf;
-
     }
 
     .paper-content .item-answer, .paper-content .item-explain {
-        text-indent:-8px;
+        /*text-indent:-8px;*/
         line-height:26px;
     }
 
@@ -154,15 +159,22 @@
     height: 60px;
     margin-top: 10px;
     border-top: 1px dashed #cfcfcf;
-    padding:10px;
+    padding:10px 0;
 }
-
+    
+    .paper-tools .paper-tools-title {
+        font-size: 14px;
+        font-weight:bold;
+        margin-right:10px;
+    }    
     .paper-tools .ivu-checkbox-wrapper {
         font-size: 14px;
+        margin-left:10px;
     }
 
     .paper-tools .ivu-checkbox {
-        margin:6px;
+        margin: 0 4px;
+        vertical-align:text-bottom;
     }
     .paper-tools .ivu-checkbox-checked .ivu-checkbox-inner {
         background: #01b4ef;
@@ -170,18 +182,106 @@
     }
 
 
+.paperTransferModal {
+    overflow: hidden;
+}
 
+    .paperTransferModal .point-list {
+        max-height: 400px;
+        overflow: auto;
+    }
 
+        .paperTransferModal .point-list .ivu-input-wrapper {
+            width: 90%;
+            margin-bottom: 10px;
+        }
 
+    .paperTransferModal .selected-point-list {
+        padding: 10px;
+        width: 100%;
+        border-top: 1px solid rgba(128, 128, 128,.3);
+        margin-top: 15px;
+    }
 
+    .paperTransferModal .bind-title {
+        margin: 10px 0;
+        font-weight: bold;
+        font-size: 14px;
+    }
 
+    .paperTransferModal .checked-point {
+        margin: 5px 10px;
+        background: rgb(16, 171, 231);
+        padding: 5px 10px;
+        color: #fff;
+        border-radius: 5px;
+        display: inline-block;
+    }
 
+    .paperTransferModal .ivu-checkbox-checked .ivu-checkbox-inner {
+        background: rgb(16, 171, 231);
+        border-color: rgb(16, 171, 231);
+    }
 
+    .paperTransferModal .ivu-icon {
+        color: rgb(16, 171, 231);
+    }
 
+    .paperTransferModal .btn-clear {
+        float: right;
+        font-weight: 500;
+        font-size: 12px;
+        color: rgb(16, 171, 231);
+        cursor: pointer;
+        letter-spacing: 1px;
+    }
 
+    .paperTransferModal .point-checkbox {
+        margin-left: 10px;
+        border-radius: 2px;
+        width: 15px;
+        height: 15px;
+        padding: 2px;
+        vertical-align: middle;
+        box-sizing: border-box;
+        border: 1px solid #dcdee2;
+    }
 
+    .paperTransferModal .point-checked {
+        background: rgb(16, 171, 231);
+        background-clip: content-box;
+    }
 
+    .paperTransferModal .ivu-tabs-nav-scroll {
+        display: flex;
+        flex-direction: row;
+        justify-content: center;
+    }
 
+    .paperTransferModal .ivu-tree-empty {
+        text-align: center;
+        margin: 15px;
+        color: rgb(128, 128, 128);
+    }
+
+.point-list::-webkit-scrollbar { /*滚动条整体样式*/
+    width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
+    height: 1px;
+}
+
+.point-list:hover .ztree_box::-webkit-scrollbar {
+    width: 5px;
+}
+
+.point-list::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
+    border-radius: 10px;
+    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
+    background: #70707026;
+}
+
+.point-list::-webkit-scrollbar-track { /*滚动条里面轨道*/
+    background: #f4f4f400;
+}
 
 
 

+ 229 - 18
TEAMModelOS/ClientApp/view/evaluation/index/TestPaper.vue

@@ -8,7 +8,7 @@
     <!-- 试卷编辑工具栏 -->
     <div class="paper-toolbar filter-wrap">
 
-      <!--<div class="filter-item">
+      <div class="filter-item">
         <span class="filter-title">测试用途:</span>
         <RadioGroup v-model="testAttr.testType" type="button" @on-change="filterTypeChange">
           <Radio label="0">正式考试</Radio>
@@ -25,7 +25,7 @@
           <Radio label="3">小考</Radio>
           <Radio label="4">自定义</Radio>
         </RadioGroup>
-      </div>-->
+      </div>
       <!--<div class="filter-item">
         <span class="filter-title">测试对象:</span>
         <RadioGroup v-model="testAttr.testTarget" type="button" @on-change="filterTargetChange">
@@ -43,7 +43,12 @@
         </RadioGroup>
       </div>-->
       <div class="paper-tools">
-        <Checkbox v-model="isShowAnswer" @on-change="changeShowAnswer">展示答案与解析</Checkbox>
+        <span class="paper-tools-title">选择展示:</span>
+        <Checkbox v-model="isShowAnswer">答案与解析</Checkbox>
+        <Checkbox v-model="isShowConcept">关联知识点</Checkbox>
+        <Checkbox v-model="isShowTitle">评测标题</Checkbox>
+        <Checkbox v-model="isShowInfo">评测信息</Checkbox>
+        <Checkbox v-model="isShowPart">题块</Checkbox>
       </div>
     </div>
 
@@ -57,19 +62,24 @@
       <div class="paper-body">
         <!-- 试卷头部信息 -->
         <div class="paper-header flex-col-center">
-          <p class="paper-title">{{paperInfo.title}}</p>
-          <p class="paper-subTitle">{{paperInfo.subTitle}}</p>
-          <p class="paper-info">考试时间:{{paperInfo.time}} 出卷人:{{paperInfo.builder}}</p>
+          <Tooltip content="点击可编辑修改主标题" placement="right">
+            <p class="paper-title" v-show="isShowTitle" contenteditable="true" @blur="titleChange($event)">{{paperInfo.title}}</p>
+          </Tooltip>
+          <Tooltip content="点击可编辑修改副标题" placement="right">
+            <p class="paper-subTitle" v-show="isShowInfo" contenteditable="true" @blur="subTitleChange($event)">{{paperInfo.subTitle}}</p>
+          </Tooltip>
+            <p class="paper-info" v-show="isShowInfo">考试时间:<span contenteditable="true" @blur="timeChange($event)">{{paperInfo.time}}</span> 出卷人:{{paperInfo.builder}}</p>
         </div>
         <!-- 题目类型及列表 -->
         <div class="paper-part" v-for="(item,order) in paperInfo.parts">
-          <div class="paper-content-section">{{numberConvertToUppercase(order)+'、'+item.name}}<span>(共6题,每题5分,共30分)</span></div>
+          <div class="paper-content-section" v-show="isShowPart">{{numberConvertToUppercase(order)+'、'+item.name}}<span>(共6题,每题5分,共30分)</span></div>
           <div v-if="list.length == 0">暂无数据</div>
           <div class="content-wrap" v-else>
             <div class="exercise-item" v-for="(question,index) of item.questions" @mouseenter="exerciseMouseover($event)" @mouseleave="exerciseMouseleave($event)">
               <div class="item-tools">
                 <div class="item-tools-t flex-row-center"><Icon type="ios-list-box-outline" />试题挑错</div>
-                <div class="item-tools-t flex-row-center"><Icon type="ios-brush-outline" />编辑</div>
+                <div class="item-tools-t flex-row-center" @click="handleBindPoint([])"><Icon type="ios-list-box-outline" />绑定知识点</div>
+                <div class="item-tools-t flex-row-center" @click="handleToolEdit(question)"><Icon type="ios-brush-outline" />编辑</div>
                 <div class="item-tools-t flex-row-center"><Icon type="ios-archive-outline" />删除</div>
                 <div class="item-tools-t flex-row-center"><Icon type="md-arrow-up" />上移</div>
                 <div class="item-tools-t flex-row-center"><Icon type="md-arrow-down" />下移</div>
@@ -89,6 +99,9 @@
                 <div v-for="(childOption,childOptionIndex) in childQuestion.option">
                   <p>{{String.fromCharCode(64 + parseInt(childOptionIndex+1))}} : <span v-html="childOption.value"></span></p>
                 </div>
+                <div class="item-answer" v-show="isShowAnswer">
+                  <span style="color:#01b4ef">【知识点】:</span>
+                </div>
                 <div class="item-answer" v-show="isShowAnswer">
                   <span style="color:#01b4ef">【答案】:</span>
                   <span v-html="childQuestion.answer[0] || childQuestion.answer" v-if="childQuestion.type == 'Subjective'"></span>
@@ -103,6 +116,9 @@
 
 
               <!-- 答案与解析部分选择是否展示 -->
+              <div class="item-concept" v-show="isShowConcept">
+                <span style="color:#01b4ef">【知识点】:</span>
+              </div>
               <div class="item-answer" v-show="isShowAnswer && question.type != 'Compose'">
                 <span style="color:#01b4ef">【答案】:</span>
                 <span v-html="question.answer[0] || question.answer" v-if="question.type == 'Subjective'"></span>
@@ -121,16 +137,43 @@
     <div class="paper-footer">
       <Button type="primary">保存试卷</Button>
     </div>
+    <!-- 绑定知识点弹窗开始 -->
+    <Modal v-model="bindPointModal"
+           title="绑定知识点"
+           width="500"
+           class-name="paperTransferModal"
+           @on-ok="handleTransferBlock"
+           @on-cancel="">
+      <div class="point-list">
+        <p class="bind-title">选择知识点</p>
+        <Input search placeholder="搜索知识点..." v-model="searchWord" @on-change="filterChange" />
+        <Tabs v-model="tabSelectVal">
+          <TabPane label="校本知识点" name="school">
+            <Tree :data="knowPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
+          </TabPane>
+          <TabPane label="标准知识点" name="all">
+            <Tree :data="allPointList" ref="pointTree" :render="renderContent" check-strictly></Tree>
+          </TabPane>
+        </Tabs>
+        <Spin fix v-show="pointListLoading"></Spin>
+      </div>
+      <div class="selected-point-list">
+        <p class="bind-title">已选知识点<span style="font-weight:500;font-size:12px"> (最多绑定5个知识点,颜色代表不同来源)</span><span class="btn-clear" @click="handleClearChecked">清空</span></p>
+        <span class="checked-point" :style="{background:item.origin=='school'?'#10abe7':'#12b9ab'}" v-for="item in checkedPointList">{{item.name}}<Icon type="md-close" color="#fff" style="margin-left:5px;cursor:pointer" @click="deleteCheckedPoint(item)" /></span>
+      </div>
+    </Modal>
+    <!-- 绑定知识点弹窗结束 -->
   </div>
 </template>
 <script>
-  
+
   import questions from './list.json'
   import paper from './paper.json'
   export default {
     data() {
       return {
         list: [],
+        schoolInfo: {},
         paperInfo: {},
         exersicesType: {
           single: "单选",
@@ -155,12 +198,25 @@
         pageSize: 5,
         pageNum: 1,
         totalNum: 100,
-        allList: questions.list,
-        isShowAnswer: false
+        allList: questions.result.data,
+        isShowAnswer: false,
+        isShowPart: false,
+        isShowConcept: false,
+        isShowTitle: true,
+        isShowInfo:false,
+        bindPointModal: false,
+        knowPointList: [],
+        schoolPointList: [],
+        allPointList: [],
+        checkedPointList: [],
+        searchWord: '',
+        pointListLoading: true,
+        tabSelectVal: "school"
       }
     },
     created() {
-      this.list = questions.list;
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
+      this.list = questions.result.data;
       this.paperInfo = paper;
       let flag = this.$route.params.flag;
       if (flag == 1) {
@@ -171,6 +227,18 @@
     },
     methods: {
 
+      titleChange(e) {
+        this.paperInfo.title = e.target.innerHTML
+      },
+
+      subTitleChange(e) {
+        this.paperInfo.subTitle = e.target.innerHTML
+      },
+  
+      timeChange(e) {
+        this.paperInfo.time = e.target.innerHTML
+      },
+
       //返回创建评测页面
       backToAdd() {
         this.$router.push({
@@ -200,7 +268,7 @@
       pageChange(page) {
         let start = this.pageSize * (page - 1);
         let end = this.pageSize * page;
-        let list = questions.list;
+        let list = questions.result.data;
         this.list = list.slice(start, end);
         window.scroll(0, 0);
       },
@@ -243,18 +311,161 @@
 
       },
 
-      changeShowAnswer(val) {
-        console.log(this.isShowAnswer);
-      }
+      handleToolEdit(item) {
+        item.options = item.option;
+        item.difficulty = item.difficulty || 2;
+        this.$router.push({
+          name: item.type == 'Compose' ? 'createCompose':'createExercises',
+          params: {
+            item: item,
+          }
+        })
+      },
+
+      //确认编辑知识块
+      handleTransferBlock() {
+
+      },
+
+      //绑定知识点操作
+      handleBindPoint(concepts) {
+        this.bindPointModal = true;
+        //this.checkedPointList = concepts;
+        this.checkedPointList = [];
+        this.knowPointList = this.schoolPointList;
+        console.log(concepts);
+      },
+
+      //获取标准知识块数据
+      getStandardList() {
+        let data = {
+          periods: ["Period_21"],
+          pointParams: {
+            SubjectCode: "Subject_Chinese",
+            PartitionKey: "zh-CN",
+          }
+        }
+        this.$api.FindKnowledgeBlockAndPointByDict(data).then(res => {
+          let list = res.result.data;
+          this.allPointList = list;
+        })
+      },
+
+      //获取学校知识块仓库数据
+      getSchoolPoints() {
+        let data = {
+          pointParams: {
+            SubjectCode: "Subject_Chinese",
+            PartitionKey: "zh-CN",
+            SchoolCode: this.schoolInfo.claim[0].claimCode,
+            Status: 1
+          }
+        }
+        this.$api.FindSchoolBlockAndPointByDict(data).then(res => {
+          let list = res.result.data;
+          list.forEach(item => {
+            item.expand = !item.expand;
+          })
+          this.schoolPointList = list;
+          this.pointListLoading = false;
+        })
+      },
+
+      //知识点树形结构渲染
+      renderContent(h, { root, node, data }) {
+        return h(
+          "span",
+          {
+            domProps: {
+              className: "singleClass"
+            },
+            on: {
+              click: () => {
+                this.titleClick(root, node, data, event);
+              }
+            }
+          }, [
+            h("span", [
+              h("Icon", {
+                props: {
+                  type:
+                    data.children && data.children.length > 0
+                      ? "md-albums"
+                      : "ios-paper-outline"
+                },
+                style: {
+                  marginRight: "5px",
+                }
+              }),
+              h("span", data.name),
+              h('span', {
+                domProps: {
+                  className: this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) > -1 ? "point-checkbox point-checked" : "point-checkbox point-unchecked"
+                },
+                style: {
+                  display: data.children && data.children.length > 0
+                    ? "none"
+                    : "inline-block"
+                },
+                on: {
+                  click: () => {
+                    let conceptData = {};
+                    if (this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey) == -1) {
+                      if (this.checkedPointList.length < 5) {
+                        conceptData.origin = this.tabSelectVal;
+                        conceptData.knowledgeId = data.knowledgeId || data.rowKey;
+                        conceptData.name = data.name;
+                        conceptData.subjectCode = data.subjectCode;
+                        this.checkedPointList.push(conceptData);
+                      } else {
+                        this.$Message.warning("最多绑定5个知识点!");
+                      }
+                    } else {
+                      this.checkedPointList.splice(this.checkedPointList.map(item => item.knowledgeId).indexOf(data.knowledgeId || data.rowKey), 1);
+                    }
+
+                    console.log(this.checkedPointList);
+                  }
+                }
+              })
+            ])
+          ]
+        );
+      },
+      //标题点击收缩展开
+      titleClick(root, node, data, event) {
+        data.expand = !data.expand;
+      },
+
+      //清空已选知识点
+      handleClearChecked() {
+        this.checkedPointList = [];
+      },
+
+      //删除指定知识点
+      deleteCheckedPoint(item) {
+        this.checkedPointList.splice(this.checkedPointList.indexOf(item), 1);
+      },
+
+      //知识点筛选功能
+      filterChange() {
+        this.knowPointList = !this.searchWord ? this.schoolPointList : this.schoolPointList.filter(item => item.name.toUpperCase().indexOf(this.searchWord.toUpperCase()) > -1)
+      },
+
 
     },
     mounted() {
-
+      this.getStandardList();
+      this.getSchoolPoints();
     }
   }
 </script>
+<!--<style src="../index/TestPaper.css" scoped></style>-->
 <style src="../index/ExercisesList.css" scoped></style>
-<style src="../index/TestPaper.css" scoped></style>
+
+<style scoped>
+  @import "../index/TestPaper.css";
+</style>
 <style>
 
   .content-wrap .exercise-item p {

+ 9 - 9
TEAMModelOS/ClientApp/view/evaluation/index/TestPaperList.vue

@@ -55,7 +55,7 @@
       <div class="exercise-item" v-for="(item,index) of list">
         <img class="icon-paper" src="../../../assets/icon/icon_paper.png" />
         <div class="paper-content">
-          <p class="paper-title" v-html="item.explain"></p>
+          <p class="paper-title" v-html="item.type"></p>
           <p class="paper-info">
             <span style="margin-left:0"><Icon type="md-clock" />修改时间:2019-06-26</span>
             <span><Icon type="md-eye" />使用次数:8</span>
@@ -115,7 +115,7 @@ import { setTimeout } from 'core-js';
         pageSize: 5,
         pageNum: 1,
         totalNum: 100,
-        allList: questions.list,
+        allList: questions.result.data,
         knowPointList: [],
         schoolPointList: [],
         allPointList:[],
@@ -124,8 +124,8 @@ import { setTimeout } from 'core-js';
     },
     created() {
       this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0];
-      this.list = questions.list.concat(questions.list);
-      this.totalNum = questions.list.length;
+      this.list = questions.result.data;
+      this.totalNum = questions.result.data.length;
       if (this.$route.params.exerciseItem) {
         this.list.unshift(this.$route.params.exerciseItem);
       }
@@ -135,18 +135,18 @@ import { setTimeout } from 'core-js';
       //筛选题型
       filterTypeChange(val) {
         if (val == "all") {
-          this.list = questions.list;
+          this.list = questions.result.data;
         } else {
-          this.list = questions.list.filter(item => item.type == val);
+          this.list = questions.result.data.filter(item => item.type == val);
         }
       },
 
       //筛选难度
       filterDiffChange(val) {
          if (val == "all") {
-          this.list = questions.list;
+          this.list = questions.result.data;
          } else {
-           this.list = questions.list.filter(item => item.difficulty == val);
+           this.list = questions.result.data.filter(item => item.difficulty == val);
         }
       },
 
@@ -187,7 +187,7 @@ import { setTimeout } from 'core-js';
       pageChange(page) {
         let start = this.pageSize * (page - 1);
         let end = this.pageSize * page;
-        let list = questions.list;
+        let list = questions.result.data;
         this.list = list.slice(start, end);
         window.scroll(0, 0);
       },

+ 182 - 24
TEAMModelOS/ClientApp/view/evaluation/index/index.vue

@@ -4,7 +4,31 @@
       <Header :parentToChild="syllabusTitle" :identityselect="identitydata"></Header>
     </div>
     <div class="ev-body">
-      <div class="ev-slide"></div>
+      <div class="ev-slide">
+        <div class="ev-slide-school"><Icon type="ios-school" size="26" color="#10abe7" style="vertical-align:sub"/> {{schoolInfo.claimName}}</div>
+        <div class="ev-slide-header">选择学段及科目</div>
+        <div class="ev-slide-select">
+          <!-- 学段选择部分 -->
+          <Select v-model="evPeriodSelect" @on-change="periodChange" label-in-value>
+            <Option v-for="item in evPeriodsList" :value="item.code" :key="item.rowKey">{{ item.name }}</Option>
+          </Select>
+
+          <!-- 科目选择部分 -->
+          <Select v-model="evSubjectSelect" @on-change="subjectChange" label-in-value>
+            <Option v-for="item in evSubjectList" :value="item.code" :key="item.rowKey">{{ item.name }}</Option>
+          </Select>
+        </div>
+        <div class="ev-slide-header ev-slide-select-volumes" style="position:relative">
+          <Loading :top="150" :borderWidth="4" v-show="!isLoadingFinish"></Loading>
+          <!--<Loading v-show="!isLoadingFinish"></Loading>-->
+
+          <!-- 册别选择部分 -->
+          <Select v-model="evVolumeSelect" @on-change="volumeChange" label-in-value placeholder="请选择册别">
+            <Option v-for="item in evVolumesList" :value="item.rowKey" :key="item.rowKey">{{ item.gradeName + '' + item.termName }}</Option>
+          </Select>
+        </div>
+        <SyllabusTree :treeDatas="treeData"></SyllabusTree>
+      </div>
       <div class="ev-content">
         <router-view />
       </div>
@@ -24,10 +48,15 @@
 </template>
 <script>
   import Header from '@/common/headers.vue'
+  import SyllabusTree from '@/components/evaluation/SyllabusTree.vue'
+  import Loading from '@/common/Loading.vue'
+import { setTimeout } from 'core-js';
 
   export default {
     components: {
-      Header
+      Header,
+      SyllabusTree,
+      Loading
     },
     data() {
       return {
@@ -36,21 +65,103 @@
           { "id": 1, "name": '成都紫藤小学', "rolename": '管理员', status: '1' },
           { "id": 2, "name": '成都七中小学', "rolename": '班主任', status: '2' }
         ],
+        treeData: [],
+        schoolInfo: {},
+        evSubjectList: [],
+        evPeriodsList: [],
+        evVolumesList: [],
+        evSubjectSelect:"",
+        evPeriodSelect: "",
+        evVolumeSelect:"",
+        isLoadingFinish:false
       }
     },
+    created() {
+      this.schoolInfo = JSON.parse(localStorage.getItem('c_role_info')).roleClaim[0].claim[0]; //默认选中第一个学校
+      this.findSchoolPeriodsByDict();
+
+    },
     methods: {
       goRouter(name) {
         this.$router.push({
           name:name
         })
+      },
+
+      //获取当前学校全部学段
+      findSchoolPeriodsByDict() {
+        this.$api.FindSchoolPeriodsByDict({SchoolCode: this.schoolInfo.claimCode}).then(res => {
+          this.evPeriodsList = res.result.data;
+          this.evPeriodSelect = res.result.data[0].code;
+          this.findSchoolSubjectsByDict();
+        })
+      },
+
+      //查找当前学校已有科目
+      findSchoolSubjectsByDict() {
+        this.$api.FindSchoolSubjectsByDict({ SchoolCode: this.schoolInfo.claimCode,Status:1 }).then(res => {
+          this.evSubjectList = res.result.data;
+          this.evSubjectSelect = res.result.data[0].code;
+          this.findVolumesBySubjectAndPeriod(this.evPeriodSelect, this.evSubjectSelect);
+        })
+      },
+
+      //根据当前选择的科目及学段获取所有册别
+      findVolumesBySubjectAndPeriod(periodCode,subjectCode) {
+        let defaultData = {
+          SchoolCode: this.schoolInfo.claimCode,
+          SubjectCode: subjectCode,
+          PeriodCode: periodCode,
+          Status:1
+        }
+        this.$api.FindSchoolVolumesByDict(defaultData).then(res => {
+          this.evVolumesList = res.result.data;
+          if (res.result.data.length) {
+            this.evVolumeSelect = res.result.data[0].rowKey;
+            this.findSyllabusByVolumeCode(res.result.data[0].rowKey);
+          } else {
+            this.evVolumeSelect = "";
+            this.treeData = [];
+          }
+         })
+      },
+
+      //根据册别来获取课纲树形结构
+      findSyllabusByVolumeCode(volumeCode) {
+        this.isLoadingFinish = false;
+        this.$api.FindSyllabusByVolumeCode({ VolumeCode: volumeCode, Status: 1 }).then(res => {
+          let list = res.result.data;
+          list.forEach(item => { item.expand = false });
+          this.treeData = list;
+          this.isLoadingFinish = true;
+        })
+      },
+
+      //选择科目变化
+      subjectChange(val) {
+        this.findVolumesBySubjectAndPeriod(this.evPeriodSelect, val.value);
+      },
+
+      //选择学段变化
+      periodChange(val) {
+        this.findVolumesBySubjectAndPeriod(val.value, this.evSubjectSelect);
+      },
+
+      //选择册别变化
+      volumeChange(val) {
+        this.findSyllabusByVolumeCode(val.value);
       }
+    },
+    mounted() {
     }
+
   }
 </script>
 <style scoped>
   .evaluation {
     background:#eee;
     width:100%;
+    min-height:100%;
     padding-bottom:50px;
     position:relative;
   }
@@ -67,14 +178,78 @@
   }
     .ev-body .ev-slide {
       width:20%;
-      height:1200px;
-      background:#e1e1e1;
+      height:auto;
+      padding:0;
+      background:#fff;
+      border-radius:5px 5px 0 0;
     }
 
-    .ev-body .ev-content {
-       width:79%;
+    .ev-body .ev-slide .ev-slide-header{
+      width:104%;
+      height:45px;
+      background:#10abe7;
+      text-align:center;
+      line-height:45px;
+      color:white;
+      font-size:16px;
+      border-radius:5px;
+      margin:20px -5px;
+      box-shadow: 0px 1px 8px 5px #dedede;
     }
 
+      .ev-body .ev-slide .ev-slide-select {
+        padding:0 10px;
+        /*background:#10abe7;*/
+      }
+
+      .ev-body .ev-slide .ev-slide-school {
+          height:40px;
+          line-height:40px;
+          text-align:center;
+          padding-top:10px;
+          font-size:14px;
+          font-weight:bold;
+          padding-right:5px;
+      }
+
+      .ev-slide /deep/ .ev-slide-select .ivu-select-selection {
+        margin-top:8px;
+        height:40px;
+      }
+
+      .ev-slide /deep/ .ev-slide-select .ivu-select-selected-value {
+        line-height:40px;
+      }
+
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-selection {
+          background:transparent;
+          border:none;
+          color:#fff;
+          width:140px;
+          margin:0 auto;
+          padding-right:10px;
+          font-size:14px;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-arrow {
+          color:#fff;
+      }
+
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-dropdown {
+          left:unset !important;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-placeholder {
+          color:#fff;
+          font-size:14px;
+      }
+      .ev-slide .ev-slide-select-volumes /deep/ .ivu-select-selected-value {
+          color:#fff;
+          font-size:14px;
+      }
+
+  .ev-body .ev-content {
+      width:79%;
+  }
+
 
   .slide-menu {
     width:150px;
@@ -116,23 +291,6 @@
       font-size:44px;
     }
 
-
-      /*.slide-menu ul li::after {
-        content: '';
-        z-index: -1;
-        background-color: hsla(0, 0%, 100%, 0.2);
-        position: absolute;
-        top: -50%;
-        bottom: -50%;
-        width: 2.25em;
-        transform: translate3d(-525%, 0, 0) rotate(35deg);
-      }
-
-      .slide-menu ul li:hover::after {
-        transition: transform 0.45s ease-in-out;
-        transform: translate3d(200%, 0, 0) rotate(35deg);
-      }*/
-
       .slide-menu ul li::before {
           content: '';
           z-index: -1;
@@ -158,6 +316,6 @@
           transform: translate3d(120%, 50%, 0) scale3d(25, 15, 15);
         }
 
-  
+
 
 </style>

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 168 - 0
TEAMModelOS/ClientApp/view/evaluation/index/list.json


+ 1 - 1
TEAMModelOS/ClientApp/view/evaluation/types/BaseJudge.vue

@@ -51,7 +51,7 @@
       if (Object.keys(this.editInfo).length > 0) {
         this.stemEditor.txt.html(this.editInfo.question);
         this.stemContent = this.editInfo.question;
-        this.trueAnswer = this.editInfo.answer;
+        this.trueAnswer = this.editInfo.answer[0] == 'A' ? '正确' :'错误';
       }
 
     }

+ 1 - 0
TEAMModelOS/ClientApp/view/syllabus/index/Syllabus.vue

@@ -242,6 +242,7 @@ import { setTimeout } from 'core-js';
       },
       //查找当前学校已有科目
       findSchoolSubjectsByDict() {
+        console.log(this.schoolInfo);
         this.$api.FindSchoolSubjectsByDict({ SchoolCode: this.schoolInfo.claimCode,Status:1 }).then(res => {
           this.currentSubjectList = res.result.data;
           if (res.result.data.length > 0) {

+ 1 - 1
TEAMModelOS/Views/Shared/_Layout.cshtml

@@ -16,7 +16,7 @@
 <body>
     @RenderBody()
     <script src="~/dist/vendor.js" asp-append-version="true"></script>
-    <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" asp-append-version="true"></script>
+    @*<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML" asp-append-version="true"></script>*@
 
     @RenderSection("scripts", required: false)
 </body>

+ 30 - 0
TeamModelOS.OfficeDoc.Test/App_Start/BundleConfig.cs

@@ -0,0 +1,30 @@
+using System.Web;
+using System.Web.Optimization;
+
+namespace TeamModelOS.OfficeDoc.Test
+{
+    public class BundleConfig
+    {
+        // 有关捆绑的详细信息,请访问 https://go.microsoft.com/fwlink/?LinkId=301862
+        public static void RegisterBundles(BundleCollection bundles)
+        {
+            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
+                        "~/Scripts/jquery-{version}.js"));
+
+            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
+                        "~/Scripts/jquery.validate*"));
+
+            // 使用要用于开发和学习的 Modernizr 的开发版本。然后,当你做好
+            // 生产准备就绪,请使用 https://modernizr.com 上的生成工具仅选择所需的测试。
+            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
+                        "~/Scripts/modernizr-*"));
+
+            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
+                      "~/Scripts/bootstrap.js"));
+
+            bundles.Add(new StyleBundle("~/Content/css").Include(
+                      "~/Content/bootstrap.css",
+                      "~/Content/site.css"));
+        }
+    }
+}

+ 13 - 0
TeamModelOS.OfficeDoc.Test/App_Start/FilterConfig.cs

@@ -0,0 +1,13 @@
+using System.Web;
+using System.Web.Mvc;
+
+namespace TeamModelOS.OfficeDoc.Test
+{
+    public class FilterConfig
+    {
+        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
+        {
+            filters.Add(new HandleErrorAttribute());
+        }
+    }
+}

+ 23 - 0
TeamModelOS.OfficeDoc.Test/App_Start/RouteConfig.cs

@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace TeamModelOS.OfficeDoc.Test
+{
+    public class RouteConfig
+    {
+        public static void RegisterRoutes(RouteCollection routes)
+        {
+            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+            routes.MapRoute(
+                name: "Default",
+                url: "{controller}/{action}/{id}",
+                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
+            );
+        }
+    }
+}

+ 24 - 0
TeamModelOS.OfficeDoc.Test/Content/Site.css

@@ -0,0 +1,24 @@
+body {
+    padding-top: 50px;
+    padding-bottom: 20px;
+}
+
+/* Set padding to keep content from hitting the edges */
+.body-content {
+    padding-left: 15px;
+    padding-right: 15px;
+}
+
+/* Override the default bootstrap behavior where horizontal description lists 
+   will truncate terms that are too long to fit in the left column 
+*/
+.dl-horizontal dt {
+    white-space: normal;
+}
+
+/* Set width on the form input elements since they're 100% wide by default */
+input,
+select,
+textarea {
+    max-width: 280px;
+}

+ 587 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.css

@@ -0,0 +1,587 @@
+/*!
+ * Bootstrap v3.4.1 (https://getbootstrap.com/)
+ * Copyright 2011-2019 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+.btn-default,
+.btn-primary,
+.btn-success,
+.btn-info,
+.btn-warning,
+.btn-danger {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+.btn-default:active,
+.btn-primary:active,
+.btn-success:active,
+.btn-info:active,
+.btn-warning:active,
+.btn-danger:active,
+.btn-default.active,
+.btn-primary.active,
+.btn-success.active,
+.btn-info.active,
+.btn-warning.active,
+.btn-danger.active {
+  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+  box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
+.btn-default.disabled,
+.btn-primary.disabled,
+.btn-success.disabled,
+.btn-info.disabled,
+.btn-warning.disabled,
+.btn-danger.disabled,
+.btn-default[disabled],
+.btn-primary[disabled],
+.btn-success[disabled],
+.btn-info[disabled],
+.btn-warning[disabled],
+.btn-danger[disabled],
+fieldset[disabled] .btn-default,
+fieldset[disabled] .btn-primary,
+fieldset[disabled] .btn-success,
+fieldset[disabled] .btn-info,
+fieldset[disabled] .btn-warning,
+fieldset[disabled] .btn-danger {
+  -webkit-box-shadow: none;
+  box-shadow: none;
+}
+.btn-default .badge,
+.btn-primary .badge,
+.btn-success .badge,
+.btn-info .badge,
+.btn-warning .badge,
+.btn-danger .badge {
+  text-shadow: none;
+}
+.btn:active,
+.btn.active {
+  background-image: none;
+}
+.btn-default {
+  background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+  background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
+  background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #dbdbdb;
+  text-shadow: 0 1px 0 #fff;
+  border-color: #ccc;
+}
+.btn-default:hover,
+.btn-default:focus {
+  background-color: #e0e0e0;
+  background-position: 0 -15px;
+}
+.btn-default:active,
+.btn-default.active {
+  background-color: #e0e0e0;
+  border-color: #dbdbdb;
+}
+.btn-default.disabled,
+.btn-default[disabled],
+fieldset[disabled] .btn-default,
+.btn-default.disabled:hover,
+.btn-default[disabled]:hover,
+fieldset[disabled] .btn-default:hover,
+.btn-default.disabled:focus,
+.btn-default[disabled]:focus,
+fieldset[disabled] .btn-default:focus,
+.btn-default.disabled.focus,
+.btn-default[disabled].focus,
+fieldset[disabled] .btn-default.focus,
+.btn-default.disabled:active,
+.btn-default[disabled]:active,
+fieldset[disabled] .btn-default:active,
+.btn-default.disabled.active,
+.btn-default[disabled].active,
+fieldset[disabled] .btn-default.active {
+  background-color: #e0e0e0;
+  background-image: none;
+}
+.btn-primary {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
+  background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
+  background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #245580;
+}
+.btn-primary:hover,
+.btn-primary:focus {
+  background-color: #265a88;
+  background-position: 0 -15px;
+}
+.btn-primary:active,
+.btn-primary.active {
+  background-color: #265a88;
+  border-color: #245580;
+}
+.btn-primary.disabled,
+.btn-primary[disabled],
+fieldset[disabled] .btn-primary,
+.btn-primary.disabled:hover,
+.btn-primary[disabled]:hover,
+fieldset[disabled] .btn-primary:hover,
+.btn-primary.disabled:focus,
+.btn-primary[disabled]:focus,
+fieldset[disabled] .btn-primary:focus,
+.btn-primary.disabled.focus,
+.btn-primary[disabled].focus,
+fieldset[disabled] .btn-primary.focus,
+.btn-primary.disabled:active,
+.btn-primary[disabled]:active,
+fieldset[disabled] .btn-primary:active,
+.btn-primary.disabled.active,
+.btn-primary[disabled].active,
+fieldset[disabled] .btn-primary.active {
+  background-color: #265a88;
+  background-image: none;
+}
+.btn-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
+  background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
+  background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #3e8f3e;
+}
+.btn-success:hover,
+.btn-success:focus {
+  background-color: #419641;
+  background-position: 0 -15px;
+}
+.btn-success:active,
+.btn-success.active {
+  background-color: #419641;
+  border-color: #3e8f3e;
+}
+.btn-success.disabled,
+.btn-success[disabled],
+fieldset[disabled] .btn-success,
+.btn-success.disabled:hover,
+.btn-success[disabled]:hover,
+fieldset[disabled] .btn-success:hover,
+.btn-success.disabled:focus,
+.btn-success[disabled]:focus,
+fieldset[disabled] .btn-success:focus,
+.btn-success.disabled.focus,
+.btn-success[disabled].focus,
+fieldset[disabled] .btn-success.focus,
+.btn-success.disabled:active,
+.btn-success[disabled]:active,
+fieldset[disabled] .btn-success:active,
+.btn-success.disabled.active,
+.btn-success[disabled].active,
+fieldset[disabled] .btn-success.active {
+  background-color: #419641;
+  background-image: none;
+}
+.btn-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+  background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
+  background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #28a4c9;
+}
+.btn-info:hover,
+.btn-info:focus {
+  background-color: #2aabd2;
+  background-position: 0 -15px;
+}
+.btn-info:active,
+.btn-info.active {
+  background-color: #2aabd2;
+  border-color: #28a4c9;
+}
+.btn-info.disabled,
+.btn-info[disabled],
+fieldset[disabled] .btn-info,
+.btn-info.disabled:hover,
+.btn-info[disabled]:hover,
+fieldset[disabled] .btn-info:hover,
+.btn-info.disabled:focus,
+.btn-info[disabled]:focus,
+fieldset[disabled] .btn-info:focus,
+.btn-info.disabled.focus,
+.btn-info[disabled].focus,
+fieldset[disabled] .btn-info.focus,
+.btn-info.disabled:active,
+.btn-info[disabled]:active,
+fieldset[disabled] .btn-info:active,
+.btn-info.disabled.active,
+.btn-info[disabled].active,
+fieldset[disabled] .btn-info.active {
+  background-color: #2aabd2;
+  background-image: none;
+}
+.btn-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+  background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
+  background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #e38d13;
+}
+.btn-warning:hover,
+.btn-warning:focus {
+  background-color: #eb9316;
+  background-position: 0 -15px;
+}
+.btn-warning:active,
+.btn-warning.active {
+  background-color: #eb9316;
+  border-color: #e38d13;
+}
+.btn-warning.disabled,
+.btn-warning[disabled],
+fieldset[disabled] .btn-warning,
+.btn-warning.disabled:hover,
+.btn-warning[disabled]:hover,
+fieldset[disabled] .btn-warning:hover,
+.btn-warning.disabled:focus,
+.btn-warning[disabled]:focus,
+fieldset[disabled] .btn-warning:focus,
+.btn-warning.disabled.focus,
+.btn-warning[disabled].focus,
+fieldset[disabled] .btn-warning.focus,
+.btn-warning.disabled:active,
+.btn-warning[disabled]:active,
+fieldset[disabled] .btn-warning:active,
+.btn-warning.disabled.active,
+.btn-warning[disabled].active,
+fieldset[disabled] .btn-warning.active {
+  background-color: #eb9316;
+  background-image: none;
+}
+.btn-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+  background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
+  background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  background-repeat: repeat-x;
+  border-color: #b92c28;
+}
+.btn-danger:hover,
+.btn-danger:focus {
+  background-color: #c12e2a;
+  background-position: 0 -15px;
+}
+.btn-danger:active,
+.btn-danger.active {
+  background-color: #c12e2a;
+  border-color: #b92c28;
+}
+.btn-danger.disabled,
+.btn-danger[disabled],
+fieldset[disabled] .btn-danger,
+.btn-danger.disabled:hover,
+.btn-danger[disabled]:hover,
+fieldset[disabled] .btn-danger:hover,
+.btn-danger.disabled:focus,
+.btn-danger[disabled]:focus,
+fieldset[disabled] .btn-danger:focus,
+.btn-danger.disabled.focus,
+.btn-danger[disabled].focus,
+fieldset[disabled] .btn-danger.focus,
+.btn-danger.disabled:active,
+.btn-danger[disabled]:active,
+fieldset[disabled] .btn-danger:active,
+.btn-danger.disabled.active,
+.btn-danger[disabled].active,
+fieldset[disabled] .btn-danger.active {
+  background-color: #c12e2a;
+  background-image: none;
+}
+.thumbnail,
+.img-thumbnail {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
+}
+.dropdown-menu > li > a:hover,
+.dropdown-menu > li > a:focus {
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+  background-color: #e8e8e8;
+}
+.dropdown-menu > .active > a,
+.dropdown-menu > .active > a:hover,
+.dropdown-menu > .active > a:focus {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+  background-repeat: repeat-x;
+  background-color: #2e6da4;
+}
+.navbar-default {
+  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
+  background-image: -o-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#f8f8f8));
+  background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  border-radius: 4px;
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);
+}
+.navbar-default .navbar-nav > .open > a,
+.navbar-default .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+  background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
+  background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
+  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);
+}
+.navbar-brand,
+.navbar-nav > li > a {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);
+}
+.navbar-inverse {
+  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
+  background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
+  background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
+  background-repeat: repeat-x;
+  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+  border-radius: 4px;
+}
+.navbar-inverse .navbar-nav > .open > a,
+.navbar-inverse .navbar-nav > .active > a {
+  background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+  background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
+  background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
+  background-repeat: repeat-x;
+  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
+  box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);
+}
+.navbar-inverse .navbar-brand,
+.navbar-inverse .navbar-nav > li > a {
+  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+.navbar-static-top,
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+  border-radius: 0;
+}
+@media (max-width: 767px) {
+  .navbar .navbar-nav .open .dropdown-menu > .active > a,
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
+  .navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
+    color: #fff;
+    background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+    background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+    background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+    background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+    background-repeat: repeat-x;
+  }
+}
+.alert {
+  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);
+  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
+  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+.alert-success {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+  background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
+  background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #b2dba1;
+}
+.alert-info {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+  background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
+  background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #9acfea;
+}
+.alert-warning {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+  background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
+  background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #f5e79e;
+}
+.alert-danger {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+  background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
+  background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dca7a7;
+}
+.progress {
+  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+  background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
+  background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
+  background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
+  background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-success {
+  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+  background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
+  background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-info {
+  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+  background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
+  background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-warning {
+  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+  background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
+  background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-danger {
+  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+  background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
+  background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
+  background-repeat: repeat-x;
+}
+.progress-bar-striped {
+  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+.list-group {
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);
+}
+.list-group-item.active,
+.list-group-item.active:hover,
+.list-group-item.active:focus {
+  text-shadow: 0 -1px 0 #286090;
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+  background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
+  background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #2b669a;
+}
+.list-group-item.active .badge,
+.list-group-item.active:hover .badge,
+.list-group-item.active:focus .badge {
+  text-shadow: none;
+}
+.panel {
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+.panel-default > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
+  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-primary > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
+  background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-success > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+  background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
+  background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-info > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+  background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
+  background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-warning > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+  background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
+  background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.panel-danger > .panel-heading {
+  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+  background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
+  background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
+  background-repeat: repeat-x;
+}
+.well {
+  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+  background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
+  background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
+  background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
+  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
+  background-repeat: repeat-x;
+  border-color: #dcdcdc;
+  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
+  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);
+}
+/*# sourceMappingURL=bootstrap-theme.css.map */

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.css.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 6 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.min.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap-theme.min.css.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 6834 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap.css.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 6 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap.min.css


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Content/bootstrap.min.css.map


+ 30 - 0
TeamModelOS.OfficeDoc.Test/Controllers/HomeController.cs

@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+namespace TeamModelOS.OfficeDoc.Test.Controllers
+{
+    public class HomeController : Controller
+    {
+        public ActionResult Index()
+        {
+            return View();
+        }
+
+        public ActionResult About()
+        {
+            ViewBag.Message = "Your application description page.";
+
+            return View();
+        }
+
+        public ActionResult Contact()
+        {
+            ViewBag.Message = "Your contact page.";
+
+            return View();
+        }
+    }
+}

+ 1 - 0
TeamModelOS.OfficeDoc.Test/Global.asax

@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="TeamModelOS.OfficeDoc.Test.MvcApplication" Language="C#" %>

+ 21 - 0
TeamModelOS.OfficeDoc.Test/Global.asax.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Optimization;
+using System.Web.Routing;
+
+namespace TeamModelOS.OfficeDoc.Test
+{
+    public class MvcApplication : System.Web.HttpApplication
+    {
+        protected void Application_Start()
+        {
+            AreaRegistration.RegisterAllAreas();
+            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
+            RouteConfig.RegisterRoutes(RouteTable.Routes);
+            BundleConfig.RegisterBundles(BundleTable.Bundles);
+        }
+    }
+}

+ 35 - 0
TeamModelOS.OfficeDoc.Test/Properties/AssemblyInfo.cs

@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// 有关程序集的常规信息是通过以下项进行控制的
+// 控制。更改这些特性值可修改
+// 与程序集关联的信息。
+[assembly: AssemblyTitle("TeamModelOS.OfficeDoc.Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("TeamModelOS.OfficeDoc.Test")]
+[assembly: AssemblyCopyright("版权所有(C)  2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 将 ComVisible 设置为 false 将使此程序集中的类型
+// 对 COM 组件不可见。如果需要
+// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。
+[assembly: ComVisible(false)]
+
+// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID
+[assembly: Guid("9e096f09-356d-46fc-a004-a1449cdcae23")]
+
+// 程序集的版本信息由下列四个值组成:
+//
+//      主版本
+//      次版本
+//      内部版本号
+//      修订版本
+//
+// 你可以指定所有值,也可以让修订版本和内部版本号采用默认值,
+// 方法是按如下所示使用 "*":
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2580 - 0
TeamModelOS.OfficeDoc.Test/Scripts/bootstrap.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 6 - 0
TeamModelOS.OfficeDoc.Test/Scripts/bootstrap.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2670 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.intellisense.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 10364 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.min.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 8269 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 2 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery-3.3.1.slim.min.map


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1288 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate-vsdoc.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1601 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 4 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.min.js


+ 432 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.unobtrusive.js

@@ -0,0 +1,432 @@
+// Unobtrusive validation support library for jQuery and jQuery Validate
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+// @version v3.2.11
+
+/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
+/*global document: false, jQuery: false */
+
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        // AMD. Register as an anonymous module.
+        define("jquery.validate.unobtrusive", ['jquery-validation'], factory);
+    } else if (typeof module === 'object' && module.exports) {
+        // CommonJS-like environments that support module.exports     
+        module.exports = factory(require('jquery-validation'));
+    } else {
+        // Browser global
+        jQuery.validator.unobtrusive = factory(jQuery);
+    }
+}(function ($) {
+    var $jQval = $.validator,
+        adapters,
+        data_validation = "unobtrusiveValidation";
+
+    function setValidationValues(options, ruleName, value) {
+        options.rules[ruleName] = value;
+        if (options.message) {
+            options.messages[ruleName] = options.message;
+        }
+    }
+
+    function splitAndTrim(value) {
+        return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
+    }
+
+    function escapeAttributeValue(value) {
+        // As mentioned on http://api.jquery.com/category/selectors/
+        return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
+    }
+
+    function getModelPrefix(fieldName) {
+        return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
+    }
+
+    function appendModelPrefix(value, prefix) {
+        if (value.indexOf("*.") === 0) {
+            value = value.replace("*.", prefix);
+        }
+        return value;
+    }
+
+    function onError(error, inputElement) {  // 'this' is the form element
+        var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
+            replaceAttrValue = container.attr("data-valmsg-replace"),
+            replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
+
+        container.removeClass("field-validation-valid").addClass("field-validation-error");
+        error.data("unobtrusiveContainer", container);
+
+        if (replace) {
+            container.empty();
+            error.removeClass("input-validation-error").appendTo(container);
+        }
+        else {
+            error.hide();
+        }
+    }
+
+    function onErrors(event, validator) {  // 'this' is the form element
+        var container = $(this).find("[data-valmsg-summary=true]"),
+            list = container.find("ul");
+
+        if (list && list.length && validator.errorList.length) {
+            list.empty();
+            container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
+
+            $.each(validator.errorList, function () {
+                $("<li />").html(this.message).appendTo(list);
+            });
+        }
+    }
+
+    function onSuccess(error) {  // 'this' is the form element
+        var container = error.data("unobtrusiveContainer");
+
+        if (container) {
+            var replaceAttrValue = container.attr("data-valmsg-replace"),
+                replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
+
+            container.addClass("field-validation-valid").removeClass("field-validation-error");
+            error.removeData("unobtrusiveContainer");
+
+            if (replace) {
+                container.empty();
+            }
+        }
+    }
+
+    function onReset(event) {  // 'this' is the form element
+        var $form = $(this),
+            key = '__jquery_unobtrusive_validation_form_reset';
+        if ($form.data(key)) {
+            return;
+        }
+        // Set a flag that indicates we're currently resetting the form.
+        $form.data(key, true);
+        try {
+            $form.data("validator").resetForm();
+        } finally {
+            $form.removeData(key);
+        }
+
+        $form.find(".validation-summary-errors")
+            .addClass("validation-summary-valid")
+            .removeClass("validation-summary-errors");
+        $form.find(".field-validation-error")
+            .addClass("field-validation-valid")
+            .removeClass("field-validation-error")
+            .removeData("unobtrusiveContainer")
+            .find(">*")  // If we were using valmsg-replace, get the underlying error
+            .removeData("unobtrusiveContainer");
+    }
+
+    function validationInfo(form) {
+        var $form = $(form),
+            result = $form.data(data_validation),
+            onResetProxy = $.proxy(onReset, form),
+            defaultOptions = $jQval.unobtrusive.options || {},
+            execInContext = function (name, args) {
+                var func = defaultOptions[name];
+                func && $.isFunction(func) && func.apply(form, args);
+            };
+
+        if (!result) {
+            result = {
+                options: {  // options structure passed to jQuery Validate's validate() method
+                    errorClass: defaultOptions.errorClass || "input-validation-error",
+                    errorElement: defaultOptions.errorElement || "span",
+                    errorPlacement: function () {
+                        onError.apply(form, arguments);
+                        execInContext("errorPlacement", arguments);
+                    },
+                    invalidHandler: function () {
+                        onErrors.apply(form, arguments);
+                        execInContext("invalidHandler", arguments);
+                    },
+                    messages: {},
+                    rules: {},
+                    success: function () {
+                        onSuccess.apply(form, arguments);
+                        execInContext("success", arguments);
+                    }
+                },
+                attachValidation: function () {
+                    $form
+                        .off("reset." + data_validation, onResetProxy)
+                        .on("reset." + data_validation, onResetProxy)
+                        .validate(this.options);
+                },
+                validate: function () {  // a validation function that is called by unobtrusive Ajax
+                    $form.validate();
+                    return $form.valid();
+                }
+            };
+            $form.data(data_validation, result);
+        }
+
+        return result;
+    }
+
+    $jQval.unobtrusive = {
+        adapters: [],
+
+        parseElement: function (element, skipAttach) {
+            /// <summary>
+            /// Parses a single HTML element for unobtrusive validation attributes.
+            /// </summary>
+            /// <param name="element" domElement="true">The HTML element to be parsed.</param>
+            /// <param name="skipAttach" type="Boolean">[Optional] true to skip attaching the
+            /// validation to the form. If parsing just this single element, you should specify true.
+            /// If parsing several elements, you should specify false, and manually attach the validation
+            /// to the form when you are finished. The default is false.</param>
+            var $element = $(element),
+                form = $element.parents("form")[0],
+                valInfo, rules, messages;
+
+            if (!form) {  // Cannot do client-side validation without a form
+                return;
+            }
+
+            valInfo = validationInfo(form);
+            valInfo.options.rules[element.name] = rules = {};
+            valInfo.options.messages[element.name] = messages = {};
+
+            $.each(this.adapters, function () {
+                var prefix = "data-val-" + this.name,
+                    message = $element.attr(prefix),
+                    paramValues = {};
+
+                if (message !== undefined) {  // Compare against undefined, because an empty message is legal (and falsy)
+                    prefix += "-";
+
+                    $.each(this.params, function () {
+                        paramValues[this] = $element.attr(prefix + this);
+                    });
+
+                    this.adapt({
+                        element: element,
+                        form: form,
+                        message: message,
+                        params: paramValues,
+                        rules: rules,
+                        messages: messages
+                    });
+                }
+            });
+
+            $.extend(rules, { "__dummy__": true });
+
+            if (!skipAttach) {
+                valInfo.attachValidation();
+            }
+        },
+
+        parse: function (selector) {
+            /// <summary>
+            /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
+            /// with the [data-val=true] attribute value and enables validation according to the data-val-*
+            /// attribute values.
+            /// </summary>
+            /// <param name="selector" type="String">Any valid jQuery selector.</param>
+
+            // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
+            // element with data-val=true
+            var $selector = $(selector),
+                $forms = $selector.parents()
+                    .addBack()
+                    .filter("form")
+                    .add($selector.find("form"))
+                    .has("[data-val=true]");
+
+            $selector.find("[data-val=true]").each(function () {
+                $jQval.unobtrusive.parseElement(this, true);
+            });
+
+            $forms.each(function () {
+                var info = validationInfo(this);
+                if (info) {
+                    info.attachValidation();
+                }
+            });
+        }
+    };
+
+    adapters = $jQval.unobtrusive.adapters;
+
+    adapters.add = function (adapterName, params, fn) {
+        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.</summary>
+        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
+        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
+        /// <param name="params" type="Array" optional="true">[Optional] An array of parameter names (strings) that will
+        /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
+        /// mmmm is the parameter name).</param>
+        /// <param name="fn" type="Function">The function to call, which adapts the values from the HTML
+        /// attributes into jQuery Validate rules and/or messages.</param>
+        /// <returns type="jQuery.validator.unobtrusive.adapters" />
+        if (!fn) {  // Called with no params, just a function
+            fn = params;
+            params = [];
+        }
+        this.push({ name: adapterName, params: params, adapt: fn });
+        return this;
+    };
+
+    adapters.addBool = function (adapterName, ruleName) {
+        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+        /// the jQuery Validate validation rule has no parameter values.</summary>
+        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
+        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
+        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
+        /// of adapterName will be used instead.</param>
+        /// <returns type="jQuery.validator.unobtrusive.adapters" />
+        return this.add(adapterName, function (options) {
+            setValidationValues(options, ruleName || adapterName, true);
+        });
+    };
+
+    adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
+        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+        /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
+        /// one for min-and-max). The HTML parameters are expected to be named -min and -max.</summary>
+        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
+        /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).</param>
+        /// <param name="minRuleName" type="String">The name of the jQuery Validate rule to be used when you only
+        /// have a minimum value.</param>
+        /// <param name="maxRuleName" type="String">The name of the jQuery Validate rule to be used when you only
+        /// have a maximum value.</param>
+        /// <param name="minMaxRuleName" type="String">The name of the jQuery Validate rule to be used when you
+        /// have both a minimum and maximum value.</param>
+        /// <param name="minAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
+        /// contains the minimum value. The default is "min".</param>
+        /// <param name="maxAttribute" type="String" optional="true">[Optional] The name of the HTML attribute that
+        /// contains the maximum value. The default is "max".</param>
+        /// <returns type="jQuery.validator.unobtrusive.adapters" />
+        return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
+            var min = options.params.min,
+                max = options.params.max;
+
+            if (min && max) {
+                setValidationValues(options, minMaxRuleName, [min, max]);
+            }
+            else if (min) {
+                setValidationValues(options, minRuleName, min);
+            }
+            else if (max) {
+                setValidationValues(options, maxRuleName, max);
+            }
+        });
+    };
+
+    adapters.addSingleVal = function (adapterName, attribute, ruleName) {
+        /// <summary>Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
+        /// the jQuery Validate validation rule has a single value.</summary>
+        /// <param name="adapterName" type="String">The name of the adapter to be added. This matches the name used
+        /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).</param>
+        /// <param name="attribute" type="String">[Optional] The name of the HTML attribute that contains the value.
+        /// The default is "val".</param>
+        /// <param name="ruleName" type="String" optional="true">[Optional] The name of the jQuery Validate rule. If not provided, the value
+        /// of adapterName will be used instead.</param>
+        /// <returns type="jQuery.validator.unobtrusive.adapters" />
+        return this.add(adapterName, [attribute || "val"], function (options) {
+            setValidationValues(options, ruleName || adapterName, options.params[attribute]);
+        });
+    };
+
+    $jQval.addMethod("__dummy__", function (value, element, params) {
+        return true;
+    });
+
+    $jQval.addMethod("regex", function (value, element, params) {
+        var match;
+        if (this.optional(element)) {
+            return true;
+        }
+
+        match = new RegExp(params).exec(value);
+        return (match && (match.index === 0) && (match[0].length === value.length));
+    });
+
+    $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
+        var match;
+        if (nonalphamin) {
+            match = value.match(/\W/g);
+            match = match && match.length >= nonalphamin;
+        }
+        return match;
+    });
+
+    if ($jQval.methods.extension) {
+        adapters.addSingleVal("accept", "mimtype");
+        adapters.addSingleVal("extension", "extension");
+    } else {
+        // for backward compatibility, when the 'extension' validation method does not exist, such as with versions
+        // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
+        // validating the extension, and ignore mime-type validations as they are not supported.
+        adapters.addSingleVal("extension", "extension", "accept");
+    }
+
+    adapters.addSingleVal("regex", "pattern");
+    adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
+    adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
+    adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
+    adapters.add("equalto", ["other"], function (options) {
+        var prefix = getModelPrefix(options.element.name),
+            other = options.params.other,
+            fullOtherName = appendModelPrefix(other, prefix),
+            element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
+
+        setValidationValues(options, "equalTo", element);
+    });
+    adapters.add("required", function (options) {
+        // jQuery Validate equates "required" with "mandatory" for checkbox elements
+        if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
+            setValidationValues(options, "required", true);
+        }
+    });
+    adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
+        var value = {
+            url: options.params.url,
+            type: options.params.type || "GET",
+            data: {}
+        },
+            prefix = getModelPrefix(options.element.name);
+
+        $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
+            var paramName = appendModelPrefix(fieldName, prefix);
+            value.data[paramName] = function () {
+                var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
+                // For checkboxes and radio buttons, only pick up values from checked fields.
+                if (field.is(":checkbox")) {
+                    return field.filter(":checked").val() || field.filter(":hidden").val() || '';
+                }
+                else if (field.is(":radio")) {
+                    return field.filter(":checked").val() || '';
+                }
+                return field.val();
+            };
+        });
+
+        setValidationValues(options, "remote", value);
+    });
+    adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
+        if (options.params.min) {
+            setValidationValues(options, "minlength", options.params.min);
+        }
+        if (options.params.nonalphamin) {
+            setValidationValues(options, "nonalphamin", options.params.nonalphamin);
+        }
+        if (options.params.regex) {
+            setValidationValues(options, "regex", options.params.regex);
+        }
+    });
+    adapters.add("fileextensions", ["extensions"], function (options) {
+        setValidationValues(options, "extension", options.params.extensions);
+    });
+
+    $(function () {
+        $jQval.unobtrusive.parse(document);
+    });
+
+    return $jQval.unobtrusive;
+}));

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 5 - 0
TeamModelOS.OfficeDoc.Test/Scripts/jquery.validate.unobtrusive.min.js


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 1406 - 0
TeamModelOS.OfficeDoc.Test/Scripts/modernizr-2.8.3.js


+ 240 - 0
TeamModelOS.OfficeDoc.Test/TeamModelOS.OfficeDoc.Test.csproj

@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
+  <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>
+    <ProductVersion>
+    </ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{E5E2E853-AAE9-45D8-A59B-BC054434F9AD}</ProjectGuid>
+    <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>TeamModelOS.OfficeDoc.Test</RootNamespace>
+    <AssemblyName>TeamModelOS.OfficeDoc.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
+    <MvcBuildViews>false</MvcBuildViews>
+    <UseIISExpress>true</UseIISExpress>
+    <Use64BitIISExpress />
+    <IISExpressSSLPort>44319</IISExpressSSLPort>
+    <IISExpressAnonymousAuthentication />
+    <IISExpressWindowsAuthentication />
+    <IISExpressUseClassicPipelineMode />
+    <UseGlobalApplicationHostFile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="DocumentFormat.OpenXml, Version=2.9.1.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
+      <HintPath>..\packages\DocumentFormat.OpenXml.2.9.1\lib\net46\DocumentFormat.OpenXml.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="Microsoft.Office.Interop.PowerPoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
+      <HintPath>..\packages\Microsoft.Office.Interop.PowerPoint.15.0.4420.1017\lib\net20\Microsoft.Office.Interop.PowerPoint.dll</HintPath>
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.IO.FileSystem.Primitives, Version=4.0.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll</HintPath>
+      <Private>True</Private>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="System.IO.Packaging, Version=4.0.3.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
+      <HintPath>..\packages\System.IO.Packaging.4.5.0\lib\net46\System.IO.Packaging.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Web.DynamicData" />
+    <Reference Include="System.Web.Entity" />
+    <Reference Include="System.Web.ApplicationServices" />
+    <Reference Include="System.ComponentModel.DataAnnotations" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Web.Extensions" />
+    <Reference Include="System.Web.Abstractions" />
+    <Reference Include="System.Web.Routing" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Web.Services" />
+    <Reference Include="System.EnterpriseServices" />
+    <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Net.Http">
+    </Reference>
+    <Reference Include="System.Net.Http.WebRequest">
+    </Reference>
+    <Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.Optimization">
+      <HintPath>..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <Private>True</Private>
+      <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.11.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="WebGrease">
+      <Private>True</Private>
+      <HintPath>..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
+    </Reference>
+    <Reference Include="Antlr3.Runtime">
+      <Private>True</Private>
+      <HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
+    </Reference>
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform">
+      <HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="App_Start\BundleConfig.cs" />
+    <Compile Include="App_Start\FilterConfig.cs" />
+    <Compile Include="App_Start\RouteConfig.cs" />
+    <Compile Include="Controllers\HomeController.cs" />
+    <Compile Include="Global.asax.cs">
+      <DependentUpon>Global.asax</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Content\bootstrap-theme.css" />
+    <Content Include="Content\bootstrap-theme.min.css" />
+    <Content Include="Content\bootstrap.css" />
+    <Content Include="Content\bootstrap.min.css" />
+    <Content Include="favicon.ico" />
+    <Content Include="fonts\glyphicons-halflings-regular.svg" />
+    <Content Include="Global.asax" />
+    <Content Include="Content\Site.css" />
+    <Content Include="Scripts\bootstrap.js" />
+    <Content Include="Scripts\bootstrap.min.js" />
+    <None Include="Scripts\jquery-3.3.1.intellisense.js" />
+    <Content Include="Scripts\jquery-3.3.1.js" />
+    <Content Include="Scripts\jquery-3.3.1.min.js" />
+    <Content Include="Scripts\jquery-3.3.1.slim.js" />
+    <Content Include="Scripts\jquery-3.3.1.slim.min.js" />
+    <None Include="Scripts\jquery.validate-vsdoc.js" />
+    <Content Include="Scripts\jquery.validate.js" />
+    <Content Include="Scripts\jquery.validate.min.js" />
+    <Content Include="Scripts\jquery.validate.unobtrusive.js" />
+    <Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
+    <Content Include="Scripts\modernizr-2.8.3.js" />
+    <Content Include="Web.config" />
+    <Content Include="Web.Debug.config">
+      <DependentUpon>Web.config</DependentUpon>
+    </Content>
+    <Content Include="Web.Release.config">
+      <DependentUpon>Web.config</DependentUpon>
+    </Content>
+    <Content Include="Views\Web.config" />
+    <Content Include="Views\_ViewStart.cshtml" />
+    <Content Include="Views\Shared\Error.cshtml" />
+    <Content Include="Views\Shared\_Layout.cshtml" />
+    <Content Include="Views\Home\About.cshtml" />
+    <Content Include="Views\Home\Contact.cshtml" />
+    <Content Include="Views\Home\Index.cshtml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="App_Data\" />
+    <Folder Include="Models\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="fonts\glyphicons-halflings-regular.woff2" />
+    <Content Include="fonts\glyphicons-halflings-regular.woff" />
+    <Content Include="fonts\glyphicons-halflings-regular.ttf" />
+    <Content Include="fonts\glyphicons-halflings-regular.eot" />
+    <Content Include="Content\bootstrap.min.css.map" />
+    <Content Include="Content\bootstrap.css.map" />
+    <Content Include="Content\bootstrap-theme.min.css.map" />
+    <Content Include="Content\bootstrap-theme.css.map" />
+    <None Include="packages.config" />
+    <Content Include="Scripts\jquery-3.3.1.slim.min.map" />
+    <Content Include="Scripts\jquery-3.3.1.min.map" />
+  </ItemGroup>
+  <PropertyGroup>
+    <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+    <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+  </PropertyGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
+  <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
+    <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
+  </Target>
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+        <WebProjectProperties>
+          <UseIIS>True</UseIIS>
+          <AutoAssignPort>True</AutoAssignPort>
+          <DevelopmentServerPort>49718</DevelopmentServerPort>
+          <DevelopmentServerVPath>/</DevelopmentServerVPath>
+          <IISUrl>https://localhost:44319/</IISUrl>
+          <NTLMAuthentication>False</NTLMAuthentication>
+          <UseCustomServer>False</UseCustomServer>
+          <CustomServerUrl>
+          </CustomServerUrl>
+          <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+        </WebProjectProperties>
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.0\build\net46\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
+  </Target>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target> -->
+</Project>

+ 7 - 0
TeamModelOS.OfficeDoc.Test/Views/Home/About.cshtml

@@ -0,0 +1,7 @@
+@{
+    ViewBag.Title = "About";
+}
+<h2>@ViewBag.Title.</h2>
+<h3>@ViewBag.Message</h3>
+
+<p>Use this area to provide additional information.</p>

+ 17 - 0
TeamModelOS.OfficeDoc.Test/Views/Home/Contact.cshtml

@@ -0,0 +1,17 @@
+@{
+    ViewBag.Title = "Contact";
+}
+<h2>@ViewBag.Title.</h2>
+<h3>@ViewBag.Message</h3>
+
+<address>
+    One Microsoft Way<br />
+    Redmond, WA 98052-6399<br />
+    <abbr title="Phone">P:</abbr>
+    425.555.0100
+</address>
+
+<address>
+    <strong>Support:</strong>   <a href="mailto:Support@example.com">Support@example.com</a><br />
+    <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
+</address>

+ 31 - 0
TeamModelOS.OfficeDoc.Test/Views/Home/Index.cshtml

@@ -0,0 +1,31 @@
+@{
+    ViewBag.Title = "Home Page";
+}
+
+<div class="jumbotron">
+    <h1>ASP.NET</h1>
+    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
+    <p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
+</div>
+
+<div class="row">
+    <div class="col-md-4">
+        <h2>Getting started</h2>
+        <p>
+            ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
+            enables a clean separation of concerns and gives you full control over markup
+            for enjoyable, agile development.
+        </p>
+        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more &raquo;</a></p>
+    </div>
+    <div class="col-md-4">
+        <h2>Get more libraries</h2>
+        <p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
+        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more &raquo;</a></p>
+    </div>
+    <div class="col-md-4">
+        <h2>Web Hosting</h2>
+        <p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
+        <p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more &raquo;</a></p>
+    </div>
+</div>

+ 14 - 0
TeamModelOS.OfficeDoc.Test/Views/Shared/Error.cshtml

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <meta name="viewport" content="width=device-width" />
+    <title>错误</title>
+</head>
+<body>
+    <hgroup>
+        <h1>错误。</h1>
+        <h2>处理你的请求时出错。</h2>
+    </hgroup>
+</body>
+</html>

+ 43 - 0
TeamModelOS.OfficeDoc.Test/Views/Shared/_Layout.cshtml

@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+    <meta charset="utf-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>@ViewBag.Title - 我的 ASP.NET 应用程序</title>
+    @Styles.Render("~/Content/css")
+    @Scripts.Render("~/bundles/modernizr")
+</head>
+<body>
+    <div class="navbar navbar-inverse navbar-fixed-top">
+        <div class="container">
+            <div class="navbar-header">
+                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                    <span class="icon-bar"></span>
+                </button>
+                @Html.ActionLink("应用程序名称", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" })
+            </div>
+            <div class="navbar-collapse collapse">
+                <ul class="nav navbar-nav">
+                    <li>@Html.ActionLink("主页", "Index", "Home")</li>
+                    <li>@Html.ActionLink("关于", "About", "Home")</li>
+                    <li>@Html.ActionLink("联系方式", "Contact", "Home")</li>
+                </ul>
+            </div>
+        </div>
+    </div>
+    <div class="container body-content">
+        @RenderBody()
+        <hr />
+        <footer>
+            <p>&copy; @DateTime.Now.Year - 我的 ASP.NET 应用程序</p>
+        </footer>
+    </div>
+
+    @Scripts.Render("~/bundles/jquery")
+    @Scripts.Render("~/bundles/bootstrap")
+    @RenderSection("scripts", required: false)
+</body>
+</html>

+ 43 - 0
TeamModelOS.OfficeDoc.Test/Views/Web.config

@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+
+<configuration>
+  <configSections>
+    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+    </sectionGroup>
+  </configSections>
+
+  <system.web.webPages.razor>
+    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+    <pages pageBaseType="System.Web.Mvc.WebViewPage">
+      <namespaces>
+        <add namespace="System.Web.Mvc" />
+        <add namespace="System.Web.Mvc.Ajax" />
+        <add namespace="System.Web.Mvc.Html" />
+        <add namespace="System.Web.Optimization"/>
+        <add namespace="System.Web.Routing" />
+        <add namespace="TeamModelOS.OfficeDoc.Test" />
+      </namespaces>
+    </pages>
+  </system.web.webPages.razor>
+
+  <appSettings>
+    <add key="webpages:Enabled" value="false" />
+  </appSettings>
+
+  <system.webServer>
+    <handlers>
+      <remove name="BlockViewHandler"/>
+      <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+    </handlers>
+  </system.webServer>
+
+  <system.web>
+    <compilation>
+      <assemblies>
+        <add assembly="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+      </assemblies>
+    </compilation>
+  </system.web>
+</configuration>

+ 3 - 0
TeamModelOS.OfficeDoc.Test/Views/_ViewStart.cshtml

@@ -0,0 +1,3 @@
+@{
+    Layout = "~/Views/Shared/_Layout.cshtml";
+}

+ 30 - 0
TeamModelOS.OfficeDoc.Test/Web.Debug.config

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- For more information on using Web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=301874 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+  <!--
+    在下例中,“SetAttributes”转换将更改
+    “connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
+    特性“name”时使用“ReleaseSQLServer”。
+
+    <connectionStrings>
+      <add name="MyDB"
+        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+    </connectionStrings>
+  -->
+  <system.web>
+    <!--
+      在以下示例中,"Replace" 转换将替换 Web.config 文件的
+      整个 <customErrors> 节。
+      请注意,由于在 <system.web> 节点下只有一个
+       customErrors 节,因此无需使用 "xdt:Locator" 属性。
+
+      <customErrors defaultRedirect="GenericError.htm"
+        mode="RemoteOnly" xdt:Transform="Replace">
+        <error statusCode="500" redirect="InternalError.htm"/>
+      </customErrors>
+    -->
+  </system.web>
+</configuration>

+ 31 - 0
TeamModelOS.OfficeDoc.Test/Web.Release.config

@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- For more information on using Web.config transformation visit https://go.microsoft.com/fwlink/?LinkId=301874 -->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+  <!--
+    在下例中,“SetAttributes”转换将更改
+    “connectionString”的值,仅在“Match”定位器找到值为“MyDB”的
+    特性“name”时使用“ReleaseSQLServer”。
+
+    <connectionStrings>
+      <add name="MyDB"
+        connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+        xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+    </connectionStrings>
+  -->
+  <system.web>
+    <compilation xdt:Transform="RemoveAttributes(debug)" />
+    <!--
+      在以下示例中,"Replace" 转换将替换 Web.config 文件的
+      整个 <customErrors> 节。
+      请注意,由于在 <system.web> 节点下只有一个
+       customErrors 节,因此无需使用 "xdt:Locator" 属性。
+
+      <customErrors defaultRedirect="GenericError.htm"
+        mode="RemoteOnly" xdt:Transform="Replace">
+        <error statusCode="500" redirect="InternalError.htm"/>
+      </customErrors>
+    -->
+  </system.web>
+</configuration>

+ 55 - 0
TeamModelOS.OfficeDoc.Test/Web.config

@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  有关如何配置 ASP.NET 应用程序的详细信息,请访问
+  https://go.microsoft.com/fwlink/?LinkId=301880
+  -->
+<configuration>
+  <appSettings>
+    <add key="webpages:Version" value="3.0.0.0" />
+    <add key="webpages:Enabled" value="false" />
+    <add key="ClientValidationEnabled" value="true" />
+    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
+  </appSettings>
+  <system.web>
+    <compilation debug="true" targetFramework="4.7.2" />
+    <httpRuntime targetFramework="4.7.2" />
+  </system.web>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
+        <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
+        <bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
+        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
+        <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
+        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
+        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+        <bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
+  <system.codedom>
+    <compilers>
+      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
+      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
+    </compilers>
+  </system.codedom>
+</configuration>

BIN
TeamModelOS.OfficeDoc.Test/favicon.ico


BIN
TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.eot


La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 288 - 0
TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.svg


BIN
TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.ttf


BIN
TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.woff


BIN
TeamModelOS.OfficeDoc.Test/fonts/glyphicons-halflings-regular.woff2


+ 25 - 0
TeamModelOS.OfficeDoc.Test/packages.config

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Antlr" version="3.5.0.2" targetFramework="net472" />
+  <package id="bootstrap" version="3.4.1" targetFramework="net472" />
+  <package id="DocumentFormat.OpenXml" version="2.9.1" targetFramework="net472" />
+  <package id="jQuery" version="3.3.1" targetFramework="net472" />
+  <package id="jQuery.Validation" version="1.17.0" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Mvc.zh-Hans" version="5.2.7" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Razor.zh-Hans" version="3.2.7" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net472" />
+  <package id="Microsoft.AspNet.Web.Optimization.zh-Hans" version="1.1.3" targetFramework="net472" />
+  <package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net472" />
+  <package id="Microsoft.AspNet.WebPages.zh-Hans" version="3.2.7" targetFramework="net472" />
+  <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.0" targetFramework="net472" />
+  <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.11" targetFramework="net472" />
+  <package id="Microsoft.Office.Interop.PowerPoint" version="15.0.4420.1017" targetFramework="net472" />
+  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net472" />
+  <package id="Modernizr" version="2.8.3" targetFramework="net472" />
+  <package id="Newtonsoft.Json" version="11.0.1" targetFramework="net472" />
+  <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="net472" />
+  <package id="System.IO.Packaging" version="4.5.0" targetFramework="net472" />
+  <package id="WebGrease" version="1.6.0" targetFramework="net472" />
+</packages>