ystl_myq 6 месяцев назад
Родитель
Сommit
27fcd3af77
34 измененных файлов с 1377 добавлено и 395 удалено
  1. 3 5
      .vscode/settings.json
  2. BIN
      dist.zip
  3. 10 0
      src/api/draw.ts
  4. 2 2
      src/api/userSetting.ts
  5. 9 8
      src/components/echarts/big/fullBig.vue
  6. 100 73
      src/components/import/index.vue
  7. 248 126
      src/components/rankTable/draw.vue
  8. 257 2
      src/components/rankTable/index.vue
  9. 3 0
      src/views/background/framework/proson/components/addPerson.vue
  10. 1 4
      src/views/background/framework/proson/components/changeRole.vue
  11. 3 0
      src/views/background/framework/proson/components/personDetailsDrawer.vue
  12. 14 4
      src/views/background/framework/proson/components/prosonEditDrawer.vue
  13. 8 0
      src/views/background/framework/roles/components/addPerson.vue
  14. 8 0
      src/views/background/framework/users/components/addPerson.vue
  15. 29 7
      src/views/background/framework/users/components/editPerson.vue
  16. 4 4
      src/views/background/framework/users/index.vue
  17. 1 1
      src/views/draw/children/department/componements/seach.vue
  18. 19 12
      src/views/draw/children/department/departmentDrank.vue
  19. 1 3
      src/views/draw/children/department/departmentRank.vue
  20. 9 4
      src/views/draw/children/head/headDrank.vue
  21. 5 3
      src/views/draw/children/head/headRank.vue
  22. 9 4
      src/views/draw/children/health/healthDrank.vue
  23. 5 3
      src/views/draw/children/health/healthRank.vue
  24. 36 14
      src/views/draw/children/worker/componements/seach.vue
  25. 12 5
      src/views/draw/children/worker/workerDrak.vue
  26. 1 0
      src/views/evaluate/children/change/components/editMould.vue
  27. 5 5
      src/views/evaluate/children/change/components/newAdd.vue
  28. 212 13
      src/views/evaluate/children/change/components/settingIndexDrawer.vue
  29. 10 2
      src/views/evaluate/children/change/manage.vue
  30. 51 10
      src/views/evaluate/children/change/manage/addExam.vue
  31. 189 23
      src/views/evaluate/children/change/mould/manageObject.vue
  32. 111 57
      src/views/evaluate/children/change/mould/message.vue
  33. 1 1
      src/views/indexDefine/children/components/dialog.vue
  34. 1 0
      src/views/indexDefine/children/components/editDrawer.vue

+ 3 - 5
.vscode/settings.json

@@ -2,7 +2,7 @@
   "editor.formatOnType": true,
   "editor.formatOnSave": true,
   "[vue]": {
-    "editor.defaultFormatter": "Vue.volar"
+    "editor.defaultFormatter": "vscode.typescript-language-features"
   },
   "editor.tabSize": 2,
   "editor.formatOnPaste": true,
@@ -27,7 +27,5 @@
   "editor.codeActionsOnSave": {
     "source.fixAll.eslint": "explicit"
   },
-  "iconify.excludes": [
-    "el"
-  ]
-}
+  "iconify.excludes": ["el"]
+}


+ 10 - 0
src/api/draw.ts

@@ -99,3 +99,13 @@ export const getUserListObjectByModelId = params => {
     }
   );
 };
+// 根据考核模板查询所有被考核对象
+export const getDeptListByUserList = data => {
+  return http.request<quotaList>(
+    "post",
+    "/specialPortrait/getDeptListByUserList",
+    {
+      data
+    }
+  );
+};

+ 2 - 2
src/api/userSetting.ts

@@ -58,8 +58,8 @@ export const userPageWhitOrganization = data => {
   });
 };
 // 获取所有负责人数据(deptCode不转返回所有)
-export const getLeaderList = (data?: string) => {
+export const getLeaderList = (params?: string) => {
   return http.request<userPageList>("get", "/user/getLeaderList", {
-    data
+    params
   });
 };

+ 9 - 8
src/components/echarts/big/fullBig.vue

@@ -14,11 +14,14 @@ const route = useRoute();
 const params = ref({});
 const title = ref();
 onMounted(() => {
-  title.value = route.query.title;
-  Object.assign(params.value, route.query);
-  delete params.value.title;
-  barDimEchartsRef.value.init(params.value);
-  init();
+  nextTick(() => {
+    console.log("full-bigroute", route.query);
+    title.value = route.query.dimensionName;
+    Object.assign(params.value, route.query);
+    console.log("full-bigroute", params.value);
+    barDimEchartsRef.value.init(params.value);
+    init();
+  });
 });
 
 // 柱状图
@@ -35,13 +38,11 @@ const init = async () => {
   const { data, code } = await getPersonDimensionChartsList({
     ...params.value
   });
+  console.log("full-bigroutedata", data);
   if (code == 200) {
     personListRef.value.init(data);
   }
 };
-nextTick(() => {
-  init();
-});
 defineExpose({
   dataList
 });

+ 100 - 73
src/components/import/index.vue

@@ -17,21 +17,16 @@ const emit = defineEmits(["handleImport"]);
 const uploadShow = ref(true);
 const query = ref({});
 const fileDocument = ref<File | null>(null); // 存储文件
-
+const assessmentType = ref();
 onMounted(() => {
   // assessmentType
   Object.assign(query.value, route.query);
+  assessmentType.value = Number(query.value.assessmentType);
   console.log("111", query.value);
 });
 const uploadFile = () => {};
 const tableHeaders = ref<any>([]);
-const tableData = ref<any>([
-  { name: "" },
-  { defin: "" },
-  { caliber: "" },
-  { type: "" },
-  { from: "" }
-]);
+const tableData = ref<any>([]);
 const handleUploadChange = async (file: File) => {
   fileDocument.value = file; // 保存文件
   const formData = new FormData();
@@ -44,66 +39,69 @@ const handleUploadChange = async (file: File) => {
   });
   const reader = new FileReader();
   let fileType = file.name.slice(-4);
-  if (fileType == "xlsx") {
-    if (data.code == 200) {
-      reader.onload = e => {
-        const data = new Uint8Array(e.target?.result as ArrayBuffer);
-        const workbook = XLSX.read(data, { type: "array" }); // 读取 Excel 文件
-        const firstSheetName = workbook.SheetNames[0]; // 获取第一个工作表名
-        const worksheet = workbook.Sheets[firstSheetName]; // 获取第一个工作表
-        const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 将工作表转为 JSON
-        if (
-          jsonData[1].length == 6 &&
-          (query.value.assessmentType == 0 || query.value.assessmentType == 1)
-        ) {
-          tableHeaders.value = jsonData[1];
-          const arr = jsonData.slice(2).map(row => {
-            if (row[0] && row[1] && row[2] && row[3]) {
-              const rowData = {};
-              tableHeaders.value.forEach((header, index) => {
-                if (row[index]) {
-                  rowData[header] = row[index];
-                }
-              });
-              return rowData;
-            }
-          });
-          tableData.value = arr.filter(item => item);
-          ElMessage.success("文件上传成功");
-          uploadShow.value = false; // 隐藏上传区域,显示数据表
-        } else if (query.value.assessmentType == 2) {
-          tableHeaders.value = [
-            "用户组",
-            "用户组编号",
-            "考核模板",
-            "指标名称",
-            "完成值",
-            "得分"
-          ]; // 表头
-          const arr = jsonData.slice(2).map(row => {
-            if (row[0] && row[1] && row[2] && row[3]) {
-              const rowData = {};
-              tableHeaders.value.forEach((header, index) => {
-                if (row[index]) {
-                  rowData[header] = row[index];
-                }
-              });
-              return rowData;
-            }
-          });
-          tableData.value = arr.filter(item => item);
-          ElMessage.success("文件上传成功");
-          uploadShow.value = false; // 隐藏上传区域,显示数据表
-        } else {
-          ElMessage.error("文件为空或格式不正确");
-        }
-      };
-    } else {
-      ElMessage.error(data.msg);
-    }
+  // if (fileType == "xlsx") {
+  if (data.code == 200) {
+    uploadShow.value = false; // 隐藏上传区域,显示数据表
+    tableData.value = data.data;
+    // reader.onload = e => {
+    //   const data = new Uint8Array(e.target?.result as ArrayBuffer);
+    //   const workbook = XLSX.read(data, { type: "array" }); // 读取 Excel 文件
+    //   const firstSheetName = workbook.SheetNames[0]; // 获取第一个工作表名
+    //   const worksheet = workbook.Sheets[firstSheetName]; // 获取第一个工作表
+    //   const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }); // 将工作表转为 JSON
+    //   if (
+    //     jsonData[1].length == 6 &&
+    //     (query.value.assessmentType == 0 || query.value.assessmentType == 1)
+    //   ) {
+    //     tableHeaders.value = jsonData[1];
+    //     const arr = jsonData.slice(2).map(row => {
+    //       if (row[0] && row[1] && row[2] && row[3]) {
+    //         const rowData = {};
+    //         tableHeaders.value.forEach((header, index) => {
+    //           if (row[index]) {
+    //             rowData[header] = row[index];
+    //           }
+    //         });
+    //         return rowData;
+    //       }
+    //     });
+    //     tableData.value = arr.filter(item => item);
+    //     ElMessage.success("文件上传成功");
+    //     uploadShow.value = false; // 隐藏上传区域,显示数据表
+    //   } else if (query.value.assessmentType == 2) {
+    //     tableHeaders.value = [
+    //       "用户组",
+    //       "用户组编号",
+    //       "考核模板",
+    //       "指标名称",
+    //       "完成值",
+    //       "得分"
+    //     ]; // 表头
+    //     const arr = jsonData.slice(2).map(row => {
+    //       if (row[0] && row[1] && row[2] && row[3]) {
+    //         const rowData = {};
+    //         tableHeaders.value.forEach((header, index) => {
+    //           if (row[index]) {
+    //             rowData[header] = row[index];
+    //           }
+    //         });
+    //         return rowData;
+    //       }
+    //     });
+    //     tableData.value = arr.filter(item => item);
+    //     ElMessage.success("文件上传成功");
+    //     uploadShow.value = false; // 隐藏上传区域,显示数据表
+    //   } else {
+    //     ElMessage.error("文件为空或格式不正确");
+    //   }
+    // };
+    console.log(data);
   } else {
-    ElMessage.error("请上传xlsx文件");
+    ElMessage.error(data.msg);
   }
+  // } else {
+  //   ElMessage.error("请上传xlsx文件");
+  // }
 
   reader.readAsArrayBuffer(file); // 读取文件为 ArrayBuffer
 };
@@ -181,7 +179,7 @@ const backDefine = () => {
         <el-button class="mt-2"
           ><el-icon> <Download /> </el-icon
           ><a
-            v-if="query.assessmentType == 0"
+            v-if="query.assessmentType == 0 || query.assessmentType == 3"
             href="http://116.148.231.9:9999/download/考核数据导入模板-人员.xlsx"
             download="考核数据导入模板-人员.xlsx"
             >下载空的模板表格</a
@@ -221,17 +219,46 @@ const backDefine = () => {
         </div>
         <div v-else class="mb-2">
           <el-table
+            v-if="query.assessmentType == 0 || query.assessmentType == 3"
+            :data="tableData"
+            border
+            style="width: 100%"
+            max-height="250"
+          >
+            <el-table-column label="工号" prop="hospitalCode" />
+            <el-table-column label="人员" prop="realName" />
+            <el-table-column label="考核模板" prop="tpName" />
+            <el-table-column label="指标名称" prop="quotaName" />
+            <el-table-column label="完成值" prop="finalValue" />
+            <el-table-column label="得分" prop="score" />
+          </el-table>
+          <el-table
+            v-if="query.assessmentType == 1"
+            :data="tableData"
+            border
+            style="width: 100%"
+            max-height="250"
+          >
+            <el-table-column label="部门" prop="deptName" />
+            <el-table-column label="部门编号" prop="hospitalCode" />
+            <el-table-column label="考核模板" prop="tpName" />
+            <el-table-column label="指标名称" prop="quotaName" />
+            <el-table-column label="完成值" prop="finalValue" />
+            <el-table-column label="得分" prop="score" />
+          </el-table>
+          <el-table
+            v-if="query.assessmentType == 2"
             :data="tableData"
             border
             style="width: 100%"
             max-height="250"
           >
-            <el-table-column
-              v-for="header in tableHeaders"
-              :key="header"
-              :label="header"
-              :prop="header"
-            />
+            <el-table-column label="用户组" prop="groupName" />
+            <el-table-column label="用户组编号" prop="hospitalCode" />
+            <el-table-column label="考核模板" prop="tpName" />
+            <el-table-column label="指标名称" prop="quotaName" />
+            <el-table-column label="完成值" prop="finalValue" />
+            <el-table-column label="得分" prop="score" />
           </el-table>
         </div>
         <div class="float-right">

+ 248 - 126
src/components/rankTable/draw.vue

@@ -1,48 +1,10 @@
-<template>
-  <!-- <el-table :data="tableData" style="width: 100%">
-    <el-table-column type="index" label="排名" width="80" fixed>
-      <template #default="scope">
-        <div v-if="scope.$index > 2" class="diamond">
-          {{ scope.row.ranking }}
-        </div>
-        <div v-else class="text-center">
-          <img :src="RANK_IMG[scope.row.ranking - 1]" alt="" />
-        </div>
-      </template>
-</el-table-column>
-<el-table-column prop="deptName" :label="deptName" fixed width="150" />
-<el-table-column v-if="name" prop="assessmentObjectName" :label="name" fixed width="100" />
-<div v-for="(ita, itk) in tableData" :key="itk">
-  <el-table-column prop="deptName" :label="deptName" fixed width="150" />
-  <div v-for="(item, index) in ita.dimensionList" :key="item.dimId">
-    <el-table-column :label="`${item.dimName}(${item.soreRate}%)`">
-      <el-table-column v-for="(it, id) in item.quotaList" :key="it.quotaId" :prop="it.quotaScore"
-        :label="`${it.quotaName}(${it.quotaWeight}%)`" width="140" />
-    </el-table-column>
-    <el-table-column :prop="item.totalSore" label="总分`" />
-  </div>
-</div>
-<el-table-column prop="allScore" label="总得分" fixed width="150" />
-</el-table> -->
-  <vxe-table
-    v-if="$route.name != 'workerDrak'"
-    border
-    style="width: 100%"
-    height="400"
-    show-overflow
-    show-header-overflow
-    show-footer-overflow
-    :data="tableData"
-    :column-config="{ resizable: true }"
-    :scroll-x="{ enabled: true, gt: 0 }"
-    :merge-cells="mergeCells"
-  >
+<!-- <template>
+  <vxe-table v-if="$route.name != 'workerDrak'" border style="width: 100%" height="400" show-overflow
+    show-header-overflow show-footer-overflow :data="tableData" :column-config="{ resizable: true }"
+    :scroll-x="{ enabled: true, gt: 0 }" :merge-cells="mergeCells">
     <vxe-column field="index" title="排名" width="80" fixed="left">
       <template #default="scope">
-        <div
-          v-if="scope._rowIndex == 0"
-          class="text-center text-sm font-extrabold text-[#000000] pt-4"
-        >
+        <div v-if="scope._rowIndex == 0" class="text-center text-sm font-extrabold text-[#000000] pt-4">
           平均得分
         </div>
         <div v-if="scope._rowIndex > imgIndex" class="diamond">
@@ -53,39 +15,16 @@
         </div>
       </template>
     </vxe-column>
-    <vxe-column
-      v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
-      field="deptName"
-      :title="deptName"
-      fixed="left"
-      width="150"
-    />
-    <vxe-column
-      v-else
-      field="assessmentObjectName"
-      :title="deptName"
-      fixed="left"
-      width="150"
-    />
-    <vxe-column
-      v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
-      field="assessmentObjectName"
-      fixed="left"
-      title="姓名"
-      width="100"
-    />
+    <vxe-column v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'" field="deptName" :title="deptName"
+      fixed="left" width="150" />
+    <vxe-column v-else field="assessmentObjectName" :title="deptName" fixed="left" width="150" />
+    <vxe-column v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'" field="assessmentObjectName"
+      fixed="left" title="姓名" width="100" />
     <template v-for="(ita, itk) in tableData" :key="itk">
       <template v-for="item in ita.dimensionList" :key="item.dimId">
-        <vxe-colgroup
-          :title="`${item.dimName}(${soreRate(item.soreRate)}%)`"
-          width="150"
-        >
+        <vxe-colgroup :title="`${item.dimName}(${soreRate(item.soreRate)}%)`" width="150">
           <template v-for="it in item.quotaList" :key="it.quotaId">
-            <vxe-column
-              :field="it.quotaScore"
-              :title="`${it.quotaName}(${soreRate(it.quotaWeight)}%)`"
-              width="150"
-            />
+            <vxe-column :field="it.quotaScore" :title="`${it.quotaName}(${soreRate(it.quotaWeight)}%)`" width="150" />
           </template>
         </vxe-colgroup>
         <vxe-column field="totalSore" title="总分" width="150" />
@@ -93,14 +32,7 @@
     </template>
     <vxe-column field="allScore" title="总得分" fixed="right" width="150" />
   </vxe-table>
-  <vxe-table
-    v-else
-    border
-    show-overflow
-    style="width: 100%"
-    height="400"
-    :data="tableDataNewValue"
-  >
+  <vxe-table v-else border show-overflow style="width: 100%" height="400" :data="tableData">
     <vxe-column field="index" title="排名" width="80" fixed="left">
       <template #default="scope">
         <div v-if="scope._rowIndex > 2" class="diamond">
@@ -111,40 +43,17 @@
         </div>
       </template>
     </vxe-column>
-    <vxe-column
-      v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
-      field="deptName"
-      :title="deptName"
-      fixed="left"
-      width="150"
-    />
-    <vxe-column
-      v-else
-      field="assessmentObjectName"
-      :title="deptName"
-      fixed="left"
-      width="150"
-    />
-    <vxe-column
-      v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'"
-      field="assessmentObjectName"
-      fixed="left"
-      title="姓名"
-      width="100"
-    />
+    <vxe-column v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'" field="deptName" :title="deptName"
+      fixed="left" width="150" />
+    <vxe-column v-else field="assessmentObjectName" :title="deptName" fixed="left" width="150" />
+    <vxe-column v-if="$route.name == 'workerDrak' || $route.name == 'workerRank'" field="assessmentObjectName"
+      fixed="left" title="姓名" width="100" />
     <template v-for="(ita, itk) in tableData" :key="itk">
       <template v-for="item in ita.dimensionList" :key="item.dimId">
-        <vxe-colgroup
-          :title="`${item.dimName}(${soreRate(item.soreRate)}%)`"
-          width="150"
-        >
+        <vxe-colgroup :title="`${item.dimName}(${soreRate(item.soreRate)}%)`" width="150">
           <template v-for="it in item.quotaList" :key="it.quotaId">
-            <vxe-column
-              v-if="!isDuplicate(item)"
-              :field="it.quotaScore"
-              :title="`${it.quotaName}(${soreRate(it.quotaWeight)}%)`"
-              width="150"
-            />
+            <vxe-column v-if="!isDuplicate(item)" :field="it.quotaScore"
+              :title="`${it.quotaName}(${soreRate(it.quotaWeight)}%)`" width="150" />
           </template>
         </vxe-colgroup>
         <vxe-column field="totalSore" title="总分" width="150" />
@@ -192,7 +101,7 @@ function isDuplicate(item) {
 }
 const init = (item, deptNames, names) => {
   tableData.value = item;
-  item.map((it, id) => {});
+  item.map((it, id) => { });
   deptName.value = deptNames;
   name.value = names;
   if ($route.name != "workerDrak") {
@@ -201,19 +110,6 @@ const init = (item, deptNames, names) => {
   console.log("item111", item);
   console.log("tableData", tableData.value);
 };
-const tableDataNewValue = computed(() => {
-  const seen = new Set();
-  return tableData.value.map(ita => ({
-    ...ita,
-    dimensionList: ita.dimensionList.filter(item => {
-      if (seen.has(item.dimId)) {
-        return false; // 如果已经存在,则不返回此项
-      }
-      seen.add(item.dimId);
-      return true; // 否则返回此项
-    })
-  }));
-});
 const soreRate = row => {
   if (row) {
     return row;
@@ -224,6 +120,232 @@ const soreRate = row => {
 defineExpose({
   init
 });
+</script> -->
+<template>
+  <div class="w-full">
+    <vxe-grid
+      v-if="$route.name != 'workerDrak'"
+      v-bind="gridOptions"
+      :merge-cells="mergeCells"
+    >
+      <template #imgUrl_default="{ row }">
+        <div>
+          <div
+            v-if="!row.ranking"
+            class="text-center text-sm font-extrabold text-[#000000]"
+          >
+            平均得分
+          </div>
+          <div v-if="row.ranking <= 3" class="text-center">
+            <img class="mt-auto" :src="RANK_IMG[Number(row.ranking) - 1]" />
+          </div>
+          <div v-else-if="row.ranking" class="diamond">{{ row.ranking }}</div>
+        </div>
+      </template>
+      <template #dim-allScore="{ row }">
+        {{ row.allScore }}
+      </template>
+    </vxe-grid>
+    <vxe-grid v-else v-bind="gridOptions">
+      <template #imgUrl_default="{ row }">
+        <div v-if="row.ranking <= 3" class="text-center">
+          <img class="mt-auto" :src="RANK_IMG[Number(row.ranking) - 1]" />
+        </div>
+        <div v-else-if="row.ranking" class="diamond">{{ row.ranking }}</div>
+      </template>
+      <template #dim-allScore="{ row }">
+        {{ row.allScore }}
+      </template>
+    </vxe-grid>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, watch } from "vue";
+import rank1 from "@/assets/rank/rank1.png";
+import rank2 from "@/assets/rank/rank2.png";
+import rank3 from "@/assets/rank/rank3.png";
+import { useRoute } from "vue-router";
+
+const $route = useRoute();
+const RANK_IMG = [rank1, rank2, rank3];
+const deptName = ref("");
+const name = ref("");
+const mergeCells = ref([
+  // 合并第一行前两列
+  { row: 0, col: 0, rowspan: 1, colspan: 2 },
+  { row: 2, col: 1, rowspan: 0, colspan: 0 }
+]);
+const averageData = averageSore => {
+  if (rawData.value.length > 0) {
+    let num = 0;
+    rawData.value.map(it => {
+      num = num + it.allScore;
+    });
+    num = num / rawData.value.length;
+    rawData.value.unshift({
+      dimensionList: [],
+      allScore: num
+    });
+  }
+};
+const selectYear = ref("2024-01-01");
+const gridOptions = reactive({
+  border: true,
+  loading: false,
+  height: 500,
+  columns: [],
+  data: [],
+  showOverflow: true,
+  showHeaderOverflow: true,
+  showFooterOverflow: true,
+  columnConfig: {
+    resizable: true
+  },
+  scrollX: {
+    enabled: true,
+    gt: 0
+  }
+});
+const tableConfig = reactive({});
+
+// 模拟接口数据
+const rawData = ref([]);
+const init = (item, deptNames, names) => {
+  rawData.value = item;
+  console.log("111-item", item);
+  deptName.value = deptNames;
+  name.value = names;
+  if ($route.name != "workerDrak") {
+    averageData(item.averageSore);
+  }
+  // 初始化
+  createColumns();
+  loadData();
+};
+defineExpose({
+  init
+});
+
+// 生成动态表头
+// 生成动态表头
+const createColumns = () => {
+  const columns = [
+    {
+      title: "排名",
+      field: "ranking",
+      width: 70,
+      slots: { default: "imgUrl_default" },
+      fixed: "left" // 将此列固定在左侧
+    },
+    {
+      title: "姓名",
+      field: "assessmentObjectName",
+      width: 100,
+      fixed: "left" // 将此列固定在左侧
+    },
+    {
+      title: "部门",
+      field: "deptName",
+      width: 150,
+      fixed: "left" // 将此列固定在左侧
+    },
+    {
+      title: "总得分",
+      field: "allScore",
+      width: 150,
+      fixed: "right", // 将此列固定在右侧
+      slots: { default: "dim-allScore" }
+    }
+  ];
+
+  const headerMap = new Map();
+
+  // 遍历数据生成表头结构
+  rawData.value.forEach(item => {
+    item.dimensionList.forEach(dim => {
+      if (!headerMap.has(dim.dimName)) {
+        // 存储维度相关信息,包括 totalSore
+        headerMap.set(dim.dimName, {
+          totalSore: dim.totalSore,
+          quotas: [] // 用于存储 quota 列表
+        });
+      }
+      dim.quotaList.forEach(quota => {
+        const dimData = headerMap.get(dim.dimName);
+        if (!dimData.quotas.some(q => q.quotaName === quota.quotaName)) {
+          dimData.quotas.push({ quotaName: quota.quotaName });
+        }
+      });
+    });
+  });
+
+  // 构建多级表头
+  headerMap.forEach((dimData, dimName) => {
+    const children = dimData.quotas.map(quota => ({
+      title: quota.quotaName,
+      width: 120,
+      field: `${dimName}_${quota.quotaName}` // 确保字段唯一
+    }));
+
+    // 添加维度名称及其对应的子列
+    columns.push({
+      title: dimName,
+      children
+    });
+
+    // 添加该维度的总分列
+    columns.push({
+      title: `总分`, // 可根据需要调整标题
+      field: `${dimName}_totalSore`,
+      width: 120
+    });
+  });
+
+  gridOptions.columns = columns;
+};
+
+// 加载数据
+const loadData = () => {
+  gridOptions.loading = true;
+
+  const tableData = rawData.value.map(item => {
+    const row = {
+      assessmentObjectName: item.assessmentObjectName,
+      deptName: item.deptName,
+      ranking: item.ranking,
+      allScore: item.allScore
+    };
+
+    item.dimensionList.forEach(dim => {
+      let totalScore = 0;
+
+      // 填充指标得分
+      dim.quotaList.forEach(quota => {
+        const fieldName = `${dim.dimName}_${quota.quotaName}`;
+        row[fieldName] = quota.quotaScore;
+        totalScore += quota.quotaScore;
+      });
+
+      // 填充维度总分
+      const totalFieldName = `${dim.dimName}_totalSore`;
+      row[totalFieldName] = dim.totalSore || totalScore; // 使用 dim.totalSore 或计算得出的总分
+    });
+
+    return row;
+  });
+
+  setTimeout(() => {
+    gridOptions.data = tableData;
+    gridOptions.loading = false;
+  }, 500);
+};
+
+// 监听年份变化,重新渲染
+watch(selectYear, () => {
+  createColumns();
+  loadData();
+});
 </script>
 
 <style lang="scss" scoped>

+ 257 - 2
src/components/rankTable/index.vue

@@ -1,4 +1,4 @@
-<template>
+<!-- <template>
   <vxe-table
     border
     style="width: 100%"
@@ -131,8 +131,263 @@ const soreRate = row => {
 defineExpose({
   init
 });
-</script>
+</script> -->
+
+<template>
+  <div class="w-full">
+    <vxe-grid
+      v-if="$route.name != 'workerDrak'"
+      v-bind="gridOptions"
+      :merge-cells="mergeCells"
+    >
+      <template #imgUrl_default="{ row }">
+        <div>
+          <div
+            v-if="!row.ranking"
+            class="text-center text-sm font-extrabold text-[#000000]"
+          >
+            平均得分
+          </div>
+          <div v-if="row.ranking <= 3" class="text-center">
+            <img class="mt-auto" :src="RANK_IMG[Number(row.ranking) - 1]" />
+          </div>
+          <div v-else-if="row.ranking" class="diamond">{{ row.ranking }}</div>
+        </div>
+      </template>
+      <template #dim-allScore="{ row }">
+        {{ row.allScore }}
+      </template>
+    </vxe-grid>
+    <vxe-grid v-else v-bind="gridOptions">
+      <template #imgUrl_default="{ row }">
+        <div v-if="row.ranking <= 3" class="text-center">
+          <img class="mt-auto" :src="RANK_IMG[Number(row.ranking) - 1]" />
+        </div>
+        <div v-else-if="row.ranking" class="diamond">{{ row.ranking }}</div>
+      </template>
+      <template #dim-allScore="{ row }">
+        {{ row.allScore }}
+      </template>
+    </vxe-grid>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, watch } from "vue";
+import rank1 from "@/assets/rank/rank1.png";
+import rank2 from "@/assets/rank/rank2.png";
+import rank3 from "@/assets/rank/rank3.png";
+import { useRoute } from "vue-router";
+
+const $route = useRoute();
+const RANK_IMG = [rank1, rank2, rank3];
+const deptName = ref("");
+const name = ref("");
+const mergeCells = ref([
+  // 合并第一行前两列
+  { row: 0, col: 0, rowspan: 1, colspan: 2 },
+  { row: 2, col: 1, rowspan: 0, colspan: 0 }
+]);
+const averageData = averageSore => {
+  if (rawData.value.length > 0) {
+    let num = 0;
+    rawData.value.map(it => {
+      num = num + it.allScore;
+    });
+    num = num / rawData.value.length;
+    rawData.value.unshift({
+      dimensionList: [],
+      allScore: num
+    });
+  }
+};
+const selectYear = ref("2024-01-01");
+const gridOptions = reactive({
+  border: true,
+  loading: false,
+  columns: [],
+  data: [],
+  showOverflow: true,
+  showHeaderOverflow: true,
+  showFooterOverflow: true,
+  columnConfig: {
+    resizable: true
+  },
+  scrollX: {
+    enabled: true,
+    gt: 0
+  }
+});
+const tableConfig = reactive({});
+const tabTitle = ref();
+// 模拟接口数据
+const rawData = ref([]);
+const init = (item, deptNames, names) => {
+  rawData.value = item;
+  console.log("111-item", item);
+  deptName.value = deptNames;
+  name.value = names;
+  if ($route.name != "workerDrak") {
+    averageData(item.averageSore);
+  }
+  if ($route.name == "healthDrank" || $route.name == "healthRank") {
+    tabTitle.value = "医疗组";
+  } else {
+    tabTitle.value = "科室";
+  }
+  // 初始化
+  createColumns();
+  loadData();
+};
+defineExpose({
+  init
+});
+
+// 生成动态表头
+// 生成动态表头
+const createColumns = () => {
+  let columns = [];
+  if ($route.name == "workerRank") {
+    columns = [
+      {
+        title: "排名",
+        field: "ranking",
+        width: 70,
+        slots: { default: "imgUrl_default" },
+        fixed: "left" // 将此列固定在左侧
+      },
+      {
+        title: "姓名",
+        field: "assessmentObjectName",
+        width: 100,
+        fixed: "left" // 将此列固定在左侧
+      },
+      {
+        title: "部门",
+        field: "deptName",
+        width: 150,
+        fixed: "left" // 将此列固定在左侧
+      },
+      {
+        title: "总得分",
+        field: "allScore",
+        width: 150,
+        fixed: "right", // 将此列固定在右侧
+        slots: { default: "dim-allScore" }
+      }
+    ];
+  } else {
+    columns = [
+      {
+        title: "排名",
+        field: "ranking",
+        width: 70,
+        slots: { default: "imgUrl_default" },
+        fixed: "left" // 将此列固定在左侧
+      },
+      {
+        title: tabTitle.value,
+        field: "assessmentObjectName",
+        width: 100,
+        fixed: "left" // 将此列固定在左侧
+      },
+      {
+        title: "总得分",
+        field: "allScore",
+        width: 150,
+        fixed: "right", // 将此列固定在右侧
+        slots: { default: "dim-allScore" }
+      }
+    ];
+  }
+  const headerMap = new Map();
+
+  // 遍历数据生成表头结构
+  rawData.value.forEach(item => {
+    item.dimensionList.forEach(dim => {
+      if (!headerMap.has(dim.dimName)) {
+        // 存储维度相关信息,包括 totalSore
+        headerMap.set(dim.dimName, {
+          totalSore: dim.totalSore,
+          quotas: [] // 用于存储 quota 列表
+        });
+      }
+      dim.quotaList.forEach(quota => {
+        const dimData = headerMap.get(dim.dimName);
+        if (!dimData.quotas.some(q => q.quotaName === quota.quotaName)) {
+          dimData.quotas.push({ quotaName: quota.quotaName });
+        }
+      });
+    });
+  });
 
+  // 构建多级表头
+  headerMap.forEach((dimData, dimName) => {
+    const children = dimData.quotas.map(quota => ({
+      title: quota.quotaName,
+      width: 120,
+      field: `${dimName}_${quota.quotaName}` // 确保字段唯一
+    }));
+
+    // 添加维度名称及其对应的子列
+    columns.push({
+      title: dimName,
+      children
+    });
+
+    // 添加该维度的总分列
+    columns.push({
+      title: `总分`, // 可根据需要调整标题
+      field: `${dimName}_totalSore`,
+      width: 120
+    });
+  });
+
+  gridOptions.columns = columns;
+};
+
+// 加载数据
+const loadData = () => {
+  gridOptions.loading = true;
+
+  const tableData = rawData.value.map(item => {
+    const row = {
+      assessmentObjectName: item.assessmentObjectName,
+      deptName: item.deptName,
+      ranking: item.ranking,
+      allScore: item.allScore
+    };
+
+    item.dimensionList.forEach(dim => {
+      let totalScore = 0;
+
+      // 填充指标得分
+      dim.quotaList.forEach(quota => {
+        const fieldName = `${dim.dimName}_${quota.quotaName}`;
+        row[fieldName] = quota.quotaScore;
+        totalScore += quota.quotaScore;
+      });
+
+      // 填充维度总分
+      const totalFieldName = `${dim.dimName}_totalSore`;
+      row[totalFieldName] = dim.totalSore || totalScore; // 使用 dim.totalSore 或计算得出的总分
+    });
+
+    return row;
+  });
+
+  setTimeout(() => {
+    gridOptions.data = tableData;
+    gridOptions.loading = false;
+  }, 500);
+};
+
+// 监听年份变化,重新渲染
+watch(selectYear, () => {
+  createColumns();
+  loadData();
+});
+</script>
 <style lang="scss" scoped>
 .diamond {
   display: flex;

+ 3 - 0
src/views/background/framework/proson/components/addPerson.vue

@@ -32,6 +32,9 @@ const handleClose = () => {
   dialogVisibleAdd.value = !dialogVisibleAdd.value;
 };
 const postDeptUserAddApi = async () => {
+  if (!form.birth) {
+    delete form.birth;
+  }
   const { code, data, msg } = await postDeptUserAdd(form);
   if (code == 200) {
     ElMessage({

+ 1 - 4
src/views/background/framework/proson/components/changeRole.vue

@@ -63,13 +63,10 @@ const open = (item, user) => {
   if (user == "用户") {
     rolesList.assignmentParams.sourceCodes = [];
     rolesList.assignmentParams.sourceCodes.push(item.userCode);
-    // rolesList.assignmentParams.targetCodes = [];
-    // rolesList.assignmentParams.targetCodes.push(item.userCode);
+    rolesList.assignmentParams.correlatedModel = "userRole";
   } else {
     rolesList.assignmentParams.sourceCodes = [];
     rolesList.assignmentParams.sourceCodes.push(item.data.deptCode);
-    // rolesList.assignmentParams.targetCodes = [];
-    // rolesList.assignmentParams.targetCodes.push(item.data.deptCode);
   }
   rolesData();
 };

+ 3 - 0
src/views/background/framework/proson/components/personDetailsDrawer.vue

@@ -58,6 +58,9 @@ function confirmClick() {
   });
 }
 const postUpdateUserInfoApi = async () => {
+  if (!formLabelAlign.birth) {
+    delete formLabelAlign.birth;
+  }
   const { code, msg } = await postUpdateUserInfo(formLabelAlign);
   if (code === 200) {
     ElMessage({

+ 14 - 4
src/views/background/framework/proson/components/prosonEditDrawer.vue

@@ -17,7 +17,8 @@ const formLabelAlign = reactive({
   type: "",
   parentCode: "",
   hospitalCode: "",
-  leader: ""
+  leader: "",
+  leaderCode: ""
 });
 
 // 部门负责人
@@ -89,8 +90,8 @@ const open = row => {
   formLabelAlign.deptCode = row.data.deptCode;
   formLabelAlign.hospitalCode = row.data.hospitalCode;
   formLabelAlign.parentCode = row.data.parentCode;
-  formLabelAlign.leader = row.data.leader;
-  // console.log("数据", row.data);
+  formLabelAlign.leaderCode = row.data.leader;
+  console.log("数据", row.data);
   postListTreeApi();
   postUserListApi();
   drawer.value = true;
@@ -109,6 +110,14 @@ const postListTreeApi = async () => {
     parentOptions.value = data;
   }
 };
+const handClickInit = value => {
+  if (value) {
+    const selectedItem = optiones.leaderOptions.find(
+      item => item.userCode === value
+    );
+    formLabelAlign.leader = selectedItem.realName;
+  }
+};
 defineExpose({
   open
 });
@@ -178,9 +187,10 @@ const timer = ref("");
             </el-form-item>
             <el-form-item label="部门负责人" label-position="top">
               <el-select
-                v-model="formLabelAlign.leader"
+                v-model="formLabelAlign.leaderCode"
                 placeholder="请选择部门负责人"
                 :disabled="disabledValue"
+                @change="handClickInit"
               >
                 <el-option
                   v-for="item in optiones.leaderOptions"

+ 8 - 0
src/views/background/framework/roles/components/addPerson.vue

@@ -32,6 +32,14 @@ const open = item => {
   filterText.value = "";
 };
 const postAssignmentUserApi = async () => {
+  // 清除为null的数据
+  let sourceCodes = [];
+  form.sourceCodes.map(item => {
+    if (item) {
+      sourceCodes.push(item);
+    }
+  });
+  form.sourceCodes = sourceCodes;
   const { code, msg } = await postAssignmentUser(form);
   if (code === 200) {
     ElMessage({

+ 8 - 0
src/views/background/framework/users/components/addPerson.vue

@@ -30,6 +30,14 @@ const open = (item, list) => {
   // form.sourceCodes.push(item.groupCode);
 };
 const postAssignmentUserApi = async () => {
+  // 清除为null的数据
+  let sourceCodes = [];
+  form.sourceCodes.map(item => {
+    if (item) {
+      sourceCodes.push(item);
+    }
+  });
+  form.sourceCodes = sourceCodes;
   const { code, msg } = await postAssignmentUser(form);
   if (code == 200) {
     $emit("handleClick");

+ 29 - 7
src/views/background/framework/users/components/editPerson.vue

@@ -12,6 +12,7 @@ const direction = ref<DrawerProps["direction"]>("rtl");
 const formLabelAlign = reactive({
   groupName: "",
   leaderCode: "",
+  leader: "",
   groupCode: "",
   hospitalCode: ""
 });
@@ -37,17 +38,20 @@ const handleClose = (done: () => void) => {
   editShow.value = true;
 };
 function cancelClick() {
-  formRef.value.validate(valid => {
-    if (valid) {
-      disabledValue.value = true;
-      editShow.value = true;
-    }
-  });
+  // formRef.value.validate(valid => {
+  //   if (valid) {
+  disabledValue.value = true;
+  editShow.value = true;
+  formRef.value.clearValidate(); // 清除验证错误
+  formRef.value.resetFields(); // 重置表单字段
+  //   }
+  // });
   // drawer.value = false;
 }
 function confirmClick() {
   formRef.value.validate(valid => {
     if (valid) {
+      console.log(valid);
       disabledValue.value = true;
       editShow.value = true;
       drawer.value = !drawer.value;
@@ -86,6 +90,12 @@ const editClick = () => {
   editShow.value = false;
   disabledValue.value = false;
 };
+const handClickInit = value => {
+  if (value) {
+    const selectedItem = leader.value.find(item => item.userCode === value);
+    formLabelAlign.leader = selectedItem.realName;
+  }
+};
 defineExpose({
   open
 });
@@ -110,7 +120,18 @@ const timer = ref("");
             label-width="auto"
             :model="formLabelAlign"
           >
-            <el-form-item label="用户组名称" label-position="top">
+            <el-form-item
+              label="用户组名称"
+              prop="groupName"
+              label-position="top"
+              :rules="[
+                {
+                  required: true,
+                  message: '用户组名称不可为空',
+                  trigger: 'blur'
+                }
+              ]"
+            >
               <el-input
                 v-model="formLabelAlign.groupName"
                 :disabled="disabledValue"
@@ -127,6 +148,7 @@ const timer = ref("");
                 v-model="formLabelAlign.leaderCode"
                 :disabled="disabledValue"
                 placeholder="请选择"
+                @change="handClickInit"
               >
                 <el-option
                   v-for="item in leader"

+ 4 - 4
src/views/background/framework/users/index.vue

@@ -62,8 +62,8 @@ const lookRoles = item => {
   bgColor.value = item.id;
   rolesList.rolesName = item.groupName;
   Object.assign(rolesList.addPerson, item);
-  UserTable.value.handleNodeClick(item, "group");
-  addPersonClick.value = UserTable.value.handleNodeClick(item, "group");
+  UserTable?.value?.handleNodeClick(item, "group");
+  addPersonClick.value = UserTable?.value?.handleNodeClick(item, "group");
   paramsItem.value = item;
 };
 // 标签选择
@@ -131,7 +131,7 @@ const deltetePerson = row => {
         row.userCode,
         UserTable.value.postOrganizationUserPageApi
       );
-      UserTable.value.handleNodeClick(row, "group");
+      UserTable?.value?.handleNodeClick(row, "group");
     })
     .catch(() => {
       ElMessage({
@@ -141,7 +141,7 @@ const deltetePerson = row => {
 };
 const addPersonClickList = () => {
   postPageGroupApi();
-  UserTable.value.handleNodeClick(paramsItem.value, "group");
+  UserTable?.value?.handleNodeClick(paramsItem.value, "group");
 };
 </script>
 

+ 1 - 1
src/views/draw/children/department/componements/seach.vue

@@ -75,7 +75,7 @@ const handClickInit1 = value => {
   }
   Object.assign(dataList.params, {
     assessmentModelId: "",
-    deptCode: ""
+    assessmentObjectId: ""
   });
   $emit(
     "handClick",

+ 19 - 12
src/views/draw/children/department/departmentDrank.vue

@@ -81,9 +81,12 @@ const getPersonDimensionChartsListApi = async (
   if (code == 200) {
     if (data.length > 0) {
       if (dimensionName && dimId) {
+        console.log("文化", personListRef.value);
         setTimeout(() => {
           nextTick(() => {
-            personListRef.value[tabIndex - 1].init(data);
+            if (personListRef.value) {
+              personListRef?.value[tabIndex - 1]?.init(data);
+            }
           });
         }, 500);
       } else {
@@ -125,14 +128,12 @@ const init = (item, type) => {
   setTimeout(() => {
     nextTick(() => {
       if (barDimEchartsRef.value) {
-        if (barDimEchartsRef.value) {
-          if (Array.isArray(barDimEchartsRef.value)) {
-            dataList.dimName.map((it, id) => {
-              barDimEchartsRef.value[id - 1].init(seachParams.value, 1);
-            });
-          } else {
-            barDimEchartsRef.value.init(seachParams.value, 1);
-          }
+        if (Array.isArray(barDimEchartsRef.value)) {
+          dataList.dimName.map((it, id) => {
+            barDimEchartsRef?.value[id - 1]?.init(seachParams.value, 1);
+          });
+        } else {
+          barDimEchartsRef.value.init(seachParams.value, 1);
         }
       }
     });
@@ -149,12 +150,18 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
     getPersonDimensionChartsListApi(tab.props.label, tab.props.name, tab.index);
     getPersonDimensionChartsRankingApi(tab.props.label, tab.props.name);
   }
-  barEchartsRef.value.init(tab.props);
+  // barEchartsRef.value.init(tab.props);
 };
 const fullBig = (item: any) => {
+  console.log(item);
   router.push({
     path: "/fullBig",
-    query: { title: item, ...seachParams.value, type: 1 }
+    query: {
+      dimensionName: item.name,
+      dimId: item.id,
+      ...seachParams.value,
+      type: 1
+    }
   });
 };
 </script>
@@ -204,7 +211,7 @@ const fullBig = (item: any) => {
                 <personList ref="personListRef" class="w-11/12" />
                 <div
                   class="w-[30px] h-[30px] mr-10 cursor-pointer"
-                  @click="fullBig(item.name)"
+                  @click="fullBig(item)"
                 >
                   <img class="w-full h-full" :src="qvanping" alt="" />
                 </div>

+ 1 - 3
src/views/draw/children/department/departmentRank.vue

@@ -30,9 +30,7 @@ const getPersonDimensionChartsListApi = async () => {
 };
 const init = (item, type) => {
   seachParams.value = item;
-  console.log(111111, type);
-  console.log(111111, item);
-  if (type) {
+  if (Number(type)) {
     getPersonDimensionChartsListApi();
   }
 };

+ 9 - 4
src/views/draw/children/head/headDrank.vue

@@ -84,7 +84,7 @@ const getPersonDimensionChartsListApi = async (
       if (dimensionName && dimId) {
         setTimeout(() => {
           nextTick(() => {
-            personListRef.value[tabIndex - 1].init(data);
+            personListRef?.value[tabIndex - 1]?.init(data);
           });
         }, 500);
       } else {
@@ -129,7 +129,7 @@ const init = (item, type) => {
       if (barDimEchartsRef.value) {
         if (Array.isArray(barDimEchartsRef.value)) {
           dataList.dimName.map((it, id) => {
-            barDimEchartsRef.value[id - 1].init(seachParams.value, 0);
+            barDimEchartsRef?.value[id - 1]?.init(seachParams.value, 0);
           });
         } else {
           barDimEchartsRef.value.init(seachParams.value, 0);
@@ -155,7 +155,12 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
 const fullBig = (item: any) => {
   router.push({
     path: "/fullBig",
-    query: { title: item, ...seachParams.value, type: 3 }
+    query: {
+      dimensionName: item.name,
+      dimId: item.id,
+      ...seachParams.value,
+      type: 3
+    }
   });
 };
 </script>
@@ -205,7 +210,7 @@ const fullBig = (item: any) => {
                 <personList ref="personListRef" class="w-11/12" />
                 <div
                   class="w-[30px] h-[30px] mr-10 cursor-pointer"
-                  @click="fullBig(item.name)"
+                  @click="fullBig(item)"
                 >
                   <img class="w-full h-full" :src="qvanping" alt="" />
                 </div>

+ 5 - 3
src/views/draw/children/head/headRank.vue

@@ -2,7 +2,7 @@
 defineOptions({
   name: "healthRank"
 });
-import rankTableDraw from "@/components/rankTable/draw.vue";
+import rankTableDraw from "@/components/rankTable/index.vue";
 import seachData from "./componements/seach.vue";
 import { getChartsList } from "@/api/draw";
 
@@ -27,9 +27,11 @@ const getPersonDimensionChartsListApi = async () => {
     }
   }
 };
-const init = item => {
+const init = (item, type) => {
   seachParams.value = item;
-  getPersonDimensionChartsListApi();
+  if (Number(type)) {
+    getPersonDimensionChartsListApi();
+  }
 };
 </script>
 

+ 9 - 4
src/views/draw/children/health/healthDrank.vue

@@ -86,7 +86,7 @@ const getPersonDimensionChartsListApi = async (
       if (dimensionName && dimId) {
         setTimeout(() => {
           nextTick(() => {
-            personListRef.value[tabIndex - 1].init(data);
+            personListRef?.value[tabIndex - 1]?.init(data);
           });
         }, 500);
       } else {
@@ -133,7 +133,7 @@ const init = (item, type) => {
         // barDimEchartsRef.value[0].init(seachParams.value, 0);
         if (Array.isArray(barDimEchartsRef.value)) {
           dataList.dimName.map((it, id) => {
-            barDimEchartsRef.value[id - 1].init(seachParams.value, 0);
+            barDimEchartsRef?.value[id - 1]?.init(seachParams.value, 0);
           });
         } else {
           barDimEchartsRef.value.init(seachParams.value, 0);
@@ -158,7 +158,12 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
 const fullBig = (item: any) => {
   router.push({
     path: "/fullBig",
-    query: { title: item, ...seachParams.value, type: 2 }
+    query: {
+      dimensionName: item.name,
+      dimId: item.id,
+      ...seachParams.value,
+      type: 2
+    }
   });
 };
 </script>
@@ -208,7 +213,7 @@ const fullBig = (item: any) => {
                 <personList ref="personListRef" class="w-11/12" />
                 <div
                   class="w-[30px] h-[30px] mr-10 cursor-pointer"
-                  @click="fullBig(item.name)"
+                  @click="fullBig(item)"
                 >
                   <img class="w-full h-full" :src="qvanping" alt="" />
                 </div>

+ 5 - 3
src/views/draw/children/health/healthRank.vue

@@ -2,7 +2,7 @@
 defineOptions({
   name: "headRank"
 });
-import rankTableDraw from "@/components/rankTable/draw.vue";
+import rankTableDraw from "@/components/rankTable/index.vue";
 import seachData from "./componements/seach.vue";
 import { getPersonDimensionChartsList, getChartsList } from "@/api/draw";
 
@@ -27,9 +27,11 @@ const getPersonDimensionChartsListApi = async () => {
     }
   }
 };
-const init = item => {
+const init = (item, type) => {
   seachParams.value = item;
-  getPersonDimensionChartsListApi();
+  if (Number(type)) {
+    getPersonDimensionChartsListApi();
+  }
 };
 </script>
 

+ 36 - 14
src/views/draw/children/worker/componements/seach.vue

@@ -7,7 +7,8 @@ import { postListTree } from "@/api/department";
 import {
   getAssessmentList,
   getModelListByAssessmentId,
-  getUserListObjectByModelId
+  getUserListObjectByModelId,
+  getDeptListByUserList
 } from "@/api/draw";
 import { useRouter, useRoute } from "vue-router";
 
@@ -44,18 +45,39 @@ const userPageWhitOrganizationApi = async selectedItem => {
   });
   if (code === 200) {
     dataList.personList = data;
+    data.map(item => {
+      if (item.assessmentObjectId.substring(0, 4) == "user") {
+        userCodeList.value.push(item.assessmentObjectId);
+      }
+    });
+    getDeptListByUserListApi();
   }
 };
 
 // 部门
-const postListTreeApi = async selectedItem => {
-  const { data, code } = await getUserListObjectByModelId({
-    modelId: selectedItem.assessmentModelId,
-    type: 1,
-    assessmentId: selectedItem.assessmentId
-  });
+// const postListTreeApi = async selectedItem => {
+//   const { data, code } = await getUserListObjectByModelId({
+//     modelId: selectedItem.assessmentModelId,
+//     type: 1,
+//     assessmentId: selectedItem.assessmentId
+//   });
+//   if (code === 200) {
+//     dataList.deptList = data;
+//   }
+// };
+const userCodeList = ref([]);
+const getDeptListByUserListApi = async () => {
+  const { data, code } = await getDeptListByUserList(userCodeList.value);
+  console.log(data, code);
   if (code === 200) {
-    dataList.deptList = data;
+    const uniqueDeptCodes = {};
+    dataList.deptList = data.filter(item => {
+      if (!uniqueDeptCodes[item.deptCode]) {
+        uniqueDeptCodes[item.deptCode] = true;
+        return true; // 保留该项
+      }
+      return false; // 过滤掉重复项
+    });
   }
 };
 // postListTreeApi();
@@ -94,7 +116,7 @@ const handClickInit2 = value => {
     );
     init.assessmentModelName = selectedItem.assessmentModelName;
     userPageWhitOrganizationApi(selectedItem);
-    postListTreeApi(selectedItem);
+    // postListTreeApi(selectedItem);
   }
   Object.assign(dataList.params, {
     deptCode: "",
@@ -112,9 +134,9 @@ const handClickInit2 = value => {
 const handClickInit3 = value => {
   if (value) {
     const selectedItem = dataList.personList.find(
-      item => item.assessmentObjectId === value
+      item => item.deptCode === value
     );
-    init.deptName = selectedItem.assessmentObjectName;
+    init.deptName = selectedItem?.deptName;
     // init.deptName = value.deptName;
   }
   $emit(
@@ -239,9 +261,9 @@ getAssessmentPageListApi();
           >
             <el-option
               v-for="item in dataList.deptList"
-              :key="item.assessmentObjectId"
-              :label="item.assessmentObjectName"
-              :value="item.assessmentObjectId"
+              :key="item.deptCode"
+              :label="item.deptName"
+              :value="item.deptCode"
             />
           </el-select>
           <!-- <el-tree-select

+ 12 - 5
src/views/draw/children/worker/workerDrak.vue

@@ -34,9 +34,11 @@ const getChartsListApi = async () => {
     type: 0
   });
   if (code == 200) {
-    showLength.value = data.length;
     setTimeout(() => {
       nextTick(() => {
+        if (data) {
+          showLength.value = data.length;
+        }
         if (rankTableRef.value) {
           rankTableRef.value.init(data, "科室", "姓名");
         }
@@ -87,7 +89,7 @@ const getPersonDimensionChartsListApi = async (
       setTimeout(() => {
         nextTick(() => {
           if (personListRef.value) {
-            personListRef.value[tabIndex - 1].init(data);
+            personListRef?.value[tabIndex - 1]?.init(data);
           }
         });
       }, 0);
@@ -133,7 +135,7 @@ const init = (item, type) => {
       if (barDimEchartsRef.value) {
         if (Array.isArray(barDimEchartsRef.value)) {
           dataList.dimName.map((it, id) => {
-            barDimEchartsRef.value[id - 1].init(seachParams.value, 0);
+            barDimEchartsRef?.value[id - 1]?.init(seachParams.value, 0);
           });
         } else {
           barDimEchartsRef.value.init(seachParams.value, 0);
@@ -169,7 +171,12 @@ const handleClick = (tab: TabsPaneContext, event: Event) => {
 const fullBig = (item: any) => {
   router.push({
     path: "/fullBig",
-    query: { title: item, ...seachParams.value, type: 0 }
+    query: {
+      dimensionName: item.name,
+      dimId: item.id,
+      ...seachParams.value,
+      type: 0
+    }
   });
 };
 </script>
@@ -217,7 +224,7 @@ const fullBig = (item: any) => {
                 <personList ref="personListRef" class="w-11/12" />
                 <div
                   class="w-[30px] h-[30px] mr-10 cursor-pointer"
-                  @click="fullBig(item.name)"
+                  @click="fullBig(item)"
                 >
                   <img class="w-full h-full" :src="qvanping" alt="" />
                 </div>

+ 1 - 0
src/views/evaluate/children/change/components/editMould.vue

@@ -28,6 +28,7 @@ const formLabelAlign = reactive({
   ],
   dimName: "",
   dimWeight: 0,
+  dimWeightBol: false,
   mode: 1,
   showIndicRemark: 1,
   showScoreRule: 1,

+ 5 - 5
src/views/evaluate/children/change/components/newAdd.vue

@@ -361,10 +361,10 @@ const onUpdate = (e: DraggableEvent) => {};
 //   });
 // };
 
-const postUpdateApi = async () => {
+const postUpdateApi = async row => {
   console.log();
   // indexOf.indName = indexOf.name
-  const { code, msg } = await postUpdate(indexOf);
+  const { code, msg } = await postUpdate(row);
   if (code == 200) {
     getListByApi();
     ElMessage.success("编辑成功");
@@ -405,11 +405,11 @@ const editConfig = ref<any>({
 });
 const tableVxeRef = ref();
 const editClosedEvent = ({ row, column }) => {
-  console.log("row", row);
   const $table = tableVxeRef.value;
   if ($table) {
     Object.assign(indexOf, row);
-    postUpdateApi();
+    console.log("indexOf", indexOf);
+    postUpdateApi(row);
   }
 };
 // 列表行拖拽
@@ -607,7 +607,7 @@ const titleShowClick = () => {
                 "
               />
               <vxe-column
-                v-if="item.mode"
+                v-if="item.mode == 0 || item.dimWeight != 0"
                 field="weight"
                 title="权重"
                 :edit-render="{ name: 'input' }"

+ 212 - 13
src/views/evaluate/children/change/components/settingIndexDrawer.vue

@@ -162,6 +162,8 @@ const dialogFormVisibleFormula = ref(false);
 const formulaForm = ref([]);
 const grade = ref();
 const conditionVerifyApi = async () => {
+  grade.value = null;
+  formulaForm.value = [];
   dialogFormVisibleFormula.value = true;
   try {
     formulaForm.value = [];
@@ -223,6 +225,33 @@ function reverseReplace(oldValue, dataObject) {
   });
   return dataObject;
 }
+function calculateScore(inputString) {
+  // 将 formulaForm.value 转换为一个键值对映射,方便替换
+  const valueMap = formulaForm.value.reduce((map, item) => {
+    map[item.name] = item.value !== null ? item.value : 0; // 用 0 替代 null
+    return map;
+  }, {});
+
+  // 替换字符串中的关键字为对应的 value 值
+  let formula = inputString;
+  for (const [key, value] of Object.entries(valueMap)) {
+    if (formula.includes(key)) {
+      // 使用正则替换所有匹配的关键字
+      const regex = new RegExp(key, "g");
+      formula = formula.replace(regex, value);
+    }
+  }
+
+  try {
+    // 使用 eval 计算公式
+    const result = eval(formula);
+    return result;
+  } catch (error) {
+    console.error("公式计算出错:", error);
+    return null;
+  }
+}
+
 const countComputed = async () => {
   try {
     if (params.formulaType == 0) {
@@ -269,14 +298,58 @@ const countComputed = async () => {
         });
       }
     } else if (params.formulaType == 1) {
-      let oldValue = {};
-      Object.assign(oldValue, addmanyChange);
-      let formListNum = formulaForm.value;
-      let newValue = reverseReplace(formListNum, oldValue);
-      const { code, msg, data } =
-        await calculateScoreByConditionMoCondition(newValue);
-      if (code == 200) {
-        grade.value = data;
+      let oldValue = JSON.parse(JSON.stringify(addmanyChange));
+      // Object.assign(oldValue, addmanyChange);
+      const formulaPar = JSON.stringify(oldValue);
+      const res = await conditionVerify({
+        formulaType: params.formulaType,
+        formula: formulaPar
+      });
+      if (res.code == 200) {
+        if (oldValue.outerConditionValue) {
+          oldValue.outerConditionValue = calculateScore(
+            oldValue.outerConditionValue
+          );
+        }
+        if (oldValue.innerConditionExpression.length > 0) {
+          oldValue.innerConditionExpression.map(itEx => {
+            if (itEx.startValue) {
+              itEx.startValue = calculateScore(itEx.startValue);
+            }
+            if (itEx.endValue) {
+              itEx.endValue = calculateScore(itEx.endValue);
+            }
+            if (itEx.innerScore) {
+              itEx.innerScore = calculateScore(itEx.innerScore);
+            }
+            if (itEx?.scoreRuleMoreInnerVO[0]?.innerConditionValue) {
+              itEx.scoreRuleMoreInnerVO[0].innerConditionValue = calculateScore(
+                itEx.scoreRuleMoreInnerVO[0].innerConditionValue
+              );
+            }
+            if (itEx?.scoreRuleMoreInnerVO[0]?.scoreRules.length > 0) {
+              itEx.scoreRuleMoreInnerVO[0].scoreRules.map(itRule => {
+                if (itRule.score) {
+                  itRule.score = calculateScore(itRule.score);
+                }
+                if (itRule.startValue) {
+                  itRule.startValue = calculateScore(itRule.startValue);
+                }
+                if (itRule.endValue) {
+                  itRule.endValue = calculateScore(itRule.endValue);
+                }
+              });
+            }
+          });
+        }
+        console.log("计算后的数据oldValue", oldValue);
+        console.log("计算后的数据addmanyChange", addmanyChange);
+        // let newValue = reverseReplace(formListNum, oldValue);
+        const { code, msg, data } =
+          await calculateScoreByConditionMoCondition(oldValue);
+        if (code == 200) {
+          grade.value = data;
+        }
       } else {
         ElMessageBox.confirm(
           "如果不修改将无法计算得分",
@@ -384,6 +457,7 @@ const open = row => {
     ]
   });
   getIndexInfoApi(row.id);
+  calculatorShow.value = true;
 };
 const editShow = ref(true);
 defineExpose({
@@ -523,19 +597,23 @@ const addItemFormulaList = (item, index) => {
     }
   ];
   addmanyChange.innerConditionExpression[index].innerScore = "";
+  changeAddMay();
 };
 
 const deleteItem = index => {
   addmanyChange.innerConditionExpression.splice(index, 1);
+  changeAddMay();
 };
 const dataleListItem = (index, indexList) => {
   addmanyChange.innerConditionExpression[
     index
   ].scoreRuleMoreInnerVO[0].scoreRules.splice(indexList, 1);
+  changeAddMay();
 };
 // 条件变量
 const dataleListItemAll = (item, index) => {
   item.scoreRuleMoreInnerVO = [];
+  changeAddMay();
 };
 const addNewItem = () => {
   addmanyChange.innerConditionExpression.push({
@@ -546,6 +624,7 @@ const addNewItem = () => {
     comparisonEnd: null,
     scoreRuleMoreInnerVO: []
   });
+  changeAddMay();
 };
 const addNewItemOldValue = item => {
   addmanyChange.innerConditionExpression.push({
@@ -556,6 +635,7 @@ const addNewItemOldValue = item => {
     comparisonEnd: null,
     scoreRuleMoreInnerVO: []
   });
+  changeAddMay();
 };
 const addItemDataList = (
   index: number,
@@ -575,9 +655,10 @@ const addItemDataList = (
     comparisonEnd: null
   });
   addmanyChange.innerConditionExpression[index].innerScore = "";
+  changeAddMay();
 };
 // 多条件公式验证
-const keywords = ["目标值", "完成值", "挑战值", "增幅", "降幅"];
+const keywords = ["目标值", "完成值", "挑战值", "门槛值", "增幅", "降幅"];
 // 处理字符串,提取关键词
 function extractKeywords(value) {
   // 如果是字符串,处理包含的关键词
@@ -613,21 +694,76 @@ function traverseObject(obj) {
     }
   }
 }
+function extractKeywordsAndPush(keywordsList, inputString) {
+  keywords.forEach(keyword => {
+    if (
+      inputString?.includes(keyword) && // 检查字符串是否包含关键字
+      !formulaForm.value.some(item => item.name === keyword) // 确保没有重复
+    ) {
+      // 如果包含且未重复,构造对象并push到formulaForm.value
+      formulaForm.value.push({
+        name: keyword,
+        value: null // 根据需求赋值
+      });
+    }
+  });
+
+  return formulaForm;
+}
 const manyConditions = () => {
+  grade.value = null;
   dialogFormVisibleFormula.value = true;
   formulaForm.value = [];
   // 提取 addmanyChange 对象中的条件值
-  const oldValue = addmanyChange;
-  traverseObject(oldValue);
+  let oldValue = addmanyChange;
+  if (oldValue.outerConditionValue) {
+    extractKeywordsAndPush(keywords, oldValue.outerConditionValue);
+  }
+  if (oldValue.innerConditionExpression.length > 0) {
+    oldValue.innerConditionExpression.map(itemExp => {
+      if (itemExp.startValue) {
+        extractKeywordsAndPush(keywords, itemExp.startValue);
+      }
+      if (itemExp.endValue) {
+        extractKeywordsAndPush(keywords, itemExp.endValue);
+      }
+      if (itemExp.innerScore) {
+        extractKeywordsAndPush(keywords, itemExp.innerScore);
+      }
+      if (itemExp?.scoreRuleMoreInnerVO[0]?.innerConditionValue) {
+        extractKeywordsAndPush(
+          keywords,
+          itemExp.scoreRuleMoreInnerVO[0].innerConditionValue
+        );
+      }
+      if (itemExp?.scoreRuleMoreInnerVO.length > 0) {
+        if (itemExp?.scoreRuleMoreInnerVO[0]?.scoreRules.length > 0) {
+          itemExp?.scoreRuleMoreInnerVO[0]?.scoreRules.map(itSc => {
+            if (itSc.score) {
+              extractKeywordsAndPush(keywords, itSc.score);
+            }
+            if (itSc.startValue) {
+              extractKeywordsAndPush(keywords, itSc.startValue);
+            }
+            if (itSc.endValue) {
+              extractKeywordsAndPush(keywords, itSc.endValue);
+            }
+          });
+        }
+      }
+    });
+  }
 };
 // 计算器
 const jishuanqiRef = ref();
 const countNoConditionFormula = item => {
   addmanyChange.outerConditionValue = item;
+  changeAddMay();
 };
 const jishuanqiRef1 = ref();
 const countNoConditionFormula1 = (item, index) => {
   addmanyChange.innerConditionExpression[index].endValue = item;
+  changeAddMay();
 };
 const jishuanqiRef2 = ref();
 const countNoConditionFormula2 = (item, index) => {
@@ -635,20 +771,24 @@ const countNoConditionFormula2 = (item, index) => {
   addmanyChange.innerConditionExpression[
     index
   ].scoreRuleMoreInnerVO[0].innerConditionValue = item;
+  changeAddMay();
 };
 const jishuanqiRef3 = ref();
 const countNoConditionFormula3 = (item, index, indexList) => {
   addmanyChange.innerConditionExpression[
     index
   ].scoreRuleMoreInnerVO[0].scoreRules[indexList].endValue = item;
+  changeAddMay();
 };
 const countNoConditionFormula4 = (item, index, indexList) => {
   addmanyChange.innerConditionExpression[
     index
   ].scoreRuleMoreInnerVO[0].scoreRules[indexList].score = item;
+  changeAddMay();
 };
 const countNoConditionFormulaInnerScore = (item, index, indexList) => {
   addmanyChange.innerConditionExpression[index].innerScore = item;
+  changeAddMay();
 };
 
 // 转换函数 --- 人员
@@ -675,6 +815,60 @@ const handleRreeSelect = () => {
   });
   params.designatedPersonnel = arr.map(item => item.value).join(",");
 };
+// 取消计算
+const quxiaoCmputed = () => {
+  formulaForm.value = [];
+  dialogFormVisibleFormula.value = false;
+};
+// 监听数据变化
+const changeAddMay = () => {
+  let addmanyChangeOldVal = JSON.parse(JSON.stringify(addmanyChange));
+  addmanyChange.innerConditionExpression.forEach((item, index, arr) => {
+    if (index + 1 <= arr.length) {
+      console.log("12312", addmanyChangeOldVal.innerConditionExpression);
+      if (item.endValue) {
+        if (addmanyChangeOldVal.innerConditionExpression.length > 1) {
+          addmanyChangeOldVal.innerConditionExpression[index + 1].startValue =
+            item?.endValue;
+          addmanyChangeOldVal.innerConditionExpression[index + 1].startExpress =
+            item?.endExpress;
+          addmanyChangeOldVal.innerConditionExpression[
+            index + 1
+          ].comparisonStart = item?.comparisonEnd == "≥" ? ">" : "≥";
+        }
+      }
+      if (item.scoreRuleMoreInnerVO.length > 0) {
+        if (item.scoreRuleMoreInnerVO[0].scoreRules.length > 0) {
+          item.scoreRuleMoreInnerVO[0].scoreRules.map((it, id, arrChild) => {
+            if (id + 1 <= arrChild.length) {
+              if (it.endValue) {
+                // if (
+                //   addmanyChangeOldVal.innerConditionExpression[index + 1]
+                //     .scoreRuleMoreInnerVO.length > 0
+                // ) {
+                addmanyChangeOldVal.innerConditionExpression[
+                  index
+                ].scoreRuleMoreInnerVO[0].scoreRules[id + 1].startValue =
+                  it?.endValue;
+                addmanyChangeOldVal.innerConditionExpression[
+                  index
+                ].scoreRuleMoreInnerVO[0].scoreRules[id + 1].startExpress =
+                  it?.startExpress;
+                addmanyChangeOldVal.innerConditionExpression[
+                  index
+                ].scoreRuleMoreInnerVO[0].scoreRules[id + 1].comparisonStart =
+                  it?.comparisonEnd;
+                // }
+              }
+            }
+          });
+        }
+      }
+    }
+  });
+  Object.assign(addmanyChange, addmanyChangeOldVal);
+};
+// { deep: true };
 </script>
 
 <template>
@@ -1264,7 +1458,12 @@ const handleRreeSelect = () => {
       </template>
     </el-drawer>
     <!-- 公式验证 -->
-    <el-dialog v-model="dialogFormVisibleFormula" title="完成值" width="500">
+    <el-dialog
+      v-model="dialogFormVisibleFormula"
+      title="完成值"
+      width="500"
+      :before-close="quxiaoCmputed"
+    >
       <el-form :model="formulaForm">
         <div v-for="(itemF, indexF) in formulaForm" :key="indexF">
           <el-form-item :label="itemF.name">
@@ -1277,7 +1476,7 @@ const handleRreeSelect = () => {
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button @click="dialogFormVisibleFormula = false">取消</el-button>
+          <el-button @click="quxiaoCmputed">取消</el-button>
           <el-button type="primary" @click="countComputed"> 计算 </el-button>
         </div>
       </template>

+ 10 - 2
src/views/evaluate/children/change/manage.vue

@@ -99,6 +99,9 @@ const saveCopy = async () => {
     //   ElMessage.error(msg);
   }
 };
+const arrData = i => {
+  console.log(i);
+};
 </script>
 
 <template>
@@ -166,8 +169,13 @@ const saveCopy = async () => {
             show-overflow-tooltip
           >
             <template #default="{ row }">
-              <div @click="setEdit(row)">
-                {{ row.assessmentModelNameList }}
+              <div
+                v-for="(item, index) in row.assessmentModelNameList"
+                :key="index"
+                @click="setEdit(row)"
+              >
+                <!-- {{ JSON.parse(.replace(/'/g, '"') }} -->
+                <span v-if="item">{{ item }}</span>
               </div>
             </template>
           </el-table-column>

+ 51 - 10
src/views/evaluate/children/change/manage/addExam.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { ref, reactive, nextTick } from "vue";
+import { ref, reactive, nextTick, watch } from "vue";
 import { ElMessageBox, ElMessage } from "element-plus";
 import { Calendar } from "@element-plus/icons-vue";
 import dayjs from "dayjs";
@@ -84,8 +84,16 @@ const transformArrayFormat = data => {
 };
 // 添加部门保存
 const saveDepartment = async () => {
-  form.cycleValue = dayjs(form.cycleValue).format(format.value);
   form.assessmentObjectList = transformArrayFormat(form.listArr);
+  if (timeType.value == "月度") {
+    form.cycleValue = dayjs(new Date(form.cycleValue)).format("YYYY-MM");
+  }
+  if (timeType.value == "年度") {
+    form.cycleValue = dayjs(new Date(form.cycleValue)).format("YYYY");
+  }
+  if (timeType.value == "日期") {
+    form.cycleValue = dayjs(new Date(form.cycleValue)).format("YYYY-MM-DD");
+  }
   const { code, msg } = await postAddAssessment(form);
   if (code === 200) {
     ElMessage({
@@ -100,6 +108,7 @@ const saveDepartment = async () => {
 };
 const open = (item: any, index: string) => {
   // postListTreeWithUserApi();
+  assessmentTypeShow.value = true;
   Object.assign(form, {
     name: "",
     cycle: "月度",
@@ -142,6 +151,7 @@ const format = ref<any>("YYYY-MM");
 const pickerType = ref<any>("month");
 const handleRegionChange = (value: any) => {
   timeType.value = value;
+  console.log("timeType.value", timeType.value);
   switch (value) {
     case "年度":
       form.cycleValue = "";
@@ -209,7 +219,7 @@ const monthOne = item => {
       end = `${yearTime.value}-12-31`;
       break;
   }
-  form.cycleValue = `${yearTime.value}年${item}`;
+  form.cycleValue = `${yearTime.value}年${item}`;
   // return `从 ${start} 到 ${end}`; // 设置时间区间
 };
 // 部门人员与考核模板数据
@@ -229,14 +239,29 @@ const handChange = index => {
   form.listArr[index].assessmentObjectId = arr.map(item => item.groupCode);
   form.listArr[index].assessmentObjectName = arr.map(item => item.groupName);
 };
+const handChange1 = index => {
+  const arr = treeDeptList.value.filter(item => {
+    return form.listArr[index].idList.includes(item.userCode);
+  });
+  form.listArr[index].assessmentObjectId = arr.map(item => item.userCode);
+  form.listArr[index].assessmentObjectName = arr.map(item => item.realName);
+};
 
 const assessmentTypeRef = ref();
 const handleRreeSelect = index => {
   const arr = assessmentTypeRef.value[index].getCheckedNodes().filter(item => {
     return item.children.length == 0;
   });
-  form.listArr[index].assessmentObjectId = arr.map(item => item.value);
-  form.listArr[index].assessmentObjectName = arr.map(item => item.label);
+  form.listArr[index].assessmentObjectId = arr.map(item => {
+    if (item.value.substring(0, 4) == "user") {
+      return item.value;
+    }
+  });
+  form.listArr[index].assessmentObjectName = arr.map(item => {
+    if (item.value.substring(0, 4) == "user") {
+      return item.label;
+    }
+  });
 };
 const handleSelect = index => {
   form.listArr[index].assessmentModelName = form.listArr[index].am.tpName;
@@ -278,7 +303,9 @@ const convertDepartmentDataRecursive_Person = data => {
   });
 };
 const treeDeptListOkay = ref([]);
+const assessmentTypeShow = ref(true);
 const assessmentTypeApi = async value => {
+  assessmentTypeShow.value = false;
   // 人员,医疗组,负责人
   const { data, code } = await getTemplateInfoList(templateparams);
   resTmp.value = data.records;
@@ -298,8 +325,9 @@ const assessmentTypeApi = async value => {
       treeDeptList.value = yiliao.data.records;
       break;
     case 3:
-      const fuzhere = await getLeaderList();
-      console.log(fuzhere);
+      const fuzhere = await getLeaderList({
+        type: "dept"
+      });
       treeDeptList.value = fuzhere.data;
   }
 };
@@ -457,9 +485,7 @@ const idList = ref([]);
                       @check-change="handleRreeSelect(index)"
                     />
                     <el-select
-                      v-if="
-                        form.assessmentType != 0 && form.assessmentType != 1
-                      "
+                      v-if="form.assessmentType == 2"
                       ref="selectRefs"
                       v-model="item.idList"
                       multiple
@@ -472,6 +498,21 @@ const idList = ref([]);
                         :value="it.groupCode"
                       />
                     </el-select>
+                    <el-select
+                      v-if="form.assessmentType == 3"
+                      ref="selectRefs"
+                      v-model="item.idList"
+                      multiple
+                      @change="handChange1(index)"
+                    >
+                      <el-option
+                        v-for="it in treeDeptList"
+                        :key="it.userCode"
+                        :label="it.realName"
+                        :value="it.userCode"
+                      />
+                    </el-select>
+                    <el-select v-if="assessmentTypeShow" multiple />
                   </div>
                 </el-form-item>
               </el-form>

+ 189 - 23
src/views/evaluate/children/change/mould/manageObject.vue

@@ -158,7 +158,7 @@ const assessmentTypeApi = async value => {
       treeDeptList.value = yiliao.data.records;
       break;
     case 3:
-      const fuzhere = await getLeaderList();
+      const fuzhere = await getLeaderList({ type: "dept" });
       console.log(fuzhere);
       treeDeptList.value = fuzhere.data;
   }
@@ -167,7 +167,7 @@ const assessmentTypeApi = async value => {
 const alterFinishValueApi = async () => {
   const { code, msg } = await alterFinishValue(initParams.indexParams);
   if (code != 200) {
-    ElMessage.error(msg);
+    // ElMessage.error(msg);
   }
 };
 // 指标分页查询
@@ -184,7 +184,7 @@ const getAssessmentQuotaDetailsApi = async () => {
 const getTemplateInfoListApi = async () => {
   const { data, code } = await getTemplateInfoList(initParams.params);
   if (code == 200) {
-    initParams.tmpList = data.records;
+    // initParams.tmpList = data.records;
   }
 };
 // 删除
@@ -266,7 +266,7 @@ const dialogVisibleAdd = ref(false);
 const assessmentTypeRef = ref();
 const transformArrayFormat = data => {
   return data.assessmentObjectId
-    .map((item, index) => {
+    ?.map((item, index) => {
       return {
         assessmentObjectId: item,
         assessmentObjectName: data.assessmentObjectName[index]
@@ -275,24 +275,94 @@ const transformArrayFormat = data => {
     .flat();
 };
 // 人员 ---- 部门
+function flattenTree(data) {
+  let result = [];
+  for (const item of data) {
+    // 添加当前节点到结果数组
+    result.push({ value: item.value, label: item.label });
+    // 如果有子节点,递归处理子节点
+    if (item.children && item.children.length > 0) {
+      result = result.concat(flattenTree(item.children));
+    }
+  }
+  return result;
+}
+const handleNodeRreeSelect = data => {
+  let dataList;
+  console.log("data", data);
+  if ($props.message.assessmentType == 1) {
+    if (Array.isArray([data])) {
+      dataList = flattenTree([data]);
+      dataList.map(item => {
+        addPersonParams?.objectAddVoList?.push({
+          assessmentObjectId: item.value,
+          assessmentObjectName: item.label
+        });
+      });
+    }
+  }
+};
 const handleRreeSelect = data => {
   const list = ref({});
+  let dataList;
+  // console.log("data", data);
+  if ($props.message.assessmentType == 0) {
+    if (Array.isArray(data)) {
+      dataList = flattenTree(data);
+      dataList.map(item => {
+        if (item.value.substring(0, 4) == "user") {
+          addPersonParams.objectAddVoList.push({
+            assessmentObjectId: item.value,
+            assessmentObjectName: item.label
+          });
+        }
+      });
+    } else {
+      addPersonParams?.objectAddVoList?.push({
+        assessmentObjectId: data.value,
+        assessmentObjectName: data.label
+      });
+    }
+  }
   const arr = assessmentTypeRef.value.getCheckedNodes().filter(item => {
     return item.children.length == 0;
   });
   list.value.assessmentObjectId = arr.map(item => item.value);
   list.value.assessmentObjectName = arr.map(item => item.label);
-  addPersonParams.objectAddVoList = transformArrayFormat(list);
+  // addPersonParams.objectAddVoList = transformArrayFormat(list);
 };
 // 医疗 --- 医疗主任
-const handChange = () => {
+const handChange = data => {
+  console.log("data", data);
+  let gropList = [];
+  treeDeptList.value.map(it => {
+    data.map(id => {
+      if ($props.message.assessmentType == 2) {
+        if (it.groupCode == id) {
+          gropList.push({
+            assessmentObjectId: it.groupCode,
+            assessmentObjectName: it.groupName
+          });
+        }
+      }
+      if ($props.message.assessmentType == 3) {
+        if (it.userCode == id) {
+          gropList.push({
+            assessmentObjectId: it.userCode,
+            assessmentObjectName: it.realName
+          });
+        }
+      }
+      addPersonParams.objectAddVoList = gropList;
+    });
+  });
   const list = ref({});
   const arr = treeDeptList.value.filter(item => {
     return value1.value.includes(item.groupCode);
   });
   list.value.assessmentObjectId = arr.map(item => item.groupCode);
   list.value.assessmentObjectName = arr.map(item => item.groupName);
-  addPersonParams.objectAddVoList = transformArrayFormat(list);
+  // addPersonParams.objectAddVoList = transformArrayFormat(list);
 };
 
 const dialogVisibleAddShow = () => {
@@ -331,6 +401,19 @@ const getAssessmentObjectDetailsApi = async () => {
   const { data, msg, code } = await getAssessmentObjectDetails(
     initParams.objParams
   );
+  const res = await getAssessmentObjectDetails({
+    pageNumber: 1,
+    pageSize: 1000,
+    assessmentId: initParams.objParams.assessmentId
+  });
+  if (res.code == 200) {
+    // initParams.tmpList = res.data.records;
+    initParams.tmpList = Array.from(
+      new Map(
+        res.data.records.map(item => [item.assessmentModelId, item])
+      ).values()
+    );
+  }
   if (code === 200) {
     objList.value = data.records;
     initParams.total = data.totalRow;
@@ -384,11 +467,15 @@ const editClosedEvent = ({ row, column }) => {
   if ($table) {
     const updateRecords = $table.getUpdateRecords();
     if (updateRecords.length > 0) {
-      if (
-        updateRecords[-1]?.score != row?.score ||
-        updateRecords[-1]?.finalValue != row?.finalValue
-      ) {
-        updateAssessmentQuotaDetailsApi(row);
+      if (updateRecords[-1]?.score != row?.score) {
+        if (row?.score) {
+          updateAssessmentQuotaDetailsApi(row);
+        }
+      }
+      if (updateRecords[-1]?.finalValue != row?.finalValue) {
+        if (row?.finalValue) {
+          updateAssessmentQuotaDetailsApi(row);
+        }
       }
     }
   }
@@ -406,6 +493,15 @@ const closePerson = () => {
 // 添加被考核人
 const addPerson = async () => {
   addPersonParams.assessmentId = $props.message.id;
+  let arr = [];
+  if ($props.message.assessmentType == 0) {
+    addPersonParams.objectAddVoList.map(it => {
+      if (it.assessmentObjectId.substring(0, 4) == "user") {
+        arr.push(it);
+      }
+      addPersonParams.objectAddVoList = arr;
+    });
+  }
   const { data, msg, code } = await postAddAssessmentObject(addPersonParams);
   if (code === 200) {
     ElMessage.success("添加成功");
@@ -473,15 +569,15 @@ const changTitle = () => {
               <el-option
                 v-for="itemTmp in initParams.tmpList"
                 :key="itemTmp.id"
-                :label="itemTmp.tpName"
-                :value="itemTmp.tpName"
+                :label="itemTmp.assessmentModelName"
+                :value="itemTmp.assessmentModelName"
               />
             </el-select>
             <el-input
               v-model="initParams.objParams.userName"
               class="ml-2"
               clearable
-              placeholder="搜索人员"
+              placeholder="搜索"
               :prefix-icon="Search"
               @change="getAssessmentObjectDetailsApi"
             />
@@ -604,9 +700,62 @@ const changTitle = () => {
           @selection-change="changeSelection"
         >
           <vxe-column type="checkbox" width="60" />
-          <vxe-column field="realName" fixed title="人员" width="100" />
-          <vxe-column field="userName" fixed title="工号" width="180" />
-          <vxe-column field="deptName" fixed title="部门" width="180" />
+          <vxe-column
+            v-if="state.tableType == 0 || state.tableType == 3"
+            field="realName"
+            fixed
+            title="人员"
+            width="100"
+          />
+          <!-- :员工,1:部门,2:医疗组,3:部门负责人 -->
+          <vxe-column
+            v-if="state.tableType == 0 || state.tableType == 3"
+            field="userName"
+            fixed
+            title="工号"
+            width="180"
+          />
+          <vxe-column
+            v-if="state.tableType == 0 || state.tableType == 3"
+            field="deptName"
+            fixed
+            title="部门"
+            width="180"
+          />
+          <vxe-column
+            v-if="state.tableType == 2"
+            field="userGroupName"
+            fixed
+            title="医疗组"
+            width="180"
+          />
+          <vxe-column
+            v-if="state.tableType == 2"
+            field="userGroupCode"
+            fixed
+            title="医疗组编号"
+            width="180"
+          />
+          <vxe-column
+            v-if="state.tableType == 1"
+            field="deptName"
+            fixed
+            title="部门"
+            width="180"
+          />
+          <vxe-column
+            v-if="state.tableType == 1"
+            field="deptCode"
+            fixed
+            title="部门编号"
+            width="200"
+          />
+          <vxe-column
+            field="assessmentModelName"
+            fixed
+            title="考核模板"
+            width="180"
+          />
           <vxe-column field="name" fixed title="指标名称" width="180" />
           <vxe-column field="scoreRule" fixed title="评价标准" width="180" />
           <vxe-column field="source" fixed title="数据来源" width="180" />
@@ -682,7 +831,12 @@ const changTitle = () => {
       </el-tab-pane>
     </el-tabs>
     <!-- 添加被考核人 -->
-    <el-dialog v-model="dialogVisibleAdd" :title="changTitle()" width="500">
+    <el-dialog
+      v-model="dialogVisibleAdd"
+      :title="changTitle()"
+      width="500"
+      :before-close="closePerson"
+    >
       <div>
         <el-form
           ref="ruleFormRef"
@@ -712,12 +866,10 @@ const changTitle = () => {
               show-checkbox
               style="width: 240px"
               @check-change="handleRreeSelect"
+              @check="handleNodeRreeSelect"
             />
             <el-select
-              v-if="
-                $props.message.assessmentType != 0 &&
-                $props.message.assessmentType != 1
-              "
+              v-if="$props.message.assessmentType == 2"
               ref="selectRefs"
               v-model="value1"
               multiple
@@ -730,6 +882,20 @@ const changTitle = () => {
                 :value="it.groupCode"
               />
             </el-select>
+            <el-select
+              v-if="$props.message.assessmentType == 3"
+              ref="selectRefs"
+              v-model="value1"
+              multiple
+              @change="handChange"
+            >
+              <el-option
+                v-for="(it, id) in treeDeptList"
+                :key="id"
+                :label="it.realName"
+                :value="it.userCode"
+              />
+            </el-select>
           </el-form-item>
         </el-form>
       </div>

+ 111 - 57
src/views/evaluate/children/change/mould/message.vue

@@ -212,7 +212,6 @@ const getPersonList = async () => {
     };
   });
   treeDept_person.value = transformData_person(treeList);
-  console.log(treeDept_person.value, "人员获取的值");
 };
 
 postListTreeWithUserApi();
@@ -235,11 +234,61 @@ function transformData(arr) {
 }
 // 详情
 const treeDeptList = ref([]);
+const optionValue = ref([]);
+// 考核对象
+const assessmentObjectList = ref([]);
+// 考核模板
+const assessmentModelList = ref([]);
+
 const getAssessmentDetailsApi = async () => {
   const { data, code, msg } = await getAssessmentDetails({ id: params.id });
   if (code === 200) {
     Object.assign(form, data);
-    console.log(form, "获取的值");
+    console.log(123123, form.assessmentObjectList);
+    // 用于存放分组后的数组
+    let groupedData = [];
+    // 用于存储每个 `assessmentModelId` 的组
+    let modelIdMap = {};
+    // 遍历数据,将数据按 `assessmentModelId` 分组
+    form.assessmentObjectList.forEach(item => {
+      const modelId = item.assessmentModelId;
+      // 如果该 modelId 已存在,则将数据加入对应的组
+      if (!modelIdMap[modelId]) {
+        modelIdMap[modelId] = [];
+      }
+      modelIdMap[modelId].push(item);
+    });
+    // 将分组后的数据转为二维数组
+    for (let modelId in modelIdMap) {
+      groupedData.push(modelIdMap[modelId]);
+    }
+    // 打印结果
+    console.log(groupedData);
+    assessmentObjectList.value = groupedData;
+    form.assessmentObjectList.map(item => {
+      // assessmentObjectList.value.push({
+      //   assessmentObjectId: item.assessmentObjectId,
+      //   assessmentObjectName: item.assessmentObjectName
+      // });
+      assessmentModelList.value.push({
+        assessmentModelId: item.assessmentModelId,
+        assessmentModelName: item.assessmentModelName
+      });
+    });
+    // assessmentObjectList.value = Array.from(
+    //   new Map(
+    //     assessmentObjectList.value.map(item => [item.assessmentObjectId, item])
+    //   ).values()
+    // );
+    assessmentModelList.value = Array.from(
+      new Map(
+        assessmentModelList.value.map(item => [item.assessmentModelId, item])
+      ).values()
+    );
+    form.assessmentObjectList.map(item => {
+      optionValue.value.push(item.assessmentObjectId);
+    });
+
     if (form.assessmentType === 1) {
       postListTreeWithUserApi();
     } else if (form.assessmentType === 0) {
@@ -250,7 +299,6 @@ const getAssessmentDetailsApi = async () => {
         pageSize: 1000
       });
       treeDeptList.value = yiliao.data.records;
-      console.log("获取的医疗组的值", treeDeptList.value);
     }
   } else {
     ElMessage.error(msg);
@@ -394,54 +442,33 @@ onMounted(() => {
               :rules="formLeftRules"
             >
               <el-form-item label="被考核对象" prop="left">
-                <div
-                  v-for="(item, index) in form.assessmentObjectList"
-                  :key="index"
-                  class="w-full mt-1"
-                >
-                  <el-tree-select
-                    v-if="form.assessmentType === 1"
-                    v-model="item.assessmentObjectId"
-                    :data="treeDept"
-                    :render-after-expand="false"
-                    show-checkbox
-                    disabled
-                    :props="{
-                      label: 'userName',
-                      value: 'userCode',
-                      children: 'childrenRes'
-                    }"
-                    style="width: 180px"
-                  />
-                  <!-- 员工多个 -->
-                  <el-tree-select
-                    v-if="form.assessmentType === 0"
-                    v-model="item.assessmentObjectId"
-                    :data="treeDept_person"
-                    :render-after-expand="false"
-                    show-checkbox
-                    disabled
-                    style="width: 180px"
-                    :props="{
-                      label: 'userNameNew',
-                      value: 'userCodeNew',
-                      children: 'children'
-                    }"
-                  />
-
-                  <!-- 医疗组,负责人 -->
-                  <el-select
-                    v-if="form.assessmentType != 0 && form.assessmentType != 1"
-                    v-model="item.assessmentObjectId"
+                <div class="w-full mt-1 flex flex-wrap">
+                  <!-- 人员,负责人 -->
+                  <!-- <el-select
+                    v-if="form.assessmentType == 0 || form.assessmentType == 3"
+                    v-model="optionValue"
+                    multiple
                     disabled
                   >
                     <el-option
-                      v-for="(it, id) in treeDeptList"
+                      v-for="(it, id) in form.assessmentObjectList"
                       :key="id"
-                      :label="it.groupName"
-                      :value="it.groupCode"
+                      :label="it.assessmentObjectName"
+                      :value="it.assessmentObjectId"
                     />
-                  </el-select>
+                  </el-select> -->
+                  {{
+                    console.log("assessmentObjectList", assessmentObjectList)
+                  }}
+                  <div
+                    v-for="(item, index) in assessmentObjectList"
+                    :key="index"
+                    class="text-gray-400 w-full flex flex-wrap object mt-1"
+                  >
+                    <div v-for="(it, id) in item" :key="id" class="h-6">
+                      {{ it.assessmentObjectName }},
+                    </div>
+                  </div>
                 </div>
               </el-form-item>
             </el-form>
@@ -453,12 +480,8 @@ onMounted(() => {
               :rules="formRightRules"
             >
               <el-form-item label="考核模板" prop="right">
-                <div
-                  v-for="(item, index) in form.assessmentObjectList"
-                  :key="index"
-                  class="w-full flex mt-1"
-                >
-                  <el-select
+                <div class="w-full flex flex-wrap mt-1 aaa">
+                  <!-- <el-select
                     v-model="item.assessmentModelId"
                     disabled
                     placeholder="请选择"
@@ -466,12 +489,19 @@ onMounted(() => {
                     style="width: 180px"
                   >
                     <el-option
-                      v-for="itemTmp in resTmp"
-                      :key="itemTmp.id"
-                      :label="itemTmp.tpName"
-                      :value="itemTmp.id"
+                      v-for="itemTmp in form.assessmentObjectList"
+                      :key="itemTmp.assessmentModelId"
+                      :label="itemTmp.assessmentModelName"
+                      :value="itemTmp.assessmentModelId"
                     />
-                  </el-select>
+                  </el-select> -->
+                  <div
+                    v-for="(item, index) in assessmentModelList"
+                    :key="index"
+                    class="text-gray-400"
+                  >
+                    <div class="mt-2">{{ item.assessmentModelName }}</div>
+                  </div>
                 </div>
               </el-form-item>
             </el-form>
@@ -492,3 +522,27 @@ onMounted(() => {
     </div>
   </div>
 </template>
+
+<style scoped>
+.aaa {
+  font-size: 12px;
+
+  div {
+    overflow: hidden; /* 隐藏超出的部分 */
+    text-overflow: ellipsis; /* 显示省略号 */
+    white-space: nowrap; /* 防止文本换行 */
+    div {
+      font-weight: 500;
+      border: 1px solid gray;
+      border-radius: 5px;
+    }
+  }
+}
+
+.object {
+  font-size: 12px;
+  font-weight: 500;
+  border: 1px solid gray;
+  border-radius: 5px;
+}
+</style>

+ 1 - 1
src/views/indexDefine/children/components/dialog.vue

@@ -153,7 +153,7 @@ const handleClose = (done: () => void) => {
           />
         </el-form-item>
         <el-form-item label="来源">
-          <el-select v-model="form.source" placeholder="请选择">
+          <el-select v-model="form.source" placeholder="请选择" clearable>
             <el-option
               v-for="item in sourceDataList"
               :key="item.id"

+ 1 - 0
src/views/indexDefine/children/components/editDrawer.vue

@@ -159,6 +159,7 @@ defineExpose({
               <el-select
                 v-model="formLabelAlign.source"
                 :disabled="disabledShow"
+                clearable
                 placeholder="请选择来源"
               >
                 <el-option