当前位置: 首页 > news >正文

消费 $83,用Claude 实现临床护理系统记录单(所见即所得版)

又到周末了,手又痒痒了,又想用AI做点东西。。。
上个月做过➡️体温单了,那就做一个所见即所得的护理记录单吧,把参照图丢给 CHATGPT,提示词如下:

要求用 react 实现一款移动护理系统里用到的护理记录单功能,需要你帮我以前梳理一下思路。如图所示,单击日期和时间,会自动赋值当前的。病情观察及护理措施,点击后,弹窗,textarea 点确定后,根据长度回显到记录单里。签名那里单击弹窗输入工号密码,正确后渲染上签名图片。
一页写满后,可以新建一页记录单。自己可以创建不同类型的护理记录单,配置不同的表格项。

在这里插入图片描述


老规矩,先用ChatGPT打头阵!

🏗 功能拆解

  1. 表格基础结构

    • 表格按“记录单页”划分,一页多行,每行对应一条护理记录。

    • 每条记录包含:

      • 日期(单击自动填充当前日期)
      • 时间(单击自动填充当前时间)
      • 体温、脉搏、呼吸、血压、SpO₂ 等数值字段(输入框)
      • 病情观察及护理措施(textarea 弹窗输入,回显到表格)
      • 签名(弹窗输入工号+密码,校验后渲染签名图片)
  2. 交互逻辑

    • 点击“日期/时间” → 自动赋值 new Date()
    • 点击“病情观察及护理措施” → 弹窗 Modal + textarea
    • 点击“签名” → 弹窗 Modal 输入工号/密码 → 校验成功 → 显示签名图片
    • 当前页满了(比如 20 行),可以点击“新建一页” → 新增一张护理记录单
  3. 记录单类型管理

    • 护理记录单类型可以自定义
    • 不同类型对应不同表格列配置(类似于动态表单配置)
    • 配置方式:后端提供 JSON 配置,前端动态渲染列和输入控件

🔑 技术实现思路

  1. 数据结构设计

    const recordPage = {id: 'page-1',type: 'general', // 记录单类型rows: [{date: '2023-07-24',time: '08:05',temperature: 36.1,pulse: 72,respiration: 21,bp: '115/68',spo2: 98,note: '病情观察...',signature: '/uploads/sign/123.png'}]
    };
    
  2. 表格组件

    • RecordTable:渲染当前页
    • RecordRow:渲染单行,可点击单元格编辑
    • 通过 columns 配置项动态渲染
    const columns = [{ key: 'date', label: '日期', type: 'autoDate' },{ key: 'time', label: '时间', type: 'autoTime' },{ key: 'temperature', label: '体温', type: 'input' },{ key: 'pulse', label: '脉搏', type: 'input' },{ key: 'respiration', label: '呼吸', type: 'input' },{ key: 'bp', label: '血压', type: 'input' },{ key: 'spo2', label: 'SpO2', type: 'input' },{ key: 'note', label: '病情观察及护理措施', type: 'modalTextarea' },{ key: 'signature', label: '签名', type: 'modalSignature' }
    ];
    
  3. 弹窗交互

    • 病情观察及护理措施

      • 点击 → 弹出 Modal + textarea
      • 点确定 → 保存内容 → 超过长度自动换行/截断
    • 签名

      • 点击 → 弹出 工号+密码输入框
      • 校验接口 → 返回签名图片 URL → 渲染到表格中
  4. 分页逻辑

    • 每页固定 20 行(可配置)
    • 填满后,点击“新建一页” → 追加一个 recordPage
    • 多页之间可切换(tabs 或翻页器)
  5. 记录单类型

    后端返回不同配置:

    {"general": [{ "key": "date", "label": "日期", "type": "autoDate" },{ "key": "time", "label": "时间", "type": "autoTime" },{ "key": "temperature", "label": "体温", "type": "input" },...],"icu": [{ "key": "date", "label": "日期", "type": "autoDate" },{ "key": "consciousness", "label": "意识", "type": "select", "options": ["清醒", "嗜睡", "昏迷"] },...]
    }
    

    前端根据配置动态渲染不同的表格结构。


示例代码(React 16.8+)

import React, { useState } from "react";
import { Modal } from "antd"; // 这里用 antd 的 Modal,你也可以换成 antd-mobileconst FIXED_ROWS = 20;const initialRow = () => ({date: "",time: "",temperature: "",pulse: "",respiration: "",bp: "",spo2: "",note: "",signature: "",
});function RecordPage({ pageIndex, rows, onUpdateRow }) {const [noteModal, setNoteModal] = useState({ visible: false, rowIndex: null, value: "" });const [signModal, setSignModal] = useState({ visible: false, rowIndex: null, job: "", password: "" });const handleDateClick = (rowIndex) => {const now = new Date();onUpdateRow(rowIndex, {date: now.toLocaleDateString(),time: now.toLocaleTimeString().slice(0, 5),});};return (<div className="record-page"><h3>护理记录单 - 第 {pageIndex + 1} 页</h3><table border="1" cellPadding="4" style={{ width: "100%", borderCollapse: "collapse" }}><thead><tr><th>日期</th><th>时间</th><th>体温</th><th>脉搏</th><th>呼吸</th><th>血压</th><th>SpO₂</th><th>病情观察及护理措施</th><th>签名</th></tr></thead><tbody>{rows.map((row, idx) => (<tr key={idx}><td onClick={() => handleDateClick(idx)}>{row.date || "点击生成"}</td><td onClick={() => handleDateClick(idx)}>{row.time || "点击生成"}</td><td><inputvalue={row.temperature}onChange={(e) => onUpdateRow(idx, { temperature: e.target.value })}/></td><td><inputvalue={row.pulse}onChange={(e) => onUpdateRow(idx, { pulse: e.target.value })}/></td><td><inputvalue={row.respiration}onChange={(e) => onUpdateRow(idx, { respiration: e.target.value })}/></td><td><inputvalue={row.bp}onChange={(e) => onUpdateRow(idx, { bp: e.target.value })}/></td><td><inputvalue={row.spo2}onChange={(e) => onUpdateRow(idx, { spo2: e.target.value })}/></td><tdstyle={{ cursor: "pointer" }}onClick={() => setNoteModal({ visible: true, rowIndex: idx, value: row.note })}>{row.note || "点击填写"}</td><tdstyle={{ cursor: "pointer" }}onClick={() => setSignModal({ visible: true, rowIndex: idx, job: "", password: "" })}>{row.signature ? (<img src={row.signature} alt="签名" style={{ height: 24 }} />) : ("点击签名")}</td></tr>))}</tbody></table>{/* 病情观察 Modal */}<Modalvisible={noteModal.visible}title="填写病情观察及护理措施"onCancel={() => setNoteModal({ visible: false, rowIndex: null, value: "" })}onOk={() => {onUpdateRow(noteModal.rowIndex, { note: noteModal.value });setNoteModal({ visible: false, rowIndex: null, value: "" });}}><textareastyle={{ width: "100%", minHeight: 120 }}value={noteModal.value}onChange={(e) => setNoteModal({ ...noteModal, value: e.target.value })}/></Modal>{/* 签名 Modal */}<Modalvisible={signModal.visible}title="护士签名"onCancel={() => setSignModal({ visible: false, rowIndex: null, job: "", password: "" })}onOk={() => {// 模拟校验,这里写死一个账号密码if (signModal.job === "123" && signModal.password === "123456") {onUpdateRow(signModal.rowIndex, { signature: "/signatures/demo-sign.png" });setSignModal({ visible: false, rowIndex: null, job: "", password: "" });} else {alert("工号或密码错误!");}}}><div>工号:{" "}<inputvalue={signModal.job}onChange={(e) => setSignModal({ ...signModal, job: e.target.value })}/></div><div style={{ marginTop: 8 }}>密码:{" "}<inputtype="password"value={signModal.password}onChange={(e) => setSignModal({ ...signModal, password: e.target.value })}/></div></Modal></div>);
}export default function NursingRecord() {const [pages, setPages] = useState([{ id: 1, rows: Array.from({ length: FIXED_ROWS }, () => initialRow()) },]);const updateRow = (pageIndex, rowIndex, newData) => {setPages((prev) =>prev.map((page, pIdx) =>pIdx === pageIndex? {...page,rows: page.rows.map((r, rIdx) => (rIdx === rowIndex ? { ...r, ...newData } : r)),}: page));};const addPage = () => {setPages((prev) => [...prev, { id: prev.length + 1, rows: Array.from({ length: FIXED_ROWS }, () => initialRow()) }]);};return (<div>{pages.map((page, idx) => (<RecordPagekey={page.id}pageIndex={idx}rows={page.rows}onUpdateRow={(rowIdx, data) => updateRow(idx, rowIdx, data)}/>))}<button onClick={addPage}>新建一页</button></div>);
}

我需要的不是一个文件,而是一个demo


1️⃣ 初始化项目

在命令行执行:

npx create-react-app nursing-record-demo
cd nursing-record-demo
npm install antd
npm start

这样你就有一个干净的 React 环境。
注:这里要注意你的 react 版本和 antd 版本兼容情况。


2️⃣ 替换 src/App.js

把我之前写的代码整体放进 src/App.js 里(删掉默认的内容)。
完整版本如下(可直接运行):

import React, { useState } from "react";
import { Modal } from "antd";
import "antd/dist/antd.css";const FIXED_ROWS = 20;const initialRow = () => ({date: "",time: "",temperature: "",pulse: "",respiration: "",bp: "",spo2: "",note: "",signature: "",
});function RecordPage({ pageIndex, rows, onUpdateRow }) {const [noteModal, setNoteModal] = useState({ visible: false, rowIndex: null, value: "" });const [signModal, setSignModal] = useState({ visible: false, rowIndex: null, job: "", password: "" });const handleDateClick = (rowIndex) => {const now = new Date();onUpdateRow(rowIndex, {date: now.toLocaleDateString(),time: now.toLocaleTimeString().slice(0, 5),});};return (<div className="record-page"><h3>护理记录单 - 第 {pageIndex + 1} 页</h3><table border="1" cellPadding="4" style={{ width: "100%", borderCollapse: "collapse" }}><thead><tr><th>日期</th><th>时间</th><th>体温</th><th>脉搏</th><th>呼吸</th><th>血压</th><th>SpO₂</th><th>病情观察及护理措施</th><th>签名</th></tr></thead><tbody>{rows.map((row, idx) => (<tr key={idx}><td onClick={() => handleDateClick(idx)}>{row.date || "点击生成"}</td><td onClick={() => handleDateClick(idx)}>{row.time || "点击生成"}</td><td><inputvalue={row.temperature}onChange={(e) => onUpdateRow(idx, { temperature: e.target.value })}/></td><td><inputvalue={row.pulse}onChange={(e) => onUpdateRow(idx, { pulse: e.target.value })}/></td><td><inputvalue={row.respiration}onChange={(e) => onUpdateRow(idx, { respiration: e.target.value })}/></td><td><inputvalue={row.bp}onChange={(e) => onUpdateRow(idx, { bp: e.target.value })}/></td><td><inputvalue={row.spo2}onChange={(e) => onUpdateRow(idx, { spo2: e.target.value })}/></td><tdstyle={{ cursor: "pointer" }}onClick={() => setNoteModal({ visible: true, rowIndex: idx, value: row.note })}>{row.note || "点击填写"}</td><tdstyle={{ cursor: "pointer" }}onClick={() => setSignModal({ visible: true, rowIndex: idx, job: "", password: "" })}>{row.signature ? (<img src={row.signature} alt="签名" style={{ height: 24 }} />) : ("点击签名")}</td></tr>))}</tbody></table>{/* 病情观察 Modal */}<Modalopen={noteModal.visible}title="填写病情观察及护理措施"onCancel={() => setNoteModal({ visible: false, rowIndex: null, value: "" })}onOk={() => {onUpdateRow(noteModal.rowIndex, { note: noteModal.value });setNoteModal({ visible: false, rowIndex: null, value: "" });}}><textareastyle={{ width: "100%", minHeight: 120 }}value={noteModal.value}onChange={(e) => setNoteModal({ ...noteModal, value: e.target.value })}/></Modal>{/* 签名 Modal */}<Modalopen={signModal.visible}title="护士签名"onCancel={() => setSignModal({ visible: false, rowIndex: null, job: "", password: "" })}onOk={() => {if (signModal.job === "123" && signModal.password === "123456") {onUpdateRow(signModal.rowIndex, { signature: "https://via.placeholder.com/80x24?text=签名" });setSignModal({ visible: false, rowIndex: null, job: "", password: "" });} else {alert("工号或密码错误!");}}}><div>工号:{" "}<inputvalue={signModal.job}onChange={(e) => setSignModal({ ...signModal, job: e.target.value })}/></div><div style={{ marginTop: 8 }}>密码:{" "}<inputtype="password"value={signModal.password}onChange={(e) => setSignModal({ ...signModal, password: e.target.value })}/></div></Modal></div>);
}export default function NursingRecord() {const [pages, setPages] = useState([{ id: 1, rows: Array.from({ length: FIXED_ROWS }, () => initialRow()) },]);const updateRow = (pageIndex, rowIndex, newData) => {setPages((prev) =>prev.map((page, pIdx) =>pIdx === pageIndex? {...page,rows: page.rows.map((r, rIdx) => (rIdx === rowIndex ? { ...r, ...newData } : r)),}: page));};return (<div style={{ padding: 20 }}>{pages.map((page, idx) => (<RecordPagekey={page.id}pageIndex={idx}rows={page.rows}onUpdateRow={(rowIdx, data) => updateRow(idx, rowIdx, data)}/>))}</div>);
}

3️⃣ 运行

执行:

npm start

浏览器打开 http://localhost:3000,就能看到护理记录单 demo:

  • 点击 日期/时间 自动生成当前值
  • 点击 病情观察 弹窗 textarea
  • 点击 签名 弹窗工号/密码(输入 123 / 123456 成功显示签名图片)

做到这,发现 CHATGPT 又到了限额了,而系统根本没完成。。。
想起自己在➡️ anyrouter 里还有签到攒的几百刀(由于网络经常不稳,一直也没怎么用)。今天一试发现网络就竟然正常,响应速度很快,这么好的机会可不能浪费!😃

在这里插入图片描述
在这里插入图片描述
跑起来后,无论怎么改,都感觉很乱。Claude感觉就弄不明白了。
正想着最近没怎么用Claude,怎么退步成这样了?最终还是我发现,它竟然愚蠢的没加载css文件……

在这里插入图片描述

  • 有了样式,立马不一样了。接着就是一系列的细节优化。。。

看成果!

  • 日期/时间 自动取当前时间
  • 意识支持选择
  • 病情观察自动根据长度计算分行,当前页显示不开,自动创建新页
  • 支持按行删除和按页删除
  • 输入工号密码签名,支持签名取消

在这里插入图片描述
在这里插入图片描述
优化空间还有不少(网络报错了,今天没法继续了)

  1. 目前支持tab键来移动单元格,可以加上方向键左右控制
  2. 每页都应该带一个表头
  3. 病情观察首行开头空两格
  4. 打印目前还没有调完

AI编程,一定注意要做好版本管理 !!

在这里插入图片描述


其实做完似乎也没啥实际使用场景,好像就是单纯为了消费,哈哈!

  • 看看消费情况统计(花掉就是赚到)

其实 $83.83,真是不便宜,不过是签到送的就不心疼了!😛

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述


P.S.无聊,又整理了一版生词……

Accomplishing、Actualizing、Animating、Beboppin、Billowing、Blanching、Brewing、Caramelizing、Cerebrating、Coalescing、Cogitating、Combobulating、Concocting、Contemplating、Crunching、Deciphering、Deliberating、Determining、Discombobulating、Divining、Drizzling、Effecting、Enchanting、Finagling、Flibbertigibbeting、Forging、Gallivanting、Germinating、Harmonizing、Hatching、Herding、Hustling、Ideating、Incubating、Jiving、Julienning、Levitating、Lollygagging、Orbiting、Percolating、Philosophising、Photosynthesizing、Pondering、Marinating、Moseying、Mulling、Mustering、Nesting、Noodling、Recombobulating、Ruminating、Schlepping、Seasoning、Shimmying、Shucking、Slithering、Spining、Stewing、Swooping、Syncopating、Synthesizing、Thaumaturging、Tinkering、Tomfoolering、Transmuting、Unfurling、Vibing、Wandering、Whatchamacalliting、Wibbling、Wizarding……


CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a React-based nursing record management system (nursing-record-demo) built with Create React App. The application provides an interactive interface for healthcare professionals to create, edit, and manage nursing records with support for multiple templates and electronic signatures.

Common Development Commands

  • Start development server: npm start (opens http://localhost:3000)
  • Run tests: npm test (runs in interactive watch mode)
  • Build for production: npm run build
  • Linting: Uses built-in ESLint configuration from react-scripts

Architecture & Core Components

Main Application Structure

  • App.js: Main application component containing the core nursing record table interface, pagination, and modal management
  • Templates System (src/config/templates.js): Configurable templates for different nursing specialties (General, ICU, Surgery, Pediatric)
  • Component Library (src/components/):
    • PatientHeader.js: Static patient information display component
    • ProfessionalTable.js: Main table component for nursing records with row rendering and interaction handling
    • SignatureAuth.js: Electronic and password-based signature authentication with canvas drawing support
    • EnhancedNoteModal.js: Enhanced modal for editing patient observations
    • InputComponents.js: Specialized input components for different data types (vitals, intake/output, drainage, etc.)

Data Management

  • Storage (src/utils/storage.js): LocalStorage-based persistence with auto-save functionality
    • Records data, user settings, patient information
    • NursingRecordStorage class for data operations
    • AutoSaveManager class for automatic data persistence with configurable intervals
  • Helpers (src/utils/helpers.js): Utility functions for text processing, date/time formatting, and validation
    • TextUtils: Chinese/English mixed text wrapping with character width calculation
    • DateTimeUtils: Date/time formatting and manipulation
    • ValidationUtils: Form validation for job numbers, passwords, and vital signs

Key Data Structures

  • displayRows: Array representing the visual table rows (null for empty rows, objects for record data with {recordId, lineText, isFirst})
  • recordsRef.current: Map of record IDs to complete record data including vitals, observations, and signatures
  • Patient Information: Static display data for patient demographics and case information
  • Page Management: Fixed 17-row pages with intelligent pagination and cross-page content handling

User Interface Features

  • Dynamic Row Management: Click empty rows to create records, intelligent text wrapping for observations across page boundaries
  • Multi-page Support: Each page contains exactly 17 rows with alternating background colors and page-specific controls
  • Fixed Navigation Bar: Sticky top toolbar with page jump functionality (1-20, 21-40, etc.) and print controls
  • Smart Content Distribution: Observations automatically span multiple rows, with signatures appearing on the last line of each record
  • Auto-fill DateTime: Click date/time cells to populate with current timestamp
  • Electronic Signatures: Support for both electronic signature drawing and password-based authentication
  • Consciousness Selection: Dropdown selection for consciousness levels (清醒, 嗜睡, 昏睡, 昏迷, etc.)

Template System

Templates define column layouts for different nursing specialties:

  • GENERAL: Basic nursing with vitals and observations
  • ICU: Intensive care with intake/output tracking
  • SURGERY: Surgical nursing with drainage and wound monitoring
  • PEDIATRIC: Pediatric-specific fields like feeding and excretion

Each template specifies:

  • Column configuration (type, width, fields)
  • Input validation rules
  • Character limits for text wrapping
  • Specialized input components

Data Persistence

All data is stored in browser localStorage with these keys:

  • nursing_records: Main record data and display state
  • current_template: Active template selection
  • user_settings: User preferences and auto-save settings
  • custom_templates: User-defined templates

Auto-save functionality operates on a 30-second interval by default, automatically persisting changes without user intervention.

Key Constants

  • ROWS_PER_PAGE: 20 rows per page
  • MAX_CHARS_PER_LINE: 22 characters per line for text wrapping (template-configurable)

Development Notes

  • React 16.13.1 with functional components and hooks
  • Ant Design 4.x for UI components
  • No external state management - uses React state and refs
  • Chinese language interface with mixed Chinese/English character width handling
  • Testing setup with React Testing Library and Jest

http://www.dtcms.com/a/358511.html

相关文章:

  • 拦截器Intercepter
  • 基于单片机智能垃圾桶/垃圾分类/语音垃圾桶
  • Spring MVC 参数绑定的默认行为解析
  • MySQL错误1449: The user specified as a definer (‘root‘@‘%‘) does not exist
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 1: MapReduce
  • JC系列串口通信说明
  • day45-Ansible流程控制
  • 同步/异步日志库
  • 佳易王钟表维修养护管理系统:开启钟表维修高效管理新篇章​就#软件操作教程
  • Compare With Java And Python
  • springboot 实现不同接口指定上传文件大小
  • Linux 定时器:工作原理与实现机制深入分析
  • AI公司是怎样对权重和损失函数做处理的?
  • Oracle下载安装(学习版)
  • 向华为学习——解读73页业务迁移基本流程设计与华为迁移方案【附全文阅读】
  • 计算机三级嵌入式填空题——真题库(26)原题附答案速记
  • Java学习历程17——利用泛型优化自定义动态数组
  • 深度学习入门,基于python的理论与实现
  • PostgreSQL WAL机制深度解析与优化
  • 如何简单建设一个网站,让用户快速找到你。
  • 【物联网】BLE 系统架构全景图
  • 常量指针与指针常量习题(一)
  • Swift 解法详解:LeetCode 367《有效的完全平方数》
  • Notepad++使用技巧1
  • 2025-08-18面试题(nginx,mysql,zabbix为主)
  • C#正则表达式与用法
  • unity学习——视觉小说开发(二)
  • JsMind 常用配置项
  • Qt中的锁(1)
  • AFSIM仿真工具介绍与源码编译