Browse Source

优化护理日志展示

xiongxing 2 tuần trước cách đây
mục cha
commit
9058795b92
1 tập tin đã thay đổi với 59 bổ sung47 xóa
  1. 59 47
      src/views/elderly/nursing/nursing-log-list/Detail.vue

+ 59 - 47
src/views/elderly/nursing/nursing-log-list/Detail.vue

@@ -68,22 +68,23 @@
         <el-table-column label="完成时间" prop="finishTime" :formatter="dateFormatter" />
         <el-table-column label="备注" min-width="200">
           <template #default="scope">
+            <!-- 高频:解析 remark JSON,有内容才展示 -->
             <template v-if="scope.row.frequencyCategoryType == 1">
               <template
-                v-for="rv in [getRemarkView(scope.row.remark)]"
-                :key="'rk-' + rv.mode + '-' + (scope.row.id ?? scope.$index)"
+                v-for="blocks in [getHighFreqRemarkBlocks(scope.row.remark)]"
+                :key="'hb-' + blocks.length + '-' + (scope.row.id ?? scope.$index)"
               >
-                <div v-if="rv.mode === 'blocks'" class="remark-cell-compact">
+                <div v-if="blocks.length" class="remark-cell-compact">
                   <div class="remark-compact-main">
                     <div
                       class="remark-summary-line"
-                      :title="getStructuredRemarkSummaryFull(rv.blocks)"
+                      :title="getStructuredRemarkSummaryFull(blocks)"
                     >
-                      {{ getStructuredRemarkSummary(rv.blocks) }}
+                      {{ getStructuredRemarkSummary(blocks) }}
                     </div>
                     <div class="remark-compact-meta">
                       <el-tag size="small" type="info" effect="plain">
-                        {{ getStructuredRemarkModuleCount(rv.blocks) }}
+                        {{ getStructuredRemarkModuleCount(blocks) }}
                       </el-tag>
                       <el-popover
                         placement="left-start"
@@ -98,7 +99,7 @@
                           </el-button>
                         </template>
                         <div class="structured-remark structured-remark--popover">
-                          <div v-for="block in rv.blocks" :key="block.title" class="sr-section">
+                          <div v-for="block in blocks" :key="block.title" class="sr-section">
                             <div class="sr-title">{{ block.title }}</div>
                             <div
                               v-for="(line, li) in block.lines"
@@ -131,13 +132,10 @@
                     </div>
                   </div>
                 </div>
-                <span v-else-if="rv.mode === 'json-fallback'" class="sr-fallback">{{
-                  rv.text
-                }}</span>
-                <span v-else class="remark-plain">{{ rv.text }}</span>
               </template>
             </template>
-            <span v-else>{{ scope.row.remark }}</span>
+            <!-- 中/低频:直接显示 remark 原文 -->
+            <span v-else class="remark-plain">{{ scope.row.remark || '-' }}</span>
           </template>
         </el-table-column>
         <el-table-column
@@ -479,24 +477,45 @@ function normalizePhotoUrls(raw: unknown): string[] {
     .filter(Boolean)
 }
 
-function parseRemarkObject(remark: string): Record<string, unknown> | null {
-  const t = remark?.trim()
-  if (!t || t[0] !== '{') return null
-  try {
-    const o = JSON.parse(t) as unknown
-    if (o && typeof o === 'object' && !Array.isArray(o)) return o as Record<string, unknown>
-  } catch {
-    //
+function parseRemarkObject(remark: unknown): Record<string, unknown> | null {
+  if (remark == null) return null
+  if (typeof remark === 'object' && !Array.isArray(remark)) {
+    return remark as Record<string, unknown>
   }
-  return null
-}
+  if (typeof remark !== 'string') return null
+
+  let t = remark.trim()
+  if (!t) return null
 
-/** 是否为小程序高频护理整单 JSON(与中/低频纯文本区分) */
-function isStructuredRemark(remark?: string): boolean {
-  if (!remark || typeof remark !== 'string') return false
-  const o = parseRemarkObject(remark)
-  if (!o) return false
-  return 'food' in o || 'skin' in o || 'bowel' in o
+  // 接口/库中可能 JSON.stringify 整段 remark,支持多层解包
+  for (let depth = 0; depth < 3; depth++) {
+    if (t[0] === '{') {
+      try {
+        const o = JSON.parse(t) as unknown
+        if (o && typeof o === 'object' && !Array.isArray(o)) return o as Record<string, unknown>
+      } catch {
+        //
+      }
+      break
+    }
+    if (t[0] === '"') {
+      try {
+        const unwrapped = JSON.parse(t) as unknown
+        if (typeof unwrapped === 'string') {
+          t = unwrapped.trim()
+          continue
+        }
+        if (unwrapped && typeof unwrapped === 'object' && !Array.isArray(unwrapped)) {
+          return unwrapped as Record<string, unknown>
+        }
+      } catch {
+        //
+      }
+      break
+    }
+    break
+  }
+  return null
 }
 
 function extractFieldValue(sectionKey: string, field: FormField, root: unknown): unknown {
@@ -550,9 +569,9 @@ function extractFieldValue(sectionKey: string, field: FormField, root: unknown):
     if (Array.isArray(v)) return v.filter(Boolean).join('、')
     return v
   }
-  // 扁平:饮食/皮肤/大小便/睡眠/过期/情绪
+  // 扁平:饮食/皮肤/大小便/睡眠/过期/情绪 — { key, value, remark?, photo? }
   if (field.type === 'select' || field.type === 'datetime') {
-    if (r.key === field.key) return r.value
+    if (r.key === field.key || r.key == null) return r.value
     return undefined
   }
   if (
@@ -599,7 +618,9 @@ function buildSectionLines(sec: FormSection, parsed: Record<string, unknown>): R
   return lines
 }
 
-function getStructuredRemarkDisplay(remark: string): Array<{ title: string; lines: RemarkLine[] }> {
+function getStructuredRemarkDisplay(
+  remark: unknown
+): Array<{ title: string; lines: RemarkLine[] }> {
   const parsed = parseRemarkObject(remark)
   if (!parsed) return []
   const out: Array<{ title: string; lines: RemarkLine[] }> = []
@@ -610,23 +631,14 @@ function getStructuredRemarkDisplay(remark: string): Array<{ title: string; line
   return out
 }
 
-/** 单行备注展示:一次解析,供表格列模板使用 */
-function getRemarkView(remark?: string): {
-  mode: 'plain' | 'blocks' | 'json-fallback'
-  text: string
-  blocks: Array<{ title: string; lines: RemarkLine[] }>
-} {
-  if (!remark || !String(remark).trim()) {
-    return { mode: 'plain', text: '-', blocks: [] }
-  }
-  if (!isStructuredRemark(remark)) {
-    return { mode: 'plain', text: remark, blocks: [] }
-  }
-  const blocks = getStructuredRemarkDisplay(remark)
-  if (blocks.length) {
-    return { mode: 'blocks', text: remark, blocks }
+/** 高频护理 remark:解析 JSON,仅返回有内容的展示块 */
+function getHighFreqRemarkBlocks(
+  remark?: unknown
+): Array<{ title: string; lines: RemarkLine[] }> {
+  if (remark == null || (typeof remark === 'string' && !remark.trim())) {
+    return []
   }
-  return { mode: 'json-fallback', text: remark, blocks: [] }
+  return getStructuredRemarkDisplay(remark)
 }
 
 /** 表格单元格内一行摘要(前几项 + 等 N 项),控制列宽 */