要了解 **FHIR Patient data** 並設計輸入網頁,我建議分兩個層次來看: --- ## 一、FHIR Patient Resource 基礎 FHIR (**Fast Healthcare Interoperability Resources**) 是 HL7 制定的標準,用於醫療資料交換。 其中 **Patient resource** 用來描述病患的基本資料。 ### 1. Patient 主要欄位(常用) 以下是最常會用到的欄位(FHIR JSON 格式): ```json { "resourceType": "Patient", "id": "example", "identifier": [ { "system": "http://hospital.org/patient-id", "value": "1234567890" } ], "name": [ { "use": "official", "family": "Wang", "given": ["Chieh-An"] } ], "gender": "male", "birthDate": "1995-08-19", "telecom": [ { "system": "phone", "value": "0912345678", "use": "mobile" }, { "system": "email", "value": "test@example.com" } ], "address": [ { "use": "home", "line": ["台北市中正區某某路 100 號"], "city": "Taipei", "postalCode": "100" } ] } ``` 👉 常見對應: * **identifier** → 身分證號或病歷號 * **name** → 姓名(可有多個版本,例如官方/暱稱) * **gender** → 性別 * **birthDate** → 生日 * **telecom** → 聯絡方式(電話、Email) * **address** → 地址 FHIR 的結構有點「JSON 文件式」,所以資料可擴展、支援多值。 --- ## 二、設計輸入網頁 (表單) 假設你要做一個簡單的輸入網頁,可以對應上述欄位,讓使用者輸入病患基本資料,最後轉換成 FHIR JSON。 ### 1. 前端欄位設計 表單欄位建議如下: * **身分證號 / 病歷號 (identifier)** * **姓名 (name.family, name.given)** * **性別 (gender: male/female/other/unknown)** * **生日 (birthDate, date picker)** * **電話 (telecom\[phone])** * **Email (telecom\[email])** * **住址 (address.line, address.city, postalCode)** ### 2. HTML 表單範例 這裡示範簡單 HTML + JavaScript: ```html <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>FHIR Patient 輸入表單</title> </head> <body> <h2>病患資料輸入</h2> <form id="patientForm"> <label>病歷號/身分證號: <input type="text" id="identifier"></label><br><br> <label>姓氏: <input type="text" id="family"></label><br> <label>名字: <input type="text" id="given"></label><br><br> <label>性別: <select id="gender"> <option value="male">男</option> <option value="female">女</option> <option value="other">其他</option> <option value="unknown">未知</option> </select> </label><br><br> <label>生日: <input type="date" id="birthDate"></label><br><br> <label>電話: <input type="text" id="phone"></label><br> <label>Email: <input type="email" id="email"></label><br><br> <label>住址: <input type="text" id="address"></label><br> <label>城市: <input type="text" id="city"></label><br> <label>郵遞區號: <input type="text" id="postalCode"></label><br><br> <button type="button" onclick="generateFHIR()">轉換為FHIR JSON</button> </form> <h3>FHIR JSON 結果</h3> <pre id="output"></pre> <script> function generateFHIR() { const patient = { resourceType: "Patient", identifier: [ { system: "http://hospital.org/patient-id", value: document.getElementById("identifier").value } ], name: [ { use: "official", family: document.getElementById("family").value, given: [document.getElementById("given").value] } ], gender: document.getElementById("gender").value, birthDate: document.getElementById("birthDate").value, telecom: [ { system: "phone", value: document.getElementById("phone").value, use: "mobile" }, { system: "email", value: document.getElementById("email").value } ], address: [ { use: "home", line: [document.getElementById("address").value], city: document.getElementById("city").value, postalCode: document.getElementById("postalCode").value } ] }; document.getElementById("output").textContent = JSON.stringify(patient, null, 2); } </script> </body> </html> ``` 輸入資料後,點「轉換為FHIR JSON」就會生成一個符合 FHIR Patient resource 的 JSON。 --- ✅ 建議流程: 1. 先理解 FHIR Patient 的資料模型 2. 設計表單 → 欄位與 FHIR 對應 3. 產生 JSON → 後端可直接存 DB 或透過 FHIR API 發送 --- 要不要我幫你設計一個 **進階版本**(有驗證、防呆,例如必填檢查、格式檢查,並可直接送到 FHIR Server)? 太好了 👍 我們來做一個 **進階版 FHIR Patient 輸入網頁**,除了輸入 → 轉換成 JSON 外,還會加上 **必填欄位檢查**、**格式驗證**,並提供一個按鈕把資料送到 **FHIR Server**(例如 HAPI FHIR 測試伺服器)。 --- ## 一、必填/防呆設計 * **identifier (病歷號/身分證號)** → 必填 * **family / given (姓名)** → 必填 * **gender** → 必填(預設 male/female) * **birthDate** → 必填,且必須符合 `YYYY-MM-DD` * **phone** → 格式檢查(只允許數字與 `+` 開頭) * **email** → 格式檢查(用 HTML5 的 email type) --- ## 二、進階表單程式碼 這個網頁會: 1. 先檢查輸入格式 2. 若正確 → 產生 JSON 3. 可選擇送出到 HAPI FHIR Public Server ```html <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>FHIR Patient 輸入表單</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } label { display: block; margin-top: 10px; } input, select { padding: 5px; width: 300px; } button { margin-top: 15px; padding: 8px 12px; border: none; border-radius: 6px; background: #4CAF50; color: white; cursor: pointer; } button:hover { background: #45a049; } pre { background: #f4f4f4; padding: 10px; border-radius: 8px; } .error { color: red; font-size: 0.9em; } </style> </head> <body> <h2>FHIR Patient 輸入表單</h2> <form id="patientForm"> <label>病歷號/身分證號*: <input type="text" id="identifier" required> <span class="error" id="idError"></span> </label> <label>姓氏*: <input type="text" id="family" required> </label> <label>名字*: <input type="text" id="given" required> </label> <label>性別*: <select id="gender" required> <option value="">請選擇</option> <option value="male">男</option> <option value="female">女</option> <option value="other">其他</option> <option value="unknown">未知</option> </select> </label> <label>生日*: <input type="date" id="birthDate" required> <span class="error" id="birthError"></span> </label> <label>電話: <input type="text" id="phone" pattern="^\\+?[0-9]+$" placeholder="+886912345678"> <span class="error" id="phoneError"></span> </label> <label>Email: <input type="email" id="email" placeholder="example@test.com"> </label> <label>住址: <input type="text" id="address"> </label> <label>城市: <input type="text" id="city"> </label> <label>郵遞區號: <input type="text" id="postalCode" pattern="^[0-9]{3,6}$"> </label> <button type="button" onclick="generateFHIR()">產生 FHIR JSON</button> <button type="button" onclick="sendFHIR()">送到 FHIR Server</button> </form> <h3>FHIR JSON 結果</h3> <pre id="output"></pre> <script> let patientFHIR = null; function validateForm() { let valid = true; // 驗證生日 const birthDate = document.getElementById("birthDate").value; if (!/^\d{4}-\d{2}-\d{2}$/.test(birthDate)) { document.getElementById("birthError").textContent = "生日格式必須是 YYYY-MM-DD"; valid = false; } else { document.getElementById("birthError").textContent = ""; } // 驗證電話 const phone = document.getElementById("phone").value; if (phone && !/^\+?[0-9]+$/.test(phone)) { document.getElementById("phoneError").textContent = "電話只能包含數字或 +"; valid = false; } else { document.getElementById("phoneError").textContent = ""; } return valid; } function generateFHIR() { if (!validateForm()) return; patientFHIR = { resourceType: "Patient", identifier: [ { system: "http://hospital.org/patient-id", value: document.getElementById("identifier").value } ], name: [ { use: "official", family: document.getElementById("family").value, given: [document.getElementById("given").value] } ], gender: document.getElementById("gender").value, birthDate: document.getElementById("birthDate").value, telecom: [], address: [ { use: "home", line: [document.getElementById("address").value], city: document.getElementById("city").value, postalCode: document.getElementById("postalCode").value } ] }; // 電話 & Email const phone = document.getElementById("phone").value; if (phone) patientFHIR.telecom.push({ system: "phone", value: phone, use: "mobile" }); const email = document.getElementById("email").value; if (email) patientFHIR.telecom.push({ system: "email", value: email }); document.getElementById("output").textContent = JSON.stringify(patientFHIR, null, 2); } async function sendFHIR() { if (!patientFHIR) { alert("請先產生 FHIR JSON"); return; } try { const response = await fetch("https://hapi.fhir.org/baseR4/Patient", { method: "POST", headers: { "Content-Type": "application/fhir+json" }, body: JSON.stringify(patientFHIR) }); if (response.ok) { const data = await response.json(); alert("已成功送出到 FHIR Server!\n新建 ID: " + data.id); } else { alert("送出失敗,HTTP 狀態: " + response.status); } } catch (err) { alert("錯誤: " + err.message); } } </script> </body> </html> ``` --- ### 三、功能說明 1. **表單輸入** * 必填 & 格式驗證 * 錯誤訊息會即時顯示 2. **產生 JSON** * 按下 `產生 FHIR JSON` → 輸出 FHIR 標準的 Patient 資料 3. **送到 FHIR Server** * 使用 `fetch()` 送 POST 到 [HAPI FHIR public server](https://hapi.fhir.org/baseR4/) * 成功後會回傳一個新的 Patient ID ---