浏览代码

Merge branch 'master' of http://121.4.203.192:9000/mingxue/front

唐宏才 3 年之前
父节点
当前提交
208a847796
共有 79 个文件被更改,包括 4405 次插入2625 次删除
  1. 18 5
      doc/Mind/ElectiveGeneration.cs
  2. 0 2
      doc/Mind/FacultyEstimate.cs
  3. 1 1
      doc/Mind/PrimaryElective.cs
  4. 10 10
      mock/modules/elective-generation.js
  5. 215 0
      mock/modules/elective-subject.js
  6. 1 0
      package.json
  7. 33 0
      src/api/webApi/elective/ selected-subject.js
  8. 68 4
      src/api/webApi/elective/generation.js
  9. 7 7
      src/api/webApi/mxjbSelectedScore.js
  10. 53 53
      src/api/webApi/mxjbSelectedScoreImport.js
  11. 30 0
      src/api/webApi/professlib.js
  12. 49 0
      src/api/webApi/vocation.js
  13. 8 0
      src/api/webApi/webQue.js
  14. 6 1
      src/assets/styles/common.scss
  15. 217 200
      src/assets/styles/index.scss
  16. 44 44
      src/assets/styles/variables.scss
  17. 17 8
      src/common/mx-config.js
  18. 6 0
      src/components/Cache/modules/mx-select-translate-mixin.js
  19. 3 1
      src/components/Cache/mx-cache-mixin.js
  20. 20 0
      src/components/MxCondition/condition-object/condition-location.js
  21. 29 0
      src/components/MxCondition/condition-object/condition-shiftline-level.js
  22. 29 0
      src/components/MxCondition/condition-object/condition-shiftline-type.js
  23. 23 0
      src/components/MxCondition/condition-object/condition-shiftline-university.js
  24. 31 0
      src/components/MxCondition/condition-object/condition-shiftline-year.js
  25. 24 0
      src/components/MxCondition/condition-object/condition-year-admission.js
  26. 20 0
      src/components/MxCondition/condition-object/condition-yfyd-location.js
  27. 25 0
      src/components/MxCondition/condition-object/condition-yfyd-mode.js
  28. 24 0
      src/components/MxCondition/condition-object/condition-yfyd-year.js
  29. 97 0
      src/components/MxSearch/mx-search-group.vue
  30. 118 0
      src/components/VueEsign/index.vue
  31. 3 1
      src/main.js
  32. 5 5
      src/router/index.js
  33. 22 0
      src/utils/index.js
  34. 1 0
      src/utils/request.js
  35. 6 1
      src/views/career/components/UniversitiesLine.vue
  36. 81 72
      src/views/career/components/UniversitiesLineTable.vue
  37. 75 83
      src/views/career/components/VolunteerList.vue
  38. 187 206
      src/views/career/components/careerTestReport.vue
  39. 32 36
      src/views/career/index.vue
  40. 1 1
      src/views/career/plan/ProfessLib.vue
  41. 433 0
      src/views/career/plan/new-profess-detail.vue
  42. 217 0
      src/views/career/plan/new-profess-lib.vue
  43. 39 0
      src/views/career/subject/choose-subject.vue
  44. 1 1
      src/views/career/subject/majorChoice.vue
  45. 0 318
      src/views/career/subject/majorChoice.vue.unused
  46. 71 55
      src/views/career/subject/subjectChoice.vue
  47. 0 854
      src/views/career/subject/subjectChoice.vue.unused
  48. 463 0
      src/views/career/vocation/new-detail.vue
  49. 178 0
      src/views/career/vocation/new-index.vue
  50. 0 0
      src/views/career/vocation/old-detail.vue
  51. 1 1
      src/views/career/vocation/old-index.vue
  52. 1 1
      src/views/career/zhiyuan/ShiftLine.vue
  53. 1 1
      src/views/career/zhiyuan/SimulatedVolunteer.vue
  54. 159 200
      src/views/career/zhiyuan/batch.vue
  55. 134 133
      src/views/career/zhiyuan/gkmc.vue
  56. 138 236
      src/views/career/zhiyuan/yfyd.vue
  57. 17 10
      src/views/elective/dispatch/components/choose-class.vue
  58. 16 16
      src/views/elective/dispatch/components/dispatch-table.vue
  59. 7 1
      src/views/elective/dispatch/components/edit-group.vue
  60. 17 0
      src/views/elective/dispatch/detail.vue
  61. 15 1
      src/views/elective/dispatch/index.vue
  62. 81 8
      src/views/elective/generation/components/elective-generation-commands.vue
  63. 18 4
      src/views/elective/generation/components/elective-generation-master.vue
  64. 69 0
      src/views/elective/generation/components/elective-generation-push-setting.vue
  65. 20 0
      src/views/elective/generation/components/elective-generation-table.vue
  66. 1 1
      src/views/elective/generation/detail.vue
  67. 13 0
      src/views/elective/report/index.vue
  68. 1 0
      src/views/idc/EvaluationDatabase/detailList.bak.vue
  69. 2 2
      src/views/permission/components/round-score-query.vue
  70. 1 22
      src/views/permission/components/round-settings.vue
  71. 0 1
      src/views/permission/components/steps/round-setting-publish.vue
  72. 40 0
      src/views/system/user/profile/components/choose-subject-dialog.vue
  73. 74 0
      src/views/system/user/profile/components/groups-match.vue
  74. 233 0
      src/views/system/user/profile/components/report-table.vue
  75. 101 0
      src/views/system/user/profile/components/select-subject.vue
  76. 61 0
      src/views/system/user/profile/components/single-group-match.vue
  77. 93 0
      src/views/system/user/profile/components/test-drage.vue
  78. 30 1
      src/views/system/user/profile/round-select.vue
  79. 20 17
      src/views/videocourse/video_course.vue

+ 18 - 5
doc/Mind/ElectiveGeneration.cs

@@ -94,7 +94,7 @@ namespace mxdemo.Mind
 
         // + new fields
         int disenrollCount; // 未录取学生数量 - 用于图表展示,或者内部判定allMatched
-        // bool enablePushNextDMGeneration; // 是否可以强制推进下一代决策进程 = 当前为报名进程,且学生均已报名
+        bool enablePushNextDMGeneration; // 是否可以强制推进下一代决策进程 = 当前为报名进程,且学生均已报名
         bool allowDMAlgorithm; // 当前为决策进程,支持运行匹配算法(BackTrackingDM,FinalAdjustDM)
         bool doneDMAlgorithm; // 当前为决策进程,且已经运行了匹配算法
         bool allowForce; // 当前进程代是否允许强制调剂录取(原来BackTrackingDM,FinalAdjustDM,RankBalance),现在调整为(FinalAdjustDM,RankBalance)
@@ -112,6 +112,8 @@ namespace mxdemo.Mind
         DateTime end;
         bool onlyRecommand; // 仅允许学生选择推荐组合, 否则允许学生填报有空缺的组合
         bool onlyAgree; // 调剂阶段,只允许学生选择同意, 否则允许学生拒绝
+        bool useRecommandWhileDisagree; // 如果拒绝,按推荐报名处理
+        bool useRecommandWhileNonaction; // 如果不报名,按推荐报名处理
     }
 
     public class ElectiveEsign
@@ -206,6 +208,11 @@ namespace mxdemo.Mind
 
     public interface IElectiveService
     {
+        /// <summary>
+        /// 校长-选科状态
+        /// </summary>
+        RoundForFlow getElectiveStatus({year, roundId});
+
         #region getElectiveSummary
         /// <summary>
         /// 选科过程中的统计数据值,除了要展示之外还需要做查询支持
@@ -299,7 +306,7 @@ namespace mxdemo.Mind
          *  {'forcedCount', '调剂录取人数'} -- 到此阶段为止,调剂录取人数
          *  {'esignedCount', '已签人数'} -- 到此阶段为止,触发的有效签名统计 这个先
          *  {'esigningCount', '待签人数'} -- 到此阶段为止,阶段触发有效的应签未签统计 [4.18 因为签字提前和强制调剂更改,所以只有FinalAdjustDM RankBalance这两代会产生待签数据了]
-         *
+     注意:上述一与二的数据不能随意变动,会影响后续图表展示
          *  三、ElectiveGenerationSummary.categories 只统计某代的数据
          *  A PrimaryDM
          *  {'indicateCount','指标'} -- 正负表示超过设置的人数,负数表示低于设置的人数
@@ -383,6 +390,12 @@ namespace mxdemo.Mind
         {
             ElectiveGenerationFlowHistory[] histories; // 4.19 当前student截止到当前代的全部generation flow data数据,但需要转换为业务格式
 
+            // 5.5 hht 允许此条数据触发强制调剂。具体进行到哪代可以调剂、哪些数据可以调剂???
+            // 5.5 hht 暂定:所有学生录取完毕的决策代或者二次补录决策代允许调剂,可调剂对象为已录取(包含正常录与调剂录)和二级补录决策中未录取的。
+            public bool enableForce;
+            // 5.5 hht 如果允许强制调剂,禁止调剂到哪个组合?一般禁止调剂到被录取组合,因为原地不动不叫调剂。没有禁止的给0或者null
+            public int disableForceGroupId;
+
             public long id { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
             public string category { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
             public EnumElectiveGeneration generation { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
@@ -430,8 +443,8 @@ namespace mxdemo.Mind
         /// </summary>
         /// <param name="roundId"></param>
         /// <param name="generation">当前进程代</param>
-        /// <param name="groupId">针对组合的查询会传,否则传0或者''(具体看返回的时候给的什么值,比如未报名的)</param>
-        /// <param name="queryCode"></param>
+        /// <param name="groupId">针对组合的查询会传,否则传0或者''(具体看返回的时候给的什么值,比如未报名的)</param> 按行
+        /// <param name="queryCode"></param> 按列
         /// <returns></returns>
         ElectiveGenerationDetailWrapper getElectiveGenerationDetails(int pageNo, int pageSize, int roundId, int generation, int groupId, string queryCode);
 
@@ -491,7 +504,7 @@ namespace mxdemo.Mind
         /// <summary>
         /// 决策完毕时,推进下一代进行
         /// </summary>
-        /// <param name="setting"></param>
+        /// <param name="setting">推进配置</param>
         void pushGenerationSetting(FlowPushSetting setting);
 
         /// <summary>

+ 0 - 2
doc/Mind/FacultyEstimate.cs

@@ -27,8 +27,6 @@ namespace mxdemo.Mind
         public int actualClassesCount; // 实际课时
         public int missingClassesCount; // 缺少课时,正数表示缺的,负数表示超的
         public int missingTeacherCount; // 缺少老师,正负同上
-
-        public bool completed; // 是否计算结束
     }
 
     public class GroupSetting

+ 1 - 1
doc/Mind/PrimaryElective.cs

@@ -124,7 +124,7 @@ namespace mxdemo.Mind
         // 学生获取自选专业及匹配情况
         List<ElectiveOptionalMajor> getOptionalMajors();
 
-        // 初选报名。这里简化原型里的操作,直接提交,如需排序,调sortElectiveSelected接口,并刷新getPrimaryElectives
+        // 初选报名。这里简化原型里的操作,直接提交,如需排序,调sortElectiveSelected接口,并刷新getPrimaryElectivesx
         void submitPrimaryElective(ElectiveSelectModel model);
 
         // 调整排序。这里简化原型里的操作,并刷新getPrimaryElectives

+ 10 - 10
mock/modules/elective-generation.js

@@ -1,13 +1,13 @@
 const Mock = require('mockjs')
 const Random = Mock['Random']
 
-const mockGeneration = 8 // primary
+const mockGeneration = 7 // primary
 const mockGroups = [1, 2, 3, 4, 5, 6]
 const mockPreferenceCount = 3 // 1 or 3 // 1志愿/3志愿
 
 module.exports = [
   {
-    url: '/mock/front/report/getElectiveStatus',
+    url: '/mock/front/elective/generation/getElectiveStatus',
     type: 'get',
     response: config => {
       return {
@@ -27,21 +27,21 @@ module.exports = [
             limitPerson: false,
             rankOut: false
           })),
-          allMatched: Random.boolean(1, 10, 8),
+          allMatched: true,
           currentGeneration: mockGeneration,
 
           // +
-          disenrollCount: Random.integer(20, 100), // 未录人数
-          enablePushNextDMGeneration: Random.boolean(1, 10, 8),
+          disenrollCount: 0, // 未录人数
+          enablePushNextDMGeneration: true,
           allowDMAlgorithm: true,
-          doneDMAlgorithm: Random.boolean(1, 10, 8),
-          allowForce: Random.boolean(1, 10, 8)
+          doneDMAlgorithm: true,
+          allowForce: true,
         }
       }
     }
   },
   {
-    url: '/mock/front/report/getElectiveSummary',
+    url: '/mock/front/elective/generation/getElectiveSummary',
     type: 'get',
     response: config => {
       const results = []
@@ -458,7 +458,7 @@ module.exports = [
     }
   },
   {
-    url: '/mock/front/report/getElectiveGenerationDetails',
+    url: '/mock/front/elective/generation/getElectiveGenerationDetails',
     type: 'get',
     response: config => {
       return {
@@ -503,7 +503,7 @@ module.exports = [
     }
   },
   {
-    url: '/mock/front/report/getGenerationOptionalMajorsBatch',
+    url: '/mock/front/elective/generation/getGenerationOptionalMajorsBatch',
     type: 'get',
     response: config => {
       let studentIds = config.query.studentIds

+ 215 - 0
mock/modules/elective-subject.js

@@ -0,0 +1,215 @@
+
+const Mock = require('mockjs')
+
+module.exports = [
+  {
+    url: '/mock/front/elective/optionalMajors',
+    type:'get',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data:[
+          {
+            collegeId: 1,
+            collegeName: '北京大学',
+            majorCategoryName: '计算机技术',  // 专业类别
+            majorCategoryCode: '1',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [3,2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 2,
+            collegeName: '湖南大学',
+            majorCategoryName: '医学',  // 专业类别
+            majorCategoryCode: '2',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 3,
+            collegeName: '中南大学',
+            majorCategoryName: '法学',  // 专业类别
+            majorCategoryCode: '3',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1,2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 3,
+            collegeName: '中南大学',
+            majorCategoryName: '土木工程',  // 专业类别
+            majorCategoryCode: 'a',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1], // 匹配哪几个组合?
+          }
+        ]
+      }
+    }
+  },
+  {
+    url: '/mock/front/elective/optionalMajors',
+    type:'get',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data:[
+          {
+            collegeId: 1,
+            collegeName: '北京大学',
+            majorCategoryName: '计算机技术',  // 专业类别
+            majorCategoryCode: '1',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [3,2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 2,
+            collegeName: '湖南大学',
+            majorCategoryName: '医学',  // 专业类别
+            majorCategoryCode: '2',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 3,
+            collegeName: '中南大学',
+            majorCategoryName: '法学',  // 专业类别
+            majorCategoryCode: '3',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1,2], // 匹配哪几个组合?
+          },
+          {
+            collegeId: 3,
+            collegeName: '中南大学',
+            majorCategoryName: '土木工程',  // 专业类别
+            majorCategoryCode: 'a',  // 专业编码
+            majors: [],          // 类别下分类
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1], // 匹配哪几个组合?
+          }
+        ]
+      }
+    }
+  },
+  // 评测推荐专业
+  {
+    url: '/mock/front/elective/evaluationMajors',
+    type:'get',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data:[
+          {
+            majorCategoryName: '法学',  // 专业类别
+            majorCategoryCode: '1',  // 专业编码
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [3,2], // 匹配哪几个组合?
+          },
+          {
+            majorCategoryName: '心理学',  // 专业类别
+            majorCategoryCode: '2',  // 专业编码
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [2], // 匹配哪几个组合?
+          },
+          {
+            majorCategoryName: '管理学',  // 专业类别
+            majorCategoryCode: '3',  // 专业编码
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1,2], // 匹配哪几个组合?
+          },
+          {
+            majorCategoryName: '土木工程',  // 专业类别
+            majorCategoryCode: 'a',  // 专业编码
+            limitationA: '',
+            limitationB: '',
+            matchedGroupIds: [1,3], // 匹配哪几个组合?
+          }
+        ]
+      }
+    }
+  },
+  {
+    url: '/mock/front/elective/primaryElectives',
+    type:'get',
+    response: config => {
+      return {
+        code: 200,
+        msg: 'success',
+        data:[
+          {
+            groupId: 1, // 组合
+            groupName: '物化生', // 名称
+            classCount: 5,  // 班级数
+            personCount: 200,  // 限制人数
+            personInTime: 100,  // 实时人数
+            rankInGroup: 53, // 选科实时排名
+            rankInGrade: 64, // 选科全校排名
+            allowSelect: true, // 是否可以报名
+            disabledReason: '不知道', // 不可报名时的原因
+            selected:  false, // 报名状态
+            selectedRank:  1, // 多志愿时的排序
+          },
+          {
+            groupId: 2, // 组合
+            groupName: '物化政', // 名称
+            classCount: 4,  // 班级数
+            personCount: 180,  // 限制人数
+            personInTime: 60,  // 实时人数
+            rankInGroup: 32, // 选科实时排名
+            rankInGrade: 67, // 选科全校排名
+            allowSelect: true, // 是否可以报名
+            disabledReason: '不知道', // 不可报名时的原因
+            selected:  false, // 报名状态
+            selectedRank:  2, // 多志愿时的排序
+          },
+          {
+            groupId: 3, // 组合
+            groupName: '历化政', // 名称
+            classCount: 3,  // 班级数
+            personCount: 180,  // 限制人数
+            personInTime: 60,  // 实时人数
+            rankInGroup: 32, // 选科实时排名
+            rankInGrade: 67, // 选科全校排名
+            allowSelect: true, // 是否可以报名
+            disabledReason: '不知道', // 不可报名时的原因
+            selected:  false, // 报名状态
+            selectedRank:  2, // 多志愿时的排序
+          },
+          {
+            groupId: 4, // 组合
+            groupName: '历化地', // 名称
+            classCount: 4,  // 班级数
+            personCount: 180,  // 限制人数
+            personInTime: 60,  // 实时人数
+            rankInGroup: 32, // 选科实时排名
+            rankInGrade: 67, // 选科全校排名
+            allowSelect: true, // 是否可以报名
+            disabledReason: '不知道', // 不可报名时的原因
+            selected:  false, // 报名状态
+            selectedRank:  2, // 多志愿时的排序
+          },
+        ]
+      }
+    }
+  },
+
+]

+ 1 - 0
package.json

@@ -65,6 +65,7 @@
     "vue-aliplayer": "^1.0.0",
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
+    "vue-esign": "^1.1.0",
     "vue-router": "3.4.9",
     "vue-video-player": "^5.0.2",
     "vuedraggable": "2.24.3",

+ 33 - 0
src/api/webApi/elective/ selected-subject.js

@@ -0,0 +1,33 @@
+import request from '@/utils/request'
+// 选科报名接口
+
+// 学生获取自选专业及匹配情况
+export function getOptionalMajors(params) {
+  return request({
+    url: '/front/elective/enroll/getOptionalMajors',
+    method: 'get',
+    params
+  })
+}
+
+// 学生获取选科状态数据,得到是每个组合最终状态和结果
+export function getPrimaryElectives(params) {
+  return request({
+    url: '/mock/front/elective/primaryElectives',
+    method: 'get',
+    params
+  })
+}
+
+// 学生获取评测推荐专业
+export function getEvaluationMajors(params) {
+  return request({
+    url: '/mock/front/elective/evaluationMajors',
+    method: 'get',
+    params
+  })
+}
+
+
+
+

+ 68 - 4
src/api/webApi/elective/generation.js

@@ -2,7 +2,7 @@ import request from '@/utils/request'
 
 export function getElectiveStatus(params) {
   return request({
-    url: '/mock/front/report/getElectiveStatus',
+    url: '/mock/front/elective/generation/getElectiveStatus',
     method: 'get',
     params
   })
@@ -10,7 +10,7 @@ export function getElectiveStatus(params) {
 
 export function getElectiveSummary(params) {
   return request({
-    url: '/mock/front/report/getElectiveSummary',
+    url: '/mock/front/elective/generation/getElectiveSummary',
     method: 'get',
     params
   })
@@ -18,7 +18,7 @@ export function getElectiveSummary(params) {
 
 export function getElectiveGenerationDetails(params) {
   return request({
-    url: '/mock/front/report/getElectiveGenerationDetails',
+    url: '/mock/front/elective/generation/getElectiveGenerationDetails',
     method: 'get',
     params
   })
@@ -26,8 +26,72 @@ export function getElectiveGenerationDetails(params) {
 
 export function getGenerationOptionalMajorsBatch(params) {
   return request({
-    url: '/mock/front/report/getGenerationOptionalMajorsBatch',
+    url: '/mock/front/elective/generation/getGenerationOptionalMajorsBatch',
     method: 'get',
     params
   })
 }
+
+// /prod-api/front/elective/generation/applyElectiveDMAlgorithm
+// 执行选科匹配算法。为减少错误,对DM代数据全删全加可能好点。
+export function applyElectiveDMAlgorithm(algorithm) {
+  return request({
+    url: '/front/elective/generation/applyElectiveDMAlgorithm?algorithm=' + algorithm,
+    method: 'post'
+  })
+}
+
+// /prod-api/front/elective/generation/cancelEnrollByForce
+// 取消强制调剂操作
+export function cancelEnrollByForce(id) {
+  return request({
+    url: '/front/elective/generation/cancelEnrollByForce?id=' + id,
+    method: 'post'
+  })
+}
+
+// /front/elective/generation/enrollByForce
+// 决策阶段,强制调剂录取
+export function enrollByForce(groupId, studentId) {
+  return request({
+    url: '/front/elective/generation/enrollByForce?groupId=' + id + '&studentId=' + studentId,
+    method: 'post'
+  })
+}
+
+// /front/elective/generation/flushIntoGenerationDM
+// 在任意报名阶段,如果校长发现数据已经完全OK,则可以强制推进进程,提前进入决策
+export function flushIntoGenerationDM() {
+  return request({
+    url: '/front/elective/generation/flushIntoGenerationDM',
+    method: 'post'
+  })
+}
+
+// /front/elective/generation/jumpGenerationRankBalance
+// 如果在所有学生全部录取的情况,可以在任意决策结点跳转至排名均衡
+export function jumpGenerationRankBalance() {
+  return request({
+    url: '/front/elective/generation/jumpGenerationRankBalance',
+    method: 'post'
+  })
+}
+
+// /prod-api/front/elective/generation/pushGenerationSetting
+// 决策完毕时,推进下一代进行
+export function pushGenerationSetting(data) {
+  return request({
+    url: '/front/elective/generation/pushGenerationSetting',
+    method: 'post',
+    data
+  })
+}
+
+// /front/elective/generation/terminateGeneration
+// 如果在所有学生全部录取的情况,可以在任意决策结点跳转至终止态,封存数据
+export function terminateGeneration() {
+  return request({
+    url: '/front/elective/generation/terminateGeneration',
+    method: 'post'
+  })
+}

+ 7 - 7
src/api/webApi/mxjbSelectedScore.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 查询选科分数列表
 export function listMxjbSelectedScore(query) {
   return request({
-    url: '/mxjb/mxjbSelectedScore/list',
+    url: '/front/selected/score/list',
     method: 'get',
     params: query
   })
@@ -12,7 +12,7 @@ export function listMxjbSelectedScore(query) {
 // 查询选科分数详细
 export function getMxjbSelectedScore(id) {
   return request({
-    url: '/mxjb/mxjbSelectedScore/' + id,
+    url: '/front/selected/score/' + id,
     method: 'get'
   })
 }
@@ -20,7 +20,7 @@ export function getMxjbSelectedScore(id) {
 // 新增选科分数
 export function addMxjbSelectedScore(data) {
   return request({
-    url: '/mxjb/mxjbSelectedScore',
+    url: '/front/selected/score',
     method: 'post',
     data: data
   })
@@ -29,7 +29,7 @@ export function addMxjbSelectedScore(data) {
 // 修改选科分数
 export function updateMxjbSelectedScore(data) {
   return request({
-    url: '/mxjb/mxjbSelectedScore',
+    url: '/front/selected/score',
     method: 'put',
     data: data
   })
@@ -38,7 +38,7 @@ export function updateMxjbSelectedScore(data) {
 // 删除选科分数
 export function delMxjbSelectedScore(id) {
   return request({
-    url: '/mxjb/mxjbSelectedScore/' + id,
+    url: '/front/selected/score/' + id,
     method: 'delete'
   })
 }
@@ -46,7 +46,7 @@ export function delMxjbSelectedScore(id) {
 // 下载导入模板
 export function importTemplate() {
   return request({
-    url: '/mxjb/mxjbSelectedScore/importTemplate',
+    url: '/front/selected/score/importTemplate',
     method: 'get'
   })
 }
@@ -54,7 +54,7 @@ export function importTemplate() {
 // 导出选科分数
 export function exportMxjbSelectedScore(query) {
   return request({
-    url: '/mxjb/mxjbSelectedScore/export',
+    url: '/front/selected/score/export',
     method: 'get',
     params: query
   })

+ 53 - 53
src/api/webApi/mxjbSelectedScoreImport.js

@@ -1,53 +1,53 @@
-import request from '@/utils/request'
-
-// 查询成绩导入文件列表
-export function listMxjbSelectedScoreImport(query) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport/list',
-    method: 'get',
-    params: query
-  })
-}
-
-// 查询成绩导入文件详细
-export function getMxjbSelectedScoreImport(importId) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport/' + importId,
-    method: 'get'
-  })
-}
-
-// 新增成绩导入文件
-export function addMxjbSelectedScoreImport(data) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport',
-    method: 'post',
-    data: data
-  })
-}
-
-// 修改成绩导入文件
-export function updateMxjbSelectedScoreImport(data) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport',
-    method: 'put',
-    data: data
-  })
-}
-
-// 删除成绩导入文件
-export function delMxjbSelectedScoreImport(importId) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport/' + importId,
-    method: 'delete'
-  })
-}
-
-// 导出成绩导入文件
-export function exportMxjbSelectedScoreImport(query) {
-  return request({
-    url: '/mxjb/mxjbSelectedScoreImport/export',
-    method: 'get',
-    params: query
-  })
-}
+import request from '@/utils/request'
+
+// 查询成绩导入文件列表
+export function listMxjbSelectedScoreImport(query) {
+  return request({
+    url: '/front/selected/scoreImport/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询成绩导入文件详细
+export function getMxjbSelectedScoreImport(importId) {
+  return request({
+    url: '/front/selected/scoreImport/' + importId,
+    method: 'get'
+  })
+}
+
+// 新增成绩导入文件
+export function addMxjbSelectedScoreImport(data) {
+  return request({
+    url: '/front/selected/scoreImport',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改成绩导入文件
+export function updateMxjbSelectedScoreImport(data) {
+  return request({
+    url: '/front/selected/scoreImport',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除成绩导入文件
+export function delMxjbSelectedScoreImport(importId) {
+  return request({
+    url: '/front/selected/scoreImport/' + importId,
+    method: 'delete'
+  })
+}
+
+// 导出成绩导入文件
+export function exportMxjbSelectedScoreImport(query) {
+  return request({
+    url: '/front/selected/scoreImport/export',
+    method: 'get',
+    params: query
+  })
+}

+ 30 - 0
src/api/webApi/professlib.js

@@ -1,5 +1,35 @@
 import request from '@/utils/request'
 
+
+
+
+// 专业库-所有专业
+export function allMajor(params) {
+  return request({
+    url: '/front/major/getAllMajor',
+    method: 'get',
+    params:params
+  })
+}
+
+// 专业库-专业详情--专业概况
+export function majorOverview(params) {
+  return request({
+    url: '/front/major/getMajorOverviewByCode',
+    method: 'get',
+    params:params
+  })
+}
+
+// 专业库-专业详情--就业前景
+export function careerProspects(params) {
+  return request({
+    url: '/front/major/getMajorCareerProspectsByCode',
+    method: 'get',
+    params:params
+  })
+}
+
 // 专业库-专业大类
 export function getProfesslibData(params) {
   return request({

+ 49 - 0
src/api/webApi/vocation.js

@@ -7,6 +7,55 @@ export function selectJobsList(params){
   })
 }
 
+/**
+ * 职业库 level:1 1级
+ *       level:2 2级
+ */
+export function getAllVocation(params){
+  return request({
+    url:`front/vocational/getAllVocation`,
+    method:'get',
+    params
+  })
+}
+
+
+// 职业概况
+export function vocationalOverview(params){
+  return request({
+    url:`front/vocational/getVocationalOverview`,
+    method:'get',
+    params
+  })
+}
+
+/**
+ * 获取就业岗位
+ * @param params
+ */
+export function vocationalPosts(params){
+  return request({
+    url:`front/vocational/getVocationalPosts`,
+    method:'get',
+    params
+  })
+}
+
+
+
+
+/**
+ * 获取职业就业详情
+ * @param params
+ */
+export function vocationalPostsDetail(params){
+  return request({
+    url:`/front/vocational/getVocationalPostDetailByPostName`,
+    method:'get',
+    params
+  })
+}
+
 /**
  * 获取职业详情
  * @param params

+ 8 - 0
src/api/webApi/webQue.js

@@ -640,6 +640,14 @@ export function schemeDfRemove(query) {
     params: query,
   })
 }
+export function saveSelectCourse(query) {
+  return request({
+    url: '/front/syzy/xkcx/saveSelectCourse',
+    method: 'get',
+    params: query,
+  })
+}
+
 
 // /prod-api/front/v2/papers/saveToPersonResources
 // 保存到个人资料库(课件资源)

+ 6 - 1
src/assets/styles/common.scss

@@ -645,7 +645,9 @@
 .f24 {
   font-size: 24px;
 }
-
+.f28 {
+  font-size: 28px;
+}
 .f-red {
   color: #dd524d;
 }
@@ -704,3 +706,6 @@
 .pointer {
   cursor: pointer;
 }
+.pd20{
+  padding: 20px ;
+}

+ 217 - 200
src/assets/styles/index.scss

@@ -1,200 +1,217 @@
-@import './variables.scss';
-@import './mixin.scss';
-@import './transition.scss';
-@import './element-ui.scss';
-@import './sidebar.scss';
-@import './btn.scss';
-
-body {
-  height: 100%;
-  -moz-osx-font-smoothing: grayscale;
-  -webkit-font-smoothing: antialiased;
-  text-rendering: optimizeLegibility;
-  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
-}
-
-label {
-  font-weight: 700;
-}
-
-html {
-  height: 100%;
-  box-sizing: border-box;
-}
-
-#app {
-  height: 100%;
-}
-
-*,
-*:before,
-*:after {
-  box-sizing: inherit;
-}
-.no-padding {
-  padding: 0px !important;
-}
-
-.padding-content {
-  padding: 4px 0;
-}
-
-a:focus,
-a:active {
-  outline: none;
-}
-
-a,
-a:focus,
-a:hover {
-  cursor: pointer;
-  color: inherit;
-  text-decoration: none;
-}
-
-div:focus {
-  outline: none;
-}
-
-.fr {
-  float: right;
-}
-
-.fl {
-  float: left;
-}
-
-.pr-5 {
-  padding-right: 5px;
-}
-
-.pl-5 {
-  padding-left: 5px;
-}
-
-.block {
-  display: block;
-}
-
-.pointer {
-  cursor: pointer;
-}
-
-.inlineBlock {
-  display: block;
-}
-
-.clearfix {
-  &:after {
-    visibility: hidden;
-    display: block;
-    font-size: 0;
-    content: " ";
-    clear: both;
-    height: 0;
-  }
-}
-
-aside {
-  background: #eef1f6;
-  padding: 8px 24px;
-  margin-bottom: 20px;
-  border-radius: 2px;
-  display: block;
-  line-height: 32px;
-  font-size: 16px;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
-  color: #2c3e50;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-
-  a {
-    color: #337ab7;
-    cursor: pointer;
-
-    &:hover {
-      color: rgb(32, 160, 255);
-    }
-  }
-}
-
-//main-container全局样式
-.app-container {
-  padding: 20px;
-}
-
-.components-container {
-  margin: 30px 50px;
-  position: relative;
-}
-
-.pagination-container {
-  margin-top: 30px;
-}
-
-.text-center {
-  text-align: center
-}
-
-.sub-navbar {
-  height: 50px;
-  line-height: 50px;
-  position: relative;
-  width: 100%;
-  text-align: right;
-  padding-right: 20px;
-  transition: 600ms ease position;
-  background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
-
-  .subtitle {
-    font-size: 20px;
-    color: #fff;
-  }
-
-  &.draft {
-    background: #d0d0d0;
-  }
-
-  &.deleted {
-    background: #d0d0d0;
-  }
-}
-
-.link-type,
-.link-type:focus {
-  color: #337ab7;
-  cursor: pointer;
-
-  &:hover {
-    color: rgb(32, 160, 255);
-  }
-}
-
-.filter-container {
-  padding-bottom: 10px;
-
-  .filter-item {
-    display: inline-block;
-    vertical-align: middle;
-    margin-bottom: 10px;
-  }
-}
-
-//refine vue-multiselect plugin
-.multiselect {
-  line-height: 16px;
-}
-
-.multiselect--active {
-  z-index: 1000 !important;
-}
-
-.evaluation-card-wrapper {
-  padding-left: 6px;
-  padding-right: 6px;
-  margin-bottom: 10px;
-}
-
-tr.highlight-row {
-  color: red; 
-}
+@import './variables.scss';
+@import './mixin.scss';
+@import './transition.scss';
+@import './element-ui.scss';
+@import './sidebar.scss';
+@import './btn.scss';
+
+body {
+  height: 100%;
+  -moz-osx-font-smoothing: grayscale;
+  -webkit-font-smoothing: antialiased;
+  text-rendering: optimizeLegibility;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
+}
+
+label {
+  font-weight: 700;
+}
+
+html {
+  height: 100%;
+  box-sizing: border-box;
+}
+
+#app {
+  height: 100%;
+}
+
+*,
+*:before,
+*:after {
+  box-sizing: inherit;
+}
+.no-padding {
+  padding: 0px !important;
+}
+
+.padding-content {
+  padding: 4px 0;
+}
+
+a:focus,
+a:active {
+  outline: none;
+}
+
+a,
+a:focus,
+a:hover {
+  cursor: pointer;
+  color: inherit;
+  text-decoration: none;
+}
+
+div:focus {
+  outline: none;
+}
+
+.fr {
+  float: right;
+}
+
+.fl {
+  float: left;
+}
+
+.pr-5 {
+  padding-right: 5px;
+}
+
+.pl-5 {
+  padding-left: 5px;
+}
+
+.block {
+  display: block;
+}
+
+.pointer {
+  cursor: pointer;
+}
+
+.inlineBlock {
+  display: block;
+}
+
+.clearfix {
+  &:after {
+    visibility: hidden;
+    display: block;
+    font-size: 0;
+    content: " ";
+    clear: both;
+    height: 0;
+  }
+}
+
+aside {
+  background: #eef1f6;
+  padding: 8px 24px;
+  margin-bottom: 20px;
+  border-radius: 2px;
+  display: block;
+  line-height: 32px;
+  font-size: 16px;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+  color: #2c3e50;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+  a {
+    color: #337ab7;
+    cursor: pointer;
+
+    &:hover {
+      color: rgb(32, 160, 255);
+    }
+  }
+}
+
+//main-container全局样式
+.app-container {
+  padding: 20px;
+}
+
+.components-container {
+  margin: 30px 50px;
+  position: relative;
+}
+
+.pagination-container {
+  margin-top: 30px;
+}
+
+.text-center {
+  text-align: center
+}
+.btn-blue{
+  color: deepskyblue;
+  padding: 0 5px;
+  border-bottom: 1px solid deepskyblue;
+  cursor: pointer;
+}
+.btn-red{
+  color: orangered;
+  padding: 0 5px;
+  border-bottom: 1px solid orangered;
+  cursor: pointer;
+}
+.btn-green{
+  color: #1ab394;
+  padding: 0 5px;
+  border-bottom: 1px solid #1ab394;
+  cursor: pointer;
+}
+.sub-navbar {
+  height: 50px;
+  line-height: 50px;
+  position: relative;
+  width: 100%;
+  text-align: right;
+  padding-right: 20px;
+  transition: 600ms ease position;
+  background: linear-gradient(90deg, rgba(32, 182, 249, 1) 0%, rgba(32, 182, 249, 1) 0%, rgba(33, 120, 241, 1) 100%, rgba(33, 120, 241, 1) 100%);
+
+  .subtitle {
+    font-size: 20px;
+    color: #fff;
+  }
+
+  &.draft {
+    background: #d0d0d0;
+  }
+
+  &.deleted {
+    background: #d0d0d0;
+  }
+}
+
+.link-type,
+.link-type:focus {
+  color: #337ab7;
+  cursor: pointer;
+
+  &:hover {
+    color: rgb(32, 160, 255);
+  }
+}
+
+.filter-container {
+  padding-bottom: 10px;
+
+  .filter-item {
+    display: inline-block;
+    vertical-align: middle;
+    margin-bottom: 10px;
+  }
+}
+
+//refine vue-multiselect plugin
+.multiselect {
+  line-height: 16px;
+}
+
+.multiselect--active {
+  z-index: 1000 !important;
+}
+
+.evaluation-card-wrapper {
+  padding-left: 6px;
+  padding-right: 6px;
+  margin-bottom: 10px;
+}
+
+tr.highlight-row {
+  color: red;
+}

+ 44 - 44
src/assets/styles/variables.scss

@@ -1,44 +1,44 @@
-// base color
-$blue:#324157;
-$light-blue:#3A71A8;
-$red:#C03639;
-$pink: #E65D6E;
-$green: #30B08F;
-$tiffany: #4AB7BD;
-$yellow:#FEC171;
-$panGreen: #30B08F;
-
-// sidebar
-$menuText:#bfcbd9;
-$menuActiveText:#409EFF;
-$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
-
-$menuBg:#304156;
-$menuHover:#263445;
-$sidebarTitle: #ffffff;
-
-$menuLightBg:#ffffff;
-$menuLightHover:#f0f1f5;
-$sidebarLightTitle: #001529;
-
-$subMenuBg:#1f2d3d;
-$subMenuHover:#001528;
-
-$sideBarWidth: 250px;
-
-// the :export directive is the magic sauce for webpack
-// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
-:export {
-  menuText: $menuText;
-  menuActiveText: $menuActiveText;
-  subMenuActiveText: $subMenuActiveText;
-  menuBg: $menuBg;
-  menuHover: $menuHover;
-  menuLightBg: $menuLightBg;
-  menuLightHover: $menuLightHover;
-  subMenuBg: $subMenuBg;
-  subMenuHover: $subMenuHover;
-  sideBarWidth: $sideBarWidth;
-  sidebarTitle: $sidebarTitle;
-  sidebarLightTitle: $sidebarLightTitle
-}
+// base color
+$blue:#324157;
+$light-blue:#3A71A8;
+$red:#C03639;
+$pink: #E65D6E;
+$green: #30b08f;
+$tiffany: #4AB7BD;
+$yellow:#FEC171;
+$panGreen: #30B08F;
+
+// sidebar
+$menuText:#bfcbd9;
+$menuActiveText:#409EFF;
+$subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951
+
+$menuBg:#304156;
+$menuHover:#263445;
+$sidebarTitle: #ffffff;
+
+$menuLightBg:#ffffff;
+$menuLightHover:#f0f1f5;
+$sidebarLightTitle: #001529;
+
+$subMenuBg:#1f2d3d;
+$subMenuHover:#001528;
+
+$sideBarWidth: 250px;
+
+// the :export directive is the magic sauce for webpack
+// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
+:export {
+  menuText: $menuText;
+  menuActiveText: $menuActiveText;
+  subMenuActiveText: $subMenuActiveText;
+  menuBg: $menuBg;
+  menuHover: $menuHover;
+  menuLightBg: $menuLightBg;
+  menuLightHover: $menuLightHover;
+  subMenuBg: $subMenuBg;
+  subMenuHover: $subMenuHover;
+  sideBarWidth: $sideBarWidth;
+  sidebarTitle: $sidebarTitle;
+  sidebarLightTitle: $sidebarLightTitle
+}

+ 17 - 8
src/common/mx-config.js

@@ -79,6 +79,7 @@ export default {
     init: {
       key: 'init',
       value: 0,
+      code: 'Init',
       decisionMaking: false,
       stepsVisible: false,
       title: '未开启',
@@ -88,60 +89,67 @@ export default {
     primary: {
       key: 'primary',
       value: 1,
+      code: 'Primary',
       decisionMaking: false,
       stepsVisible: true,
-      title: '初录数据',
+      title: '初录报名',
       description: '',
       icon: ''
     },
     primaryDM: {
       key: 'primaryDM',
       value: 2,
+      code: 'PrimaryDM',
       decisionMaking: true,
       stepsVisible: true,
-      title: '通知补录',
+      title: '初录结果',
       description: '',
       icon: ''
     },
     backTracking: {
       key: 'backTracking',
       value: 3,
+      code: 'BackTracking',
       decisionMaking: false,
       stepsVisible: true,
-      title: '补录数据',
+      title: '补录报名',
       description: '',
       icon: ''
     },
     backTrackingDM: {
       key: 'backTrackingDM',
       value: 4,
+      code: 'BackTrackingDM',
       decisionMaking: true,
       stepsVisible: true,
-      title: '通知二次补录',
+      title: '补录结果',
       description: '',
       icon: ''
     },
     finalAdjust: {
       key: 'finalAdjust',
       value: 5,
+      code: 'FinalAdjust',
       decisionMaking: false,
       stepsVisible: true,
-      title: '二次补录数据',
+      title: '二次补录报名',
       description: '',
       icon: ''
     },
     finalAdjustDM: {
       key: 'finalAdjustDM',
       value: 6,
+      code: 'FinalAdjustDM',
       decisionMaking: true,
       stepsVisible: true,
-      title: '调剂决策',
+      title: '二次补录结果',
       description: '',
       icon: ''
     },
     rankBalance: {
       key: 'rankBalance',
       value: 7,
+      code: 'RankBalance',
       decisionMaking: true,
       stepsVisible: true,
       title: '排名均衡',
@@ -151,6 +159,7 @@ export default {
     terminate: {
       key: 'terminate',
       value: 8,
+      code: 'Terminate',
       decisionMaking: false,
       stepsVisible: false,
       title: '选科结束',
@@ -161,12 +170,12 @@ export default {
   electiveDMAlgorithm: {
     rankFirst: {
       key: 'rankFirst',
-      value: 0,
+      value: 'RankFirst',
       title: '按成绩'
     },
     majorFirst: {
       key: 'majorFirst',
-      value: 1,
+      value: 'MajorFirst',
       title: '按专业'
     }
   }

+ 6 - 0
src/components/Cache/modules/mx-select-translate-mixin.js

@@ -27,6 +27,12 @@ export default {
     },
     translateGroup(groupId) {
       return this.listGroupsOptions.find(g => g.value == groupId)?.text || '未知选科组合'
+    },
+    translateCourse0(groupId) {
+      return this.listGroupsOptions.find(g => g.value == groupId)?.course0
+    },
+    translateCourse1(groupId) {
+      return this.listGroupsOptions.find(g => g.value == groupId)?.course1
     }
   }
 }

+ 3 - 1
src/components/Cache/mx-cache-mixin.js

@@ -77,7 +77,9 @@ export default {
         listGroups,
         res => res.data.map(g => ({
           text: g.name,
-          value: g.groupId
+          value: g.groupId,
+          course0: g.course0,
+          course1: g.course1,
         })),
         useCache)
     },

+ 20 - 0
src/components/MxCondition/condition-object/condition-location.js

@@ -0,0 +1,20 @@
+import conditionObjectBase from '../condition-object-base.js'
+import { locations } from "@/api/webApi/career-other";
+
+export default {
+  ...conditionObjectBase,
+  key: 'location',
+  title: '地域',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      locations().then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 29 - 0
src/components/MxCondition/condition-object/condition-shiftline-level.js

@@ -0,0 +1,29 @@
+import conditionObjectBase from '../condition-object-base.js'
+import {
+  selectUniversityLevels,
+} from '@/api/webApi/shiftLine'
+
+// 院校投档线  地域
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['universityLocation'],
+  key: 'universityLevel',
+  isDependencyReady(params) {
+    return params.universityLocation
+  },
+  title: '层次',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      selectUniversityLevels({
+        location: param.universityLocation
+      }).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 29 - 0
src/components/MxCondition/condition-object/condition-shiftline-type.js

@@ -0,0 +1,29 @@
+import conditionObjectBase from '../condition-object-base.js'
+import {
+  selectUniversityTypes,
+} from '@/api/webApi/shiftLine'
+
+// 院校投档线  地域
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['universityLocation'],
+  key: 'universityType',
+  isDependencyReady(params) {
+    return params.universityLocation
+  },
+  title: '科类',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      selectUniversityTypes({
+        location: param.universityLocation
+      }).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 23 - 0
src/components/MxCondition/condition-object/condition-shiftline-university.js

@@ -0,0 +1,23 @@
+import conditionObjectBase from '../condition-object-base.js'
+import {
+  selectUniversityLocations
+} from '@/api/webApi/shiftLine'
+
+// 院校投档线  地域
+export default {
+  ...conditionObjectBase,
+  key: 'universityLocation',
+  title: '地域',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      selectUniversityLocations().then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 31 - 0
src/components/MxCondition/condition-object/condition-shiftline-year.js

@@ -0,0 +1,31 @@
+import conditionObjectBase from '../condition-object-base.js'
+import {
+  selectUniversityYears
+} from '@/api/webApi/shiftLine'
+
+// 院校投档线  地域
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['universityLocation','universityType','universityLevel'],
+  key: 'universityYear',
+  isDependencyReady(params) {
+    return params.universityLocation && params.universityType && params.universityLevel
+  },
+  title: '年份',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      selectUniversityYears({
+        location: param.universityLocation,
+        level: param.universityLevel,
+        type: param.universityType
+      }).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 24 - 0
src/components/MxCondition/condition-object/condition-year-admission.js

@@ -0,0 +1,24 @@
+import conditionObjectBase from '../condition-object-base.js'
+import { years } from "@/api/webApi/career-other";
+
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['location'],
+  key: 'yearAdmission',
+  title: '学年',
+  isDependencyReady(params) {
+    return params.location
+  },
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      years(param).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 20 - 0
src/components/MxCondition/condition-object/condition-yfyd-location.js

@@ -0,0 +1,20 @@
+import conditionObjectBase from '../condition-object-base.js'
+import { yfydLocations } from "@/api/webApi/career-other";
+
+export default {
+  ...conditionObjectBase,
+  key: 'yfydLocation',
+  title: '地域',
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      yfydLocations().then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 25 - 0
src/components/MxCondition/condition-object/condition-yfyd-mode.js

@@ -0,0 +1,25 @@
+import conditionObjectBase from '../condition-object-base.js'
+import { yfydModes } from "@/api/webApi/career-other";
+
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['yfydYear'],
+  key: 'yfydMode',
+  title: '科类',
+  isDependencyReady(params) {
+    return params.yfydYear
+  },
+  getList: function(param, $ref) {
+    console.log('',$ref)
+    return new Promise((resolve, reject) => {
+      yfydModes({ location:$ref.model.yfydLocation,year:param.yfydYear }).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 24 - 0
src/components/MxCondition/condition-object/condition-yfyd-year.js

@@ -0,0 +1,24 @@
+import conditionObjectBase from '../condition-object-base.js'
+import { yfydYears } from "@/api/webApi/career-other";
+
+export default {
+  ...conditionObjectBase,
+  dependentKeys: ['yfydLocation'],
+  key: 'yfydYear',
+  title: '学年',
+  isDependencyReady(params) {
+    return params.yfydLocation
+  },
+  getList: function(param) {
+    return new Promise((resolve, reject) => {
+      yfydYears({ location:param.yfydLocation }).then(res => resolve(res.rows))
+        .catch(e => reject(e))
+    })
+  },
+  getCode: function(item) {
+    return item
+  },
+  getLabel: function(item) {
+    return item
+  }
+}

+ 97 - 0
src/components/MxSearch/mx-search-group.vue

@@ -0,0 +1,97 @@
+<template>
+  <div class="search-group">
+    <el-row :gutter="20" type="flex" :justify="justify" class="search-group-row">
+      <slot />
+      <el-col :span="span" :offset="offset">
+        <div class="keyword-box">
+          <el-input
+            :placeholder="placeholder ? placeholder : '请输入关键字'"
+            class="keyword-ipt"
+            :value="value"
+            @input="updataValue"
+            @keyup.enter.native="onEnter"
+          >
+            <div slot="suffix" class="suffix cursor-pointer" @click="onEnter">
+              <i class="el-icon-search icon-search" />
+            </div>
+          </el-input>
+<!--          <el-button v-if="showReset" plain type="primary" class="search-btn" @click="onReset">{{ '重置' }}</el-button>-->
+<!--          <el-button type="primary" class="search-btn" @click="onEnter">{{ '确定'}}</el-button>-->
+        </div>
+      </el-col>
+      <slot name="last" />
+    </el-row>
+  </div>
+</template>
+<script>
+export default {
+  props: {
+    justify: {
+      default: 'start'
+    },
+    span: {
+      type: Number,
+      default: 8
+    },
+    offset: {
+      type: Number,
+      default: 0
+    },
+    showReset: {
+      type: Boolean,
+      default: true
+    },
+    value: String,
+    placeholder: String
+  },
+  methods: {
+    updataValue(val) {
+      this.$emit('input', val)
+    },
+    onEnter() {
+      this.$emit('search')
+    },
+    onReset() {
+      this.$emit('reset')
+      const itemList = this.$children[0].$children
+      itemList.forEach(item => {
+        if (Object.hasOwnProperty.call(item, 'resetValue') &&
+          Object.prototype.toString.call(item.resetValue) === '[object Function]') {
+          item.resetValue()
+        }
+      })
+    }
+  }
+}
+</script>
+<style lang="scss">
+.search-group {
+  .keyword-box {
+    display: flex;
+    align-items: center;
+  }
+  .search-btn {
+    //  width: 100%;
+    margin-left: 20px;
+  }
+  .suffix {
+    position: relative;
+    top: 8px;
+  }
+  .icon-search {
+    font-size: 18px;
+    cursor: pointer;
+    color: #42b983;
+  }
+  .el-input__suffix {
+    padding-right: 5px;
+  }
+  .keyword-ipt {
+    flex: 1;
+    border-radius: 10px;
+  }
+  .search-group-row {
+    flex-wrap: wrap;
+  }
+}
+</style>

+ 118 - 0
src/components/VueEsign/index.vue

@@ -0,0 +1,118 @@
+<template>
+  <div>
+    <!-- 电子签名 -->
+    <el-card class="qianming-container" body-style="padding:0px">
+      <vue-esign ref="esign"  :isCrop="isCrop" :width="600" :height="300" :lineWidth="lineWidth" :lineColor="lineColor" :bgColor.sync="bgColor" ></vue-esign>
+      <div class="contro-container">
+        <el-button type="danger"  @click="handleReset">清空画板</el-button>
+        <el-button type="primary" @click="handleGenerate">生成图片</el-button>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+// import client  from 'common/js/ossClient.js'
+export default {
+  name:'Qianming',
+  data(){
+    return {
+      lineWidth: 6,
+      lineColor: '#000000',
+      bgColor: '',
+      resultImg: '',
+      isCrop: false
+    }
+  },
+  methods:{
+    //清空画板..
+    handleReset () {
+      this.$refs.esign.reset();
+      this.resultImg =''
+    },
+    //生成签名图片..
+    handleGenerate () {
+      this.$refs.esign.generate().then(res => {
+        let randnum = Math.random() * 10000000000000
+        randnum = Math.floor(randnum)
+        let fileName = "dianziqianming/" + randnum + '.png'
+        let file = this.dataURLtoFile(res,fileName)
+        client.put(fileName, file).then(res=>{
+          if(res.url){
+            this.resultImg = res.url
+          }else{
+            this.$message.error('文件上传失败')
+          }
+        }).catch(err=>{})
+      }).catch(err => {
+        this.$message.error('请签名之后提交!')
+      })
+    },
+    //将base64转换为文件..
+    dataURLtoFile(dataurl, filename) {
+      var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
+        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
+      while(n--){
+        u8arr[n] = bstr.charCodeAt(n);
+      }
+      return new File([u8arr], filename, {type:mime});
+    }
+  }
+}
+</script>
+
+<style scoped>
+button{
+  height:40px;
+}
+.show-img{
+  width:400px;
+  height:200px;
+  border:1px solid #123456;
+}
+.show-info{
+  width:400px;
+  height:200px;
+  font-size:24px;
+  display:flex;
+  align-items:center;
+  justify-content:center;
+}
+.contro-container{
+  width:600px;
+  height:50px;
+  display:flex;
+  flex-direction:row;
+  align-items:center;
+  justify-content:space-around;
+  background-color:#D3D3D3;
+  position:absolute;
+  bottom:0px;
+}
+.qianming-container{
+  width:600px;
+  height:350px;
+  margin:20px auto;
+  position:relative;
+}
+.text {
+  font-size: 14px;
+}
+.item {
+  margin-bottom: 18px;
+}
+.clearfix:before,
+.clearfix:after {
+  display: table;
+  content: "";
+}
+.clearfix:after {
+  clear: both
+}
+.box-card {
+  width: 95%;
+  margin-left:2.5%;
+  margin-top:20px;
+}
+</style>
+

+ 3 - 1
src/main.js

@@ -69,7 +69,9 @@ Vue.use(ext)
 // filters
 import filters from "@/filters/index"
 Object.keys(filters).forEach(key => Vue.filter(key, filters[key]))
-
+// 电子签名
+import vueEsign from 'vue-esign'
+Vue.use(vueEsign)
 // 全局组件挂载
 Vue.component('Pagination', Pagination)
 Vue.component('RightToolbar', RightToolbar)

+ 5 - 5
src/router/index.js

@@ -636,7 +636,7 @@ export const constantRoutes = [{
       },
       {
         path: '/career/plan/ProfessLib',
-        component: (resolve) => require(['@/views/career/plan/ProfessLib'], resolve),
+        component: (resolve) => require(['@/views/career/plan/new-profess-lib'], resolve),
         name: 'ProfessLib',
         meta: {
           title: '专业库'
@@ -644,7 +644,7 @@ export const constantRoutes = [{
       },
       {
         path: '/career/plan/ProfessLibDetail',
-        component: (resolve) => require(['@/views/career/plan/ProfessLibDetail'], resolve),
+        component: (resolve) => require(['@/views/career/plan/new-profess-detail'], resolve),
         name: 'ProfessLibDetail',
         meta: {
           title: '专业库详情'
@@ -677,7 +677,7 @@ export const constantRoutes = [{
       },
       {
         path: '/career/subject/subjectChoice',
-        component: (resolve) => require(['@/views/career/subject/subjectChoice.vue'], resolve),
+        component: (resolve) => require(['@/views/career/subject/choose-subject.vue'], resolve),
         name: 'SubjectChoice',
         meta: {
           title: '由科目选专业'
@@ -718,7 +718,7 @@ export const constantRoutes = [{
       },
       {
         path: '/career/vocation/index',
-        component: (resolve) => require(['@/views/career/vocation/index'], resolve),
+        component: (resolve) => require(['@/views/career/vocation/new-index'], resolve),
         name: 'Vocation',
         meta: {
           title: '职业库'
@@ -726,7 +726,7 @@ export const constantRoutes = [{
       },
       {
         path: '/career/vocation/Detail',
-        component: (resolve) => require(['@/views/career/vocation/Detail'], resolve),
+        component: (resolve) => require(['@/views/career/vocation/new-detail'], resolve),
         name: 'jobDetail',
         meta: {
           title: '职业-详情'

+ 22 - 0
src/utils/index.js

@@ -15,6 +15,28 @@ export function formatDate(cellValue) {
   return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
 }
 
+/**
+ * 格式化科目缩写
+ */
+export function formatSubject(cellValue) {
+  if (cellValue == null || cellValue == '') return ''
+  switch (cellValue) {
+    case '物':
+      return '物理'
+    case '历':
+      return '历史'
+    case '化':
+      return '化学'
+    case '地':
+      return '地理'
+    case '政':
+      return '政治'
+    case '生':
+      return '生物'
+
+  }
+}
+
 /**
  * @param {number} time
  * @param {string} option

+ 1 - 0
src/utils/request.js

@@ -5,6 +5,7 @@ import auth from '@/utils/auth'
 import errorCode from '@/utils/errorCode'
 
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+axios.defaults.headers['accessFrom'] = 'front'
 // 创建axios实例
 const service = axios.create({
   // axios中请求配置有baseURL选项,表示请求URL公共部分

+ 6 - 1
src/views/career/components/UniversitiesLine.vue

@@ -58,7 +58,6 @@
     selectUniversityYears
   } from '@/api/webApi/shiftLine'
   import UniversitiesLineTable from '@/views/career/components/UniversitiesLineTable'
-
   export default {
     name: "UniversitiesLine",
     components: {UniversitiesLineTable},
@@ -102,6 +101,12 @@
       this.getUniversityYears()
     },
     methods: {
+      handleQuery() {
+
+      },
+      handleInvalidQuery() {
+
+      },
       getUniversityLocations() {
         selectUniversityLocations().then(res => {
           this.locations = res.rows

+ 81 - 72
src/views/career/components/UniversitiesLineTable.vue

@@ -1,16 +1,12 @@
 <template>
   <div id="lineTable">
-    <div style="text-align: right;margin-bottom: 10px;" class="search">
-      <el-input style="width:40%;" suffix-icon=" " placeholder="搜索" v-model="tableParams.univerName" @keyup.enter.native="clickSuffix">
-           <span slot="suffix" @click="clickSuffix" style="cursor: pointer">
-            <i class="el-icon-search" style="margin-right: 10px;"></i>
-          </span>
-      </el-input>
-    </div>
-    <el-table :data="tableData" border>
+    <mx-search-group class="mb10" justify="end" :span="6" v-model="tableParams.univerName" placeholder="搜索" @search="clickSuffix"
+    ></mx-search-group>
+    <el-table :data="tableData" v-loading="tableLoading" border>
       <el-table-column prop="code" label="院校" align="center">
         <template slot-scope="scope">
-          <el-link :underline="false" @click="goDetails(scope.row.universityId)">【{{scope.row.universityName}}】</el-link>
+          <el-link :underline="false" @click="goDetails(scope.row.universityId)">【{{ scope.row.universityName }}】
+          </el-link>
         </template>
       </el-table-column>
       <el-table-column prop="location" label="所在地" align="center"></el-table-column>
@@ -33,77 +29,90 @@
 </template>
 
 <script>
-  import {selectUniversityList} from '@/api/webApi/shiftLine'
-    export default {
-        name: "UniversitiesLineTable",
-      props:{
-        universityParams:{type:Object,default(){return {}}}
-      },
-      data(){
-        return{
-          examRecordTotal:0,
-          tableParams:{
-            pageSize:20,
-            pageNum:1,
-            level:'',
-            location:'',
-            type:'',
-            univerName:'',
-            year:''
-          },
-          tableData:[]
-        }
-      },
-      watch:{
-        universityParams:{
-          immediate:true,
-          deep:true,
-          handler(val){
-            this.tableParams.level=val.levelsRes
-            this.tableParams.location=val.locationsRes
-            this.tableParams.type=val.typeRes
-            this.tableParams.year=val.yearRes
-            this.getUniversityList()
-          }
-        }
+import { selectUniversityList } from '@/api/webApi/shiftLine'
+import MxSearchGroup from '@/components/MxSearch/mx-search-group'
+
+export default {
+  name: 'UniversitiesLineTable',
+  components: {
+    MxSearchGroup
+  },
+  props: {
+    universityParams: {
+      type: Object, default() {
+        return {}
+      }
+    }
+  },
+  data() {
+    return {
+      tableLoading: '',
+      examRecordTotal: 0,
+      tableParams: {
+        pageSize: 20,
+        pageNum: 1,
+        level: '',
+        location: '',
+        type: '',
+        univerName: '',
+        year: ''
       },
-      methods:{
-        clickSuffix(){
-          this.getUniversityList()
-        },
-        getUniversityList(){
-          console.log(this.tableParams)
-          selectUniversityList(this.tableParams).then(res=>{
-            console.log(res)
-            this.tableData=res.rows
-            this.examRecordTotal=res.total
-          })
-        },
-        sizeChange(e){
-          this.tableParams.pageSize=e
-          this.getUniversityList()
-        },
-        currentChange(e){
-          //页数
-          this.tableParams.pageNum=e
-          this.getUniversityList()
-        },
-        goDetails(id){
-          this.$router.push({ name: 'UniversityDetail', params: { id: id } })
-        }
+      tableData: []
+    }
+  },
+  watch: {
+    universityParams: {
+      immediate: true,
+      deep: true,
+      handler(val) {
+        this.tableParams.level = val.levelsRes
+        this.tableParams.location = val.locationsRes
+        this.tableParams.type = val.typeRes
+        this.tableParams.year = val.yearRes
+        this.getUniversityList()
       }
     }
+  },
+  methods: {
+    clickSuffix() {
+      this.getUniversityList()
+    },
+    getUniversityList() {
+      this.tableLoading = true
+      console.log(this.tableParams)
+      selectUniversityList(this.tableParams).then(res => {
+        console.log(res)
+        this.tableData = res.rows
+        this.examRecordTotal = res.total
+      }).finally(_ => {
+        this.tableLoading = false
+      })
+    },
+    sizeChange(e) {
+      this.tableParams.pageSize = e
+      this.getUniversityList()
+    },
+    currentChange(e) {
+      //页数
+      this.tableParams.pageNum = e
+      this.getUniversityList()
+    },
+    goDetails(id) {
+      this.$router.push({ name: 'UniversityDetail', params: { id: id } })
+    }
+  }
+}
 </script>
 
 <style lang="scss">
-  #lineTable{
-    .search{
-      .el-input {
-        .el-input__inner {
-          border-radius: 50px;
-        }
+#lineTable {
+  .search {
+    .el-input {
+      .el-input__inner {
+        border-radius: 50px;
       }
     }
   }
+}
 
 </style>

+ 75 - 83
src/views/career/components/VolunteerList.vue

@@ -1,95 +1,87 @@
 <template>
-    <div  style="padding: 24px 0; background-color: #f7f7f7">
-      <el-image style="width:100%" :src="require('@/assets/images/bg_zhiyuantianbao.png')"></el-image>
-      <div style="margin-top: 20px;">
-        <el-table :data="tableData" border v-loading="loading" style="min-height: 300px;">
-          <el-table-column prop="id" label="ID" align="center"></el-table-column>
-          <el-table-column prop="name" label="名称" align="center"></el-table-column>
-          <el-table-column prop="createTime" label="填报时间" align="center"></el-table-column>
-          <el-table-column prop="batchName" label="填报批次" align="center"></el-table-column>
-          <el-table-column prop="" label="志愿概要" align="center">
-            <template slot-scope="scope">
-              <div style="line-height:30px;" v-for="(item,index) in scope.row.summary" :key="index">{{item}}</div>
-            </template>
-          </el-table-column>
-          <el-table-column label="操作" align="center">
-            <template slot-scope="scope">
-              <el-link :underline="false" type="primary" @click="goDetails(scope.row)">详情 </el-link>
-              <el-link :underline="false" type="danger" style="margin-left: 7px;" @click="delTableList(scope.row)"> 删除</el-link>
-            </template>
-          </el-table-column>
-        </el-table>
-        <el-pagination
-          style="margin-top:10px;"
-          :page-sizes="[10,20,30,40,50,60,70,80,90,100]"
-          :page-size=tableParams.pageSize
-          layout="prev,pager,next,jumper,total,sizes"
-          :total="examRecordTotal"
-          @current-change="currentChange"
-          @size-change="sizeChange"
-        >
-        </el-pagination>
-      </div>
+  <div style="padding: 24px 0; background-color: #f7f7f7">
+    <el-image style="width:100%" :src="require('@/assets/images/bg_zhiyuantianbao.png')"></el-image>
+    <div style="margin-top: 20px;">
+      <el-table :data="tableData" border v-loading="loading" style="min-height: 300px;">
+        <el-table-column prop="id" label="ID" align="center"></el-table-column>
+        <el-table-column prop="name" label="名称" align="center"></el-table-column>
+        <el-table-column prop="createTime" label="填报时间" align="center"></el-table-column>
+        <el-table-column prop="batchName" label="填报批次" align="center"></el-table-column>
+        <el-table-column prop="" label="志愿概要" align="center">
+          <template slot-scope="scope">
+            <div style="line-height:30px;" v-for="(item,index) in scope.row.summary" :key="index">{{ item }}</div>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" align="center">
+          <template slot-scope="scope">
+            <el-link :underline="false" type="primary" @click="goDetails(scope.row)">详情</el-link>
+            <el-link :underline="false" type="danger" style="margin-left: 7px;" @click="delTableList(scope.row)"> 删除
+            </el-link>
+          </template>
+        </el-table-column>
+      </el-table>
+      <pagination :total="examRecordTotal" :autoScroll="false" @pagination="onChangePage"
+                  :page.sync="tableParams.pageNum"
+                  :limit.sync="tableParams.pageSize"
+      ></pagination>
     </div>
+  </div>
 </template>
 
 <script>
-  import {selectZytbRecord,delZytbRecord} from '@/api/webApi/career-other'
-    export default {
-        name: "VolunteerList",
-      data(){
-          return{
-            examRecordTotal:0,
-            tableParams:{
-              pageSize:20,
-              pageNum:1
-            },
-            tableData:[],
-            loading:false
-          }
+import { delZytbRecord, selectZytbRecord } from '@/api/webApi/career-other'
+
+export default {
+  name: 'VolunteerList',
+  data() {
+    return {
+      examRecordTotal: 0,
+      tableParams: {
+        pageSize: 20,
+        pageNum: 1
       },
-      created(){
+      tableData: [],
+      loading: false
+    }
+  },
+  created() {
+    this.getZytbRecord()
+  },
+  methods: {
+    goDetails(data) {
+      this.$router.push({ name: 'RecordDetail', params: { data: data } })
+    },
+    delTableList(data) {
+      console.log(data)
+      this.$confirm(`是否确定删除-${data.name} ?`, '提示', {
+        confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', closeOnClickModal: false
+      }).then(() => {
+        const params = {
+          id: data.id
+        }
+        delZytbRecord(params).then(res => {
           this.getZytbRecord()
-      },
-      methods:{
-        goDetails(data){
-          this.$router.push({name:'RecordDetail',params:{data:data}})
-        },
-        delTableList(data){
-          console.log(data)
-          this.$confirm(`是否确定删除-${data.name} ?`, '提示', {
-            confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', closeOnClickModal: false
-          }).then(() => {
-            const params={
-              id:data.id
-            }
-            delZytbRecord(params).then(res=>{
-              this.getZytbRecord()
-              this.msgSuccess('删除成功')
-            })
-          }).catch(() => {
-          })
+          this.msgSuccess('删除成功')
+        })
+      }).catch(() => {
+      })
 
-        },
-        getZytbRecord(){
-          this.loading=true
-          selectZytbRecord(this.tableParams).then(res=>{
-            this.examRecordTotal=res.total
-            this.loading=false
-            this.tableData=res.rows
-          })
-        },
-        sizeChange(e){
-          this.tableParams.pageSize=e
-          this.getZytbRecord()
-        },
-        currentChange(e){
-          //页数
-          this.tableParams.pageNum=e
-          this.getZytbRecord()
-        }
-      }
+    },
+    getZytbRecord() {
+      this.loading = true
+      selectZytbRecord(this.tableParams).then(res => {
+        this.examRecordTotal = res.total
+        this.loading = false
+        this.tableData = res.rows
+      })
+    },
+    onChangePage(page) {
+      this.tableParams.pageSize = page.limit
+      this.tableParams.pageNum = page.page
+      this.getZytbRecord()
     }
+  }
+}
 </script>
 
 <style scoped>

+ 187 - 206
src/views/career/components/careerTestReport.vue

@@ -1,206 +1,187 @@
-<template>
-  <div>
-    <!-- banner -->
-    <div class="banner">
-      <img style="width: 100%" src="@/assets/images/career/banner.png" alt="" />
-      <p>生涯测评报告</p>
-    </div>
-
-    <el-card>
-      <!-- 专业兴趣测评(HOLLAND) -->
-      <div>
-        <div style="padding: 24px 0; color: #ffa400">
-          专业兴趣测评(HOLLAND)
-        </div>
-        <mx-table :rows="hollData" :propDefines="propDefines">
-          <template #time="{ value }">
-            {{ value.split(" ")[0] }}
-          </template>
-          <template #nav="{ value }">
-            <a href="#" style="color: #47c6a2">{{ value }}</a>
-          </template>
-        </mx-table>
-        <!-- 分页 -->
-        <div>
-          <el-pagination
-            @size-change="hollHandleSizeChange"
-            @current-change="hollHandleCurrentChange"
-            :current-page="hollPageForm.pageNum"
-            :page-sizes="[5, 10, 20, 40]"
-            :page-size="hollPageForm.pageSize"
-            layout=" prev,pager,next,jumper,total,sizes"
-            :total="hollTotal"
-          >
-          </el-pagination>
-        </div>
-      </div>
-      <!-- 职业性格测评(MBTI) -->
-      <div>
-        <div style="padding: 24px 0; color: #1a74d3">职业性格测评(MBTI)</div>
-        <mx-table :rows="mbtiData" :propDefines="mbtiPropDefines">
-          <template #time="{ value }">
-            {{ value.split(" ")[0] }}
-          </template>
-          <template #nav="{ value }">
-            <a href="#" style="color: #47c6a2">{{ value }}</a>
-          </template>
-        </mx-table>
-      </div>
-         <!-- 分页 -->
-        <div>
-          <el-pagination
-            @size-change="mbtiHandleSizeChange"
-            @current-change="mbtiHandleCurrentChange"
-            :current-page="mbtiPageForm.pageNum"
-            :page-sizes="[5, 10, 20, 40]"
-            :page-size="mbtiPageForm.pageSize"
-            layout=" prev,pager,next,jumper,total,sizes"
-            :total="mbtiTotal"
-          >
-          </el-pagination>
-        </div>
-    </el-card>
-  </div>
-</template>
-<script>
-import { hollandRecord, mbtiRecord } from "@/api/webApi/career-other";
-export default {
-  data() {
-    return {
-      hollData: [],
-      hollTotal: 0,
-      hollPageForm: {
-        pageNum: 1,
-        pageSize: 10,
-      },
-      mbtiData: [],
-      mbtiTotal: 0,
-      mbtiPageForm: {
-        pageNum: 1,
-        pageSize: 10,
-      },
-      propDefines: {
-        id: {
-          label: "ID",
-        },
-        createTime: {
-          label: "测评时间",
-          slot: "time",
-        },
-        scorer: {
-          label: "现实型",
-        },
-        scorea: {
-          label: "艺术型",
-        },
-        scorei: {
-          label: "研究型",
-        },
-        scores: {
-          label: "社会型",
-        },
-        scoree: {
-          label: "企业型",
-        },
-        scorec: {
-          label: "传统型",
-        },
-        ruleCode: {
-          label: "测评结果",
-          slot: "nav",
-        },
-      },
-      mbtiPropDefines: {
-        id: {
-          label: "ID",
-        },
-        createTime: {
-          label: "测评时间",
-          slot: "time",
-        },
-        scoreE: {
-          label: "外向",
-        },
-        scoreI: {
-          label: "内向",
-        },
-        scoreS: {
-          label: "实感",
-        },
-        scoreN: {
-          label: "直觉",
-        },
-        scoreT: {
-          label: "思考",
-        },
-        scoreF: {
-          label: "情感",
-        },
-        scoreJ: {
-          label: "判断",
-        },
-        scoreP: {
-          label: "认知",
-        },
-        ruleCode: {
-          label: "测评结果",
-          slot: "nav",
-        },
-      },
-    };
-  },
-  created() {
-    this.getHollandRecord();
-    this.getMbtiRecord()
-  },
-  methods: {
-    getHollandRecord() {
-      hollandRecord(this.hollPageForm).then((res) => {
-        this.hollData = res.rows;
-        this.hollTotal = res.total;
-        console.log(res);
-      });
-    },
-    getMbtiRecord() {
-      mbtiRecord(this.mbtiPageForm).then((res) => {
-        this.mbtiData = res.rows;
-        this.mbtiTotal = res.total;
-        console.log(res);
-      });
-    },
-    mbtiHandleSizeChange(val) {
-      this.mbtiPageForm.pageSize = val;
-      this.getMbtiRecord();
-    },
-    mbtiHandleCurrentChange(val) {
-      this.mbtiPageForm.pageNum = val;
-      this.getMbtiRecord();
-    },
-    hollHandleSizeChange(val) {
-      this.hollPageForm.pageSize = val;
-      this.getHollandRecord();
-      console.log(this.hollPageForm.pageSize);
-    },
-    hollHandleCurrentChange(val) {
-      this.hollPageForm.pageNum = val;
-      this.getHollandRecord();
-    },
-  },
-};
-</script>
-<style lang="scss" scoped>
-.banner {
-  position: relative;
-}
-.banner p {
-  bottom: 10%;
-  left: 50%;
-  transform: translateX(-50%);
-  font-size: 24px;
-  font-family: PingFangSC-Semibold, PingFang SC;
-  font-weight: 600;
-  color: #525252;
-  line-height: 33px;
-  position: absolute;
-}
-</style>
+<template>
+  <div>
+    <!-- banner -->
+    <div class="banner">
+      <img style="width: 100%" src="@/assets/images/career/banner.png" alt="" />
+      <p>生涯测评报告</p>
+    </div>
+
+    <el-card>
+      <!-- 专业兴趣测评(HOLLAND) -->
+      <div>
+        <div style="padding: 24px 0; color: #ffa400">
+          专业兴趣测评(HOLLAND)
+        </div>
+        <mx-table :rows="hollData" :propDefines="propDefines">
+          <template #time="{ value }">
+            {{ value.split(" ")[0] }}
+          </template>
+          <template #nav="{ value }">
+            <a href="#" style="color: #47c6a2">{{ value }}</a>
+          </template>
+        </mx-table>
+        <!-- 分页 -->
+        <div>
+          <pagination :total="hollTotal" :autoScroll="false" @pagination="onHollChangePage" :page.sync="hollPageForm.pageNum"
+                      :limit.sync="hollPageForm.pageSize"></pagination>
+        </div>
+      </div>
+      <!-- 职业性格测评(MBTI) -->
+      <div>
+        <div style="padding: 24px 0; color: #1a74d3">职业性格测评(MBTI)</div>
+        <mx-table :rows="mbtiData" :propDefines="mbtiPropDefines">
+          <template #time="{ value }">
+            {{ value.split(" ")[0] }}
+          </template>
+          <template #nav="{ value }">
+            <a href="#" style="color: #47c6a2">{{ value }}</a>
+          </template>
+        </mx-table>
+      </div>
+         <!-- 分页 -->
+        <div>
+          <pagination :total="mbtiTotal" :autoScroll="false" @pagination="onMbtiChangePage" :page.sync="mbtiPageForm.pageNum"
+                      :limit.sync="mbtiPageForm.pageSize"></pagination>
+        </div>
+    </el-card>
+  </div>
+</template>
+<script>
+import Pagination from '@/components/Pagination/index'
+import { hollandRecord, mbtiRecord } from "@/api/webApi/career-other";
+export default {
+  components: {
+    Pagination
+  },
+  data() {
+    return {
+      hollData: [],
+      hollTotal: 0,
+      hollPageForm: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      mbtiData: [],
+      mbtiTotal: 0,
+      mbtiPageForm: {
+        pageNum: 1,
+        pageSize: 10,
+      },
+      propDefines: {
+        id: {
+          label: "ID",
+        },
+        createTime: {
+          label: "测评时间",
+          slot: "time",
+        },
+        scorer: {
+          label: "现实型",
+        },
+        scorea: {
+          label: "艺术型",
+        },
+        scorei: {
+          label: "研究型",
+        },
+        scores: {
+          label: "社会型",
+        },
+        scoree: {
+          label: "企业型",
+        },
+        scorec: {
+          label: "传统型",
+        },
+        ruleCode: {
+          label: "测评结果",
+          slot: "nav",
+        },
+      },
+      mbtiPropDefines: {
+        id: {
+          label: "ID",
+        },
+        createTime: {
+          label: "测评时间",
+          slot: "time",
+        },
+        scoreE: {
+          label: "外向",
+        },
+        scoreI: {
+          label: "内向",
+        },
+        scoreS: {
+          label: "实感",
+        },
+        scoreN: {
+          label: "直觉",
+        },
+        scoreT: {
+          label: "思考",
+        },
+        scoreF: {
+          label: "情感",
+        },
+        scoreJ: {
+          label: "判断",
+        },
+        scoreP: {
+          label: "认知",
+        },
+        ruleCode: {
+          label: "测评结果",
+          slot: "nav",
+        },
+      },
+    };
+  },
+  created() {
+    this.getHollandRecord();
+    this.getMbtiRecord()
+  },
+  methods: {
+    getHollandRecord() {
+      hollandRecord(this.hollPageForm).then((res) => {
+        this.hollData = res.rows;
+        this.hollTotal = res.total;
+        console.log(res);
+      });
+    },
+    onHollChangePage(page){
+      this.hollPageForm.pageSize = page.limit;
+      this.hollPageForm.pageNum = page.page;
+      this.getHollandRecord();
+    },
+    onMbtiChangePage(page){
+      this.mbtiPageForm.pageSize = page.limit;
+      this.mbtiPageForm.pageNum = page.page;
+      this.getMbtiRecord();
+    },
+    getMbtiRecord() {
+      mbtiRecord(this.mbtiPageForm).then((res) => {
+        this.mbtiData = res.rows;
+        this.mbtiTotal = res.total;
+        console.log(res);
+      });
+    }
+  },
+};
+</script>
+<style lang="scss" scoped>
+.banner {
+  position: relative;
+}
+.banner p {
+  bottom: 10%;
+  left: 50%;
+  transform: translateX(-50%);
+  font-size: 24px;
+  font-family: PingFangSC-Semibold, PingFang SC;
+  font-weight: 600;
+  color: #525252;
+  line-height: 33px;
+  position: absolute;
+}
+</style>

+ 32 - 36
src/views/career/index.vue

@@ -1,36 +1,32 @@
-<template>
-  <div class="career-container">
-    <div class="career-wrapper">
-      <div class="career-banner">
-        <el-image :src="require('@/assets/images/career/career_banner.png')" />
-      </div>
-      <div>
-        <course-tab-page />
-      </div>
-      <div class="career-others">
-        <div class="career-others-left"></div>
-        <div class="career-others-right"></div>
-      </div>
-    </div>
-  </div>
-</template>
-<script>
-import courseTabPage from "./components/courseTabPage.vue";
-export default {
-  components: { courseTabPage },
-};
-</script>
-<style lang="scss" scoped>
-.career-container {
-  background-color: #ffffff;
-  padding: 20px;
-  display: flex;
-  justify-content: center;
-  align-items: center;
-}
-.career-wrapper {
-  width: 1184px;
-  display: flex;
-  flex-direction: column;
-}
-</style>
+<template>
+  <div class="career-container">
+    <div class="career-wrapper">
+      <div class="career-banner">
+        <el-image :src="require('@/assets/images/career/career_banner.png')" />
+      </div>
+      <div>
+        <course-tab-page />
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+import courseTabPage from "./components/courseTabPage.vue";
+export default {
+  components: { courseTabPage },
+};
+</script>
+<style lang="scss" scoped>
+.career-container {
+  background-color: #ffffff;
+  padding: 20px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+.career-wrapper {
+  width: 1184px;
+  display: flex;
+  flex-direction: column;
+}
+</style>

+ 1 - 1
src/views/career/plan/ProfessLib.vue

@@ -129,7 +129,7 @@
     getProfesslibData
   } from "@/api/webApi/professlib"
 export default {
-  name:'ProfessLib',
+  name:'OldProfessLib',
   data() {
     return {
       input1:'',

+ 433 - 0
src/views/career/plan/new-profess-detail.vue

@@ -0,0 +1,433 @@
+<template>
+  <div id="professDetail" style="padding:24px 5%">
+    <el-row :gutter="20">
+      <el-col :span="6">
+        <el-tabs type="border-card" @tab-click="tabClick" :value="type" stretch>
+          <el-tab-pane label="本科" name="本科">
+            <el-tree
+              :data="majorList"
+              :props="defaultProps"
+            ></el-tree>
+          </el-tab-pane>
+          <el-tab-pane label="专科"  name="专科">
+            <el-tree
+              :data="majorList"
+              :props="defaultProps"
+            ></el-tree>
+          </el-tab-pane>
+        </el-tabs>
+      </el-col>
+      <el-col :span="18">
+        <div >
+          <el-card style="color: #5E5E5E;" ref="navBar">
+            <el-breadcrumb separator-class="el-icon-arrow-right">
+              <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+              <el-breadcrumb-item :to="{ path: '/career/plan/ProfessLib'}">专业库</el-breadcrumb-item>
+              <el-breadcrumb-item>专业详情</el-breadcrumb-item>
+            </el-breadcrumb>
+          </el-card>
+          <div class="mt20 header-content pd20">
+            <p class="f28 f-333 mb20">{{ majorDetail.name || '' }}</p>
+            <p class="f14 f-666">{{ `国标代码${majorDetail.code}(不可用于填报)` }}</p>
+          </div>
+          <div class="tabs-wrap">
+            <span class="tabs-item" @click="tabActive = 0" :class="{'bg-primary':tabActive == 0}">专业概况</span>
+            <span class="tabs-item" @click="tabActive = 1" :class="{'bg-primary':tabActive == 1}">就业前景</span>
+            <span class="tabs-item" @click="tabActive = 2" :class="{'bg-primary':tabActive == 2}">开设院校</span>
+          </div>
+          <p class="line"></p>
+          <div
+            v-show="loading"
+            class="loading-div"
+            v-loading="loading"
+            :style="{height:windowHeight + 'px'}"
+          >
+          </div>
+
+          <div class="content-wrap mt20">
+            <!-- 专业概况  -->
+            <div v-if="tabActive == 0">
+              <div class="info-wrap">
+                <div class="info-item"></div>
+              </div>
+              <div class="desc-item" v-for="(item,index) in contentProps">
+                <p class="format-tit">{{getDetailContent(index,'title')}}</p>
+                <div class="f-666 f14" v-html="getDetailContent(index,item)"></div>
+              </div>
+            </div>
+            <!--  就业岗位-->
+            <div v-if="tabActive == 1 && !!prospects">
+              <div class="desc-item" >
+                <p class="format-tit">就业方向</p>
+                <div class="f-666 f14" v-html="prospects.jobDirection"></div>
+              </div>
+              <div class="desc-item" >
+                <p class="format-tit">平均薪酬(毕业年限) <span class="f-333 f14 ml20">{{`平均薪资:${reverseSalary[0].value}`}}</span></p>
+                <div class="f-666 f14" >
+                  <el-row :gutter="10">
+                    <el-col :span="12">
+                      <mx-chart :options="chartSalary" height="240px"></mx-chart>
+                    </el-col>
+                    <el-col style="height: 100%" :span="12">
+                      <el-row :gutter="40" type="flex" style="flex-wrap: wrap">
+                        <el-col :span="12" class="f16" v-for="(item,index) in  reverseSalary">
+                          <el-row class="format-job-wrap">
+                            <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                            <el-col :span="15" class="f-333">{{item.name}}</el-col>
+                            <el-col :span="6" class="f-666  text-right f14">{{item.value}}</el-col>
+                          </el-row>
+                        </el-col>
+                      </el-row>
+                    </el-col>
+                  </el-row>
+                </div>
+              </div>
+              <el-row :gutter="10" type="flex">
+                <el-col :span="8">
+                  <div class="desc-item" >
+                    <p class="format-tit">主要职业分布</p>
+                    <div class="f-666 f14" >
+                      <mx-chart :options="industry" height="200px"></mx-chart>
+                      <el-collapse accordion>
+                        <el-collapse-item v-for="desc in prospects.vocationalDistribution">
+                          <template slot="title">
+                            <div  style="display: flex;justify-content: space-between;width: 100%;">
+                              <span style="color: #42b983">{{ desc.name }}</span>
+                              <span class="f-red">{{ desc.value }}%</span>
+                            </div>
+                          </template>
+                          <div>{{ desc.expands }}</div>
+                        </el-collapse-item>
+                      </el-collapse>
+                    </div>
+                  </div>
+                </el-col>
+                <el-col :span="8">
+                  <div class="desc-item" >
+                    <p class="format-tit">主要行业分布</p>
+                    <div class="f-666 f14">
+                      <mx-chart :options="industry" height="200px"></mx-chart>
+                      <el-row >
+                        <el-col :span="24" class="f16" v-for="(item,index) in  prospects.industryDistribution">
+                          <el-row class="format-job-wrap">
+                            <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                            <el-col :span="18" class="f-333">{{item.name}}</el-col>
+                            <el-col  :span="3" class="f-red  text-right f14">{{item.value}}%</el-col>
+                          </el-row>
+                        </el-col>
+                      </el-row>
+                    </div>
+                  </div>
+                </el-col>
+                <el-col :span="8">
+                  <div class="desc-item" >
+                    <p class="format-tit">主要就业地区分布</p>
+                    <div class="f-666 f14">
+                      <mx-chart :options="jobAddress" height="200px"></mx-chart>
+                      <el-row >
+                        <el-col :span="24" class="f16" v-for="(item,index) in  prospects.jobRegionDistribution">
+                          <el-row class="format-job-wrap">
+                            <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                            <el-col :span="18" class="f-333">{{item.name}}</el-col>
+                            <el-col  :span="3" class="f-red  text-right f14">{{item.value}}%</el-col>
+                          </el-row>
+                        </el-col>
+                      </el-row>
+                    </div>
+                  </div>
+                </el-col>
+              </el-row>
+              <el-row :gutter="10" class="f-12 f-666">
+                <p><i class="el-icon mr5 f-16 el-icon-warning" style="color: #42b983"> </i>数据说明</p>
+                <p v-for="(desc,index) in prospects.description">
+                  {{index+  1}}、 {{desc}}
+                </p>
+              </el-row>
+            </div>
+            <div v-if="tabActive == 2 ">
+              暂无
+            </div>
+            <div v-if="tabActive == 1 && !prospects">
+              {{ desc }}
+            </div>
+          </div>
+        </div>
+      </el-col>
+    </el-row>
+
+  </div>
+</template>
+<script>
+import MxChart from '@/components/MxChart/index'
+import { allMajor, careerProspects, majorOverview } from '@/api/webApi/professlib'
+
+export default {
+  name: 'ProfessLibDetails',
+  components: {
+    MxChart
+  },
+  data() {
+    return {
+      desc: '',
+      loading: false,
+      code: '',
+      tabActive: 0,
+      defaultProps: {
+        children: 'children',
+        label: 'label'
+      },
+      type: '本科',
+      majorList: [],
+      majorDetail: {}, // 概况
+      prospects: {}, // 前景
+      contentPropsByBen: ['introduction', 'eduObjective', 'eduRequirement', 'subjectRequirement', 'loreAndAbility', 'studyDirection', 'mainCourse', 'famousScholar'], // 本科概况列
+      contentTotalByBen: ['专业介绍', '培养目标', '培养要求', '学科要求', '知识能力', '考研方向', '主要课程', '社会名人'], // 本
+      contentPropsByZhuan: ['eduObjective', 'internshipDesc', 'jobDirection', 'loreAndAbility', 'zhuanToBenOrient', 'mainCourse'], // 本科概况列
+      contentTotalByZhuan: ['培养目标', '实习实训', '职业资格证书举例', '知识能力', '专升本方向', '主要课程'], // 专
+      windowHeight: document.documentElement.clientHeight
+    }
+  },
+  computed: {
+    // 平均薪资趋势
+    reverseSalary() {
+      if (!this.prospects.averageSalary) return null
+      const averageSalary = this.deepClone(this.prospects.averageSalary)
+      return averageSalary.reverse().splice(0 ,10)
+    },
+    // 主要职业分布
+
+    // 主要行业分布
+    industry() {
+      if (!this.prospects.industryDistribution) return null
+      const pieData = this.prospects.industryDistribution
+      const options  = {
+        toolbox: {
+          show: true,
+        },
+        series: [
+          {
+            type: 'pie',
+            radius: [40, 60],
+            label:{
+              formatter: '{b}'
+            },
+            labelLine: {
+              length2: 6,
+              length: 5
+            },
+            data: pieData
+          }
+        ]
+      }
+      return options
+    },
+    // 主要就业地区分布
+    jobAddress() {
+      if(!this.prospects.jobRegionDistribution.length) return
+      const pieData = this.prospects.jobRegionDistribution
+      const options  = {
+        toolbox: {
+          show: true,
+        },
+        series: [
+          {
+            type: 'pie',
+            radius: [40, 60],
+            label:{
+              formatter: '{b}'
+            },
+            labelLine: {
+              length2: 6,
+              length: 5
+            },
+            data: pieData
+          }
+        ]
+      }
+      return options
+    },
+    chartSalary() {
+      if (!this.prospects.averageSalary) return null
+      const col = this.prospects.averageSalary.map(item => item.name + '年')
+      const row = this.prospects.averageSalary.map(item => item.value)
+      const options  = {
+        grid:{
+          left: '2%',
+          right: '2%',
+          bottom: '3%',
+          top: '14%',
+          containLabel: true
+        },
+        tooltip: {
+          trigger: 'axis'
+        },
+        xAxis: {
+          data: col,
+          axisLine: {
+            lineStyle: {
+              type: 'dashed'
+            }
+          },
+          axisTick: {
+            alignWithLabel: true
+          },
+        },
+        yAxis: {
+          type: 'value',
+        },
+        series: [
+          {
+            type: 'line',
+            color: '#47C6A2',
+            stack: 'Total',
+            label: {
+              show: true,
+              position: 'top',
+            },
+            smooth: false,
+            data: row
+          },
+        ]
+
+      }
+      return options
+    },
+    contentProps() {
+      if(this.majorDetail.eduLevel == 'ben') return this.contentPropsByBen
+      if(this.majorDetail.eduLevel == 'zhuan') return this.contentPropsByZhuan
+    },
+    contentTotal() {
+      if(this.majorDetail.eduLevel == 'ben') return this.contentTotalByBen
+      if(this.majorDetail.eduLevel == 'zhuan') return this.contentTotalByZhuan
+    },
+    getDetailContent() {
+      return function(id, type) {
+        if(type==='title'){
+          return this.contentTotal[id]
+        }
+        const flag = this.contentProps.some(item=>{
+          return item===type
+        })
+        if(flag){
+          return this.majorDetail[type]
+        }
+      }
+    }
+  },
+  watch: {
+    tabActive: {
+      handler(newVal) {
+        // 2 院校 1 前景 0 概览
+        if (newVal == 0) this.getOverView()
+        if (newVal == 1) this.getCareerProspects()
+      }
+    },
+    type: {
+      immediate: true,
+      handler(newVal) {
+        // 2 院校 1 前景 0 概览
+        this.getAllMajor()
+      }
+    },
+    '$route': {
+      immediate: true,
+      handler(val) {
+        this.code = val.query.code
+        if (val.query.code) {
+          this.getOverView()
+        }
+      }
+    }
+  },
+  methods: {
+    tabClick(type) {
+      this.type =type.name
+    },
+    getAllMajor() {
+      allMajor({
+        type: this.type
+      }).then(res => {
+        this.majorList = res.data
+      })
+    },
+    getCareerProspects() {
+      this.loading = true
+      careerProspects({
+        code: this.code
+      }).then(res => {
+        this.prospects = res.data
+        this.desc = res.msg
+        console.log(res)
+      }).finally(_ => {
+        this.loading = false
+      })
+    },
+    getOverView() {
+      this.loading = true
+      majorOverview({
+        code: this.code
+      }).then(res => {
+        console.log(res)
+        this.majorDetail = res.data
+      }).finally(_ => {
+        this.loading = false
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+#professDetail {
+  .header-content {
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(66, 185, 131, 0.1);
+  }
+
+  .tabs-wrap {
+    margin-top: 20px;
+    height: 40px;
+    .tabs-item {
+      cursor: pointer;
+      padding: 0 33px;
+      border-radius: 4px 4px 0 0;
+      display: inline-block;
+      line-height: 40px;
+      &:hover {
+        color: #47C6A2;
+      }
+      &.bg-primary {
+        background: #47C6A2;
+        color: white;
+      }
+    }
+  }
+
+  .bg-primary {
+    background: #47C6A2 !important;
+    color: white;
+  }
+  .format-tit{
+    border-left: 4px solid #47C6A2;
+    padding-left: 10px;
+    margin-bottom: 20px;
+    font-size: 20px;
+  }
+  .desc-item{
+    margin-bottom: 40px;
+  }
+  .format-job-wrap {
+    display: flex;
+    height: 44px;
+    line-height: 44px;
+    border-bottom: 1px solid #f2f2f2;
+  }
+
+  .line {
+    background: #47C6A2;
+    height: 1px;
+  }
+}
+</style>

+ 217 - 0
src/views/career/plan/new-profess-lib.vue

@@ -0,0 +1,217 @@
+<template>
+  <div id="vocation" ref="vocation">
+    <el-card style="height:158px;margin: 10px auto;">
+      <div :style="{'background-image':backimg}" class="back">
+        <p style="color:#A6A6A6;font-size:24px;font-weight:bold;">Professional library</p>
+        <p style="color:#414141;font-size:24px;font-weight:bold;">专业库</p>
+        <hr class="layui-bg-orange" style="width:40px;height:4px;margin-top:10px;" />
+      </div>
+    </el-card>
+    <el-card class="box-card" >
+      <div slot="header"  >
+        <span class="tabs-item" @click="type = '本科'" :class="{'bg-primary':type == '本科'}">本科</span>
+        <span class="tabs-item" @click="type = '专科'" :class="{'bg-primary':type == '专科'}">专科</span>
+        <p class="line"></p>
+        <div class="tags-wrap">
+          <a :href="`#${item.code}`" class="tag" v-for="item in levelOne">{{ item.name }}</a>
+        </div>
+      </div>
+      <div class="list-wrap">
+        <!--  一级 -->
+        <div class="levelOne" v-for="item in majorList" :id="item.code">
+          <!--   一级专业title-->
+          <p class="voca-title mt10 mb10" > <span class="primaryColor bold">{{`${item.name} (${item.code}) `}} </span><span class="f14 f-666">{{ `${item.childCount}4个专业类,${item.grandchildCount}个专科专业` }}</span></p>
+          <div class="last-level" v-for="subLevel in item.children">
+            <!--  二级专业 -->
+            <p class="sub-title">{{`${subLevel.name} (${subLevel.code}) `}}</p>
+            <!--  三级专业 -->
+            <div class="last-children-wrap" v-if="subLevel.children.length > 0">
+              <span @click="goDetail(vocation.code)" class="last-children" v-for="vocation in subLevel.children">{{vocation.name}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import {mapState} from 'vuex';
+import { allMajor } from '@/api/webApi/professlib';
+export default {
+  name: "index",
+  data(){
+    return {
+      backimg:'url('+require('@/assets/images/icon_pro.png')+')',
+      type: '本科',
+      masterMajorList: [],  // 本科
+      specialtyMajorList: [], // 专科
+    }
+  },
+  computed:{
+    ...mapState({theme: state => state.settings.theme}),
+    levelOne() {
+        return this.majorList.map(item=>{
+          return {
+            code: item.code,
+            name: item.name,
+          }
+        })
+    },
+    majorList() {
+      if(this.type == '本科') return this.masterMajorList
+      if(this.type == '专科') return this.specialtyMajorList
+    }
+  },
+  watch:{
+    theme:{
+      immediate:true,
+      handler(val){
+        this.$nextTick(()=>{
+          this.$refs.vocation.style.setProperty('--themeColor', val)
+        })
+      }
+    },
+    type: {
+      immediate:true,
+      handler(val){
+        console.log(val)
+        if((val  == '本科' && this.masterMajorList.length == 0) || (val  == '专科' && this.specialtyMajorList.length == 0)){
+          this.getAllMajor()
+        }
+
+      }
+    }
+  },
+  methods:{
+    goDetail(code){
+      this.$router.push({path:'/career/plan/ProfessLibDetail',query:{code:code}})
+    },
+    getAllMajor() {
+      allMajor({
+        type: this.type
+      }).then(res => {
+        if(this.type == '本科'){
+          this.masterMajorList = res.data
+        }
+        if(this.type == '专科'){
+          this.specialtyMajorList = res.data
+        }
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+#vocation{
+  .levelOne{
+    padding-top:100px;
+    margin-top:-100px;
+  }
+  .layui-bg-orange{
+    background-color: var(--themeColor);
+    margin-left:0;
+  }
+  .back{
+    padding:30px;
+    margin-top: 10px;background-color:white;background-repeat: no-repeat;background-position: bottom right;
+  }
+  .title{
+    background-color: var(--themeColor);
+    width: 162px;
+    height: 37px;
+    color: #fff;
+    font-size: 16px;
+    line-height: 37px;
+    text-align: center;
+  }
+  .line {
+    background-color: var(--themeColor);
+    height: 4px;
+  }
+  .last-children-wrap{
+    flex-wrap: wrap;
+    display: flex;
+    .last-children{
+      flex: 25%;
+      flex-grow: 0;
+      margin-bottom: 10px;
+      color: var(--themeColor);
+      &:hover{
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+
+    .tabs-item{
+      cursor: pointer;
+      padding: 0 33px;
+      border: 1px solid #f2f2f2;
+      border-bottom: 0px;
+      display: inline-block;
+      line-height: 40px;
+      &:hover{
+        color:#47C6A2;
+      }
+      &.bg-primary{
+        background: #47C6A2 ;
+        color: white;
+        border: 0px;
+      }
+    }
+
+  .tags-wrap {
+    overflow: hidden;
+    box-sizing: border-box;
+    border-top: 1px solid #e1e1e1;
+    border-left: 1px solid #e1e1e1;
+    display: flex;
+    flex-flow: row wrap;
+    justify-content: start;
+    .tag{
+      border-bottom: 1px solid #e1e1e1;
+      border-right: 1px solid #e1e1e1;
+      font-size: 12px;
+      text-align: center;
+      flex: 10%;
+      text-align: center;
+      flex-grow: 0;
+      color: #555;
+      height: 40px;
+      line-height: 40px;
+      cursor: pointer;
+      &:hover{
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+  .sub-title{
+    color: #333;
+    line-height: 26px;
+    padding: 5px 10px;
+    background: #f3f3f3;
+    margin-bottom: 2px;
+  }
+  .voca-title{
+    border-left:4px solid var(--themeColor);
+    padding:0px 5px;
+  }
+  .primaryColor{
+     color: var(--themeColor);
+  }
+  .row{
+    .rowHead{
+      background-color:#a7e6d4;
+      &:hover{
+        background-color: var(--themeColor);
+        hr{
+          background-color: #ffffff;
+        }
+      }
+    }
+  }
+}
+</style>
+

+ 39 - 0
src/views/career/subject/choose-subject.vue

@@ -0,0 +1,39 @@
+<template>
+  <div class="subject-page">
+    <el-card class="mt20 mb20" >
+      <el-breadcrumb separator="/">
+        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
+        <el-breadcrumb-item :to="{ path: '/career/plan/index' }"
+        >生涯·志愿1
+        </el-breadcrumb-item
+        >
+        <el-breadcrumb-item :to="{ path: '/career/subject/index' }"
+        >选科查询
+        </el-breadcrumb-item
+        >
+        <el-breadcrumb-item>由科目选专业</el-breadcrumb-item>
+      </el-breadcrumb>
+    </el-card>
+    <el-card>
+      <subject-choice></subject-choice>
+    </el-card>
+  </div>
+</template>
+<script>
+import SubjectChoice from'./subjectChoice'
+export default {
+  components: {
+    SubjectChoice
+  },
+  data() {
+    return{
+
+    }
+  }
+}
+</script>
+<style scoped>
+.subject-page {
+  padding: 0 100px;
+}
+</style>

+ 1 - 1
src/views/career/subject/majorChoice.vue

@@ -359,7 +359,7 @@ export default {
   border-bottom: 1px solid #eee;
   border-radius: 2px;
   background-color: #fff;
-  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
+  box-shadow: 0 1px 2px 0 rgb(0 0 0);
 }
 .content-box {
   padding: 10px 40px 10px 50px;

+ 0 - 318
src/views/career/subject/majorChoice.vue.unused

@@ -1,318 +0,0 @@
-<template>
-  <div class="major-page">
-    <div class="breadcrumb">
-      <el-breadcrumb separator="/">
-        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
-        <el-breadcrumb-item :to="{ path: '/career/plan/index' }"
-          >生涯·志愿</el-breadcrumb-item
-        >
-        <el-breadcrumb-item :to="{ path: '/career/subject/index' }"
-          >选科查询</el-breadcrumb-item
-        >
-        <el-breadcrumb-item>由专业选科目</el-breadcrumb-item>
-      </el-breadcrumb>
-    </div>
-    <div class="content-box">
-      <div class="content-top-box">
-        <div class="content-box-title">招生专业的选科要求</div>
-        <div class="my-subject-button" @click="toMyPage()">我的选科方案</div>
-      </div>
-      <div class="content-msg">
-        新高考改革方案,志愿填报将采取“专业+学校”的填报方式,由学校平行志愿转变为专业平行志愿,每个招生专业都有相应的选考科目要求。您可以通过此功能查询各学校各专业的选考科目要求。
-      </div>
-
-      <div class="table-box">
-        <mx-table
-          :rows="dataList"
-          :propDefines="propDefines"
-          @selection-change="handleSelectionChange"
-        >
-          <template #select="{ row }">
-            <img
-              class="college-icon"
-              v-if="row.collect"
-              @click="httpCollectRemove(row)"
-              src="@/assets/images/subject/icon_shoucang_pre.png"
-            />
-            <img
-              class="college-icon"
-              v-else
-              @click="httpCollectAdd(row)"
-              src="@/assets/images/subject/icon_shoucang_n.png"
-            />
-          </template>
-        </mx-table>
-        <pagination
-          v-show="total > 0"
-          :total="total"
-          :page.sync="pageNum"
-          :limit.sync="pageSize"
-          :page-size="20"
-          @pagination="onChangePage"
-        />
-      </div>
-      <div class="button-box">
-        <el-button @click="httpXkcxScheme">提交选科方案</el-button>
-      </div>
-    </div>
-    <div class="major-list-box" v-if="xkcxSchemeTotal>0">
-      <div class="major-list-title">
-        如需填报以上专业,您有以下<span>{{ xkcxSchemeTotal }}</span
-        >种选科组合可以选择
-      </div>
-      <div class="major-card-list">
-        <div
-          class="divide-equally-box"
-          v-for="(item, index) in xkcxSchemeList"
-          :key="index"
-        >
-          <div class="major-card-item">
-            <div class="major-card-title">{{ item.course }}</div>
-            <div class="major-progress-box">
-              <el-progress
-                type="circle"
-                stroke-width="14"
-                width="96"
-                color="#c8eee3"
-                :percentage="item.marjorRate"
-              ></el-progress>
-              <div class="major-progress-text">
-                可报{{ item.marjorRate }}%的专业
-              </div>
-            </div>
-            <div class="major-card-bottom-box">
-              <div class="major-card-msg" v-if="item.collect">
-                <i class="el-icon-circle-check"></i> 已加入我的选科方案
-              </div>
-              <div v-else class="major-card-button" @click="onClickJoin(item)">
-                加入我的选科方案
-              </div>
-            </div>
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { xkcxScheme, schemeAdd,xkcxlist } from "@/api/webApi/webQue";
-
-export default {
-  data() {
-    return {
-      dataList: [
-      ],
-      propDefines: {
-        selection: {
-          type: "selection"
-        },
-        universityName: {
-          label: "院校名称",
-        },
-        marjorName: {
-          label: "专业(类)名称",
-        },
-        resourcesName: {
-          label: "类中所含专业",
-          align: "left",
-        },
-        level: {
-          label: "专业层次",
-        },
-        courseRemark0: {
-          label: "首选科目",
-          align: "left",
-        },
-        courseRemark1: {
-          label: "再选科目",
-          align: "left",
-        },
-        collect: {
-          label: "选择",
-          align: "left",
-          slot: "select",
-          width: "100px",
-        },
-      },
-      selectIds: [],
-      pageNum: 1,
-      pageSize: 10,
-      total: 0,
-      xkcxSchemeTotal: 0,
-      xkcxSchemeList: [],
-    };
-  },
-  created() {
-    this.httpGetXkcxList();
-  },
-  methods: {
-    onChangePage(page) {
-      this.pageSize = page.limit;
-      this.pageNum = page.page;
-      this.httpGetXkcxList();
-    },
-    handleSelectionChange(list) {
-      let ids = [];
-      let len = list.length;
-      for (let i = 0; i < len; i++) {
-        ids.push(list[i]["id"]);
-      }
-      this.selectIds = ids;
-    },
-    onClickJoin(item) {
-      this.httpSchemeAdd(item.id);
-    },
-    httpSchemeAdd(id) {
-      schemeAdd({
-        groupId: id,
-        df: 0,
-      }).then((res) => {
-        this.httpXkcxScheme();
-        console.log(res);
-      });
-    },
-    toMyPage() {
-      this.$router.push("/career/subject/myChoice");
-    },
-    httpXkcxScheme() {
-      if (this.selectIds.length == 0) {
-        this.$message.error("请选择专业");
-        return;
-      }
-      xkcxScheme({
-        ids: this.selectIds.toString(),
-      }).then((res) => {
-        this.xkcxSchemeList = res.rows;
-        this.xkcxSchemeTotal = res.total;
-      });
-    },
-    httpGetXkcxList() {
-      xkcxlist({
-        collect:true,
-        pageNum: this.pageNum,
-        pageSize: this.pageSize,
-      })
-        .then((res) => {
-          this.dataList = res.rows;
-          this.total = res.total;
-        })
-        .catch((err) => {
-          console.log("请求出错!");
-        });
-    },
-  },
-};
-</script>
-
-
-<style scoped>
-.breadcrumb {
-  padding: 15px 30px;
-  margin: 15px 0;
-  border-bottom: 1px solid #eee;
-  border-radius: 2px;
-  background-color: #fff;
-  box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
-}
-.el-breadcrumb {
-  font-size: 16px !important;
-}
-.content-box {
-  padding: 60px 40px 60px 50px;
-}
-.content-box-title {
-  color: #47c6a2;
-  font-size: 24px;
-}
-.content-top-box {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-}
-.my-subject-button {
-  color: #47c6a2;
-  cursor: pointer;
-  font-size: 14px;
-  border: 1px solid #47c6a2;
-  padding: 13px 110px;
-}
-.content-msg {
-  margin: 32px 0;
-  font-size: 16px;
-}
-.button-box {
-  padding: 30px;
-  display: flex;
-  justify-content: center;
-}
-.major-list-title {
-  color: #4c4c4c;
-  font-size: 24px;
-  text-align: center;
-  margin-top: 100px;
-}
-.major-list-title span {
-  color: #d28140;
-}
-.major-card-list {
-  margin-top: 30px;
-  display: flex;
-  flex-wrap: wrap;
-}
-.divide-equally-box {
-  width: 33%;
-  margin: 0px auto;
-}
-.major-card-item {
-  width: 320px;
-  margin: 20px auto;
-  background: rgba(255, 255, 255, 1);
-  box-shadow: 2px 2px 10px 0px rgb(0 0 0 / 10%);
-  margin-top: 20px;
-}
-.major-card-title {
-  text-align: center;
-  background: #47c6a2;
-  color: #fff;
-  font-size: 24px;
-  font-weight: 600;
-  padding: 25px 0px;
-}
-.major-progress-box {
-  padding: 40px 0 20px 0;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-.major-progress-text {
-  margin-top: 20px;
-}
-.major-card-bottom-box {
-  border-top: 1px solid #eee;
-  margin: 0 auto;
-  width: 80%;
-  padding: 20px 0;
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-}
-.major-card-button {
-  width: 100%;
-  background: #47c6a2;
-  color: #fff;
-  height: 48px;
-  text-align: center;
-  line-height: 48px;
-  cursor: pointer;
-}
-.major-card-msg {
-  height: 48px;
-  line-height: 48px;
-  color: #73a0fa;
-}
-/deep/ .el-progress__text {
-  font-size: 18px !important;
-  color: #73a0fa;
-}
-</style>

+ 71 - 55
src/views/career/subject/subjectChoice.vue

@@ -1,21 +1,6 @@
 <template>
-  <div class="subject-page">
-    <div class="breadcrumb">
-      <el-breadcrumb separator="/">
-        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
-        <el-breadcrumb-item :to="{ path: '/career/plan/index' }"
-        >生涯·志愿1
-        </el-breadcrumb-item
-        >
-        <el-breadcrumb-item :to="{ path: '/career/subject/index' }"
-        >选科查询
-        </el-breadcrumb-item
-        >
-        <el-breadcrumb-item>由科目选专业</el-breadcrumb-item>
-      </el-breadcrumb>
-    </div>
+  <div >
     <div class="content-box">
-      <el-card>
         <div>
           <el-row class="radioInput">
             <div>
@@ -106,23 +91,25 @@
           </el-row>
         </div>
         <div class="content">
-          <div class="xkcx-input-box">
-            <div class="search_header">
-              <input
-                placeholder="请输入内容"
-                v-model="keyword"
-                @keyup.enter="httpGetXkcxList()"
-              />
-              <img
-                src="@/assets/images/icon_search2.png"
-                alt=""
-                @click="httpGetXkcxList()"
-              />
-            </div>
-          </div>
-          <div class="concerned-college-container">
+<!--          <div class="xkcx-input-box">-->
+<!--            <div class="search_header">-->
+<!--              <input-->
+<!--                placeholder="请输入内容"-->
+<!--                v-model="keyword"-->
+<!--                @keyup.enter="httpGetXkcxList()"-->
+<!--              />-->
+<!--              <img-->
+<!--                src="@/assets/images/icon_search2.png"-->
+<!--                alt=""-->
+<!--                @click="httpGetXkcxList()"-->
+<!--              />-->
+<!--            </div>-->
+<!--          </div>-->
+          <mx-search-group class="mb10" justify="end" :span="12" v-model="keyword" placeholder="请输入内容" @search="httpGetXkcxList"
+          ></mx-search-group>
+          <div class="concerned-college-container" v-loading="loading">
             <mx-table :rows="dataList" :propDefines="propDefines">
-              <template #select="{ row }">
+              <template #collect="{ row }">
                 <img
                   class="college-icon"
                   v-if="row.collect"
@@ -136,6 +123,13 @@
                   src="@/assets/images/subject/icon_shoucang_n.png"
                 />
               </template>
+              <template #select="{ row }">
+                <div @click="saveCourseCollect(row)">
+                  <i class="el-icon el-icon-success"  style="color: #42b983" v-if="row.isSelectCourse"></i>
+                  <i class="el-icon el-icon-success"  v-else></i>
+                </div>
+
+              </template>
             </mx-table>
             <pagination
               v-show="total > 0"
@@ -147,16 +141,29 @@
             />
           </div>
         </div>
-      </el-card>
     </div>
   </div>
 </template>
 
 <script>
   import { selectUniversity } from '@/api/webApi/career-course'
-  import {collectAdd, collectRemove, xkcxlist, xkcxYears} from "@/api/webApi/webQue";
+  import {collectAdd, collectRemove, xkcxlist, xkcxYears,saveSelectCourse} from "@/api/webApi/webQue";
+  import MxSearchGroup from "@/components/MxSearch/mx-search-group";
 
   export default {
+    props: {
+      course0:{
+        type: String,
+        default: ''
+      },
+      course1:{
+        type: String,
+        default: ''
+      }
+    },
+    components : {
+      MxSearchGroup
+    },
     data() {
       return {
         // 初始条件
@@ -173,6 +180,7 @@
         pageNum: 1,
         pageSize: 20,
         total: 0,
+        loading: false,
         keyword: "",
         // 查询结果
         dataList: [],
@@ -204,7 +212,13 @@
             align: "left",
           },
           collect: {
-            label: "选择",
+            label: "收藏",
+            align: "left",
+            slot: "collect",
+            width: "100px",
+          },
+          subjectCollect: {
+            label: "选科收藏",
             align: "left",
             slot: "select",
             width: "100px",
@@ -213,8 +227,12 @@
       };
     },
     created() {
+      this.selected.sciences[0] = this.course0 ? [this.course0] : []
+      this.selected.sciences[1] = this.course1? this.course1.split(',') :[]
+      if(this.course0 && this.course1) this.httpGetXkcxList()
       this.getYears();
       this.getUniversity();
+
     },
     methods: {
       // 取有效年份清单
@@ -257,6 +275,7 @@
         if (this.selected.sciences[0].length<1 || this.selected.sciences[1].length<2) return;
 
         //console.log(this.selected);return;
+        this.loading = true
         xkcxlist({
           level:this.selected.levels.toString(),
           keyword: this.keyword,
@@ -278,7 +297,9 @@
           .catch((err) => {
             console.log("请求出错!");
             this.cleanSchoolSelect();
-          });
+          }).finally(() => {
+            this.loading = false
+        })
       },
 
       onChangePage(page) {
@@ -293,6 +314,18 @@
           refId: row.id,
         });
       },
+      // 选科收藏 取消和收藏
+      saveCourseCollect(row) {
+        saveSelectCourse({
+          refId:row.id,
+          isSelectCourse: !row.isSelectCourse
+        }).then(res =>{
+          if(res.code== 200){
+            row.isSelectCourse = !row.isSelectCourse
+            this.$message.success(res.msg)
+          }
+        })
+      },
       // 取消收藏
       httpCollectRemove(row) {
         row.collect = false;
@@ -305,31 +338,14 @@
 </script>
 
 <style scoped>
-.xkcx-input-box {
-  padding: 20px 0;
-  display: flex;
-  margin-top: -3em;
+.el-icon-success{
+  cursor: pointer;
 }
-  .subject-page {
-    padding: 0 100px;
-  }
 
 .college-icon {
   cursor: pointer;
 }
 
-  .breadcrumb {
-    padding: 15px 30px;
-    margin: 15px 0;
-    border-bottom: 1px solid #eee;
-    border-radius: 2px;
-    background-color: #fff;
-    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
-  }
-
-  .content-box {
-    padding: 10px 40px 10px 50px;
-  }
 
   .search_header {
     margin-left: auto;

+ 0 - 854
src/views/career/subject/subjectChoice.vue.unused

@@ -1,854 +0,0 @@
-<template>
-  <div class="subject-page">
-    <div class="breadcrumb">
-      <el-breadcrumb separator="/">
-        <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
-        <el-breadcrumb-item :to="{ path: '/career/plan/index' }"
-        >生涯·志愿
-        </el-breadcrumb-item
-        >
-        <el-breadcrumb-item :to="{ path: '/career/subject/index' }"
-        >选科查询
-        </el-breadcrumb-item
-        >
-        <el-breadcrumb-item>由科目选专业</el-breadcrumb-item>
-      </el-breadcrumb>
-    </div>
-    <div class="content-box">
-      <div class="content-top-box">
-        <div class="content-box-title">根据科目(组合)查询可报专业</div>
-        <div class="my-subject-button" @click="toMyPage()">我的选科方案</div>
-      </div>
-      <div class="content-msg">
-        高校招生专业必须给出最多3门选考科目要求,根据考生选择的不同选考科目,未来志愿填报时可选择的专业也会有相应不同。任意一个选科组合考生有一定范围的专业选择。您可以根据自己的选考科目优势,或者选考科目的竞争度来自主搭配选考科目组合,查询可报专业。
-      </div>
-
-      <div class="select-box">
-        <div class="select-item">
-          <div class="select-msg">
-            * 请在“物理”和“历史”两门科目中,任意选择1门(必选)
-          </div>
-          <div class="select-click-list">
-            <div
-              class="select-box-click-item two"
-              :class="isShowScience(item.name) ? 'active' : ''"
-              v-for="(item, index) in scienceList"
-              :key="index"
-              @click="onClickScience(item)"
-            >
-              <div>{{ item.name }}</div>
-              <div
-                class="select-box-click-item-icon"
-                v-if="isShowScience(item.name)"
-              >
-                <i class="el-icon-check"></i>
-              </div>
-            </div>
-          </div>
-        </div>
-        <div class="select-item">
-          <div class="select-msg">
-            * 请从以下4门可选科目中点击选中2个,查询对应的可报专业信息
-          </div>
-          <div class="select-click-list">
-            <div
-              class="select-box-click-item four"
-              :class="isShowLiberalArts(item.name) ? 'active' : ''"
-              v-for="(item, index) in liberalArts"
-              @click="onClickLiberalArts(item)"
-              :key="index"
-            >
-              <div>{{ item.name }}</div>
-              <div
-                class="select-box-click-item-icon"
-                v-if="isShowLiberalArts(item.name)"
-              >
-                <i class="el-icon-check"></i>
-              </div>
-            </div>
-          </div>
-        </div>
-        <img src="@/assets/images/subject/img_dEmAZ_5698_big.png"/>
-      </div>
-      <el-button type="primary" @click="onSearch">查询可报专业</el-button>
-
-      <div class="xkcx-list-box" v-if="isShowTable">
-        <div class="xkcx-list-title">
-          <span>选择“</span>
-          <span>{{ getSubjectText() }}</span>
-          <span>”作为选考科目可填报以下{{ total }}个专业</span>
-        </div>
-        <div class="xkcx-input-box">
-          <div>
-            <el-select
-              v-model="selectNian"
-              @change="onChangeYear"
-              placeholder="全部年份"
-            >
-              <el-option
-                v-for="(item, index) in yearList"
-                :key="index"
-                :label="item"
-                :value="item"
-              >
-              </el-option>
-            </el-select>
-          </div>
-          <div class="button-school">
-            <el-button plain @click="onChangeSchoolPopup">
-              学校
-              <i class="el-icon-my-button"></i>
-            </el-button>
-          </div>
-          <div class="button-major">
-            <el-button plain @click="onChangeMajorPopup">
-              专业<i class="el-icon-my-button"></i
-            ></el-button>
-          </div>
-          <div class="search_header">
-            <input
-              placeholder="请输入内容"
-              v-model="keyword"
-              @keyup.enter="checkData()"
-            />
-            <img
-              src="@/assets/images/icon_search2.png"
-              alt=""
-              @click="checkData()"
-            />
-          </div>
-        </div>
-        <div class="concerned-college-container">
-          <mx-table :rows="dataList" :propDefines="propDefines">
-            <template #select="{ row }">
-              <img
-                class="college-icon"
-                v-if="row.collect"
-                @click="httpCollectRemove(row)"
-                src="@/assets/images/subject/icon_shoucang_pre.png"
-              />
-              <img
-                class="college-icon"
-                v-else
-                @click="httpCollectAdd(row)"
-                src="@/assets/images/subject/icon_shoucang_n.png"
-              />
-            </template>
-          </mx-table>
-          <pagination
-            v-show="total > 0"
-            :total="total"
-            :page.sync="pageNum"
-            :limit.sync="pageSize"
-            :page-size="20"
-            @pagination="onChangePage"
-          />
-        </div>
-      </div>
-    </div>
-    <div>
-      <el-dialog
-        :visible="isShowSchoolPopup"
-        width="75%"
-        :before-close="onChangeSchoolPopup"
-      >
-        <div class="popup-box">
-          <div class="popup-item">
-            <div class="popup-item-title">地域选择<span>(可多选)</span></div>
-            <div class="popup-item-content">
-              <el-checkbox-group v-model="selectLocation">
-                <el-checkbox
-                  class="check-box-item"
-                  :label="item"
-                  v-for="(item, index) in locationsList"
-                  :key="index"
-                ></el-checkbox>
-              </el-checkbox-group>
-            </div>
-          </div>
-          <div class="popup-item">
-            <div class="popup-item-title">院校特色<span>(可多选)</span></div>
-            <div class="popup-item-content">
-              <el-checkbox-group v-model="selectCharacteristic">
-                <el-checkbox
-                  class="check-box-item"
-                  :label="item.code"
-                  v-for="(item, index) in characteristicList"
-                  :key="index"
-                >{{ item.label }}
-                </el-checkbox
-                >
-              </el-checkbox-group>
-            </div>
-          </div>
-          <div class="popup-item">
-            <div class="popup-item-title">院校类别<span>(可多选)</span></div>
-            <div class="popup-item-content">
-              <el-checkbox-group v-model="selectTypes">
-                <el-checkbox
-                  class="check-box-item"
-                  :label="item"
-                  v-for="(item, index) in typesList"
-                  :key="index"
-                ></el-checkbox>
-              </el-checkbox-group>
-            </div>
-          </div>
-          <div class="bottom-box">
-            <div class="popup-msg">*请点击(或取消)以下学校信息进行筛选</div>
-            <div class="button-list">
-              <el-button @click="cleanSchoolSelect">清空</el-button>
-              <el-button @click="schoolSubmit" type="primary">确定</el-button>
-            </div>
-          </div>
-        </div>
-      </el-dialog>
-      <el-dialog
-        :visible="isShowMajorPopup"
-        width="75%"
-        :before-close="onChangeMajorPopup"
-      >
-        <div class="popup-box major-box">
-          <div class="popup-select">
-            <div
-              class="popup-select-item"
-              :class="marjorsType == '本科' ? 'active' : ''"
-              @click="clickMarjorsType('本科')"
-            >
-              本科
-            </div>
-            <div
-              class="popup-select-item"
-              :class="marjorsType == '高职专科' ? 'active' : ''"
-              @click="clickMarjorsType('高职专科')"
-            >
-              专科
-            </div>
-          </div>
-          <div class="choice-box">
-            <div class="choice-item">
-              <div
-                class="choice-item-menv"
-                v-for="(item, index) in marjorsList"
-                :key="index"
-                :class="curMarjorsCode == item.code ? 'active' : ''"
-                @click="changeMajor(item)"
-              >
-                {{ item.name }}
-              </div>
-            </div>
-            <div class="choice-item">
-              <div
-                class="choice-item-menv"
-                v-for="(item, index) in marjorsList2"
-                :key="index"
-                :class="curMarjorsCode2 == item.code ? 'active' : ''"
-                @click="changeMajor(item)"
-              >
-                {{ item.name }}
-              </div>
-            </div>
-            <div class="choice-item">
-              <el-checkbox-group v-model="curMarjorsCode3">
-                <el-checkbox
-                  class="choice-item-checkbox"
-                  label="全选"
-                  @change="onSelectMarjorsAll"
-                ></el-checkbox>
-                <el-checkbox
-                  class="choice-item-checkbox"
-                  :label="item.name"
-                  v-for="(item, index) in marjorsList3"
-                  :key="index"
-                ></el-checkbox>
-              </el-checkbox-group>
-            </div>
-          </div>
-        </div>
-        <div class="bottom-box">
-          <div class="popup-msg">*请点击(或取消)以下学校信息进行筛选</div>
-          <div class="button-list">
-            <el-button @click="cleanMajorList">清空</el-button>
-            <el-button @click="majorSubmit" type="primary">确定</el-button>
-          </div>
-        </div>
-      </el-dialog>
-    </div>
-  </div>
-</template>
-
-<script>
-  import {
-    xkcxlist,
-    xkcxYears,
-    collectAdd,
-    collectRemove,
-    universityFilters,
-    marjorsList,
-  } from "@/api/webApi/webQue";
-
-  export default {
-    data() {
-      return {
-        scienceList: [
-          {
-            name: "物理",
-            id: 1,
-          },
-          {
-            name: "历史",
-            id: 2,
-          },
-        ],
-        liberalArts: [
-          {
-            name: "化学",
-            id: 1,
-          },
-          {
-            name: "生物",
-            id: 2,
-          },
-          {
-            name: "地理",
-            id: 3,
-          },
-          {
-            name: "政治",
-            id: 4,
-          },
-        ],
-        propDefines: {
-          universityName: {
-            label: "院校名称",
-          },
-          marjorName: {
-            label: "专业(类)名称",
-          },
-          resourcesName: {
-            label: "类中所含专业",
-            align: "left",
-          },
-          level: {
-            label: "专业层次",
-          },
-          courseRemark0: {
-            label: "首选科目",
-            align: "left",
-          },
-          courseRemark1: {
-            label: "再选科目",
-            align: "left",
-          },
-          year: {
-            label: "年份",
-            align: "left",
-          },
-          collect: {
-            label: "选择",
-            align: "left",
-            slot: "select",
-            width: "100px",
-          },
-        },
-        curSelectScienceList: "",
-        curSelectLiberalArts: [],
-        options: [],
-        selectNian: "",
-        dataList: [],
-        yearList: [],
-        pageNum: 1,
-        pageSize: 20,
-        total: 0,
-        keyword: "",
-        isShowTable: false,
-        locationsList: [],
-        typesList: [],
-        characteristicList: [],
-        selectLocation: [], //地区
-        selectTypes: [], //类别
-        selectCharacteristic: [], //选中的特色
-        isShowSchoolPopup: false,
-        isShowMajorPopup: false,
-        marjorsList: [],
-        marjorsList2: [],
-        marjorsList3: [],
-        marjorsType: "本科",
-        marjorsLevel: 1,
-        marjorsCode: "",
-        curMarjorsCode: "",
-        curMarjorsCode2: "",
-        curMarjorsCode3: [],
-      };
-    },
-    created() {
-      if (this.scienceList.length > 0) {
-        this.curSelectScienceList = this.scienceList[0]["name"];
-      }
-      if (this.liberalArts.length > 2) {
-        this.curSelectLiberalArts.push(this.liberalArts[0]["name"]);
-        this.curSelectLiberalArts.push(this.liberalArts[1]["name"]);
-      }
-      this.httpGetXkcxYears();
-      this.httpUniversityFilters();
-      this.httpGetMarjorsList();
-    },
-    methods: {
-      onSelectMarjorsAll(res) {
-        if (res) {
-          let len = this.marjorsList3.length;
-          for (let i = 0; i < len; i++) {
-            let name = this.marjorsList3[i]["name"];
-            let index = this.curMarjorsCode3.indexOf(name);
-            if (index < 0) {
-              this.curMarjorsCode3.push(name);
-            }
-          }
-        } else {
-          this.curMarjorsCode3 = [];
-        }
-      },
-      onChangeSchoolPopup() {
-        this.isShowSchoolPopup = !this.isShowSchoolPopup;
-      },
-      onChangeMajorPopup() {
-        this.isShowMajorPopup = !this.isShowMajorPopup;
-      },
-      changeMajor(res) {
-        this.curMarjorsCode3 = [];
-        switch (res.level) {
-          case 1:
-            this.curMarjorsCode = res.code;
-            break;
-          case 2:
-            this.curMarjorsCode2 = res.code;
-            break;
-        }
-        this.marjorsCode = res.code;
-        this.marjorsLevel = res.level + 1;
-        this.httpGetMarjorsList();
-      },
-      schoolSubmit() {
-        this.isShowSchoolPopup = false;
-        this.checkData();
-      },
-      majorSubmit() {
-        this.isShowMajorPopup = false;
-        this.checkData();
-      },
-      cleanSchoolSelect() {
-        this.selectLocation = [];
-        this.selectTypes = [];
-        this.selectCharacteristic = [];
-      },
-      cleanMajorList() {
-        this.curMarjorsCode3 = [];
-      },
-      getSubjectText() {
-        let rText = "";
-        rText += this.curSelectScienceList + "+";
-        let lLen = this.curSelectLiberalArts.length;
-        for (let i = 0; i < lLen; i++) {
-          rText += this.curSelectLiberalArts[i];
-          if (i != lLen - 1) {
-            rText += "+";
-          }
-        }
-        return rText;
-      },
-      clickMarjorsType(type) {
-        this.marjorsType = type;
-        this.marjorsLevel = 1;
-        this.marjorsCode = "";
-        this.httpGetMarjorsList();
-      },
-      httpGetMarjorsList() {
-        marjorsList({
-          type: this.marjorsType,
-          level: this.marjorsLevel,
-          code: this.marjorsCode,
-        }).then((res) => {
-          switch (this.marjorsLevel) {
-            case 2:
-              this.marjorsList2 = res.rows;
-              this.changeMajor(res.rows[0]);
-              break;
-            case 3:
-              this.marjorsList3 = res.rows;
-              break;
-            default:
-              this.marjorsList = res.rows;
-              this.changeMajor(res.rows[0]);
-              break;
-          }
-        });
-      },
-      httpUniversityFilters() {
-        universityFilters({}).then(({data}) => {
-          this.locationsList = data.locations;
-          this.typesList = data.types;
-          this.characteristicList = data.features;
-        });
-      },
-      httpCollectAdd(row) {
-        collectAdd({
-          refId: row.id,
-        }).then((res) => {
-          this.checkData();
-        });
-      },
-      httpCollectRemove(row) {
-        collectRemove({
-          refId: row.id,
-        }).then((res) => {
-          this.checkData();
-        });
-      },
-      onChangeYear(res) {
-        //切换学年时,取第1页
-        this.pageNum = 1;
-        this.checkData();
-      },
-      onClickScience(item) {
-        if (this.curSelectScienceList == item.name) {
-          return;
-        } else {
-          this.curSelectScienceList = item.name;
-        }
-        this.isShowTable = false;
-      },
-      onClickLiberalArts(item) {
-        let index = this.curSelectLiberalArts.indexOf(item.name);
-        if (index >= 0) {
-          this.curSelectLiberalArts.splice(index, 1);
-        } else {
-          this.curSelectLiberalArts.push(item.name);
-        }
-        this.isShowTable = false;
-      },
-      isShowScience(name) {
-        return this.curSelectScienceList == name;
-      },
-      isShowLiberalArts(name) {
-        return this.curSelectLiberalArts.indexOf(name) >= 0;
-      },
-      onSearch() {
-        this.checkData();
-      },
-      httpGetXkcxYears() {
-        xkcxYears().then((res) => {
-          this.yearList = res.data || [];
-          this.selectNian = this.yearList[0]
-        });
-      },
-      onChangePage(page) {
-        this.pageSize = page.limit;
-        this.pageNum = page.page;
-        this.checkData();
-      },
-      checkData(cb) {
-        if (this.curSelectLiberalArts.length != 2) {
-          this.$message.error("请从右侧4门可选科目中点击选择2门");
-          return;
-        }
-
-        this.httpGetXkcxList();
-      },
-      toMyPage() {
-        this.$router.push("/career/subject/myChoice");
-      },
-      httpGetXkcxList() {
-        xkcxlist({
-          level:this.marjorsType,
-          keyword: this.keyword,
-          course0: this.curSelectScienceList,
-          course1: this.curSelectLiberalArts.toString(),
-          locations: this.selectLocation.toString(),
-          ts: this.selectCharacteristic.toString(),
-          types: this.selectTypes.toString(),
-          year: this.selectNian,
-          pageNum: this.pageNum,
-          marjors: this.curMarjorsCode3.toString(),
-          pageSize: this.pageSize,
-        })
-          .then((res) => {
-            this.dataList = res.rows;
-            this.total = res.total;
-            this.isShowTable = true;
-          })
-          .catch((err) => {
-            console.log("请求出错!");
-            this.cleanSchoolSelect();
-          });
-      },
-    },
-  };
-</script>
-
-<style scoped>
-  .subject-page {
-    padding: 0 100px;
-  }
-
-  .college-icon {
-    cursor: pointer;
-  }
-
-  .breadcrumb {
-    padding: 15px 30px;
-    margin: 15px 0;
-    border-bottom: 1px solid #eee;
-    border-radius: 2px;
-    background-color: #fff;
-    box-shadow: 0 1px 2px 0 rgb(0 0 0 / 5%);
-  }
-
-  .el-breadcrumb {
-    font-size: 16px !important;
-  }
-
-  .content-box {
-    padding: 60px 40px 60px 50px;
-  }
-
-  .content-box-title {
-    color: #47c6a2;
-    font-size: 24px;
-  }
-
-  .content-top-box {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-
-  .my-subject-button {
-    color: #47c6a2;
-    font-size: 14px;
-    cursor: pointer;
-    border: 1px solid #47c6a2;
-    padding: 13px 110px;
-  }
-
-  .content-msg {
-    margin: 32px 0;
-    font-size: 16px;
-  }
-
-  .select-box {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-  }
-
-  .select-item {
-    box-sizing: border-box;
-    border: 1px dashed rgba(24, 144, 255, 1);
-    height: 334px;
-    padding: 20px;
-    margin-right: 20px;
-  }
-
-  .select-msg {
-    color: #47c6a2;
-    font-size: 14px;
-  }
-
-  .select-click-list {
-    margin-top: 40px;
-    display: flex;
-    flex-wrap: wrap;
-    justify-content: space-between;
-  }
-
-  .select-box-click-item {
-    background-color: #fbfbfb;
-    cursor: pointer;
-    height: 89px;
-    line-height: 89px;
-    font-size: 24px;
-    color: #414141;
-    font-weight: 600;
-    text-align: center;
-    position: relative;
-  }
-
-  .select-box-click-item.two {
-    margin: 10px 0;
-    width: 100%;
-  }
-
-  .select-box-click-item.four {
-    margin: 10px 0;
-    width: 46%;
-  }
-
-  .select-box-click-item.active {
-    background-color: #d4eaff !important;
-  }
-
-  .select-box-click-item-icon {
-    height: 20px;
-    width: 20px;
-    border-radius: 2px;
-    background: #47c6a2;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    font-size: 16px;
-    position: absolute;
-    right: 0;
-    bottom: 0;
-    color: #fff;
-  }
-
-  .select-button {
-    padding: 0px 60px;
-  }
-
-  .xkcx-list-title {
-    width: 100%;
-    background-color: #e8e8e8;
-    padding: 30px;
-    text-align: center;
-    font-size: 24px;
-    color: #4c4c4c;
-    margin-top: 80px;
-  }
-
-  .xkcx-input-box {
-    padding: 20px 0;
-    display: flex;
-  }
-
-  .search_header {
-    margin-left: auto;
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    justify-content: flex-end;
-    position: relative;
-    margin-right: 20px;
-  }
-
-  .search_header img {
-    position: absolute;
-    right: 20px;
-    cursor: pointer;
-    top: 6px;
-  }
-
-  .search_header input {
-    background: #f7f7ff;
-    border-radius: 20px;
-    border: 1px solid #c6cbf5;
-    outline: none;
-    width: 340px;
-    height: 32px;
-    padding-left: 24px;
-  }
-
-  .button-school {
-    margin: 0 20px;
-  }
-
-  .button-icon {
-    width: 12px;
-    height: 12px;
-  }
-
-  .el-icon-my-button {
-    background: url(../../../assets/images/subject/icon_shaixuan.png) center no-repeat;
-    background-size: cover;
-  }
-
-  .el-icon-my-button:before {
-    content: "替";
-    font-size: 16px;
-    visibility: hidden;
-  }
-
-  .popup-item-title {
-    color: #414141;
-    font-size: 16px;
-    font-weight: 600;
-  }
-
-  .popup-item-title span {
-    font-size: 14px;
-    font-weight: 500;
-  }
-
-  .check-box-item {
-    padding: 8px 0;
-    min-width: 70px;
-  }
-
-  .popup-item-content {
-    padding: 20px 0;
-  }
-
-  .popup-msg {
-    color: #ffa400;
-    font-weight: 400;
-    font-size: 14px;
-  }
-
-  .bottom-box {
-    display: flex;
-    justify-content: space-between;
-  }
-
-  .button-list {
-    padding: 0 20px;
-  }
-
-  .major-box {
-    display: flex;
-    margin-bottom: 30px;
-  }
-
-  .popup-select {
-    border-right: 1px solid #d7d7d7;
-  }
-
-  .popup-select-item {
-    cursor: pointer;
-    line-height: 30px;
-    width: 100px;
-    padding: 0 20px 0 30px;
-  }
-
-  .popup-select-item.active {
-    color: #47c6a2;
-    border-right: 2px solid #47c6a2;
-  }
-
-  .choice-box {
-    display: flex;
-  }
-
-  .choice-item {
-    margin: 0 10px;
-    min-width: 300px;
-    border: 1px solid #d7d7d7;
-    height: 300px;
-    overflow-x: hidden;
-    overflow-y: auto;
-  }
-
-  .choice-item-menv {
-    margin: 15px 20px;
-    cursor: pointer;
-  }
-
-  .choice-item-menv.active {
-    color: #47c6a2;
-  }
-
-  .choice-item-checkbox {
-    padding: 10px 20px;
-    width: 100%;
-    box-sizing: border-box;
-  }
-</style>

+ 463 - 0
src/views/career/vocation/new-detail.vue

@@ -0,0 +1,463 @@
+<template>
+  <div id="jobDetail" style="padding:24px 12%" >
+    <el-card style="color: #5E5E5E;" ref="navBar">
+      <el-breadcrumb separator-class="el-icon-arrow-right">
+        <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
+        <el-breadcrumb-item :to="{ path: '/career/vocation/index'}">职业库</el-breadcrumb-item>
+        <el-breadcrumb-item>职业详情</el-breadcrumb-item>
+      </el-breadcrumb>
+    </el-card>
+    <div class="mt20 header-content pd20" >
+      <p class="f28 f-333">{{vocationDetail.name ||  ''}}</p>
+    </div>
+    <div class="tabs-wrap">
+      <span class="tabs-item" @click="tabActive = 0" :class="{'bg-primary':tabActive == 0}">职业概况</span>
+      <span class="tabs-item" @click="tabActive = 1":class="{'bg-primary':tabActive == 1}">就业岗位</span>
+    </div>
+    <p class="line"></p>
+    <div
+      v-show="loading"
+      class="loading-div"
+      v-loading="loading"
+      :style="{height:windowHeight + 'px'}">
+    </div>
+
+    <div class="content-wrap mt20" >
+      <!-- 职业概况  -->
+      <div v-if="Object.keys(vocationDetail).length > 0">
+        <div v-show="tabActive == 0">
+          <div class="desc-item">
+            <p class="format-tit">职业介绍</p>
+            <div class="text-666" v-html="vocationDetail.description"></div>
+          </div>
+          <div class="desc-item">
+            <p class="format-tit">就业岗位<span class="text-666 f14">({{vocationDetail.postJobs.length || 0}}个)</span></p>
+            <div class="post-item mb20" v-for="post in vocationDetail.postJobs">
+              <div class="post-title f16 mb10" style="cursor: pointer" @click="toJob(post)">{{post.name}}</div>
+              <div class="pb10 text-666 post-text">
+                <div>{{`${post.salaryMin}元-${post.salaryMax}元/月`}}</div>
+                <div>热门地区:{{post.hotCity}}</div>
+              </div>
+            </div>
+          </div>
+          <div class="desc-item">
+            <p class="format-tit">相关专业<span class="text-666 f14">({{vocationDetail.postMajors.length}}个)</span></p>
+            <div class="post-item mb20" v-for="post in vocationDetail.postMajors">
+              <div class="post-title f16 mb10" style="cursor: pointer">{{post.name}}</div>
+              <div class="pb10 text-666 post-text">
+                <div>国标代码:{{post.code}}</div>
+                <div>学制:{{post.learnYear}}</div>
+                <div>男女比例:{{`${post.maleRatio}/${post.femaleRatio}`}}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!--  就业岗位-->
+      <div v-if="vocationalPosts.length > 0">
+        <div v-show="tabActive == 1">
+          <el-row :gutter="20" type="flex" class="jobTabs">
+            <el-col class="job-item-wrap" :span="4" v-for="item in vocationalPosts" :key="item.name">
+              <div class="job-item f14 f-333" :class="{'bg-primary':jobActiveName == item.name}" @click="toActiveJob(item.name)">
+                <p class="mb10">{{item.name}}</p>
+                <p>{{`${item.salaryMin}-${item.salaryMax}`}}{{item.salaryUnit}}</p>
+              </div>
+            </el-col>
+          </el-row>
+          <!--  岗位详情  -->
+          <div  v-if="Object.keys(jobDetail).length > 0">
+            <!-- 图表 -->
+            <div class="desc-item">
+              <p class="format-tit">薪资情况</p>
+              <el-row :gutter="10">
+               <el-col :span="12">
+                 <p class="text-right f-333">按趋势</p>
+                 <mx-chart :options="chartExperience" height="300px"></mx-chart>
+               </el-col>
+                <el-col :span="12">
+                  <p class="text-right f-333">按分布</p>
+                  <mx-chart :options="chartSalary" height="300px"></mx-chart>
+                </el-col>
+              </el-row>
+            </div>
+            <div class="desc-item">
+              <p class="format-tit">就业形势</p>
+              <el-row :gutter="10">
+                <el-col :span="12">
+                  <p class="text-right f-333">按学历</p>
+                  <mx-chart :options="chartEdu" height="300px"></mx-chart>
+                </el-col>
+                <el-col :span="12">
+                  <p class="text-right f-333">按经验</p>
+                  <mx-chart :options="chartExp" height="300px"></mx-chart>
+                </el-col>
+              </el-row>
+            </div>
+            <div class="desc-item">
+              <p class="format-tit">招聘需求量</p>
+              <el-row :gutter="40" type="flex" class="flex-wrap">
+                <el-col :span="12" class="f16" v-for="(item,index) in  jobDetail.demand">
+                  <el-row class="format-job-wrap">
+                    <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                    <el-col :span="15" class="f-333">{{item.city}}</el-col>
+                    <el-col :span="6" class="f-666  text-right f14">{{item.count}}职位</el-col>
+                  </el-row>
+                </el-col>
+              </el-row>
+            </div>
+            <div class="desc-item">
+              <p class="format-tit">收入排行-按行业</p>
+              <el-row :gutter="40" type="flex" class="flex-wrap">
+                <el-col :span="12" class="f16" v-for="(item,index) in  jobDetail.industrySalary">
+                  <el-row class="format-job-wrap">
+                    <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                    <el-col :span="15" class="f-333">{{item.name}}</el-col>
+                    <el-col :span="6" class="f-666 text-right f14">{{item.salary}}元 / 月</el-col>
+                  </el-row>
+                </el-col>
+              </el-row>
+            </div>
+            <div class="desc-item">
+              <p class="format-tit">收入排行-按地区</p>
+              <el-row :gutter="40" type="flex" class="flex-wrap">
+                <el-col :span="12" class="f16" v-for="(item,index) in  jobDetail.citySalary">
+                  <el-row class="format-job-wrap">
+                    <el-col :span="3" class="f18 text-center f-666">{{index + 1}}</el-col>
+                    <el-col :span="15" class="f-333">{{item.city}}</el-col>
+                    <el-col :span="6" class="f-666 text-right f14">{{item.salary}}元 / 月</el-col>
+                  </el-row>
+                </el-col>
+              </el-row>
+            </div>
+          </div>
+
+          <div v-else>
+            暂无数据
+          </div>
+        </div>
+      </div>
+
+    </div>
+  </div>
+</template>
+<script>
+import MxChart from '@/components/MxChart/index'
+import { vocationalPostsDetail, vocationalOverview, vocationalPosts } from '@/api/webApi/vocation'
+export default {
+  name: "Detail",
+  components: {
+    MxChart
+  },
+  data(){
+    return {
+      loading:false,
+      code:'',
+      tabActive: 0,
+      vocationalPosts: [],  // 就业岗位
+      vocationDetail:{},  // 职业概况
+      jobActiveName: '',  // 激活状态的岗位
+      jobDetail: {},  // 岗位详情
+      windowHeight:document.documentElement.clientHeight,
+    }
+  },
+  computed:{
+    // 按工资分布
+    chartSalary() {
+      if (!this.jobDetail.salary.length) return null
+      const pieData = this.jobDetail.salary.map(item => {
+        return {
+          value: item.ratio,
+          name: `${item.min}-${item.max}元/月 ${item.ratio}%`,
+        }
+      })
+      const options  = {
+          toolbox: {
+            show: true,
+          },
+        series: [
+          {
+            name: 'Nightingale Chart',
+            type: 'pie',
+            radius: [30, 60],
+            label:{
+              formatter: '{b}'
+            },
+            data: pieData
+          }
+        ]
+      }
+      return options
+    },
+    // 按经验
+    chartExp() {
+      if (!this.jobDetail.exp.length) return null
+      const pieData = this.jobDetail.exp.map(item => {
+        return {
+          value: item.ratio,
+          name: `${item.exp}${item.ratio}%`,
+        }
+      })
+      const options  = {
+        toolbox: {
+          show: true,
+        },
+        series: [
+          {
+            name: 'Nightingale Chart',
+            type: 'pie',
+            radius: [30, 60],
+            label:{
+              formatter: '{b}'
+            },
+            data: pieData
+          }
+        ]
+      }
+      return options
+    },
+    // 按教育程度
+    chartEdu() {
+      if (!this.jobDetail.edu.length) return null
+      const pieData = this.jobDetail.edu.map(item => {
+        return {
+          value: item.ratio,
+          name: `${item.edu}${item.ratio}%`,
+        }
+      })
+      const options  = {
+        toolbox: {
+          show: true,
+        },
+        series: [
+          {
+            name: 'Nightingale Chart',
+            type: 'pie',
+            radius: [30, 60],
+            label:{
+              formatter: '{b}'
+            },
+            data: pieData
+          }
+        ]
+      }
+      return options
+    },
+    // 按工资趋势
+    chartExperience() {
+      if (!this.jobDetail.experience.length) return null
+      const col = this.jobDetail.experience.map(item => item.year)
+      const row = this.jobDetail.experience.map(item => item.salary)
+      const options  = {
+        xAxis: {
+          data: col,
+          axisLine: {
+            lineStyle: {
+              type: 'dashed'
+            }
+          },
+          axisTick: {
+            alignWithLabel: true
+          },
+        },
+        yAxis: {
+          type: 'value',
+        },
+        series: [
+          {
+            name: 'Email',
+            type: 'line',
+            color: '#47C6A2',
+            stack: 'Total',
+            label: {
+              show: true,
+              position: 'top',
+            },
+            smooth: false,
+            data: row
+          },
+        ]
+
+      }
+      return options
+    }
+  },
+  watch:{
+    tabActive: {
+      handler(newVal){
+        // 1 岗位 0 概览
+        if(newVal == 0)  this.getVocationalOverview();
+        if(newVal == 1)  this.getVocationalPosts();
+      }
+    },
+    '$route':{
+      immediate:true,
+      handler(val){
+        this.code=val.query.code;
+        if(val.query.code){
+          console.log(22222222222222222222)
+          this.getVocationalOverview();
+        }
+      }
+    }
+  },
+  methods:{
+    toJob(post) {
+      console.log(post)
+      this.tabActive = 1
+      this.toActiveJob(post.name)
+    },
+    toActiveJob(name) {
+      if(this.jobActiveName == name) return
+      this.jobActiveName = name
+      //  刷新数据
+      this.getVocationalPostsDetail()
+    },
+    //  就业岗位
+    getVocationalPosts() {
+      this.loading = true
+      const params={
+        code:this.code
+      };
+      vocationalPosts(params).then(res => {
+        this.vocationalPosts = res.data
+        if(this.jobActiveName == '') {
+          this.jobActiveName = res.data[0].name
+          this.$nextTick(_ => {
+            this.getVocationalPostsDetail()
+          })
+        }
+      }).finally(_ => {
+        this.loading = false
+      })
+    },
+    // 就业岗位详情
+    getVocationalPostsDetail() {
+      this.loading = true
+      vocationalPostsDetail({postName:this.jobActiveName }).then(res => {
+          console.log(res)
+        this.jobDetail = res.data || {}
+      }).finally(res => {
+        this.loading = false
+      })
+    },
+    //  职业概况
+    getVocationalOverview(){
+      this.loading = true
+      const params={
+        code:this.code
+      };
+      vocationalOverview(params).then(res=>{
+         console.log(res)
+        this.vocationDetail = res.data || {}
+      }).finally(_ => {
+        this.loading = false
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+#jobDetail {
+  .header-content{
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    background: rgba(66, 185, 131, 0.1);
+  }
+  .tabs-wrap{
+    margin-top: 20px;
+    height: 40px;
+    .tabs-item{
+      cursor: pointer;
+      padding: 0 33px;
+      border-radius: 4px 4px 0 0;
+      display: inline-block;
+      line-height: 40px;
+      &:hover{
+        color:#47C6A2;
+      }
+      &.bg-primary{
+        background: #47C6A2 ;
+        color: white;
+      }
+    }
+  }
+  .bg-primary{
+    background: #47C6A2 !important;
+    color: white;
+  }
+  .format-job-wrap {
+    display: flex;
+    height: 44px;
+    line-height: 44px;
+    border-bottom: 1px solid #f2f2f2;
+  }
+  .line{
+    background:  #47C6A2;
+    height: 1px;
+  }
+  .post-text{
+    display: flex;
+    div{
+      min-width: 160px;
+      &:not(:first-child):before{
+        content: "";
+        display: inline-block;
+        width: 1px;
+        height: 12px;
+        background-color: #ccc;
+        vertical-align: text-top;
+        margin-right: 60px;
+        margin-top: 4px;
+      }
+    }
+  }
+  .loading-div {
+    width: 100%;
+    position: absolute;
+    background: transparent;
+    left: 0;
+  }
+
+  .post-title{
+    color: #333;
+  }
+
+  .post-item{
+    border-bottom: 1px solid #f2f2f2;
+    color: #333;
+  }
+  .format-tit{
+    border-left: 4px solid #47C6A2;
+    padding-left: 10px;
+    margin-bottom: 20px;
+    font-size: 20px;
+  }
+  .desc-item{
+    margin-bottom: 40px;
+  }
+  .text-666{
+    font-size: 14px;
+    color: #666666 !important;
+  }
+
+  .flex-wrap{
+    flex-wrap: wrap;
+  }
+  .jobTabs{
+    flex-wrap: wrap;
+    .job-item-wrap{
+      padding: 10px;
+      margin-bottom: 20px;
+      .job-item{
+        cursor: pointer;
+        border-radius: 4px;
+        padding: 10px;
+        background: #f2f2f2;
+      }
+    }
+  }
+}
+</style>

+ 178 - 0
src/views/career/vocation/new-index.vue

@@ -0,0 +1,178 @@
+<template>
+  <div id="vocation" ref="vocation">
+    <el-card style="height:158px;margin: 10px auto;">
+      <div :style="{'background-image':backimg}" class="back">
+        <p style="color:#A6A6A6;font-size:24px;font-weight:bold;">CAREER POOL</p>
+        <p style="color:#414141;font-size:24px;font-weight:bold;">职业库</p>
+        <hr class="layui-bg-orange" style="width:40px;height:4px;margin-top:10px;" />
+      </div>
+    </el-card>
+    <el-card class="box-card">
+      <div slot="header" >
+        <div class="title">职业列表</div>
+        <p class="line"></p>
+        <div class="tags-wrap">
+          <a :href="`#${item.code}`" class="tag" v-for="item in levelOne">{{ item.name }}</a>
+        </div>
+      </div>
+      <div class="list-wrap">
+        <!--  一级 -->
+        <div class="levelOne" v-for="item in vocationList" :id="item.code">
+          <!--   一级职业title-->
+          <p class="voca-title mt10 mb10 bold" >{{item.name}}</p>
+          <div class="last-level" v-for="subLevel in item.children">
+            <!--  二级职业 -->
+            <p class="sub-title">{{subLevel.name}}</p>
+            <!--  三级职业 -->
+            <div class="last-children-wrap" v-if="subLevel.children.length > 0">
+              <span @click="goDetail(vocation.code)" class="last-children" v-for="vocation in subLevel.children">{{vocation.name}}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import {mapState} from 'vuex';
+import {getAllVocation} from '@/api/webApi/vocation';
+export default {
+  name: "index",
+  data(){
+    return {
+      backimg:'url('+require('@/assets/images/career/icon_colleges.png')+')',
+      levelOne: [],
+      vocationList: []
+    }
+  },
+  computed:{
+    ...mapState({theme: state => state.settings.theme})
+  },
+  watch:{
+    theme:{
+      immediate:true,
+      handler(val){
+        this.$nextTick(()=>{
+          this.$refs.vocation.style.setProperty('--themeColor', val)
+        })
+      }
+    },
+  },
+  created(){
+    this.getAllVocation()
+  },
+  methods:{
+    goDetail(code){
+      this.$router.push({name:'jobDetail',query:{code:code}})
+    },
+    getAllVocation() {
+      getAllVocation({
+        level: 1
+      }).then(res => {
+        console.log(res)
+        this.vocationList = res.data
+        this.levelOne = res.data.map(item => {
+            return {
+              code: item.code,
+              name: item.name,
+            }
+        })
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+#vocation{
+  .levelOne{
+    padding-top:100px;
+    margin-top:-100px;
+  }
+  .layui-bg-orange{
+    background-color: var(--themeColor);
+    margin-left:0;
+  }
+  .back{
+    padding:30px;
+    margin-top: 10px;background-color:white;background-repeat: no-repeat;background-position: bottom right;
+  }
+  .title{
+    background-color: var(--themeColor);
+    width: 162px;
+    height: 37px;
+    color: #fff;
+    font-size: 16px;
+    line-height: 37px;
+    text-align: center;
+  }
+  .line {
+    background-color: var(--themeColor);
+    height: 4px;
+  }
+  .last-children-wrap{
+    flex-wrap: wrap;
+    display: flex;
+    .last-children{
+      flex: 25%;
+      flex-grow: 0;
+      margin-bottom: 10px;
+      color: var(--themeColor);
+      &:hover{
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+  .tags-wrap {
+    overflow: hidden;
+    box-sizing: border-box;
+    border-top: 1px solid #e1e1e1;
+    border-left: 1px solid #e1e1e1;
+    display: flex;
+    flex-flow: row wrap;
+    justify-content: start;
+    .tag{
+      border-bottom: 1px solid #e1e1e1;
+      border-right: 1px solid #e1e1e1;
+      font-size: 12px;
+      text-align: center;
+      flex: 10%;
+      text-align: center;
+      flex-grow: 0;
+      color: #555;
+      height: 40px;
+      line-height: 40px;
+      cursor: pointer;
+      &:hover{
+        text-decoration: underline;
+        cursor: pointer;
+      }
+    }
+  }
+  .sub-title{
+    color: #333;
+    line-height: 26px;
+    padding: 5px 10px;
+    background: #f3f3f3;
+    margin-bottom: 2px;
+  }
+  .voca-title{
+    border-left:4px solid var(--themeColor);
+    padding:0px 5px;
+    color: var(--themeColor);
+  }
+  .row{
+    .rowHead{
+      background-color:#a7e6d4;
+      &:hover{
+        background-color: var(--themeColor);
+        hr{
+          background-color: #ffffff;
+        }
+      }
+    }
+  }
+}
+</style>
+

+ 0 - 0
src/views/career/vocation/Detail.vue → src/views/career/vocation/old-detail.vue


+ 1 - 1
src/views/career/vocation/index.vue → src/views/career/vocation/old-index.vue

@@ -14,7 +14,7 @@
       </div>
       <el-divider></el-divider>
       <el-row class="row" :gutter="20">
-        <el-col style="margin-top: 20px;" :span="6" v-for="(item,index) in layout" :key="index" class="item">
+        <el-col style="margin-top: 20px;" :span="6" v-for="(item,index) in layout" :key="old" class="item">
           <div class="rowHead" style="padding:24px 24px 10px;">
             <p style="font-size: 16px;line-height: 22px;color: #589886;">{{item.enName}}</p>
             <h4 style="margin:0;font-size: 24px;color:#525252;">{{item.type}}</h4>

+ 1 - 1
src/views/career/zhiyuan/ShiftLine.vue

@@ -14,7 +14,7 @@
   import UniversitiesLine from '@/views/career/components/UniversitiesLine'
   import CollegesLine from '@/views/career/components/CollegesLine'
     export default {
-        name: "ShiftLine",
+      name: "ShiftLine",
       components:{UniversitiesLine,CollegesLine},
       data(){
           return {

+ 1 - 1
src/views/career/zhiyuan/SimulatedVolunteer.vue

@@ -1,6 +1,6 @@
 <template>
   <div id="simulate" ref="simulate">
-    <div class="mx-flex-row mx-flex-center-center">
+    <div class="mx-flex-row mx-flex-center-center text-center">
       <el-image fit="cover" style="height:180px; width:80%" :src="require('@/assets/images/career/img_banner02.png')"></el-image>
     </div>
     <!--  内容区域-->

+ 159 - 200
src/views/career/zhiyuan/batch.vue

@@ -1,200 +1,159 @@
-<template>
-  <div class="simulation">
-    <el-card ref="UniversitiesColleges" style="margin: 20px 0">
-      <div
-        :style="{ 'background-image': backimg }"
-        style="
-          padding: 30px;
-          margin: 10px 0;
-          background-color: white;
-          background-repeat: no-repeat;
-          background-position: bottom right;
-        "
-      >
-        <p style="color: #a6a6a6; font-size: 24px; font-weight: bold">
-          BATCH CONTROL LINE
-        </p>
-        <p style="color: #414141; font-size: 24px; font-weight: bold">
-          批次控制线
-        </p>
-        <hr
-          class="layui-bg-orange"
-          style="width: 40px; height: 4px; margin-top: 10px"
-        />
-      </div>
-    </el-card>
-    <el-card>
-      <div>
-        <el-row class="radioInput">
-          <div>
-            <span class="radiaTitle">地域:</span>
-          </div>
-          <el-radio-group v-model="form.location" @change="locationChange">
-            <el-radio-button label="">所有</el-radio-button>
-            <el-radio-button
-              v-for="item in locations"
-              :key="item"
-              :label="item"
-              style="margin-bottom: 10px"
-            ></el-radio-button>
-          </el-radio-group>
-        </el-row>
-        <el-row class="radioInput">
-          <div>
-            <span class="radiaTitle">录取年份:</span>
-          </div>
-          <el-radio-group v-model="form.year" @change="yearChange">
-            <el-radio-button label="">所有</el-radio-button>
-            <el-radio-button
-              v-for="item in years"
-              :key="item"
-              :label="item"
-              style="margin-bottom: 10px"
-            ></el-radio-button>
-          </el-radio-group>
-        </el-row>
-      </div>
-      <div class="content">
-        <mx-table :rows="batchData" :propDefines="propDefines"> </mx-table>
-        <el-pagination
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
-          :current-page="pageForm.pageNum"
-          :page-sizes="[5, 10, 20, 40]"
-          :page-size="pageForm.pageSize"
-          layout=" prev,pager,next,jumper,total,sizes"
-          :total="total"
-        >
-        </el-pagination>
-      </div>
-    </el-card>
-  </div>
-</template>
-
-<script>
-import { locations, years, pckzxList } from "@/api/webApi/career-other";
-export default {
-  data() {
-    return {
-      backimg:
-        "url(" + require("@/assets/images/career/icon_colleges.png") + ")",
-      locations: [],
-      years: [],
-      form: { location: "", year: "" },
-      batchData: [],
-      pageForm: { pageNum: 1, pageSize: 10 },
-      propDefines: {
-        location: {
-          label: "地域",
-        },
-        year: {
-          label: "年份",
-        },
-        typeName: {
-          label: "批次",
-        },
-        score1: {
-          label: "文科",
-        },
-        score2: {
-          label: "理科",
-        },
-      },
-      total: 0,
-    };
-  },
-  created() {
-    this.getLocations();
-    this.getYears();
-    this.getBatchList();
-  },
-  methods: {
-    handleSizeChange(val) {
-      this.pageForm.pageSize = val;
-      this.getBatchList();
-    },
-    handleCurrentChange(val) {
-      this.pageForm.pageNum = val;
-      this.getBatchList();
-    },
-    locationChange(e) {
-      this.getYears();
-      this.pageForm.pageNum = 1;
-      this.getBatchList();
-    },
-    yearChange(e) {
-      this.pageForm.pageNum = 1;
-      this.getBatchList();
-    },
-    getLocations() {
-      locations().then((res) => {
-        this.locations = res.rows;
-        console.log(res);
-      });
-    },
-    getYears() {
-      years({ location: this.form.location }).then((res) => {
-        this.years = res.rows;
-        console.log(res);
-      });
-    },
-    getBatchList() {
-      pckzxList({ ...this.pageForm, ...this.form }).then((res) => {
-        this.batchData = res.rows;
-        this.total = res.total;
-        console.log(res);
-      });
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.layui-bg-orange {
-  background-color: #47c6a2;
-  margin-left: 0;
-}
-</style>
-<style lang="scss">
-.radioInput {
-  .el-radio {
-    .el-radio__input {
-      display: none;
-    }
-  }
-}
-.radioInput {
-  display: flex;
-  .el-radio-button .el-radio-button__inner {
-    border-radius: 4px !important;
-    border: none;
-    padding: 5px 10px !important;
-    font-weight: 400;
-    font-family: PingFangSC-Regular, PingFang SC;
-  }
-  .el-radio-button__orig-radio:checked + .el-radio-button__inner {
-    box-shadow: none;
-  }
-  .radiaTitle {
-    display: inline-block;
-    width: 130px;
-    font-size: 14px;
-    text-align: right;
-    margin-top: 2px;
-  }
-}
-.radioInput02 {
-  display: flex;
-  align-items: center;
-  .radiaTitle {
-    display: inline-block;
-    width: 130px;
-    font-size: 14px;
-    text-align: right;
-    margin-top: 2px;
-  }
-  .el-input--medium .el-input__inner {
-    border-radius: 50px;
-  }
-}
-</style>
+<template>
+  <div class="simulation">
+    <el-card  class="mt20 mb20">
+      <div
+        :style="{ 'background-image': backimg }"
+        style="
+          padding: 30px;
+          margin: 10px 0;
+          background-color: white;
+          background-repeat: no-repeat;
+          background-position: bottom right;
+        "
+      >
+        <p style="color: #a6a6a6; font-size: 24px; font-weight: bold">
+          BATCH CONTROL LINE
+        </p>
+        <p style="color: #414141; font-size: 24px; font-weight: bold">
+          批次控制线
+        </p>
+        <hr
+          class="layui-bg-orange"
+          style="width: 40px; height: 4px; margin-top: 10px"
+        />
+      </div>
+    </el-card>
+    <el-card>
+      <div>
+        <mx-condition ref="condition" :query-params="queryParams" @query="handleQuery"
+                      @invalid="handleInvalidQuery"></mx-condition>
+      </div>
+      <div class="content">
+        <mx-table :rows="batchData" :propDefines="propDefines"> </mx-table>
+        <pagination :total="pageForm.total" :autoScroll="false" @pagination="onChangePage" :page.sync="pageForm.pageNum"
+                    :limit.sync="pageForm.pageSize"></pagination>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import {  pckzxList } from "@/api/webApi/career-other";
+import MxCondition from '@/components/MxCondition/mx-condition'
+import Pagination from '@/components/Pagination/index'
+export default {
+  components:  {
+    MxCondition,
+    Pagination
+  },
+  data() {
+    return {
+      queryParams: {
+        location: '',
+        yearAdmission: '',
+      },
+      backimg:
+        "url(" + require("@/assets/images/career/icon_colleges.png") + ")",
+      batchData: [],
+      pageForm: { pageNum: 1, pageSize: 10, total: 0 },
+      propDefines: {
+        location: {
+          label: "地域",
+        },
+        year: {
+          label: "年份",
+        },
+        typeName: {
+          label: "批次",
+        },
+        score1: {
+          label: "文科",
+        },
+        score2: {
+          label: "理科",
+        },
+      }
+    };
+  },
+  created() {
+    this.getLocations();
+    this.getYears();
+    this.getBatchList();
+  },
+  methods: {
+    handleQuery() {
+        this.getBatchList()
+    },
+    handleInvalidQuery() {
+      console.log('query出错')
+      this.round = {}
+    },
+    onChangePage(page){
+      this.pageForm.pageSize = page.limit;
+      this.pageForm.pageNum = page.page;
+      this.getBatchList();
+    },
+    getBatchList() {
+      pckzxList({
+        ...this.pageForm,
+        location: this.queryParams.location,
+        year: this.queryParams.yearAdmission,
+      }).then((res) => {
+        this.batchData = res.rows;
+        this.pageForm.total = res.total;
+        console.log(res);
+      });
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.layui-bg-orange {
+  background-color: #47c6a2;
+  margin-left: 0;
+}
+</style>
+<style lang="scss">
+.radioInput {
+  .el-radio {
+    .el-radio__input {
+      display: none;
+    }
+  }
+}
+.radioInput {
+  display: flex;
+  .el-radio-button .el-radio-button__inner {
+    border-radius: 4px !important;
+    border: none;
+    padding: 5px 10px !important;
+    font-weight: 400;
+    font-family: PingFangSC-Regular, PingFang SC;
+  }
+  .el-radio-button__orig-radio:checked + .el-radio-button__inner {
+    box-shadow: none;
+  }
+  .radiaTitle {
+    display: inline-block;
+    width: 130px;
+    font-size: 14px;
+    text-align: right;
+    margin-top: 2px;
+  }
+}
+.radioInput02 {
+  display: flex;
+  align-items: center;
+  .radiaTitle {
+    display: inline-block;
+    width: 130px;
+    font-size: 14px;
+    text-align: right;
+    margin-top: 2px;
+  }
+  .el-input--medium .el-input__inner {
+    border-radius: 50px;
+  }
+}
+</style>

+ 134 - 133
src/views/career/zhiyuan/gkmc.vue

@@ -1,133 +1,134 @@
-<template>
-  <div class="simulation">
-    <div class="top">
-      <img
-        src="@/assets/images/career/img_bg.png"
-        style="width: 100%; margin: 20px 0"
-        alt=""
-      />
-      <div class="desc">
-        <p>志愿必修——带你快速了解高考的方方面面</p>
-        <p>
-          对于很多刚接触高考志愿填报的家长而言,填报的过程中会遇到各种的名词术语,一时之间找不到合适的专业人士来咨询,了解的志愿填报就更是挑战。下面为大家整理了高考志愿填报过程中常见的专业术语,帮助各位考生和家长加深理解。
-        </p>
-      </div>
-    </div>
-    <div class="container">
-      <div class="item" v-for="(item, index) in list" :key="index">
-        <div class="tag">
-          <div>{{ item.type }}</div>
-          <div class="bg"></div>
-        </div>
-        <div class="data">
-          <div
-            class="data_item"
-            v-for="(item2, index) in item.children"
-            :key="index"
-            @click="toDetail(item2.id)"
-          >
-            {{ item2.name }}
-          </div>
-        </div>
-      </div>
-    </div>
-  </div>
-</template>
-
-<script>
-import { list } from "@/api/webApi/career-other";
-export default {
-  data() {
-    return {
-      list: [],
-    };
-  },
-  created() {
-    list().then((res) => {
-      this.list = res.rows;
-      console.log(res);
-    });
-  },
-  methods:{
-      toDetail(id){
-          this.$router.push({path:'/career/gkmc/detail',query:{id:id}})
-      }
-  }
-};
-</script>
-
-<style lang="scss" scoped>
-.top {
-  position: relative;
-}
-.top .desc {
-  position: absolute;
-  top: 43px;
-  left: 43px;
-}
-.top .desc p:first-child {
-  font-size: 36px;
-  font-family: PingFangSC-Semibold, PingFang SC;
-  font-weight: 600;
-  color: #ffffff;
-  line-height: 50px;
-  margin-bottom: 32px;
-}
-.top .desc p:last-child {
-  font-size: 16px;
-  font-family: PingFangSC-Regular, PingFang SC;
-  font-weight: 400;
-  padding-right: 273px;
-  color: #525252;
-  line-height: 22px;
-}
-.item {
-  width: 100%;
-  background: #fcfcfc;
-  border: 1px solid #dcdcdc;
-  margin-bottom: 16px;
-}
-.tag {
-  position: relative;
-}
-.tag div:first-child {
-  width: 164px;
-  height: 56px;
-  position: relative;
-  top: 24px;
-  text-align: center;
-  line-height: 56px;
-  background: #47c6a2;
-  border-radius: 0px 8px 8px 0px;
-  z-index: 30;
-  color: white;
-}
-.tag .bg {
-  position: absolute;
-  left: 0;
-  top: 30px;
-  left: 8px;
-  width: 164px;
-  height: 56px;
-  background: #737373;
-  border-radius: 0px 8px 8px 0px;
-  opacity: 0.14;
-}
-.data {
-  margin-top: 38px;
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start;
-  flex-grow: 0;
-}
-.data .data_item {
-  cursor: pointer;
-  text-align: center;
-  height: 60px;
-  line-height: 60px;
-  flex: 25%;
-}
-.data .data_item:hover {
-  color: #47c6a2;
-}
-</style>
+<template>
+  <div class="simulation">
+    <div class="top">
+      <img
+        src="@/assets/images/career/img_bg.png"
+        style="width: 100%; margin: 20px 0"
+        alt=""
+      />
+      <div class="desc">
+        <p>志愿必修——带你快速了解高考的方方面面</p>
+        <p>
+          对于很多刚接触高考志愿填报的家长而言,填报的过程中会遇到各种的名词术语,一时之间找不到合适的专业人士来咨询,了解的志愿填报就更是挑战。下面为大家整理了高考志愿填报过程中常见的专业术语,帮助各位考生和家长加深理解。
+        </p>
+      </div>
+    </div>
+    <div class="container">
+      <div class="item" v-for="(item, index) in list" :key="index">
+        <div class="tag">
+          <div>{{ item.type }}</div>
+          <div class="bg"></div>
+        </div>
+        <div class="data">
+          <div
+            class="data_item"
+            v-for="(item2, index) in item.children"
+            :key="index"
+            @click="toDetail(item2.id)"
+          >
+            {{ item2.name }}
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import { list } from "@/api/webApi/career-other";
+export default {
+  data() {
+    return {
+      list: [],
+    };
+  },
+  created() {
+    list().then((res) => {
+      this.list = res.rows;
+      console.log(res);
+    });
+  },
+  methods:{
+      toDetail(id){
+          this.$router.push({path:'/career/gkmc/detail',query:{id:id}})
+      }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.top {
+  position: relative;
+}
+.top .desc {
+  position: absolute;
+  top: 43px;
+  left: 43px;
+}
+.top .desc p:first-child {
+  font-size: 36px;
+  font-family: PingFangSC-Semibold, PingFang SC;
+  font-weight: 600;
+  color: #ffffff;
+  line-height: 50px;
+  margin-bottom: 32px;
+}
+.top .desc p:last-child {
+  font-size: 16px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  padding-right: 273px;
+  color: #525252;
+  line-height: 22px;
+}
+.item {
+  width: 100%;
+  background: #fcfcfc;
+  border: 1px solid #dcdcdc;
+  margin-bottom: 16px;
+}
+.tag {
+  position: relative;
+}
+.tag div:first-child {
+  width: 164px;
+  height: 56px;
+  position: relative;
+  top: 24px;
+  text-align: center;
+  line-height: 56px;
+  background: #47c6a2;
+  border-radius: 0px 8px 8px 0px;
+  z-index: 30;
+  color: white;
+}
+.tag .bg {
+  position: absolute;
+  left: 0;
+  top: 30px;
+  left: 8px;
+  width: 164px;
+  height: 56px;
+  background: #737373;
+  border-radius: 0px 8px 8px 0px;
+  opacity: 0.14;
+}
+.data {
+  margin-top: 38px;
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: flex-start;
+  flex-grow: 0;
+}
+.data .data_item {
+  cursor: pointer;
+  text-align: center;
+  height: 60px;
+  line-height: 60px;
+  flex: 25%;
+  flex-grow: 0;
+}
+.data .data_item:hover {
+  color: #47c6a2;
+}
+</style>

+ 138 - 236
src/views/career/zhiyuan/yfyd.vue

@@ -1,236 +1,138 @@
-<template>
-  <div class="simulation">
-    <el-card ref="UniversitiesColleges" style="margin: 20px 0">
-      <div
-        :style="{ 'background-image': backimg }"
-        style="
-          padding: 30px;
-          margin: 10px 0;
-          background-color: white;
-          background-repeat: no-repeat;
-          background-position: bottom right;
-        "
-      >
-        <p style="color: #a6a6a6; font-size: 24px; font-weight: bold">
-          BATCH CONTROL LINE
-        </p>
-        <p style="color: #414141; font-size: 24px; font-weight: bold">
-          一分一段
-        </p>
-        <hr
-          class="layui-bg-orange"
-          style="width: 40px; height: 4px; margin-top: 10px"
-        />
-      </div>
-    </el-card>
-    <el-card>
-      <div>
-        <el-row class="radioInput">
-          <div>
-            <span class="radiaTitle">地域:</span>
-          </div>
-          <el-radio-group v-model="form.location" @change="locationChange">
-            <el-radio-button label="">所有</el-radio-button>
-            <el-radio-button
-              v-for="item in locations"
-              :key="item"
-              :label="item"
-              style="margin-bottom: 10px"
-            ></el-radio-button>
-          </el-radio-group>
-        </el-row>
-        <el-row class="radioInput">
-          <div>
-            <span class="radiaTitle">录取年份:</span>
-          </div>
-          <el-radio-group v-model="form.year" @change="yearChange">
-            <el-radio-button label="">所有</el-radio-button>
-            <el-radio-button
-              v-for="item in years"
-              :key="item"
-              :label="item"
-              style="margin-bottom: 10px"
-            ></el-radio-button>
-          </el-radio-group>
-        </el-row>
-        <el-row class="radioInput">
-          <div>
-            <span class="radiaTitle">科类:</span>
-          </div>
-          <el-radio-group v-model="form.mode" @change="modeChange">
-            <el-radio-button label="">所有</el-radio-button>
-            <el-radio-button
-              v-for="item in modes"
-              :key="item"
-              :label="item"
-              style="margin-bottom: 10px"
-            ></el-radio-button>
-          </el-radio-group>
-        </el-row>
-      </div>
-      <div class="content">
-        <mx-table :rows="batchData" :propDefines="propDefines"> </mx-table>
-        <el-pagination
-          @size-change="handleSizeChange"
-          @current-change="handleCurrentChange"
-          :current-page="pageForm.pageNum"
-          :page-sizes="[5, 10, 20, 40]"
-          :page-size="pageForm.pageSize"
-          layout=" prev,pager,next,jumper,total,sizes"
-          :total="total"
-        >
-        </el-pagination>
-      </div>
-    </el-card>
-  </div>
-</template>
-
-<script>
-import {
-  yfydLocations,
-  yfydYears,
-  yfydModes,
-  yfydList,
-} from "@/api/webApi/career-other";
-export default {
-  data() {
-    return {
-      backimg:
-        "url(" + require("@/assets/images/career/icon_colleges.png") + ")",
-      locations: [],
-      years: [],
-      form: { location: "", year: "", mode: "", score: "" },
-      batchData: [],
-      pageForm: { pageNum: 1, pageSize: 10 },
-      propDefines: {
-        location: {
-          label: "地域",
-        },
-        year: {
-          label: "年份",
-        },
-        mode: {
-          label: "科类",
-        },
-        score: {
-          label: "分数",
-        },
-        num: {
-          label: "人数",
-        },
-        numTotal: {
-          label: "累计人数",
-        },
-      },
-      total: 0,
-      modes: [],
-    };
-  },
-  created() {
-    this.getLocations();
-    this.getYears();
-    this.getModes();
-    this.getYfydList();
-  },
-  methods: {
-    getModes() {
-      yfydModes({ location: this.form.location, year: this.form.year }).then(
-        (res) => {
-          this.modes = res.rows;
-          console.log(res);
-        }
-      );
-    },
-    handleSizeChange(val) {
-      this.pageForm.pageSize = val;
-      this.getYfydList();
-    },
-    handleCurrentChange(val) {
-      this.pageForm.pageNum = val;
-      this.getYfydList();
-    },
-    locationChange(e) {
-      this.getYears();
-      this.pageForm.pageNum = 1;
-      this.getYfydList();
-    },
-    modeChange(e) {
-      this.pageForm.pageNum = 1;
-      this.getYfydList();
-    },
-    yearChange(e) {
-      this.pageForm.pageNum = 1;
-      this.modeChange();
-    },
-    getLocations() {
-      yfydLocations().then((res) => {
-        this.locations = res.rows;
-        console.log(res);
-      });
-    },
-    getYears() {
-      yfydYears({ location: this.form.location }).then((res) => {
-        this.years = res.rows;
-        console.log(res);
-      });
-    },
-    getYfydList() {
-      yfydList({ ...this.pageForm, ...this.form }).then((res) => {
-        this.batchData = res.rows;
-        this.total = res.total;
-        console.log(res);
-      });
-    },
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.layui-bg-orange {
-  background-color: #47c6a2;
-  margin-left: 0;
-}
-</style>
-<style lang="scss">
-.radioInput {
-  .el-radio {
-    .el-radio__input {
-      display: none;
-    }
-  }
-}
-.radioInput {
-  display: flex;
-  .el-radio-button .el-radio-button__inner {
-    border-radius: 4px !important;
-    border: none;
-    padding: 5px 10px !important;
-    font-weight: 400;
-    font-family: PingFangSC-Regular, PingFang SC;
-  }
-  .el-radio-button__orig-radio:checked + .el-radio-button__inner {
-    box-shadow: none;
-  }
-  .radiaTitle {
-    display: inline-block;
-    width: 130px;
-    font-size: 14px;
-    text-align: right;
-    margin-top: 2px;
-  }
-}
-.radioInput02 {
-  display: flex;
-  align-items: center;
-  .radiaTitle {
-    display: inline-block;
-    width: 130px;
-    font-size: 14px;
-    text-align: right;
-    margin-top: 2px;
-  }
-  .el-input--medium .el-input__inner {
-    border-radius: 50px;
-  }
-}
-</style>
+<template>
+  <div class="simulation">
+    <el-card class="mt20 mb20">
+      <div
+        :style="{ 'background-image': backimg }"
+        class="back"
+      >
+        <p class="f24 bold" style="color: #a6a6a6">
+          BATCH CONTROL LINE
+        </p>
+        <p class="f24" style="color: #414141;">
+          一分一段
+        </p>
+        <hr
+          class="layui-bg-orange f24 bold mt10"
+          style="width: 40px; height: 4px"
+        />
+      </div>
+    </el-card>
+    <el-card>
+      <mx-search-group class="mb10" justify="end" :span="6" v-model="score" placeholder="请输入分数" @search="getList"
+      ></mx-search-group>
+      <mx-condition ref="condition" :query-params="queryParams" @query="handleQuery"
+                    @invalid="handleInvalidQuery"
+      ></mx-condition>
+      <div class="content">
+        <div class="table-wrap" v-loading="loading">
+          <mx-table :rows="batchData" :propDefines="propDefines"></mx-table>
+        </div>
+
+        <pagination :total="pageForm.total" :autoScroll="false" @pagination="onChangePage" :page.sync="pageForm.pageNum"
+                    :limit.sync="pageForm.pageSize"
+        ></pagination>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { yfydList } from '@/api/webApi/career-other'
+import MxCondition from '@/components/MxCondition/mx-condition'
+import MxSearchGroup from '@/components/MxSearch/mx-search-group'
+import Pagination from '@/components/Pagination'
+
+export default {
+  components: {
+    MxCondition,
+    Pagination,
+    MxSearchGroup
+  },
+  data() {
+    return {
+      loading: false,
+      queryParams: {
+        yfydLocation: '',
+        yfydYear: '',
+        yfydMode: ''
+      },
+      pageForm: { pageNum: 1, pageSize: 10, total: 0 },
+      backimg:
+        'url(' + require('@/assets/images/career/icon_colleges.png') + ')',
+      batchData: [],
+      score: '',
+      propDefines: {
+        location: {
+          label: '地域'
+        },
+        year: {
+          label: '年份'
+        },
+        mode: {
+          label: '科类'
+        },
+        score: {
+          label: '分数'
+        },
+        num: {
+          label: '人数'
+        },
+        numTotal: {
+          label: '累计人数'
+        }
+      }
+    }
+  },
+  created() {
+  },
+  methods: {
+    getList() {
+      if (this.score == '') return
+      this.getYfydList()
+    },
+    handleInvalidQuery() {
+
+    },
+    onChangePage(page) {
+      this.pageForm.pageSize = page.limit
+      this.pageForm.pageNum = page.page
+      this.getYfydList()
+    },
+    handleQuery() {
+      this.pageForm.pageNum = 1
+      this.getYfydList()
+    },
+    getYfydList() {
+      this.loading = true
+      yfydList({
+        year: this.queryParams.yfydYear,
+        location: this.queryParams.yfydLocation,
+        mode: this.queryParams.yfydMode,
+        score: this.score,
+        ...this.pageForm
+      }).then((res) => {
+        this.batchData = res.rows
+        this.pageForm.total = res.total
+        console.log(res)
+      }).finally(_ => {
+        this.loading = false
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.layui-bg-orange {
+  background-color: #47c6a2;
+  margin-left: 0;
+}
+
+.back {
+  padding: 30px;
+  margin: 10px 0;
+  background-color: white;
+  background-repeat: no-repeat;
+  background-position: bottom right;
+}
+</style>

+ 17 - 10
src/views/elective/dispatch/components/choose-class.vue

@@ -72,7 +72,8 @@ export default {
       if (!this.year) return []
       // 获取该年份下的年级
       const classTree = this.classTree[this.classTree.findIndex(i => i.year = this.year)]
-      this.form.gradeId = classTree.gradeId
+      console.log(classTree.gradeId)
+      this.form.gradeId = classTree.grade
       this.form.year = classTree.year
       return this.classTree[this.classTree.findIndex(i => i.year = this.year)].classList.map(item => {
         item['disabled'] = this.settingContainer.some(c => c.classId == item.classId && c.groupId !== this.roundGroup.groupId)
@@ -81,9 +82,6 @@ export default {
     }
   },
   methods: {
-    close() {
-      this.handleInputConfirm()
-    },
     validate() {
       //
       if (this.tmpClassIds.length !== this.roundGroup.classCount) return false
@@ -132,12 +130,21 @@ export default {
       })
     },
     addClass() {
-      busiClass.add(this.form).then(res => {
-        this.form.name = ''
-        this.msgSuccess('保存成功')
-        // this.getClassTreeByCache(false)
-        this.refreshClassTree()
-      }).finally()
+      this.$confirm(`是否要创建名称为${this.form.name}的班级`, {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        busiClass.add(this.form).then(res => {
+          this.form.name = ''
+          this.msgSuccess('保存成功')
+          // this.getClassTreeByCache(false)
+          this.refreshClassTree()
+        }).finally()
+      }).catch(() => {
+        this.$message.warning('已取消创建')
+      });
+      console.log(this.form)
     },
     refreshClassTree() {
       this.$store.dispatch('GetInfo') // 借机清除了用户缓存 // clear cache

+ 16 - 16
src/views/elective/dispatch/components/dispatch-table.vue

@@ -2,7 +2,7 @@
   <el-row>
     <mx-table  :propDefines="propDefines" :rows="displayRows">
       <template #classCount="{row,$index}">
-        <el-input-number size="small" v-model="row.classCount" @change="classCountChange(row,$index)" :min="0"
+        <el-input-number size="mini" v-model="row.classCount" @change="classCountChange(row,$index)" :min="0"
                          :disabled="row.classCount != 0" label="label"
         ></el-input-number>
       </template>
@@ -35,8 +35,6 @@
           @click="adjust(row)"
         >调整
         </el-button>
-      </template>
-      <template #detail="{row}">
         <el-button
           type="success"
           plain
@@ -93,7 +91,8 @@ export default {
         },
         classCount: {
           label: '班级数',
-          slot: 'classCount'
+          slot: 'classCount',
+          width: 150
         },
         edit: {
           label: '分班编辑',
@@ -106,17 +105,14 @@ export default {
         expectedCount: {
           label: '人数'
         },
+        proportion: {
+          label: '男女比例',
+        },
         adjust: {
           label: '操作',
+          width: 200,
           slot: 'adjust'
         },
-        proportion: {
-          label: '男女比例',
-        },
-        detail: {
-          label: '详情',
-          slot: 'detail'
-        }
       }
     }
   },
@@ -146,9 +142,7 @@ export default {
       return rows
     }
   },
-  created() {
-
-  },
+  inject: ['parentQuery'],
   methods: {
     openEditDialog(row) {
       if (!row.classCount) {
@@ -168,10 +162,16 @@ export default {
       this.$refs.adjustDialog.open(row,this.settings.filter(item => item.groupId == row.groupId))
     },
     toDetail(row,classId ='') {
+      const filterSettings = this.settings.filter(item => item.groupId == row.groupId)
+      if(filterSettings.length == 0){
+        this.$message.warning('该组合还未设定班级')
+        return
+      }
       console.log(classId)
-      const params = {group: row,classId:classId,groupIds: (this.round.groupIds &&this.round.groupIds.split(','))||[]}
+      const params = {group: row,classId:classId,groupIds: (this.round.groupIds &&this.round.groupIds.split(','))||[],
+      parentQuery: this.parentQuery
+      }
       const path = '/elective/dispatch/detail'
-      console.log('prev transfer', row, this.round)
       this.transferTo(path, params)
     },
     editCount(row) {

+ 7 - 1
src/views/elective/dispatch/components/edit-group.vue

@@ -20,7 +20,7 @@
       </div>
     </div>
     <span slot="footer" class="dialog-footer">
-      <el-button @click="show = false">取 消</el-button>
+      <el-button @click="hidden">取 消</el-button>
       <el-button type="primary" @click="save()" :disabled="active != 1">确 定</el-button>
     </span>
   </el-dialog>
@@ -50,6 +50,12 @@ export default {
     }
   },
   methods: {
+    hidden() {
+      this.show = false
+      if(this.active == 0) {
+        this.$refs.editClassDialog.handleInputConfirm()
+      }
+    },
     open(roundGroup, settingContainer) {
       this.active = 0
       this.show = true

+ 17 - 0
src/views/elective/dispatch/detail.vue

@@ -1,6 +1,12 @@
 <template>
   <!-- 分班完成的详情 -->
   <div class="app-container">
+    <evaluation-title
+      navBackButton
+      :title="`${title}(分班完成名单)`"
+      :navAction="closeDetail"
+    ></evaluation-title>
+
     <el-card class="box-card" style="margin-bottom: 10px;">
       <mx-condition :query-params="queryParams" :require-fields="requireFields" :local-data="groupSource"
                     @query="handleGroupQuery" class="mb10"
@@ -17,6 +23,7 @@ import MxCondition from '@/components/MxCondition/mx-condition'
 import MxTransferMixin from '@/components/mx-transfer-mixin.js'
 import ClassTable from '@/views/elective/dispatch/components/class-table'
 import { classesResult } from '@/api/webApi/elective/dispatch'
+import { mapGetters } from 'vuex'
 
 export default {
   mixins: [MxTransferMixin, MxSelectTranslateMixin],
@@ -30,6 +37,7 @@ export default {
     }
   },
   computed: {
+    ...mapGetters(['school']),
     groupSource() {
       if (!this.listGroupsOptions.length) return {}
       if (!this.prevData.groupIds?.length) return {}
@@ -49,9 +57,18 @@ export default {
         dispatchRoundId: this.prevData.group.roundId
       })
       return source
+    },
+    title() {
+      const school = this.school.schoolName
+      // const round = this.prevData.parentQuery.round  暂时只能取到Id
+      const year = this.prevData.parentQuery.year + '届'
+      return `${school}${year}选科分班`
     }
   },
   methods: {
+    closeDetail()  {
+      this.$router.go(-1)
+    },
     handleGroupQuery() {
        this.getDispatchResult()
     },

+ 15 - 1
src/views/elective/dispatch/index.vue

@@ -5,6 +5,7 @@
                     @invalid="handleInvalidQuery"
       ></mx-condition>
     </el-card>
+    <p class="text-right mb10"><el-button @click="lockDispatch" type="primary">发布分班</el-button></p>
     <dispatch-table :loading="loading" :round="round" :settings="settings"></dispatch-table>
   </div>
 </template>
@@ -32,7 +33,8 @@ export default {
   },
   provide() {
     return {
-      refreshData: this.handleQuery
+      refreshData: this.handleQuery,
+      parentQuery: this.queryParams
     }
   },
   methods: {
@@ -40,6 +42,18 @@ export default {
       this.getRound()
       this.getSettings()
     },
+    lockDispatch() {
+      // 班级数累计
+      const classCounts = this.round.roundGroups.reduce((prev,cur) => {
+        return prev += cur.classCount
+      },0)
+      console.log(classCounts)
+      if(classCounts > this.settings.length){
+        this.$message.warning('还有组合未分班')
+        return
+      }
+
+    },
     // 获取批次的setting
     getSettings() {
       getSettings({

+ 81 - 8
src/views/elective/generation/components/elective-generation-commands.vue

@@ -1,22 +1,43 @@
 <template>
   <div class="fx-row fx-bet-cen">
     <div class="fx-1">
-      <el-button v-if="showDMAlgorithm" type="primary">智能匹配</el-button>
-      <el-button v-if="showDMAlgorithmResults" type="primary">查看匹配明细</el-button>
-      <el-button v-if="showForceAdjust" type="primary">调剂/提醒</el-button>
+      <el-button v-if="showDMAlgorithm" type="primary" @click="applyAlgorithm">智能匹配</el-button>
+      <el-button v-if="showDMAlgorithmResults" type="primary" @click="goDetailPage">查看匹配明细</el-button>
+      <el-button v-if="showForceAdjust" type="primary" @click="goDetailPage">查看/调剂</el-button>
     </div>
     <div>
-      <el-button v-if="showFastPush" type="primary">提前进入{{ nextStepName }}</el-button>
-      <el-button v-if="showSend" type="primary">发送</el-button>
-      <el-button v-if="showRankBalance" type="primary">排名均衡</el-button>
-      <el-button v-if="showClassDispatch" type="primary">选科分班</el-button>
+      <el-button v-if="showFastPush" type="primary" @click="flushIntoDM">提前进入{{ nextStepName }}</el-button>
+      <el-button v-if="showSend" type="primary" @click="pushGeneration">发送</el-button>
+      <el-button v-if="showRankBalance" type="primary" @click="jumpRankBalance">排名均衡</el-button>
+      <el-button v-if="showClassDispatch" type="primary" @click="terminateAndJumpDispatch">选科分班</el-button>
+      <el-button v-else type="primary" @click="jumpDispatch">选科分班</el-button>
     </div>
+    <el-dialog v-if="pushSettingFormVisible" :visible.sync="pushSettingFormVisible"
+               :title="nextStepName+'设置'" width="350">
+      <elective-generation-push-setting ref="settingForm"/>
+      <div class="fx-row fx-end-cen mt15">
+        <el-button @click="pushSettingFormVisible=false">取消</el-button>
+        <el-button type="primary" @click="commitPushSetting">确认</el-button>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script>
+import {
+  applyElectiveDMAlgorithm,
+  flushIntoGenerationDM,
+  jumpGenerationRankBalance, pushGenerationSetting,
+  terminateGeneration
+} from '@/api/webApi/elective/generation'
+import config from '@/common/mx-config'
+import ElectiveGenerationPushSetting from '@/views/elective/generation/components/elective-generation-push-setting'
+import transferMixin from '@/components/mx-transfer-mixin'
+
 export default {
+  mixins: [transferMixin],
   name: 'elective-generation-commands',
+  components: { ElectiveGenerationPushSetting },
   inject: ['refreshData'],
   props: ['chartBinding', 'disabled'],
   computed: {
@@ -56,7 +77,59 @@ export default {
       return this.status.allMatched && this.generation.current <= options.rankBalance.value
     }
   },
-  methods: {}
+  data() {
+    return {
+      pushSettingFormVisible: false
+    }
+  },
+  methods: {
+    notifyRootRefresh() {
+      this.refreshData()
+    },
+    applyAlgorithm() {
+      // 暂时只支持一种算法,不排队以后会支持多种
+      const algorithm = config.electiveDMAlgorithm.rankFirst.value
+      applyElectiveDMAlgorithm(algorithm).finally(() => {
+        this.notifyRootRefresh()
+      })
+    },
+    goDetailPage() {
+      // 默认跳第1个可查询项 // 外抛让table子组件处理
+      this.$emit('jumpDetail')
+    },
+    flushIntoDM() {
+      flushIntoGenerationDM().finally(() => {
+        this.notifyRootRefresh()
+      })
+    },
+    pushGeneration() {
+      // show dialog form for push settings
+      // then call push api
+      this.pushSettingFormVisible = true
+    },
+    async commitPushSetting() {
+      const setting = await this.$refs.settingForm.validate()
+      setting.roundId = this.status.roundId
+      pushGenerationSetting(setting).finally(() => {
+        this.notifyRootRefresh()
+      })
+    },
+    jumpRankBalance() {
+      jumpGenerationRankBalance().finally(() => {
+        this.notifyRootRefresh()
+      })
+    },
+    terminateAndJumpDispatch() {
+      terminateGeneration().then(res => {
+        // this.refreshData()
+        this.jumpDispatch()
+      }).catch(_ => this.notifyRootRefresh())
+    },
+    jumpDispatch() {
+      const path = '/evaluating/master-manage/permission/elective/dispatch/index'
+      this.transferTo(path)
+    }
+  }
 }
 </script>
 

+ 18 - 4
src/views/elective/generation/components/elective-generation-master.vue

@@ -8,15 +8,18 @@
         </div>
         <div class="fx-1">
           <slot :name="activeKey+'-header'" v-bind="chartBinding">
-            <elective-generation-commands v-if="!stepDisabled" :chart-binding="chartBinding"/>
+            <elective-generation-commands v-if="!stepDisabled" :chart-binding="chartBinding"
+                                          @jumpDetail="handleJumpDetail"/>
           </slot>
         </div>
         <div>
-          <slot name="header-suffix"></slot>
+          <slot name="header-suffix">
+            <el-button type="primary" @click="jumpReport" class="ml10">选科数据</el-button>
+          </slot>
         </div>
       </div>
       <slot :name="activeKey" v-bind="chartBinding">
-        <elective-generation-table :chart-binding="chartBinding"></elective-generation-table>
+        <elective-generation-table :chart-binding="chartBinding" ref="gTable"></elective-generation-table>
       </slot>
       <slot name="footer-prefix"></slot>
       <slot :name="activeKey+'-footer'" v-bind="chartBinding">
@@ -32,8 +35,10 @@
 import ElectiveGenerationTable from '@/views/elective/generation/components/elective-generation-table'
 import ElectiveGenerationCharts from '@/views/elective/generation/components/elective-generation-charts'
 import ElectiveGenerationCommands from '@/views/elective/generation/components/elective-generation-commands'
+import transferMixin from '@/components/mx-transfer-mixin'
 
 export default {
+  mixins: [transferMixin],
   name: 'elective-generation-master',
   components: { ElectiveGenerationCommands, ElectiveGenerationCharts, ElectiveGenerationTable },
   props: {
@@ -87,7 +92,16 @@ export default {
       }
     }
   },
-  methods: {}
+  methods: {
+    jumpReport() {
+      // 跳转选科数据
+      // TODO: 页面还没有定义好
+    },
+    handleJumpDetail() {
+      // 跳列表,模拟点击第一列
+      this.$refs.gTable.simulateGoDetails()
+    }
+  }
 }
 </script>
 

+ 69 - 0
src/views/elective/generation/components/elective-generation-push-setting.vue

@@ -0,0 +1,69 @@
+<template>
+  <el-form ref="form" :model="model" :rules="rules" label-width="80px" label-position="right">
+    <el-form-item prop="dateRange" label="时间">
+      <mx-date-range-picker v-model="model.dateRange" emit-all-changes></mx-date-range-picker>
+    </el-form-item>
+    <div class="fx-row fx-wrap">
+      <el-form-item prop="onlyRecommand" class="form-item-readonly">
+        <el-checkbox v-model="model.onlyRecommand">仅允许学生选择推荐组合</el-checkbox>
+      </el-form-item>
+      <el-form-item prop="onlyAgree" class="form-item-readonly">
+        <el-checkbox v-model="model.onlyAgree">只允许学生选择同意</el-checkbox>
+      </el-form-item>
+    </div>
+    <div class="fx-row fx-wrap">
+      <el-form-item prop="useRecommandWhileDisagree" class="form-item-readonly">
+        <el-checkbox v-model="model.useRecommandWhileDisagree">如果拒绝,按推荐报名处理</el-checkbox>
+      </el-form-item>
+      <el-form-item prop="useRecommandWhileNonaction" class="form-item-readonly">
+        <el-checkbox v-model="model.useRecommandWhileNonaction">如果不报名,按推荐报名处理</el-checkbox>
+      </el-form-item>
+    </div>
+  </el-form>
+</template>
+
+<script>
+import { getDefaultSelectRange } from '@/utils'
+
+export default {
+  name: 'elective-generation-push-setting',
+  data() {
+    return {
+      model: {
+        dateRange: getDefaultSelectRange(7),
+        onlyRecommand: false, // 仅允许学生选择推荐组合, 否则允许学生填报有空缺的组合
+        onlyAgree: false, // 调剂阶段,只允许学生选择同意, 否则允许学生拒绝
+        useRecommandWhileDisagree: false, // 如果拒绝,按推荐报名处理
+        useRecommandWhileNonaction: false // 如果不报名,按推荐报名处理
+      },
+      rules: {
+        dateRange: [{
+          message: '时间必填',
+          validator: function(r, v, cb) {
+            if (v.length === 2 && v.first() && v.last()) {
+              cb()
+              return
+            }
+            cb(r.message)
+          }
+        }]
+      }
+    }
+  },
+  methods: {
+    async validate() {
+      const res = await this.$refs.form.validate()
+      // to standard model
+      const commit = { ...this.model }
+      commit.begin = commit.dateRange.first()
+      commit.end = commit.dateRange.last()
+      delete commit.dateRange
+      return Promise.resolve(commit)
+    }
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 20 - 0
src/views/elective/generation/components/elective-generation-table.vue

@@ -158,6 +158,26 @@ export default {
         groups: this.chartBinding.generation.roundGroups.map(rg => ({ groupId: rg.groupId, groupName: rg.groupName }))
       }
       this.transferTo(path, nextData)
+    },
+    simulateGoDetails() {
+      if (this.resolvedTable.rows.length == 0) {
+        this.msgInfo('没有数据')
+        return
+      }
+      const current = this.chartBinding.generation.current
+      for (const column of Object.values(this.resolvedTable.columns)) {
+        if (column.children) {
+          for (const subColProp of Object.keys(column.children)) {
+            for (const row of this.resolvedTable.rows) {
+              const val = row[subColProp]
+              if (val?.generation == current) {
+                this.goDetails(val)
+                return
+              }
+            }
+          }
+        }
+      }
     }
   }
 }

+ 1 - 1
src/views/elective/generation/detail.vue

@@ -118,7 +118,7 @@ export default {
       }
     },
     logDialogWidth() {
-      const expectedWidth = (this.prevData.groups.length + 2) * 160 // 假定elective-generation-flow-log 单格宽160
+      const expectedWidth = (this.prevData.groups.length + 3) * 160 // 假定elective-generation-flow-log 单格宽160
       const finalWidth = Math.min(expectedWidth, window.innerWidth * 0.8)
       return finalWidth + 'px'
     }

+ 13 - 0
src/views/elective/report/index.vue

@@ -0,0 +1,13 @@
+<template>
+
+</template>
+
+<script>
+export default {
+  name: 'report-index'
+}
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 0
src/views/idc/EvaluationDatabase/detailList.bak.vue

@@ -259,6 +259,7 @@ export default {
   data() {
     return {
       loading: false,
+
       evaluation: {},
       queryParams: {
         evaluationClassId: "",

+ 2 - 2
src/views/permission/components/round-score-query.vue

@@ -105,8 +105,7 @@ export default {
   },
   computed: {
     groupSource() {
-      console.log(this.settingModel.roundGroups)
-      return { groups: this.settingModel.roundGroups }
+      return { groups: this.groupModel.roundGroups }
     },
     groupQuery() {
       return {
@@ -133,6 +132,7 @@ export default {
       this.localQuery.pageNum = 1
       const params = this[this.activeTab]
       const round = this.toApiModel(this.settingModel)
+      round.activeGroupModelIndex = this.groupModelIndex // NOTE: 这里重用了activeGroupModelIndex,少定义了一个参数字段
       const query = {
         ...params,
         round

+ 1 - 22
src/views/permission/components/round-settings.vue

@@ -88,27 +88,6 @@ export default {
       },
       // modify
       settingModel: {},
-      settingRules: {
-        year: [{
-          required: true,
-          message: '学年必填'
-        }],
-        name: [{
-          required: true,
-          message: '名称必填'
-        }],
-        dateRange: [{
-          required: true,
-          message: '时间必填',
-          validator: function(r, v, cb) {
-            if (v.length === 2 && v.first() && v.last()) {
-              cb()
-              return
-            }
-            cb(r.message)
-          }
-        }]
-      },
       settingDialogVisible: false
     }
   },
@@ -187,7 +166,7 @@ export default {
     handleSubmit(commit) {
       const round = this.toApiModel(commit)
       // 提交
-      saveScoreImportConfig({ round }).then(res => {
+      saveScoreImportConfig(round).then(res => {
         this.stepsVisible = false
         this.msgSuccess('保存成功')
         this.handleQuery()

+ 0 - 1
src/views/permission/components/steps/round-setting-publish.vue

@@ -85,7 +85,6 @@ export default {
           message: '模型必选'
         }],
         dateRange: [{
-          required: true,
           message: '时间必填',
           validator: function(r, v, cb) {
             if (v.length === 2 && v.first() && v.last()) {

+ 40 - 0
src/views/system/user/profile/components/choose-subject-dialog.vue

@@ -0,0 +1,40 @@
+<template>
+    <el-dialog
+      v-if="dialogVisible"
+      title="选择自选专业"
+      :visible.sync="dialogVisible"
+      width="70%"
+    >
+      <subject-choice :course0="course0" :course1="course1" ></subject-choice>
+      <span slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
+      </span>
+    </el-dialog>
+</template>
+<script>
+import SubjectChoice from'@/views/career/subject/subjectChoice'
+export default {
+  components: {
+    SubjectChoice
+  },
+  data() {
+    return{
+      dialogVisible:false,
+      course0: '',
+      course1: '',
+    }
+  },
+  methods: {
+    open(course0, course1) {
+      this.dialogVisible = true
+      this.course0 = course0
+      this.course1 = course1
+    },
+    handleClose() {
+
+    }
+  }
+}
+</script>
+<style scoped>
+</style>

+ 74 - 0
src/views/system/user/profile/components/groups-match.vue

@@ -0,0 +1,74 @@
+<template>
+  <el-dialog
+    :title="`${type == 1 ? '自选专业' : '测评专业'}整体组合匹配`"
+    :visible.sync="show"
+    width="70%"
+  >
+    <div>
+      <mx-table :propDefines="propDefines" :rows="formatList">
+      </mx-table>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="show = false">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+export default {
+  data() {
+    return {
+      show: false,
+      majors: [],
+      type: 1,
+      reports: [],
+    }
+  },
+  computed: {
+    formatList() {
+      if (!this.reports.length) return []
+      return this.reports.map(item => {
+        let tempProp = {}
+        this.majors.map(major => {
+          if(major.matchedGroupIds.findIndex(gi => item.groupId == gi) != -1) {
+            tempProp[`a${major.majorCategoryCode}`] = `符合${major.collegeName ? `(${major.collegeName})` : '' }`
+          }
+        })
+        return {
+          groupName: item.groupName,
+          rankInGrade: item.rankInGrade,
+          ...tempProp
+        }
+      })
+    },
+    propDefines() {
+        const props = {}
+        this.majors.map(item => {
+          props[`a${item.majorCategoryCode}`] = {label:item.majorCategoryName }
+        })
+        return {
+          groupName: {
+            label: '专业/组合'
+          },
+          rankInGrade: {
+            label: '当前组合全校排名'
+          },
+          ...props,
+        }
+    },
+  },
+  methods: {
+    open(reports,majors,type) {
+      this.show = true
+      this.type = type
+      this.reports = reports
+      this.majors = majors
+    },
+  }
+}
+</script>
+<style scoped>
+.cell .el-tag{
+  margin-right: 5px;
+}
+</style>

+ 233 - 0
src/views/system/user/profile/components/report-table.vue

@@ -0,0 +1,233 @@
+<template>
+  <el-card>
+    <template #header>
+      <div class="fx-row fx-bet-cen">
+        选科报名表
+      <el-button>选科历史记录</el-button>
+      </div>
+    </template>
+    <mx-table :propDefines="propDefines" :rows="formatList">
+      <template #temp="{row}">
+        <span class="btn-blue mr5" @click="toSelectSub(row)">选择</span>
+        <span class="btn-green">查看记录</span>
+        <!--        <el-button>查看</el-button>-->
+      </template>
+      <template #proportion="{row}">
+        <span :style="{color: row.personInTime > row.personCount ? 'red' : '#42b983'}">{{row.personInTime}}</span>
+        <span >/{{row.personCount}}</span>
+      </template>
+      <template #signUp="{row}">
+        <span class="btn-red" v-if="row.selected" @click="toUnSelect(row)">取消报名</span>
+        <span class="btn-green" v-else @click="toSelect(row)">报名</span>
+      </template>
+      <template #subjects="{row}">
+        <el-row>
+          <el-col :span="8" v-for="subject in row.subjects">
+            <el-tag type="success" class="mr10 mb10" >{{ subject[0] }}</el-tag>
+          </el-col>
+        </el-row>
+      </template>
+      <template #colleges="{row}">
+        <el-row>
+          <el-col :span="12" v-for="college in row.colleges">
+            <el-tag type="success" class="mb10">{{ college.major[0] }}</el-tag>:
+            <span>{{ college.college }}</span>
+          </el-col>
+        </el-row>
+      </template>
+    </mx-table>
+    <p>您的选科志愿: <span v-for="(item,index) in selectedList" >{{item.groupName}}{{index+1 < selectedList.length ? '、' : '' }}</span></p>
+    <!-- 拖拽 -->
+    <test-drage ref="drage" :sortList="selectedList"></test-drage>
+    <el-button @click="commit" type="primary">提交</el-button>
+    <el-dialog
+      title="电子签名"
+      :visible.sync="dialogVisible"
+      width="70%"
+    >
+      <vue-esign></vue-esign>
+      <span slot="footer" class="dialog-footer">
+        <el-button @click="dialogVisible = false">取 消</el-button>
+        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
+      </span>
+    </el-dialog>
+    <choose-subject-dialog ref="chooseDialog"></choose-subject-dialog>
+  </el-card>
+</template>
+<script>
+import MxSelectTranslate from '@/components/Cache/modules/mx-select-translate-mixin.js'
+import { formatSubject } from '@/utils/index'
+import TestDrage  from './test-drage'
+import VueEsign from  '@/components/VueEsign/index'
+import ChooseSubjectDialog from  './choose-subject-dialog'
+
+export default {
+  components: {
+    TestDrage,
+    VueEsign,
+    ChooseSubjectDialog
+  },
+  mixins:[MxSelectTranslate],
+  data() {
+    return {
+      list: [],
+      preferenceCount: 3,
+      optionalMajors: [],
+      dialogVisible: false,
+      propDefines: {
+        index: {
+          type: 'index',
+          label: '编号'
+        },
+        groupName: {
+          label: '选科组合'
+        },
+        classCount: {
+          label: '开设班级数'
+        },
+        personCount: {
+          label: '人数设置'
+        },
+        proportion: {
+          label: '选科人数比', // personInTime/personCount 实时人数/人数设置 = 选科人数比
+          slot: 'proportion'
+        },
+        rankInGroup: {
+          label: '当前组合实时排名'
+        },
+        rankInGrade: {
+          label: '选科全校排名'
+        },
+        allowSelect: {
+          label: '报名状态'
+        },
+        temp: {
+          label: '选择专业',
+          width: '140',
+          slot: 'temp'
+        },
+        subjects: {
+          label: '已选专业',
+          slot: 'subjects',
+          width: '150'
+        },
+        colleges: {
+          label: '院校',
+          slot: 'colleges',
+          width: '250'
+        },
+        signUp: {
+          label: '操作',
+          slot: 'signUp',
+          width:'100',
+          fixed: 'right'
+        }
+      },
+      selectedList: []
+    }
+  },
+  computed: {
+    formatList() {
+      if (!this.list.length) return []
+      if (!this.optionalMajors.length) return []
+      // 格式化
+      return this.list.map(item => {
+        item.allowSelect = item.allowSelect ? '报名中' : '无法报名'
+        item.subjects = this.optionalMajors.filter(college => {
+          if (college.matchedGroupIds.indexOf(item.groupId) != -1) return college.majorCategoryName
+        }).map(item => item.majorCategoryName)
+        item.colleges = this.optionalMajors.filter(college => {
+          if (college.matchedGroupIds.indexOf(item.groupId) != -1) return college.majorCategoryName
+        }).map(item => {
+          return {
+            college: item.collegeName,
+            major: item.majorCategoryName
+          }
+        })
+        // 增加 course0 course1
+        item.course0 = this.translateCourse0(item.groupId)
+        item.course1 = this.translateCourse1(item.groupId)
+        return item
+      })
+    }
+
+  },
+  methods: {
+    commit() {
+      console.log(this.selectedList)
+      const real = this.selectedList.filter(item=> {return item.selected  == true})
+      if(real.length < this.preferenceCount) {
+        this.$message.warning(`您要选择${this.preferenceCount}个志愿`)
+        return
+      }
+      this.dialogVisible = true
+    },
+    toSelect(row) {
+      const count = this.list.reduce((prev,cur) => {
+        return prev += cur.selected ? 1 : 0
+      },0)
+      console.log(count)
+      if(count >= this.preferenceCount) {
+        this.$message.warning(`最多选择${this.preferenceCount}个志愿`)
+        return
+      }
+      row.selected = true
+      this.selectedList.push(row)
+      this.$refs.drage.init(this.selectedList)
+    },
+    toUnSelect(row) {
+      this.$confirm(`是否解除选科组合【${row.groupName}】`, '警告', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        row.selected = false
+        this.selectedList.splice(
+          this.selectedList.indexOf(this.selectedList.find((selected) => {
+              return selected.groupId === row.groupId }
+            )
+          ), 1);
+        this.$refs.drage.init(this.selectedList)
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '已取消'
+        });
+      });
+    },
+    toSelectSub(row)  {
+      // // 首选科目
+      // const groupArr = row.groupName.split('').map(item => {
+      //   return formatSubject(item)
+      // })
+      // const firstSub =  groupArr[0] // 首选科目
+      // const lastSub = groupArr.splice(1, 2) // 次选科目
+      // console.log(groupArr)
+      // console.log(firstSub)
+      // console.log(lastSub)
+      // 打开选科弹窗
+      this.$refs.chooseDialog.open(row.course0,row.course1)
+    },
+    init(list) {
+      console.log(list)
+
+      console.log(formatSubject('物'))
+      this.list = list
+    },
+    initOption(optionalMajors) {
+      console.log(optionalMajors)
+      this.optionalMajors = optionalMajors
+    }
+    // async getOptionalMajors() {
+    //   const res = await getOptionalMajors()
+    //   this.optionalMajors = res.data
+    //   console.log(res)
+    // }
+  }
+}
+</script>
+<style scoped>
+.cell .el-tag{
+  margin-right: 5px;
+}
+</style>

+ 101 - 0
src/views/system/user/profile/components/select-subject.vue

@@ -0,0 +1,101 @@
+<template>
+  <el-row :gutter="20">
+    <el-col :span="12">
+      <el-card>
+        <template #header>
+          <div class="fx-row fx-bet-cen">
+            您的自选专业:
+            <el-button @click="toMatch(1)">整体匹配</el-button>
+          </div>
+        </template> <div>
+        <el-popover
+          placement="bottom"
+          trigger="hover"
+          v-for="item in optionalMajors"
+          popper-class="zero-padding-popover"
+        >
+          <div class="fx-column">
+            <el-button plain type="text" @click="toGroupMatch(item)">匹配组合</el-button>
+          </div>
+          <el-tag class="mr10 mb10" type="success" slot="reference">{{ item.majorCategoryName }}</el-tag>
+        </el-popover>
+      </div>
+      </el-card>
+    </el-col>
+    <el-col :span="12">
+      <el-card>
+        <template #header>
+          <div class="fx-row fx-bet-cen">
+            您的测评推荐专业:
+            <el-button @click="toMatch(2)">整体匹配</el-button>
+          </div>
+        </template>
+        <div>
+          <el-popover
+            placement="bottom"
+            trigger="hover"
+            v-for="item in evaluationMajors"
+            popper-class="zero-padding-popover"
+          >
+            <div class="fx-column">
+              <el-button plain type="text" @click="toGroupMatch(item)">匹配组合</el-button>
+            </div>
+            <el-tag class="mr10 mb10" type="success" slot="reference">{{ item.majorCategoryName }}</el-tag>
+          </el-popover>
+        </div>
+      </el-card>
+    </el-col>
+    <!-- 整体组合匹配 -->
+    <group-match ref="groupMatch"></group-match>
+    <!-- 单组合匹配-->
+    <single-group-match ref="singleMatch"></single-group-match>
+  </el-row>
+</template>
+<script>
+import GroupMatch from './groups-match'
+import SingleGroupMatch from './single-group-match'
+export default {
+  components: {
+    GroupMatch,
+    SingleGroupMatch
+  },
+  props: {
+    list: {
+      type:Array,
+      default: _ => []
+    },
+    optionalMajors: {
+      type:Array,
+      default: _ => []
+    },
+    evaluationMajors: {
+      type:Array,
+      default: _ => []
+    }
+  },
+  data() {
+    return {
+      dialogVisible:false,
+      propDefines: {},
+    }
+  },
+  created() {
+  },
+  methods: {
+    // 整体组合匹配
+    toMatch(type) {
+      // type 1 自选 2 测评
+      if(type == 1) this.$refs.groupMatch.open(this.list,this.optionalMajors,type)
+      if(type == 2) this.$refs.groupMatch.open(this.list,this.evaluationMajors,type)
+
+    },
+    // 单组合匹配
+    toGroupMatch(major) {
+      this.$refs.singleMatch.open(major,this.list)
+    }
+  }
+}
+</script>
+<style scoped>
+
+</style>

+ 61 - 0
src/views/system/user/profile/components/single-group-match.vue

@@ -0,0 +1,61 @@
+<template>
+  <el-dialog
+    title="单组合匹配"
+    :visible.sync="singleShow"
+    width="30%"
+  >
+    <div>
+      <mx-table :propDefines="propDefines" :rows="formatList">
+      </mx-table>
+    </div>
+    <span slot="footer" class="dialog-footer">
+      <el-button type="primary" @click="singleShow = false">确 定</el-button>
+    </span>
+  </el-dialog>
+</template>
+<script>
+
+export default {
+  data() {
+    return {
+      singleShow: false,
+      major: [],
+      reports: [],
+    }
+  },
+  computed: {
+    formatList() {
+      if (!this.reports.length) return []
+      return this.reports.map(item => {
+        return {
+          groupName: item.groupName,
+          status: this.major.matchedGroupIds.findIndex(gi => gi == item.groupId) != -1 ? '符合' : '不符合',
+        }
+      })
+    },
+    propDefines() {
+      if (!this.major) return {}
+      return {
+        groupName: {
+          label: `${this.major.majorCategoryName}${this.major.collegeName ? `(${this.major.collegeName})`: '' }`
+        },
+        status: {
+          label: '符合'
+        },
+      }
+    },
+  },
+  methods: {
+    open(major,reports) {
+      this.singleShow = true
+      this.major = major
+      this.reports = reports
+    },
+  }
+}
+</script>
+<style scoped>
+.cell .el-tag{
+  margin-right: 5px;
+}
+</style>

+ 93 - 0
src/views/system/user/profile/components/test-drage.vue

@@ -0,0 +1,93 @@
+<template>
+  <!--  拖拽demo-->
+  <transition-group name="drag"
+                    class="list"
+                    tag="ul"
+  >
+    <li
+      v-for="(item, index) in sortList"
+      :key="item.groupId"
+    >
+      <span>{{`第${index + 1}志愿:`}}</span>
+      <span @dragenter="dragenter($event, index)"
+            @dragover="dragover($event, index)"
+            @dragstart="dragstart(index)"
+            class="list-item"
+            draggable>{{ item.groupName }}</span>
+      <el-tag style="cursor: pointer" @click="del(index)" type="danger">删除</el-tag>
+    </li>
+  </transition-group>
+</template>
+<script>
+export default {
+  // props: {
+  //   sortList: {
+  //     type: Array,
+  //     default:_ => []
+  //   }
+  // },
+  data() {
+    return {
+      dragIndex: '',
+      enterIndex: '',
+      sortList: [],
+    }
+  },
+  methods: {
+    init(data) {
+      this.sortList = data
+    },
+    dragstart(index) {
+      this.dragIndex = index
+    },
+    dragenter(e, index) {
+      e.preventDefault()
+      // 避免源对象触发自身的dragenter事件
+      if (this.dragIndex !== index) {
+        const source = this.sortList[this.dragIndex]
+        this.sortList.splice(this.dragIndex, 1)
+        this.sortList.splice(index, 0, source)
+        // 排序变化后目标对象的索引变成源对象的索引
+        this.dragIndex = index
+      }
+    },
+    shuffle() {
+      this.sortList = this.$shuffle(this.sortList)
+    },
+    del(index) {
+      this.sortList[index].selected = false
+      this.sortList.splice(index,1)
+    },
+    dragover(e, index) {
+      e.preventDefault()
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.list {
+  padding-left: 0;
+  list-style: none;
+
+  .drag-move {
+    transition: transform .3s;
+  }
+  li{
+    font-size: 14px;
+    margin-bottom: 6px;
+  }
+  .list-item {
+    cursor: move;
+    display:inline-block ;
+    margin: 0 10px;
+    width: 160px;
+    background: #42b983;
+    border-radius: 4px;
+    font-size: 14px;
+    color: #FFF;
+    height: 30px;
+    line-height: 30px;
+    text-align: center;
+  }
+}
+</style>

+ 30 - 1
src/views/system/user/profile/round-select.vue

@@ -24,6 +24,10 @@
         </el-col>
       </el-row>
     </el-card>
+    <!--  自选专业 推荐专业  -->
+    <select-subject class="mt20" :evaluationMajors="evaluationMajors" :optionalMajors="optionalMajors" :list="reportList"></select-subject>
+    <!--  选科报名表  -->
+    <report-table class="mt20"  ref="reportRef" :list="reportList"></report-table>
     <test-summary></test-summary>
     <el-card shadow="hover" class="mt20">
       <template #header>意向选科</template>
@@ -99,9 +103,12 @@ import consts from '@/common/mx-const'
 import TestEntry from '@/views/elective/test/components/test-entry'
 import TestResult from '@/views/elective/test/components/test-result'
 import TestSummary from '@/views/elective/test/components/test-summary'
+import SelectSubject from '@/views/system/user/profile/components/select-subject'
+import ReportTable from '@/views/system/user/profile/components/report-table'
+import { getOptionalMajors, getPrimaryElectives, getEvaluationMajors } from '@/api/webApi/elective/ selected-subject'
 
 export default {
-  components: { TestSummary, TestResult, TestEntry },
+  components: { SelectSubject, TestSummary, TestResult, TestEntry,ReportTable },
   mixins: [transferMixin],
   name: 'round-select',
   data() {
@@ -111,6 +118,9 @@ export default {
         src: '9fca0b997b8346ce8c3ce69feaf89294',
         aliIdType: 2
       },
+      reportList: [],
+      optionalMajors: [],
+      evaluationMajors: [],
       form: {
         groupId: ''
       },
@@ -136,8 +146,27 @@ export default {
   },
   mounted() {
     this.loadStudentSelected()
+
+    this.getOptionalMajors()
+    this.getReportList()
+    this.getEvaluationMajors()
   },
   methods: {
+    async getEvaluationMajors() {
+      const res = await getEvaluationMajors()
+      this.evaluationMajors= res.data
+    },
+    async getReportList() {
+      const res = await getPrimaryElectives()
+      this.reportList = res.data
+      this.$refs.reportRef.init(this.reportList)
+    },
+    async getOptionalMajors() {
+      const res = await getOptionalMajors()
+      this.optionalMajors = res.data
+      this.$refs.reportRef.initOption(this.optionalMajors)
+      console.log(res)
+    },
     loadStudentSelected() {
       getStudentSelected().then(res => {
         console.log('getStudentSelected', res)

+ 20 - 17
src/views/videocourse/video_course.vue

@@ -1,24 +1,26 @@
 <template >
   <div class="video_contianer">
     <el-card>
-      <div slot="header" class="header">
-        <div class="spans">
+      <div slot="header" >
+        <mx-search-group  justify="space-between" :span="6" v-model="form.sectionName" placeholder="请输入搜索内容" @search="searchVideo">
+          <div class="spans">
           <span
             v-for="item in videoType"
             :key="item.code"
             :class="typeActive == item.code ? 'active_text' : ''"
             @click="toggleType(item.code)"
-            >{{ item.label }}</span
+          >{{ item.label }}</span
           >
-        </div>
-        <div class="search_btn" style="float: right; overflow: auto">
-          <input
-            v-model="form.sectionName"
-            @keyup.enter="searchVideo"
-            placeholder="请输入搜索内容"
-          />
-          <img src="@/assets/images/icon_search.png" @click="searchVideo" />
-        </div>
+          </div>
+        </mx-search-group>
+<!--        <div class="search_btn" style="float: right; overflow: auto">-->
+<!--          <input-->
+<!--            v-model="form.sectionName"-->
+<!--            @keyup.enter="searchVideo"-->
+<!--            placeholder="请输入搜索内容"-->
+<!--          />-->
+<!--          <img src="@/assets/images/icon_search.png" @click="searchVideo" />-->
+<!--        </div>-->
       </div>
       <div class="radio_contianer">
         <div style="margin-bottom: 16px">
@@ -128,9 +130,10 @@ import {
   videoList,
   videoInfo,
 } from "@/api/webApi/webVideo";
+import MxSearchGroup from '@/components/MxSearch/mx-search-group'
 import FormSearch from "@/components/formSearch";
 export default {
-  components: { FormSearch },
+  components: {MxSearchGroup },
   data() {
     return {
       input: "",
@@ -281,16 +284,16 @@ export default {
 .el-card {
   margin-bottom: 32px;
 }
-.header {
-  padding-bottom: 17px;
-}
+
 .video_contianer {
   padding: 20px;
 }
 .spans {
-  display: inline-block;
+  margin-left: 10px;
 }
 .spans > span {
+  height: 100%;
+  display: inline-block;
   padding: 6px 19px;
   border-radius: 16px;
   font-size: 14px;