Ver código fonte

feat: 专题画像

ystl_myq 8 meses atrás
pai
commit
6d622004b4

BIN
src/assets/rank/qvanping.png


BIN
src/assets/rank/qvanping@2x.png


BIN
src/assets/rank/rank1.png


BIN
src/assets/rank/rank1@2x.png


BIN
src/assets/rank/rank2.png


BIN
src/assets/rank/rank2@2x.png


BIN
src/assets/rank/rank3.png


BIN
src/assets/rank/rank3@2x.png


+ 143 - 0
src/components/echarts/bar.vue

@@ -0,0 +1,143 @@
+<script setup lang="ts">
+import { ref, computed, onMounted, watch } from "vue";
+import { useDark, useECharts } from "@pureadmin/utils";
+import { reactive } from "vue";
+const props = defineProps({
+  title: {
+    type: Object
+  }
+});
+const dataProp = reactive({
+  title: "",
+  data: {}
+});
+onMounted(() => {});
+// 兼容dark主题
+const { isDark } = useDark();
+let theme = computed(() => {
+  return isDark.value ? "dark" : "default";
+});
+// 初始化ECharts
+const chartRef = ref();
+const { setOptions } = useECharts(chartRef, { theme });
+
+// 根据配置项渲染ECharts
+// setOptions({
+//   title: {
+//     text: `${dataProp.data.title}Top10`
+//   },
+//   tooltip: {
+//     trigger: "axis",
+//     axisPointer: {
+//       type: "shadow"
+//     }
+//   },
+//   grid: {
+//     left: "3%",
+//     right: "4%",
+//     bottom: "3%",
+//     containLabel: true
+//   },
+//   xAxis: [
+//     {
+//       type: "category",
+//       data: [
+//         "张医生",
+//         "王医生",
+//         "李医生",
+//         "吴医生",
+//         "哈哈哈",
+//         "吼吼吼",
+//         "吴医生",
+//         "哈哈哈",
+//         "吼吼吼",
+//         "啊啊啊"
+//       ],
+//       axisTick: {
+//         alignWithLabel: true
+//       }
+//     }
+//   ],
+//   yAxis: [
+//     {
+//       type: "value"
+//     }
+//   ],
+//   series: [
+//     {
+//       name: "Direct",
+//       type: "bar",
+//       barWidth: "30%",
+//       data: [10, 52, 200, 334, 390, 330, 220, 52, 390, 330]
+//     }
+//   ]
+// });
+watch(
+  () => props.title,
+  newTitle => {
+    dataProp.title = newTitle.title;
+    setOptions({
+      title: {
+        text: `${dataProp.title}Top10`
+      },
+      tooltip: {
+        trigger: "axis",
+        axisPointer: {
+          type: "shadow"
+        }
+      },
+      grid: {
+        left: "3%",
+        right: "4%",
+        bottom: "3%",
+        containLabel: true
+      },
+      xAxis: [
+        {
+          type: "category",
+          data: [
+            "张医生",
+            "王医生",
+            "李医生",
+            "吴医生",
+            "哈哈哈",
+            "吼吼吼",
+            "吴医生",
+            "哈哈哈",
+            "吼吼吼",
+            "啊啊啊"
+          ],
+          axisTick: {
+            alignWithLabel: true
+          }
+        }
+      ],
+      yAxis: [
+        {
+          type: "value"
+        }
+      ],
+      series: [
+        {
+          name: "Direct",
+          type: "bar",
+          // barWidth: "30%",
+          barWidth: dataProp.title == "总得分" ? "30%" : "40%",
+          data: [10, 52, 200, 334, 390, 330, 220, 52, 390, 330]
+        }
+      ]
+    });
+  },
+  { immediate: true }
+);
+const dataList = item => {
+  console.log("item", item);
+};
+defineExpose({
+  dataList
+});
+</script>
+
+<template>
+  <div ref="chartRef" class="w-full h-full" />
+</template>

+ 68 - 0
src/components/echarts/big/fullBig.vue

@@ -0,0 +1,68 @@
+<script setup lang="ts">
+defineOptions({
+  name: "full-big"
+});
+import { ref, reactive } from "vue";
+import { useRouter } from "vue-router";
+import barEcharts from "@/components/echarts/bar.vue";
+import rankTable from "@/components/rankTable/index.vue";
+import personList from "@/components/personList/index.vue";
+import qvanping from "@/assets/rank/qvanping@2x.png";
+const router = useRouter();
+// 柱状图
+const barEchartsRef = ref();
+// 维度表格
+const personListRef = ref();
+const barEchartsList = reactive({
+  zongfen: {
+    title: "总得分"
+  },
+  shuliang: {
+    title: "数量维度"
+  },
+  xiaolve: {
+    title: "效率维度"
+  },
+  zhiliang: {
+    title: "质量维度"
+  },
+  nandu: {
+    title: "难度维度"
+  },
+  qiandu: {
+    title: "强度维度"
+  },
+  jiaoxue: {
+    title: "教学维度"
+  },
+  keyan: {
+    title: "科研维度"
+  }
+});
+const fullSmall = () => {
+  router.back();
+};
+const dataList = item => {
+  console.log(item);
+};
+defineExpose({
+  dataList
+});
+</script>
+
+<template>
+  <div class="w-full">
+    <div class="flex justify-between">
+      <personList ref="personListRef" class="w-11/12" />
+      <div class="w-[30px] h-[30px] mr-10 cursor-pointer" @click="fullSmall">
+        <img class="w-full h-full" :src="qvanping" alt="" />
+      </div>
+    </div>
+    <barEcharts
+      ref="barEchartsRef"
+      class="w-[1260px] h-[380px] mt-5"
+      :title="barEchartsList.shuliang"
+    />
+    <!-- :title="barEchartsList.shuliang" -->
+  </div>
+</template>

+ 27 - 12
src/components/echarts/radar.vue

@@ -18,26 +18,41 @@ setOptions({
   legend: {
     top: 10,
     left: "left",
-    data: ["支出"]
+    data: ["得分率"]
   },
   radar: {
-    // shape: 'circle',
-    radius: "60%",
+    radius: "70%", // 调整半径以使雷达图更大
     indicator: [
-      { name: "周一" },
-      { name: "周二" },
-      { name: "周三" },
-      { name: "周四" },
-      { name: "周五" }
-    ]
+      { name: "数量" },
+      { name: "科研" },
+      { name: "教学" },
+      { name: "强度" },
+      { name: "难度" },
+      { name: "质量" },
+      { name: "效率" }
+    ],
+    axisName: {
+      color: "black"
+    }
   },
   series: [
     {
-      name: "Budget vs spending",
+      name: "得分率",
       type: "radar",
+      areaStyle: {
+        normal: {
+          color: "rgba(0, 128, 255, 0.2)" // 设置内部填充颜色和透明度
+        }
+      },
+      lineStyle: {
+        normal: {
+          width: 1, // 设置线条宽度为 1
+          color: "rgba(0, 128, 255, 1)" // 设置线条颜色
+        }
+      },
       data: [
         {
-          value: [30, 60, 90, 120, 150],
+          value: [30, 60, 90, 120, 150, 160, 10],
           name: "支出"
         }
       ]
@@ -47,5 +62,5 @@ setOptions({
 </script>
 
 <template>
-  <div ref="chartRef" style="width: 100%; height: 35vh" />
+  <div ref="chartRef" class="w-72 h-64 m-auto mt-2" />
 </template>

+ 33 - 0
src/components/personList/index.vue

@@ -0,0 +1,33 @@
+<template>
+  <div class="mr-8">
+    <el-table :data="tableData" style="width: 100%">
+      <el-table-column prop="title" width="100">
+        <template #default="scope">
+          <div class="text-black">{{ scope.row.title }}</div>
+        </template>
+      </el-table-column>
+      <el-table-column prop="date" label="完成值" />
+      <el-table-column prop="name" label="门槛值" />
+      <el-table-column prop="address" label="挑战值" />
+      <el-table-column prop="address" label="排名" />
+      <el-table-column prop="address" label="得分" />
+    </el-table>
+  </div>
+</template>
+
+<script lang="ts" setup>
+const tableData = [
+  {
+    title: "出院人次",
+    date: "2016-05-03",
+    name: "Tom",
+    address: "No. 189, Grove St, Los Angeles"
+  },
+  {
+    title: "手术人次",
+    date: "2016-05-02",
+    name: "Tom",
+    address: "No. 189, Grove St, Los Angeles"
+  }
+];
+</script>

+ 127 - 0
src/components/rankTable/index.vue

@@ -0,0 +1,127 @@
+<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.$index + 1 }}
+        </div>
+        <div class="text-center">
+          <img :src="RANK_IMG[scope.$index]" alt="" />
+        </div>
+      </template>
+    </el-table-column>
+    <el-table-column prop="date" label="科室" fixed width="150" />
+    <el-table-column prop="date" label="姓名" width="100" />
+    <el-table-column label="数量(5%)">
+      <el-table-column prop="state" label="出院人次(5%)" width="140" sortable />
+      <el-table-column prop="city" label="手术人次(15%)" width="140" />
+    </el-table-column>
+    <el-table-column
+      prop="date"
+      label="总分"
+      width="100"
+      sortable
+      :header-cell-style="{ backgroundColor: '#CCEEE2' }"
+    />
+    <el-table-column label="效率(5%)">
+      <el-table-column prop="state" label="平均住院日(5%)" width="150" />
+      <el-table-column prop="city" label="药品耗材比(5%)" width="150" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column label="质量(5%)">
+      <el-table-column prop="state" label="手术并发症发生率" width="150" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column label="难度(5%)">
+      <el-table-column prop="state" label="微创手术人次(5%)" width="150" />
+      <el-table-column prop="state" label="CMT值(5%)" width="100" />
+      <el-table-column prop="state" label="RW>2占比(5%)" width="130" />
+      <el-table-column prop="state" label="主刀四类手术(5%)" width="150" />
+      <el-table-column prop="state" label="主刀微创手术(5%)" width="150" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column label="强度(5%)">
+      <el-table-column prop="state" label="夜班数(10%)" width="150" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column label="教学(5%)">
+      <el-table-column
+        prop="state"
+        label="手术一助指导下医生(5%)"
+        width="200"
+      />
+      <el-table-column prop="date" label="教学积分(5%)" width="100" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column label="科研(5%)">
+      <el-table-column prop="state" label="科研积分(10%)" width="150" />
+    </el-table-column>
+    <el-table-column prop="date" label="总分" width="100" />
+    <el-table-column prop="date" label="总得分" width="100" />
+  </el-table>
+</template>
+
+<script lang="ts" setup>
+import rank1 from "@/assets/rank/rank1.png";
+import rank2 from "@/assets/rank/rank2.png";
+import rank3 from "@/assets/rank/rank3.png";
+const RANK_IMG = [rank1, rank2, rank3];
+const tableData = [
+  {
+    date: "2016-05-03",
+    name: "Tom",
+    state: "California",
+    city: "Los Angeles",
+    address: "No. 189, Grove St, Los Angeles",
+    zip: "CA 90036"
+  },
+  {
+    date: "2016-05-02",
+    name: "Tom",
+    state: "California",
+    city: "Los Angeles",
+    address: "No. 189, Grove St, Los Angeles",
+    zip: "CA 90036"
+  },
+  {
+    date: "2016-05-04",
+    name: "Tom",
+    state: "California",
+    city: "Los Angeles",
+    address: "No. 189, Grove St, Los Angeles",
+    zip: "CA 90036"
+  },
+  {
+    date: "2016-05-01",
+    name: "Tom",
+    state: "California",
+    city: "Los Angeles",
+    address: "No. 189, Grove St, Los Angeles",
+    zip: "CA 90036"
+  }
+];
+</script>
+
+<style lang="scss" scoped>
+.diamond {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 25px; /* 菱形宽度 */
+  height: 25px; /* 菱形高度 */
+  padding-top: 1px;
+  margin: auto;
+  clip-path: polygon(
+    50% 0%,
+    100% 25%,
+    100% 75%,
+    50% 100%,
+    0% 75%,
+    0% 25%
+  ); /* 定义六边形的形状 */
+
+  font-size: 12px;
+  color: white;
+  background-color: #d3e8f0; /* 背景颜色 */
+}
+</style>

+ 16 - 8
src/router/modules/draw.ts

@@ -23,7 +23,8 @@ export default {
             import("@/views/draw/children/worker/workerDrak.vue"),
           meta: {
             title: "员工画像",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -33,7 +34,8 @@ export default {
             import("@/views/draw/children/worker/workerRank.vue"),
           meta: {
             title: "员工排行榜",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -43,7 +45,8 @@ export default {
             import("@/views/draw/children/department/departmentDrank.vue"),
           meta: {
             title: "科室画像",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -53,7 +56,8 @@ export default {
             import("@/views/draw/children/department/departmentRank.vue"),
           meta: {
             title: "科室排行榜",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -62,7 +66,8 @@ export default {
           component: () => import("@/views/draw/children/head/headDrank.vue"),
           meta: {
             title: "科室主任画像",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -71,7 +76,8 @@ export default {
           component: () => import("@/views/draw/children/head/headRank.vue"),
           meta: {
             title: "科室主任排行榜",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -81,7 +87,8 @@ export default {
             import("@/views/draw/children/health/healthDrank.vue"),
           meta: {
             title: "医疗组画像",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         },
         {
@@ -91,7 +98,8 @@ export default {
             import("@/views/draw/children/health/healthRank.vue"),
           meta: {
             title: "医疗组排行榜",
-            showParent: true
+            showParent: true,
+            keepAlive: true
           }
         }
       ]

+ 11 - 0
src/router/modules/other.ts

@@ -0,0 +1,11 @@
+// 最简代码,也就是这些字段必须有
+export default {
+  path: "/fullBig/:title",
+  name: "full-big",
+  meta: {
+    title: "维度画像",
+    icon: "ri:list-check",
+    showLink: false
+  },
+  component: () => import("@/components/echarts/big/fullBig.vue")
+} satisfies RouteConfigsTable;

+ 220 - 1
src/views/draw/children/worker/workerDrak.vue

@@ -2,9 +2,47 @@
 defineOptions({
   name: "workerDrak"
 });
-import { ref } from "vue";
+import { ref, reactive } from "vue";
+import { useRouter } from "vue-router";
 import radar from "@/components/echarts/radar.vue";
+import barEcharts from "@/components/echarts/bar.vue";
+import rankTable from "@/components/rankTable/index.vue";
+import personList from "@/components/personList/index.vue";
+import qvanping from "@/assets/rank/qvanping@2x.png";
+import type { TabsPaneContext } from "element-plus";
+const router = useRouter();
 const value = ref("");
+const activeName = ref("1");
+// 柱状图
+const barEchartsRef = ref();
+// 维度表格
+const personListRef = ref();
+const barEchartsList = reactive({
+  zongfen: {
+    title: "总得分"
+  },
+  shuliang: {
+    title: "数量维度"
+  },
+  xiaolve: {
+    title: "效率维度"
+  },
+  zhiliang: {
+    title: "质量维度"
+  },
+  nandu: {
+    title: "难度维度"
+  },
+  qiandu: {
+    title: "强度维度"
+  },
+  jiaoxue: {
+    title: "教学维度"
+  },
+  keyan: {
+    title: "科研维度"
+  }
+});
 const options = [
   {
     value: "Option1",
@@ -27,6 +65,14 @@ const options = [
     label: "Option5"
   }
 ];
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  // console.log(tab, event);
+  barEchartsRef.value.dataList(tab.props);
+};
+const fullBig = (item: any) => {
+  console.log(item);
+  router.push({ name: "full-big", params: { ...item } });
+};
 </script>
 
 <template>
@@ -103,6 +149,179 @@ const options = [
       <div class="flex mr-2">
         <radar />
       </div>
+      <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
+        <el-tab-pane label="总览" name="1">
+          <div class="flex mr-8">
+            <rankTable />
+          </div>
+          <!-- 总得分 -->
+          <div class="mt-5 pr-8 w-full h-60">
+            <barEcharts ref="barEchartsRef" :title="barEchartsList.zongfen" />
+          </div>
+          <!-- 维度得分 -->
+          <div class="mt-5 pr-8 w-full h-60 flex justify-between item-center">
+            <div class="w-1/2 h-full">
+              <barEcharts :title="barEchartsList.shuliang" />
+            </div>
+            <div class="w-1/2 h-full">
+              <barEcharts :title="barEchartsList.xiaolve" />
+            </div>
+          </div>
+          <div class="mt-5 pr-8 w-full h-60 flex justify-between item-center">
+            <div class="w-1/2 h-full">
+              <barEcharts
+                ref="barEchartsRef"
+                :title="barEchartsList.zhiliang"
+              />
+            </div>
+            <div class="w-1/2 h-full">
+              <barEcharts ref="barEchartsRef" :title="barEchartsList.nandu" />
+            </div>
+          </div>
+          <div class="mt-5 pr-8 w-full h-60 flex justify-between item-center">
+            <div class="w-1/2 h-full">
+              <barEcharts ref="barEchartsRef" :title="barEchartsList.qiandu" />
+            </div>
+            <div class="w-1/2 h-full">
+              <barEcharts ref="barEchartsRef" :title="barEchartsList.jiaoxue" />
+            </div>
+          </div>
+          <div class="mt-5 pr-8 w-full h-60 flex justify-between item-center">
+            <div class="w-1/2 h-full">
+              <barEcharts ref="barEchartsRef" :title="barEchartsList.keyan" />
+            </div>
+            <div class="w-1/2 h-full">
+              <!-- <barEcharts :title="barEchartsList.kexue" /> -->
+            </div>
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="数量" name="2">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.shuliang)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.shuliang"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="效率" name="3">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.xiaolve)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.xiaolve"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="质量" name="4">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.zhiliang)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.zhiliang"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="难度" name="5">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.nandu)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.nandu"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="强度" name="6">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.qiandu)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.qiandu"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="教学" name="7">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.jiaoxue)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.jiaoxue"
+            />
+          </div>
+        </el-tab-pane>
+        <el-tab-pane label="科研" name="8">
+          <div class="w-full">
+            <div class="flex justify-between">
+              <personList ref="personListRef" class="w-11/12" />
+              <div
+                class="w-[30px] h-[30px] mr-10 cursor-pointer"
+                @click="fullBig(barEchartsList.keyan)"
+              >
+                <img class="w-full h-full" :src="qvanping" alt="" />
+              </div>
+            </div>
+            <barEcharts
+              ref="barEchartsRef"
+              class="w-[1260px] h-[260px] mt-5"
+              :title="barEchartsList.keyan"
+            />
+          </div>
+        </el-tab-pane>
+      </el-tabs>
     </div>
   </div>
 </template>