| src/main.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/utils/dateDisplay.js | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/collaborativeApproval/planTemplate/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/views/reportAnalysis/safetyDashboard/components/center-top.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main.js
@@ -58,7 +58,7 @@ import PageHeader from "@/components/PageHeader/index.vue"; import { getToken } from "@/utils/auth"; import { toDateOnly } from "@/utils/dateDisplay"; import { toDateOnly, toDateOnlyVNode } from "@/utils/dateDisplay"; import { calculateTaxExclusiveTotalPrice, summarizeTable, @@ -133,4 +133,31 @@ } } // 列表时间统一只展示年月日(插槽列):<template #default> 里的内容不走列 formatter, // 这里把 el-table-column 的所有插槽输出过一遍,纯文本中的日期时间只保留年月日。 const tableColumn = app._context.components.ElTableColumn; if ( tableColumn && typeof tableColumn.setup === "function" && !tableColumn.__dateOnlyPatched ) { const originalSetup = tableColumn.setup; tableColumn.setup = function (props, ctx) { try { const slots = ctx.slots; if (slots) { Object.keys(slots).forEach((name) => { const original = slots[name]; if (typeof original !== "function") return; slots[name] = (scope) => toDateOnlyVNode(original(scope)); }); } } catch (e) { // 插槽只读时退回列 formatter 兜底,不影响表格渲染 } return originalSetup(props, ctx); }; tableColumn.__dateOnlyPatched = true; } app.mount("#app"); src/utils/dateDisplay.js
@@ -2,6 +2,8 @@ * 列表展示用的日期处理:带时分秒的日期时间只保留年月日, * 本来就是日期、时间或其它内容的值原样返回。 */ import { cloneVNode } from "vue"; const DATE_TIME_PATTERN = /^(\d{4})[-/年](\d{1,2})[-/月](\d{1,2})日?[ T]\d{1,2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?$/; @@ -30,3 +32,56 @@ return `${matched[1]}-${pad2(matched[2])}-${pad2(matched[3])}`; } /** * 递归处理插槽渲染出的 vnode:把其中的纯文本按 toDateOnly 截断。 * 表格列的插槽内容(<template #default>)不会走列 formatter, * 这里在 vnode 层统一兜底,列表里就不会再冒出时分秒。 */ export function toDateOnlyVNode(node) { if (node == null || typeof node === "number" || typeof node === "boolean") { return node; } if (Array.isArray(node)) { return mapIfChanged(node, toDateOnlyVNode); } if (typeof node === "string") { return toDateOnly(node); } // vnode:文本子节点 const children = node.children; if (children == null) return node; if (typeof children === "string") { const next = toDateOnly(children); return next === children ? node : withChildren(node, next); } if (Array.isArray(children)) { const next = mapIfChanged(children, toDateOnlyVNode); return next === children ? node : withChildren(node, next); } // 组件插槽对象等其它形态不处理 return node; } // cloneVNode 的第二个参数只合并到 props,children 要单独赋值 function withChildren(vnode, children) { const cloned = cloneVNode(vnode); cloned.children = children; return cloned; } function mapIfChanged(list, mapper) { let changed = false; const mapped = list.map((item) => { const next = mapper(item); if (next !== item) changed = true; return next; }); return changed ? mapped : list; } src/views/collaborativeApproval/planTemplate/index.vue
@@ -144,7 +144,7 @@ <div class="plan-meta"> <div class="meta-item"> <el-icon><Calendar /></el-icon> <span>{{ plan.startDate }} - {{ plan.endDate }}</span> <span>{{ formatDateOnly(plan.startDate) }} - {{ formatDateOnly(plan.endDate) }}</span> </div> <div class="meta-item"> <el-icon><User /></el-icon> src/views/reportAnalysis/safetyDashboard/components/center-top.vue
@@ -59,7 +59,7 @@ </div> <div class="event-meta"> <span>{{ item.location || '—' }}</span> <span>{{ item.eventTime }}</span> <span>{{ formatDateOnly(item.eventTime) }}</span> </div> </li> </ul>