瀏覽代碼

增加九防图表

chenjun 2 周之前
父節點
當前提交
ccd6bb0762

+ 29 - 0
.workbuddy/memory/2026-08-04.md

@@ -0,0 +1,29 @@
+# 2026-08-04
+
+## nine-safety-measures/index.vue — 卡片底部留白 / 饼图标签截断
+
+**最终方案:`.grid-auto` 加 `align-items: start`,让卡片按内容高度对齐,不再被同行高卡片拉伸。**
+
+走过的弯路(记下来避免再犯):
+1. 第一次把"九防高危占比"底部留白归因到 ECharts `grid.bottom: 55` 太大——错。
+2. 改成 `bottom: 0` 后没效果,才意识到留白在 ECharts 画布**外**(卡片被 Grid `align-items: stretch` 强行拉高,而 `.chart` 写死 320px)。
+3. 第二次改成 `.card { display:flex; flex-direction:column }` + `.chart { flex:1 0 320px }`,让图表撑满卡片——这解决了柱状图,但又引出饼图标签被裁成 "…" 的新问题。
+4. 根因:ECharts 饼图 `radius: '70%'` 是按**容器短边**算的。图表被拉高后短边变成卡片宽度,饼图直径超出卡片,左侧引导线/标签被裁断。
+5. **正确做法**:别让图表撑满。给 `.grid-auto` 加 `align-items: start`,卡片高度=内容高度,既无内部留白,饼图也回到合理尺寸。
+
+副带改动(清理):`renderAssessCompletion` 的 `grid.bottom` 从 55 → 30,配合 `axisLabel.margin: 10`,给旋转 35° 的 X 轴标签留呼吸空间。
+
+**教训**:dashboard 类页面遇到"卡片底部空白",先检查外层 Grid/容器是否在拉伸子元素,别急着改图表内部的 ECharts 配置。
+
+## 移除「半年度评估频次日历」图表(约 10:50)
+
+用户要求删除该日历热力图及其相关方法/数据。已清理的内容:
+- `index.vue`:`CalendarComponent` 的 import 与 `echarts.use()` 注册;`calendarData` ref;`renderCalendar()` 函数及其在 `renderAllCharts` 的调用;`loadAllData` 中 `getMonthlyAssessCalendar` 请求、解构变量 `cal`、`calendarData.value = cal` 赋值;模板中 `半年度评估频次日历` 卡片(含 `span-full`);CSS `.chart-calendar` 与 `.grid-auto .span-full`(`span-full` 仅此卡片使用)。
+- `src/api/data-board/nine-safety.ts`:删除 `getMonthlyAssessCalendar` 函数(已无其它引用)。
+
+注意:`.grid-auto` 此前为 `align-items: start`(上一轮结论),移除全宽卡片后不影响布局。
+
+补充(约 11:15):vue-tsc 类型检查报两处 TS6133 死代码,已清理——
+- `index.vue` 中未使用的 `levelNames` 常量(疑似日历遗留);
+- `nine-safety.ts` 的 `getNineRiskCorrelation` 中未使用的 `elders` 局部变量(`generateElders` 在 `getRiskRadar` 仍使用,不受影响)。
+重新检查 nine-safety 相关文件:NO_NINE_SAFETY_ERRORS,删除干净无编译错误。

+ 0 - 17
src/api/data-board/nine-safety.ts

@@ -346,7 +346,6 @@ export const getRiskByNurseLevel = (params?: { month?: string; buildId?: string
 
 /** 11. 九防风险相关性矩阵 */
 export const getNineRiskCorrelation = (params?: { month?: string; buildId?: string | number; floorId?: string | number }) => {
-  const elders = generateElders(params?.month, params?.buildId, params?.floorId)
   const risks = NINE_RISKS.map((r) => r.name)
   const matrix: number[][] = []
   for (let i = 0; i < NINE_RISKS.length; i++) {
@@ -406,22 +405,6 @@ export const get3DRiskBar = (params?: { month?: string }) => {
   return delay({ floors, risks, data })
 }
 
-/** 14. 月度评估次数(日历热力图) */
-export const getMonthlyAssessCalendar = (params?: { buildId?: string | number }) => {
-  const data: [string, number][] = []
-  const now = new Date(2026, 6, 24)
-  const buildSeed = params?.buildId ? Number(params.buildId) : 0
-  for (let i = 180; i >= 0; i--) {
-    const d = new Date(now)
-    d.setDate(d.getDate() - i)
-    const dateStr = d.toISOString().slice(0, 10)
-    const rnd = seededRandom(dateStr.charCodeAt(0) + dateStr.charCodeAt(2) + dateStr.charCodeAt(5) + i + buildSeed)
-    const count = rnd() > 0.3 ? randInt(2, 15, rnd) : 0
-    if (count > 0) data.push([dateStr, count])
-  }
-  return delay(data)
-}
-
 /** 15. 月份列表(近 6 个月) */
 export const getMonthList = () => {
   const months: string[] = []

+ 5 - 3
src/components/BedCardComponent/index.vue

@@ -8,8 +8,8 @@
         <div style="display: flex; align-items: center">
           <h2 class="header-title">长者床头卡</h2>
         </div>
-        <div style="font-size: 16px; color: #fff;margin-right: 10px"
-          >更新时间:{{ formatToDate(patientData.updateTime)||'' }}</div
+        <div style="font-size: 16px; color: #fff; margin-right: 10px"
+          >更新时间:{{ formatToDate(patientData.updateTime) || '' }}</div
         >
         <!--        <div class="header-room">{{ patientData.roomName || '' }}</div>-->
       </div>
@@ -20,7 +20,9 @@
           <div class="bed-info">
             <div class="bed-letter" v-for="(item, index) in bedList" :key="index">
               <span>{{ item || '' }}</span>
-              <span v-if="index == (bedList || []).length - 1" class="bed-text">床</span>
+              <span v-if="index == (bedList || []).length - 1 && !item.includes('床')" class="bed-text"
+                >床</span
+              >
             </div>
           </div>
 

+ 18 - 10
src/views/data-board/comprehensive-overview/index.vue

@@ -3,6 +3,14 @@ import { ref, onMounted, onUnmounted } from 'vue'
 import echarts from '@/plugins/echarts'
 import 'echarts-gl'
 
+// 公共 tooltip 深色样式,避免白字白底看不见
+const TOOLTIP_DARK = {
+  backgroundColor: 'rgba(2, 11, 30, 0.92)',
+  borderColor: 'rgba(0, 255, 255, 0.3)',
+  borderWidth: 1,
+  padding: [8, 12],
+  textStyle: { color: '#fff' }
+}
 const overview = ref({
   totalElderly: 328,
   bedOccupancy: 89,
@@ -56,7 +64,7 @@ const initAdmissionChart = () => {
   chartAdmission = echarts.init(admissionRef.value)
   chartAdmission.setOption({
     backgroundColor: 'transparent',
-    tooltip: { trigger: 'axis', textStyle: { color: '#fff' } },
+    tooltip: { ...TOOLTIP_DARK, trigger: 'axis' },
     legend: {
       data: ['新入住', '退住', '累计在院'],
       textStyle: { color: '#c7e0ff' },
@@ -141,9 +149,9 @@ const initAgeChart = () => {
   chartAge.setOption({
     backgroundColor: 'transparent',
     tooltip: {
+      ...TOOLTIP_DARK,
       trigger: 'item',
-      formatter: '{b}<br/>人数:{c}人 ({d}%)',
-      textStyle: { color: '#fff' }
+      formatter: '{b}<br/>人数:{c}人 ({d}%)'
     },
     legend: {
       bottom: 0,
@@ -190,9 +198,9 @@ const initDiseaseChart = () => {
   chartDisease.setOption({
     backgroundColor: 'transparent',
     tooltip: {
+      ...TOOLTIP_DARK,
       trigger: 'axis',
-      axisPointer: { type: 'shadow' },
-      textStyle: { color: '#fff' }
+      axisPointer: { type: 'shadow' }
     },
     grid: { left: 90, right: 30, top: 15, bottom: 20 },
     xAxis: {
@@ -263,9 +271,9 @@ const initRevenueChart = () => {
   chartRevenue.setOption({
     backgroundColor: 'transparent',
     tooltip: {
+      ...TOOLTIP_DARK,
       trigger: 'axis',
-      axisPointer: { type: 'cross' },
-      textStyle: { color: '#fff' }
+      axisPointer: { type: 'cross' }
     },
     legend: {
       data: ['床位费', '护理费', '餐饮费', '服务费', '其他'],
@@ -374,9 +382,9 @@ const initActivityChart = () => {
   chartActivity.setOption({
     backgroundColor: 'transparent',
     tooltip: {
+      ...TOOLTIP_DARK,
       trigger: 'axis',
-      axisPointer: { type: 'shadow' },
-      textStyle: { color: '#fff' }
+      axisPointer: { type: 'shadow' }
     },
     grid: { left: 60, right: 30, top: 15, bottom: 25 },
     xAxis: {
@@ -439,7 +447,7 @@ const initCampusChart = () => {
 
   chartCampus.setOption({
     backgroundColor: 'transparent',
-    tooltip: {},
+    tooltip: { ...TOOLTIP_DARK },
     visualMap: {
       show: false,
       min: 20,

文件差異過大導致無法顯示
+ 572 - 187
src/views/data-board/nine-safety-measures/index.vue


部分文件因文件數量過多而無法顯示