修改起始页和建档页
This commit is contained in:
parent
f437ff4dba
commit
edd6ed78f4
6
frontend/src/renderer/src/assets/svg/goback.svg
Normal file
6
frontend/src/renderer/src/assets/svg/goback.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="27px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="matrix(1 0 0 1 -28 -59 )">
|
||||||
|
<path d="M 14.5411734007741 23.6607265995625 L 5.81436691135277 15 L 30.0976545204611 15 C 31.0462204500389 15.0096802498529 31.9947863534941 14.2406983632777 31.9947863796167 13.0872255201793 C 31.9947863796167 12.1259981421069 31.235933651628 11.1647707905057 30.0976545204611 11.1647707640344 L 6.76293284093055 11.1647707640344 L 14.5411734007741 3.28270632737136 C 15.3000261287627 2.51372444079618 15.3000261287627 1.36025159769775 14.5411734007741 0.591269684651258 C 13.7823206727854 -0.177712201923929 12.6440415677411 -0.177712201923929 11.8851888136299 0.591269684651258 L 0.692110912530852 11.9337526770809 C 0.312684535475217 12.3182436336041 0.122971360008707 12.8949800551533 0.122971360008707 13.4717164502313 C 0.122971360008707 14.0484528717805 0.122971360008707 14.6251892933297 0.692110912530852 15.0096802498529 L 11.8851888136299 26.3521632422826 C 12.6440415416185 27.1211451288578 13.7823206466628 27.1211451288578 14.5411734007741 26.3521632422826 C 15.3000261287627 25.5831813557074 15.3000261287627 24.429708512609 14.5411734007741 23.6607265995625 Z " fill-rule="nonzero" fill="#ffffff" stroke="none" transform="matrix(1 0 0 1 28 59 )" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
6
frontend/src/renderer/src/assets/svg/logo.svg
Normal file
6
frontend/src/renderer/src/assets/svg/logo.svg
Normal file
File diff suppressed because one or more lines are too long
6
frontend/src/renderer/src/assets/svg/user.svg
Normal file
6
frontend/src/renderer/src/assets/svg/user.svg
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="matrix(1 0 0 1 -1869 -5 )">
|
||||||
|
<path d="M 16.0494983355978 0.013377921195652 C 11.5189966711956 0.10976589673913 7.72749164402174 1.68421402853261 4.73926423233696 4.67237459239131 C 1.75110366847826 7.66060200407609 0.176655502717391 11.45210703125 0.0802675611413041 15.9826086956522 C 0.176655536684783 20.5131103600543 1.75110366847826 24.2725083559783 4.73926423233696 27.2606688858696 C 7.72749164402174 30.2488963315217 11.5189966711957 31.8233444972826 16.0494983355978 31.9197324388587 C 20.58 31.8233444633152 24.3393979959239 30.2488963315217 27.3275585258152 27.260735767663 C 30.3157190557065 24.2725752038044 31.8902341032609 20.5131772418478 31.9866220788044 15.9826086956522 C 31.8902341032609 11.45210703125 30.3157859714674 7.69270903532609 27.3276254076087 4.70454850543478 C 24.3393979959239 1.6842140625 20.5800668817935 0.10976589673913 16.0494983355978 0.013377921195652 Z M 30.1230769361413 15.9825418478261 C 30.090836107337 19.8062207201087 28.644949830163 23.21210703125 26.1709030230978 25.7505685461957 C 25.3675585258152 25.364949830163 24.5000669157609 24.9472909646739 23.6325083899457 24.8509029891304 C 21.3512375 24.6581270720109 19.9374582201087 24.3046822690217 19.3912375 23.7584615149457 C 18.8770568953804 23.2121738790761 18.6521739470109 22.4410702105978 18.7486288043478 21.4449497961957 C 18.7807358355978 20.834515013587 18.9414047214674 20.4810702105978 19.2948495244565 20.3203344089674 C 19.6482943274456 20.1597324048913 20.0338461956522 19.2599999660326 20.4194649116848 17.6534447690217 C 20.5480268002717 17.1715049592391 20.6765217730978 16.7858862432065 20.8371906589674 16.4967223505435 C 20.9977926630435 16.2075584578804 21.2548495244565 15.5970567934783 21.576187330163 14.601003294837 C 21.7368562160326 13.8941136548913 21.7368562160326 13.4763879076087 21.544080298913 13.3800668478261 C 21.3513043817935 13.2836788722826 21.2227424932065 13.2515049592391 21.1907023777174 13.2836788722826 L 21.3511705842391 12.5767224184783 C 21.4475585597826 12.1268896399457 21.5117725883152 11.580668919837 21.5760535326087 10.9701672214674 C 21.7688963315217 9.36361202445652 21.4475585597826 7.98193980978261 20.61210703125 6.82521739130435 C 19.7767224184783 5.63638797554348 18.2344481657609 5.02588627717391 15.9531103600543 4.96160536684783 C 13.9288294157609 4.99371239809783 12.8684949728261 5.79705686141304 11.6796655570652 6.79311039402174 C 10.3622742527174 7.82133780570652 9.91244147418478 9.20294317255435 10.2658862771739 10.9701672554348 C 10.522943138587 12.2875585597826 10.9084949728261 13.3800000339674 10.651438111413 13.2836120584239 C 10.619331080163 13.2515050271739 10.490836107337 13.2836120584239 10.3301672214674 13.3800000339674 C 10.1694983355978 13.4763880095109 10.1373913043478 13.8941137567935 10.2658862771739 14.6009364809783 C 10.619331080163 15.4684950067935 10.8763879415761 16.0789966711957 11.0691638586956 16.4003344769022 C 11.2619397758152 16.7216053668478 11.3904347486413 17.1393311480978 11.4868896059783 17.653377955163 C 11.8082274116848 19.2278261209239 12.1294983016304 20.0953846467391 12.4829431046196 20.2559866508152 C 12.8363879076087 20.4166555366848 13.0612708559783 20.8343812839674 13.1898327445652 21.4448160665761 C 13.3505016304348 22.4409364809783 13.1577257133152 23.2120401494565 12.579331080163 23.7583277853261 C 12.0010033288043 24.3045485054348 10.619331080163 24.6579933423913 8.43438125 24.8507692595109 C 7.63110366847826 24.9471572350544 6.66715716711956 25.3327090692935 5.8960534986413 25.7183277853261 C 3.42193977581521 23.1478261209239 1.9760534986413 19.7418729279891 1.94387958559782 15.9825418478261 C 2.0402675611413 11.9982609035326 3.42193977581521 8.68876256793478 6.08882941576087 6.02180604619565 C 8.75571905570652 3.35484952445652 12.0652842730978 1.97331107336957 16.0495652173913 1.87685621603261 C 20.0337792798913 1.97324419157609 23.3433444972826 3.35491640625 25.9781271059783 6.02180604619565 C 28.6450167459239 8.68869568614131 30.0266889945652 11.9982609035326 30.1230769361413 15.9825418478261 Z " fill-rule="nonzero" fill="#f2f2f2" stroke="none" transform="matrix(1 0 0 1 1869 5 )" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
@ -16,7 +16,7 @@ api.interceptors.request.use(
|
|||||||
if (window.electronAPI) {
|
if (window.electronAPI) {
|
||||||
config.baseURL = window.electronAPI.getBackendUrl()
|
config.baseURL = window.electronAPI.getBackendUrl()
|
||||||
} else {
|
} else {
|
||||||
config.baseURL = 'http://127.0.0.1:5000'
|
config.baseURL = 'http://192.168.1.58:5000'
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加时间戳防止缓存
|
// 添加时间戳防止缓存
|
||||||
|
@ -155,7 +155,7 @@ body {
|
|||||||
|
|
||||||
/* 表单样式 */
|
/* 表单样式 */
|
||||||
.form-container {
|
.form-container {
|
||||||
max-width: 600px;
|
/* max-width: 600px; */
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,40 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dashboard-container dashboard-container-home">
|
<div class="dashboard-container dashboard-container-home">
|
||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<div class="header">
|
<Header />
|
||||||
<div class="header-left">
|
<div class="main-dashboard-top">
|
||||||
<!-- <img src="/logo.png" alt="Logo" class="logo" /> -->
|
<div class="main-dashboard-top-title">
|
||||||
<h1 class="system-title">平衡体态检测系统</h1>
|
起始页
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="main-dashboard-top-info">
|
||||||
<div class="user-info">
|
<div>测试时间:2025-08-03 17:13:18<span></span></div>
|
||||||
<el-avatar :size="40" :src="userInfo.avatar">
|
<div style="margin-left: 15px;">测试医生:<span>李医生</span></div>
|
||||||
<el-icon><User /></el-icon>
|
|
||||||
</el-avatar>
|
|
||||||
<span class="username">{{ userInfo.username }}</span>
|
|
||||||
<el-dropdown @command="handleUserCommand">
|
|
||||||
<el-button link class="user-dropdown">
|
|
||||||
<el-icon><ArrowDown /></el-icon>
|
|
||||||
</el-button>
|
|
||||||
<template #dropdown>
|
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item command="profile">个人信息</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="settings">系统设置</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 左侧功能导航 -->
|
<!-- 左侧功能导航 -->
|
||||||
<div class="main-dashboard-content">
|
<div class="main-dashboard-content">
|
||||||
<aside class="sidebar">
|
<!-- <aside class="sidebar">
|
||||||
<div class="sidebar-item active">
|
<div class="sidebar-item active">
|
||||||
<el-icon class="sidebar-icon"><UserFilled /></el-icon>
|
<el-icon class="sidebar-icon"><UserFilled /></el-icon>
|
||||||
<span class="sidebar-text">检测</span>
|
<span class="sidebar-text">检测</span>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside> -->
|
||||||
<!-- 右侧内容区域 -->
|
<!-- 右侧内容区域 -->
|
||||||
<div class="content-area">
|
<div class="content-area">
|
||||||
<!-- 患者列表区域 -->
|
<!-- 患者列表区域 -->
|
||||||
@ -42,35 +26,38 @@
|
|||||||
<div class="section-header">
|
<div class="section-header">
|
||||||
<div class="module-title">患者列表</div>
|
<div class="module-title">患者列表</div>
|
||||||
<div class="search-box">
|
<div class="search-box">
|
||||||
<el-input
|
<el-input v-model="searchKeyword" placeholder="搜索患者姓名" prefix-icon="Search" clearable
|
||||||
v-model="searchKeyword"
|
@input="handleSearch" />
|
||||||
placeholder="搜索患者姓名"
|
|
||||||
prefix-icon="Search"
|
|
||||||
clearable
|
|
||||||
@input="handleSearch"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<el-table :data="filteredPatients" style="width: 100%" border @cell-click="selectPatient" highlight-current-row>
|
<el-table :data="filteredPatients" style="width: 100%" border @cell-click="selectPatient"
|
||||||
|
highlight-current-row>
|
||||||
<el-table-column prop="name" label="姓名" min-width="60" />
|
<el-table-column prop="name" label="姓名" min-width="60" />
|
||||||
<el-table-column prop="id" label="测试者ID" min-width="60" />
|
<el-table-column prop="id" label="测试者ID" min-width="60" />
|
||||||
<el-table-column prop="updated_at" label="最后一次检查时间" min-width="60" />
|
<el-table-column prop="updated_at" label="最后一次检查时间" min-width="60" />
|
||||||
<el-table-column prop="gender" label="性别" min-width="60" />
|
<el-table-column prop="gender" label="性别" min-width="60" />
|
||||||
<el-table-column prop="num" label="测试次数" min-width="60" />
|
<el-table-column prop="num" label="测试次数" min-width="60" />
|
||||||
|
<el-table-column fixed="right" label="操作" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button link type="primary" size="small" @click="delClick(scope.row.id)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 患者详情区域 -->
|
<!-- 患者详情区域 -->
|
||||||
<div class="patient-detail" v-if="selectedPatient">
|
<div class="patient-detail" v-if="selectedPatient">
|
||||||
<div class="patient-detail-box" >
|
<div class="patient-detail-box">
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
<div class="module-title">基础信息</div>
|
<div class="module-title">基础信息</div>
|
||||||
<el-button link @click="editPatient">
|
<el-button link @click="editPatient">
|
||||||
<el-icon><Edit /></el-icon>
|
<el-icon>
|
||||||
</el-button>
|
<Edit />
|
||||||
</div>
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="basic-info-box">
|
<div class="basic-info-box">
|
||||||
<div class="basic-info-content">
|
<div class="basic-info-content">
|
||||||
<div class="basic-info-text">
|
<div class="basic-info-text">
|
||||||
<div class="basic-info-textcolor">测试者ID</div>
|
<div class="basic-info-textcolor">测试者ID</div>
|
||||||
@ -92,7 +79,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="basic-info-text">
|
<div class="basic-info-text">
|
||||||
<div class="basic-info-textcolor">年龄</div>
|
<div class="basic-info-textcolor">年龄</div>
|
||||||
<div>{{ selectedPatient.age || '-' }}</div>
|
<div>{{ calculateAge(selectedPatient.birth_date) }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info-text">
|
<div class="basic-info-text">
|
||||||
<div class="basic-info-textcolor">民族</div>
|
<div class="basic-info-textcolor">民族</div>
|
||||||
@ -123,18 +110,18 @@
|
|||||||
<div>{{ selectedPatient.created_at ? formatDate(selectedPatient.created_at) : '-' }}</div>
|
<div>{{ selectedPatient.created_at ? formatDate(selectedPatient.created_at) : '-' }}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-info-text">
|
<div class="basic-info-text">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<div class="action-buttons">
|
<div class="action-buttons">
|
||||||
<div class="action-view-buttons" @click="viewPatientProfile">查看档案</div>
|
<div class="action-view-buttons" style="width:338px;" @click="viewPatientProfile">查看档案</div>
|
||||||
<div class="action-view-buttons" @click="startDetection">检查</div>
|
<div class="action-view-buttons" style="width:338px;" @click="startDetection">平衡检测</div>
|
||||||
<div class="action-view-buttons" @click="createNewPatient">+新患者建档</div>
|
<div class="action-view-buttons" style="width:338px;" @click="createNewPatient">+新患者建档</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -155,7 +142,7 @@ import { useRouter } from 'vue-router'
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { patientAPI } from '../services/api.js'
|
import { patientAPI } from '../services/api.js'
|
||||||
import { useAuthStore } from '../stores/index.js'
|
import { useAuthStore } from '../stores/index.js'
|
||||||
|
import Header from '@/views/Header.vue'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const authStore = useAuthStore()
|
const authStore = useAuthStore()
|
||||||
|
|
||||||
@ -174,7 +161,7 @@ const filteredPatients = computed(() => {
|
|||||||
if (!searchKeyword.value) {
|
if (!searchKeyword.value) {
|
||||||
return patients.value
|
return patients.value
|
||||||
}
|
}
|
||||||
return patients.value.filter(patient =>
|
return patients.value.filter(patient =>
|
||||||
patient.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
patient.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@ -234,7 +221,7 @@ const handleLogout = async () => {
|
|||||||
cancelButtonText: '取消',
|
cancelButtonText: '取消',
|
||||||
type: 'warning'
|
type: 'warning'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 调用认证状态管理的logout方法清除所有认证信息
|
// 调用认证状态管理的logout方法清除所有认证信息
|
||||||
await authStore.logout()
|
await authStore.logout()
|
||||||
ElMessage.success('已退出登录')
|
ElMessage.success('已退出登录')
|
||||||
@ -266,6 +253,19 @@ const formatDate = (date) => {
|
|||||||
return new Date(date).toLocaleDateString('zh-CN')
|
return new Date(date).toLocaleDateString('zh-CN')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加计算年龄的方法
|
||||||
|
const calculateAge = (birthDate) => {
|
||||||
|
if (!birthDate) return '-'
|
||||||
|
const today = new Date()
|
||||||
|
const birth = new Date(birthDate)
|
||||||
|
let age = today.getFullYear() - birth.getFullYear()
|
||||||
|
const monthDiff = today.getMonth() - birth.getMonth()
|
||||||
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate())) {
|
||||||
|
age--
|
||||||
|
}
|
||||||
|
return age
|
||||||
|
}
|
||||||
|
|
||||||
const loadPatients = async () => {
|
const loadPatients = async () => {
|
||||||
try {
|
try {
|
||||||
const response = await patientAPI.getPatients()
|
const response = await patientAPI.getPatients()
|
||||||
@ -289,14 +289,14 @@ const loadPatients = async () => {
|
|||||||
gender: '男',
|
gender: '男',
|
||||||
age: 45,
|
age: 45,
|
||||||
updated_at: '2023-05-01 14:00:00',
|
updated_at: '2023-05-01 14:00:00',
|
||||||
num:4
|
num: 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2,
|
id: 2,
|
||||||
name: '李四',
|
name: '李四',
|
||||||
gender: '女',
|
gender: '女',
|
||||||
updated_at: '2023-05-01 14:00:00',
|
updated_at: '2023-05-01 14:00:00',
|
||||||
num:4
|
num: 4
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 3,
|
id: 3,
|
||||||
@ -304,8 +304,8 @@ const loadPatients = async () => {
|
|||||||
gender: '男',
|
gender: '男',
|
||||||
age: 52,
|
age: 52,
|
||||||
updated_at: '2023-05-01 14:00:00',
|
updated_at: '2023-05-01 14:00:00',
|
||||||
num:4
|
num: 4
|
||||||
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -320,10 +320,42 @@ onMounted(() => {
|
|||||||
avatar: authStore.currentUser.avatar || ''
|
avatar: authStore.currentUser.avatar || ''
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载患者列表
|
// 加载患者列表
|
||||||
loadPatients()
|
loadPatients()
|
||||||
})
|
})
|
||||||
|
function delClick(id) {
|
||||||
|
ElMessageBox.confirm('确定删除该条患者信息吗?', '删除提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
const response = await patientAPI.deletePatient(id);
|
||||||
|
if (response.success) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'success',
|
||||||
|
message: '删除成功',
|
||||||
|
});
|
||||||
|
loadPatients()
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: response.message || '删除失败',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '删除患者信息失败,请稍后重试',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -337,7 +369,7 @@ onMounted(() => {
|
|||||||
.header {
|
.header {
|
||||||
height: 60px;
|
height: 60px;
|
||||||
/* background: #fff; */
|
/* background: #fff; */
|
||||||
border-bottom: 1px solid #e4e7ed;
|
border-bottom: 1px solid #434343;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -352,15 +384,23 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
width: 40px;
|
/* width: 40px;
|
||||||
height: 40px;
|
height: 40px; */
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.system-logo {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #136166;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.system-title {
|
.system-title {
|
||||||
font-size: 20px;
|
font-size: 18px;
|
||||||
font-weight: 600;
|
color: #AAAAAA;
|
||||||
color: #fff;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,8 +502,8 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.patient-section {
|
.patient-section {
|
||||||
width: calc(100% - 420px);
|
width: calc(100% - 500px);
|
||||||
background: rgb(51,51,51);
|
background: rgb(51, 51, 51);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
@ -542,19 +582,21 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.patient-detail {
|
.patient-detail {
|
||||||
width: 400px;
|
width: 500px;
|
||||||
/* background: #fff; */
|
/* background: #fff; */
|
||||||
|
|
||||||
}
|
}
|
||||||
.patient-detail-box{
|
|
||||||
background: rgb(51,51,51);
|
.patient-detail-box {
|
||||||
|
background: rgb(51, 51, 51);
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
color:#fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-header {
|
.detail-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -602,6 +644,7 @@ onMounted(() => {
|
|||||||
/* display: flex;
|
/* display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px; */
|
gap: 12px; */
|
||||||
|
margin-top: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-btn {
|
.action-btn {
|
||||||
@ -627,7 +670,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.no-selection {
|
.no-selection {
|
||||||
width: 400px;
|
width: 500px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -642,90 +685,147 @@ onMounted(() => {
|
|||||||
|
|
||||||
|
|
||||||
.module-title {
|
.module-title {
|
||||||
|
width: 120px;
|
||||||
|
display: flex;
|
||||||
width: 120px;
|
align-items: center;
|
||||||
display: flex;
|
justify-content: center;
|
||||||
align-items: center;
|
border: 2px solid #ffffff;
|
||||||
justify-content: center;
|
border-image: linear-gradient(to right, rgb(245, 173, 7), rgb(160, 5, 216)) 1;
|
||||||
border: 2px solid #ffffff;
|
border-radius: 20px;
|
||||||
border-image: linear-gradient(to right, rgb(245, 173, 7), rgb(160, 5, 216)) 1;
|
padding: 1px 10px;
|
||||||
border-radius: 20px;
|
font-size: 16px;
|
||||||
padding: 1px 10px ;
|
font-weight: bold;
|
||||||
|
color: #ffffff;
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-input__wrapper) {
|
:deep(.el-input__wrapper) {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
}
|
}
|
||||||
.basic-info-box{
|
|
||||||
|
.basic-info-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.basic-info-content{
|
|
||||||
|
.basic-info-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.basic-info-text{
|
|
||||||
|
.basic-info-text {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
}
|
}
|
||||||
.basic-info-textcolor{
|
|
||||||
color: rgb(48,205,223);
|
.basic-info-textcolor {
|
||||||
|
color: rgb(48, 205, 223);
|
||||||
padding-bottom: 8px;
|
padding-bottom: 8px;
|
||||||
}
|
}
|
||||||
.action-view-buttons{
|
|
||||||
height: 100px;
|
.action-view-buttons {
|
||||||
line-height:100px ;
|
height: 70px;
|
||||||
|
line-height: 70px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: linear-gradient(to right, #e930aa, rgb(160, 5, 216));
|
background: linear-gradient(to right, #e930aa, rgb(160, 5, 216));
|
||||||
font-size: 40px;
|
font-size: 35px;
|
||||||
color: #FFFFFF;
|
color: #FFFFFF;
|
||||||
border-radius:50px ;
|
border-radius: 50px;
|
||||||
margin-top: 20px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-dashboard-top {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px 20px 0px;
|
||||||
|
gap: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-dashboard-top-title {
|
||||||
|
font-family: 'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 18px;
|
||||||
|
width: calc(100% - 500px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-dashboard-top-info {
|
||||||
|
display: flex;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-family: 'Arial Normal', 'Arial', sans-serif;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.dashboard-container.dashboard-container-home .el-table {
|
||||||
.dashboard-container.dashboard-container-home .el-table{
|
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table tr{
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table tr {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table thead.is-group th.el-table__cell{
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table thead.is-group th.el-table__cell {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .cell{
|
|
||||||
|
.dashboard-container.dashboard-container-home .cell {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell{
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table--enable-row-hover .el-table__body tr:hover>td.el-table__cell {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table th.el-table__cell.is-leaf{
|
|
||||||
background-color: rgb(70, 70,70 ) !important;
|
.dashboard-container.dashboard-container-home .el-table th.el-table__cell.is-leaf {
|
||||||
|
background-color: rgb(70, 70, 70) !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table td.el-table__cell{
|
|
||||||
background-color: rgb(0, 0,0 ) !important;
|
.dashboard-container.dashboard-container-home .el-table td.el-table__cell {
|
||||||
|
background-color: rgb(0, 0, 0) !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
.el-table--border .el-table__cell{
|
|
||||||
|
.el-table--border .el-table__cell {
|
||||||
border-right: transparent !important;
|
border-right: transparent !important;
|
||||||
}
|
}
|
||||||
.dashboard-container.dashboard-container-home .el-table__body tr.current-row>td.el-table__cell{
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table__body tr.current-row>td.el-table__cell {
|
||||||
background-color: rgb(121, 121, 121) !important;
|
background-color: rgb(121, 121, 121) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table--border .el-table__inner-wrapper:after,
|
||||||
|
.el-table--border:after,
|
||||||
|
.el-table--border:before,
|
||||||
|
.el-table__inner-wrapper:before {
|
||||||
|
background-color: #787878;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-table__border-bottom-patch,
|
||||||
|
.el-table__border-left-patch {
|
||||||
|
background-color: #787878;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-container.dashboard-container-home .el-input__wrapper {
|
||||||
|
box-shadow: 0 0 0 1px #787878;
|
||||||
|
}
|
||||||
|
.dashboard-container.dashboard-container-home .el-table__cell{
|
||||||
|
border-bottom: 1px solid #787878;
|
||||||
|
}
|
||||||
|
.dashboard-container.dashboard-container-home .el-table__cell{
|
||||||
|
border-bottom: 1px solid #787878;
|
||||||
|
}
|
||||||
|
.dashboard-container.dashboard-container-home .el-table__header th {
|
||||||
|
border-color: #787878;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
166
frontend/src/renderer/src/views/Header.vue
Normal file
166
frontend/src/renderer/src/views/Header.vue
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<template>
|
||||||
|
<div class="header-container">
|
||||||
|
<!-- 顶部导航栏 -->
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-left">
|
||||||
|
<div class="system-logo">
|
||||||
|
<img src="@/assets/svg/logo.svg" alt="Logo" class="logo" />
|
||||||
|
</div>
|
||||||
|
<div class="system-title">平衡体态检测系统</div>
|
||||||
|
</div>
|
||||||
|
<div class="header-right">
|
||||||
|
<div class="user-info">
|
||||||
|
<el-avatar :size="40" :src="userInfo.avatar">
|
||||||
|
<el-icon>
|
||||||
|
<User />
|
||||||
|
</el-icon>
|
||||||
|
</el-avatar>
|
||||||
|
<span class="username">{{ userInfo.username }}</span>
|
||||||
|
<el-dropdown @command="handleUserCommand">
|
||||||
|
<el-button link class="user-dropdown">
|
||||||
|
<el-icon>
|
||||||
|
<ArrowDown />
|
||||||
|
</el-icon>
|
||||||
|
</el-button>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item command="profile">个人信息</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="settings">系统设置</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="logout" divided>退出登录</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive, onMounted } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import { useAuthStore } from '../stores/index.js'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const authStore = useAuthStore()
|
||||||
|
const userInfo = reactive({
|
||||||
|
username: '医生',
|
||||||
|
avatar: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const handleUserCommand = (command) => {
|
||||||
|
switch (command) {
|
||||||
|
case 'profile':
|
||||||
|
// 个人信息
|
||||||
|
break
|
||||||
|
case 'settings':
|
||||||
|
// 系统设置
|
||||||
|
break
|
||||||
|
case 'logout':
|
||||||
|
handleLogout()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLogout = async () => {
|
||||||
|
try {
|
||||||
|
await ElMessageBox.confirm('确定要退出登录吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 调用认证状态管理的logout方法清除所有认证信息
|
||||||
|
await authStore.logout()
|
||||||
|
ElMessage.success('已退出登录')
|
||||||
|
// 使用replace而不是push,避免返回按钮回到Dashboard
|
||||||
|
router.replace('/login')
|
||||||
|
} catch {
|
||||||
|
// 用户取消
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
// 从认证状态管理中加载用户信息
|
||||||
|
if (authStore.currentUser) {
|
||||||
|
Object.assign(userInfo, {
|
||||||
|
username: authStore.currentUser.username,
|
||||||
|
avatar: authStore.currentUser.avatar || ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.dashboard-container {
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
height: 60px;
|
||||||
|
background: #000000;
|
||||||
|
border-bottom: 1px solid #434343;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 20px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
/* width: 40px;
|
||||||
|
height: 40px; */
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-logo {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #136166;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.system-title {
|
||||||
|
font-size: 18px;
|
||||||
|
color: #AAAAAA;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-dropdown {
|
||||||
|
padding: 0;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
@ -1,225 +1,130 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="patient-create-container">
|
<div class="patient-create-container">
|
||||||
<!-- 顶部导航 -->
|
<Header />
|
||||||
<div class="header">
|
<div class="nav-container">
|
||||||
<div class="header-left">
|
<div class="nav-container-title" @click="goBack">
|
||||||
<el-button link @click="goBack" class="back-btn">
|
<img src="@/assets/svg/goback.svg" alt="">
|
||||||
<el-icon><ArrowLeft /></el-icon>
|
<div style="margin-left: 20px;">
|
||||||
返回
|
建档页
|
||||||
</el-button>
|
</div>
|
||||||
<h1 class="page-title">新建患者档案</h1>
|
</div>
|
||||||
|
<div class="nav-container-info">
|
||||||
|
<div>测试时间:2025-08-03 17:13:18<span></span></div>
|
||||||
|
<div style="margin-left: 15px;">测试医生:<span>李医生</span></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 表单内容 -->
|
<!-- 表单内容 -->
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<el-form
|
<el-form ref="patientFormRef" :model="patientForm" :rules="formRules" label-width="120px" class="patient-form">
|
||||||
ref="patientFormRef"
|
|
||||||
:model="patientForm"
|
|
||||||
:rules="formRules"
|
|
||||||
label-width="120px"
|
|
||||||
class="patient-form"
|
|
||||||
>
|
|
||||||
<div class="form-section">
|
<div class="form-section">
|
||||||
<h3 class="section-title">基本信息</h3>
|
<!-- <h3 class="section-title">基本信息</h3> -->
|
||||||
|
<div class="section-title">基本信息</div>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="测试者ID" prop="testerId">
|
||||||
|
<el-input v-model="patientForm.id" disabled placeholder="请输入测试者ID" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
|
||||||
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="姓名" prop="name" required>
|
<el-form-item label="姓名" prop="name" required>
|
||||||
<el-input
|
<el-input v-model="patientForm.name" placeholder="请输入" clearable />
|
||||||
v-model="patientForm.name"
|
|
||||||
placeholder="请输入患者姓名"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="性别" prop="gender" required>
|
<el-form-item label="性别" prop="gender" required>
|
||||||
<el-radio-group v-model="patientForm.gender">
|
<el-select v-model="patientForm.gender" placeholder="请选择">
|
||||||
<el-radio label="男">男</el-radio>
|
<el-option label="男" value="男" />
|
||||||
<el-radio label="女">女</el-radio>
|
<el-option label="女" value="女" />
|
||||||
</el-radio-group>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="出生日期" prop="birthDate" required>
|
<el-form-item label="出生日期" prop="birth_date" required>
|
||||||
<el-date-picker
|
<el-date-picker v-model="patientForm.birth_date" type="date" placeholder="请选择" style="width: 100%"
|
||||||
v-model="patientForm.birthDate"
|
@change="calculateAgeres" />
|
||||||
type="date"
|
|
||||||
placeholder="选择出生日期"
|
|
||||||
style="width: 100%"
|
|
||||||
@change="calculateAge"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="年龄">
|
<el-form-item label="年龄">
|
||||||
<el-input
|
<el-input v-model="calculatedAge" placeholder="自动计算" readonly suffix-icon="Calendar" />
|
||||||
v-model="calculatedAge"
|
</el-form-item>
|
||||||
placeholder="自动计算"
|
</el-col>
|
||||||
readonly
|
<el-col :span="12">
|
||||||
suffix-icon="Calendar"
|
<el-form-item label="民族" prop="nationality">
|
||||||
/>
|
<el-select v-model="patientForm.nationality" placeholder="请选择">
|
||||||
|
<el-option v-for="item in nationalityOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="长期居住地" prop="residence">
|
||||||
|
<el-select v-model="patientForm.residence" placeholder="请选择">
|
||||||
|
<el-option v-for="item in residenceOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="身高" prop="height" required>
|
<el-form-item label="身高" prop="height" required>
|
||||||
<el-input
|
<el-input v-model="patientForm.height" placeholder="请输入" clearable>
|
||||||
v-model="patientForm.height"
|
|
||||||
placeholder="请输入身高"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<template #suffix>cm</template>
|
<template #suffix>cm</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="体重" prop="weight" required>
|
<el-form-item label="体重" prop="weight" required>
|
||||||
<el-input
|
<el-input v-model="patientForm.weight" placeholder="请输入" clearable>
|
||||||
v-model="patientForm.weight"
|
|
||||||
placeholder="请输入体重"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<template #suffix>kg</template>
|
<template #suffix>kg</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-section">
|
|
||||||
<h3 class="section-title">联系信息</h3>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="联系电话" prop="phone" required>
|
<el-form-item label="鞋码" prop="shoe_size">
|
||||||
<el-input
|
<el-input v-model="patientForm.shoe_size" placeholder="请输入" clearable />
|
||||||
v-model="patientForm.phone"
|
|
||||||
placeholder="请输入联系电话"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="紧急联系人">
|
|
||||||
<el-input
|
</el-col>
|
||||||
v-model="patientForm.emergencyContact"
|
<el-col :span="12">
|
||||||
placeholder="请输入紧急联系人"
|
<el-form-item label="电话号码" prop="phone" required>
|
||||||
clearable
|
<el-input v-model="patientForm.phone" placeholder="请输入" clearable />
|
||||||
/>
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="电子邮箱" prop="email">
|
||||||
|
<el-input v-model="patientForm.email" placeholder="请输入" clearable />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="职业" prop="occupation">
|
||||||
|
<el-select v-model="patientForm.occupation" placeholder="请选择">
|
||||||
|
<el-option v-for="item in occupationOptions" :key="item.value" :label="item.label"
|
||||||
|
:value="item.value" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="单位" prop="workplace">
|
||||||
|
<el-input v-model="patientForm.workplace" placeholder="请输入" clearable />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="紧急联系电话">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.emergencyPhone"
|
|
||||||
placeholder="请输入紧急联系电话"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="身份证号">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.idCard"
|
|
||||||
placeholder="请输入身份证号"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="鞋码">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.shoeSize"
|
|
||||||
placeholder="请输入鞋码"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-form-item label="地址">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.address"
|
|
||||||
placeholder="请输入详细地址"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-section">
|
|
||||||
<h3 class="section-title">医疗信息</h3>
|
|
||||||
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="主治医生">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.doctor"
|
|
||||||
placeholder="请输入主治医生"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="病历号">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.medicalRecordNumber"
|
|
||||||
placeholder="请输入病历号"
|
|
||||||
clearable
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<el-form-item label="既往病史">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.medicalHistory"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入既往病史"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="过敏史">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.allergies"
|
|
||||||
type="textarea"
|
|
||||||
:rows="2"
|
|
||||||
placeholder="请输入过敏史"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="备注">
|
|
||||||
<el-input
|
|
||||||
v-model="patientForm.notes"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请输入其他备注信息"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 底部操作按钮 -->
|
<!-- 底部操作按钮 -->
|
||||||
<div class="footer-actions">
|
<div class="footer-actions">
|
||||||
<el-button size="large" @click="handleCancel">退出</el-button>
|
<el-button @click="handleCancel">退出</el-button>
|
||||||
<el-button type="primary" size="large" :loading="saveLoading" @click="handleSave">
|
<el-button type="primary" :loading="saveLoading" @click="handleSave">
|
||||||
保存
|
保存
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button type="success" size="large" :loading="saveAndDetectLoading" @click="handleSaveAndDetect">
|
<el-button type="success" :loading="saveAndDetectLoading" @click="handleSaveAndDetect">
|
||||||
保存并开始检测
|
保存并开始检测
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
@ -231,6 +136,7 @@ import { ref, reactive, computed } from 'vue'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
import { patientAPI } from '../services/api.js'
|
import { patientAPI } from '../services/api.js'
|
||||||
|
import Header from '@/views/Header.vue'
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -243,37 +149,29 @@ const saveAndDetectLoading = ref(false)
|
|||||||
|
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const patientForm = reactive({
|
const patientForm = reactive({
|
||||||
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
gender: '',
|
gender: '',
|
||||||
birthDate: '',
|
birth_date: '',
|
||||||
|
nationality: '',
|
||||||
|
residence: '',
|
||||||
height: '',
|
height: '',
|
||||||
weight: '',
|
weight: '',
|
||||||
|
shoe_size: '',
|
||||||
phone: '',
|
phone: '',
|
||||||
emergencyContact: '',
|
occupation: '',
|
||||||
emergencyPhone: '',
|
workplace: '',
|
||||||
idCard: '',
|
email: ''
|
||||||
address: '',
|
|
||||||
shoeSize: '',
|
|
||||||
doctor: '',
|
|
||||||
medicalRecordNumber: '',
|
|
||||||
medicalHistory: '',
|
|
||||||
allergies: '',
|
|
||||||
notes: ''
|
|
||||||
})
|
})
|
||||||
|
const occupationOptions = ref([
|
||||||
// 计算年龄
|
{ label: '学生', value: '学生' }
|
||||||
const calculatedAge = computed(() => {
|
])
|
||||||
if (!patientForm.birthDate) return ''
|
const residenceOptions = ref([
|
||||||
const today = new Date()
|
{ label: '北京', value: '北京' }
|
||||||
const birthDate = new Date(patientForm.birthDate)
|
])
|
||||||
let age = today.getFullYear() - birthDate.getFullYear()
|
const nationalityOptions = ref([
|
||||||
const monthDiff = today.getMonth() - birthDate.getMonth()
|
{ label: '汉族', value: '汉族' }
|
||||||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
])
|
||||||
age--
|
|
||||||
}
|
|
||||||
return age + '岁'
|
|
||||||
})
|
|
||||||
|
|
||||||
// 表单验证规则
|
// 表单验证规则
|
||||||
const formRules = {
|
const formRules = {
|
||||||
name: [
|
name: [
|
||||||
@ -304,15 +202,23 @@ const formRules = {
|
|||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
router.go(-1)
|
router.go(-1)
|
||||||
}
|
}
|
||||||
|
const calculatedAge = ref('')
|
||||||
const calculateAge = () => {
|
// 实现年龄计算方法 calculateAgeres
|
||||||
// 年龄通过计算属性自动计算
|
const calculateAgeres = (date) => {
|
||||||
|
if (!date) return '0'
|
||||||
|
const today = new Date()
|
||||||
|
const birthDate = new Date(date)
|
||||||
|
let age = today.getFullYear() - birthDate.getFullYear()
|
||||||
|
const monthDiff = today.getMonth() - birthDate.getMonth()
|
||||||
|
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||||
|
age--
|
||||||
|
}
|
||||||
|
calculatedAge.value = age
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCancel = async () => {
|
const handleCancel = async () => {
|
||||||
// 检查是否有未保存的数据
|
// 检查是否有未保存的数据
|
||||||
const hasData = Object.values(patientForm).some(value => value !== '')
|
const hasData = Object.values(patientForm).some(value => value !== '')
|
||||||
|
|
||||||
if (hasData) {
|
if (hasData) {
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
@ -345,18 +251,22 @@ const validateForm = async () => {
|
|||||||
|
|
||||||
const savePatient = async () => {
|
const savePatient = async () => {
|
||||||
const patientData = {
|
const patientData = {
|
||||||
|
id: patientForm.id,
|
||||||
name: patientForm.name,
|
name: patientForm.name,
|
||||||
gender: patientForm.gender,
|
gender: patientForm.gender,
|
||||||
age: calculatedAge.value.replace('岁', ''),
|
age: calculatedAge.value,
|
||||||
birth_date: patientForm.birthDate,
|
birth_date: patientForm.birth_date,
|
||||||
height: patientForm.height,
|
height: patientForm.height,
|
||||||
weight: patientForm.weight,
|
weight: patientForm.weight,
|
||||||
|
shoe_size: patientForm.shoe_size,
|
||||||
phone: patientForm.phone,
|
phone: patientForm.phone,
|
||||||
shoe_size: patientForm.shoeSize,
|
occupation: patientForm.occupation,
|
||||||
medical_history: patientForm.medicalHistory,
|
email: patientForm.email,
|
||||||
notes: patientForm.notes
|
nationality: patientForm.nationality,
|
||||||
|
residence: patientForm.residence,
|
||||||
|
workplace: patientForm.workplace
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await patientAPI.create(patientData)
|
const response = await patientAPI.create(patientData)
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
@ -372,7 +282,7 @@ const savePatient = async () => {
|
|||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
if (!(await validateForm())) return
|
if (!(await validateForm())) return
|
||||||
|
|
||||||
saveLoading.value = true
|
saveLoading.value = true
|
||||||
try {
|
try {
|
||||||
await savePatient()
|
await savePatient()
|
||||||
@ -387,7 +297,7 @@ const handleSave = async () => {
|
|||||||
|
|
||||||
const handleSaveAndDetect = async () => {
|
const handleSaveAndDetect = async () => {
|
||||||
if (!(await validateForm())) return
|
if (!(await validateForm())) return
|
||||||
|
|
||||||
saveAndDetectLoading.value = true
|
saveAndDetectLoading.value = true
|
||||||
try {
|
try {
|
||||||
const patient = await savePatient()
|
const patient = await savePatient()
|
||||||
@ -406,23 +316,31 @@ const handleSaveAndDetect = async () => {
|
|||||||
height: 100vh;
|
height: 100vh;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: #f5f7fa;
|
background: #000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.nav-container {
|
||||||
height: 60px;
|
|
||||||
background: #fff;
|
|
||||||
border-bottom: 1px solid #e4e7ed;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
width: 100%;
|
||||||
padding: 0 20px;
|
padding: 15px 20px 0px;
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
gap: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-left {
|
.nav-container-title {
|
||||||
|
font-family: 'Arial Negreta', 'Arial Normal', 'Arial', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 18px;
|
||||||
|
width: calc(100% - 500px);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
}
|
||||||
gap: 15px;
|
|
||||||
|
.nav-container-info {
|
||||||
|
display: flex;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-family: 'Arial Normal', 'Arial', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.back-btn {
|
.back-btn {
|
||||||
@ -447,13 +365,14 @@ const handleSaveAndDetect = async () => {
|
|||||||
.form-container {
|
.form-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
padding: 20px;
|
padding: 20px 20px 0px;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.patient-form {
|
.patient-form {
|
||||||
max-width: 800px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
background: #fff;
|
background: #333333;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 30px;
|
padding: 30px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
@ -468,18 +387,24 @@ const handleSaveAndDetect = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.section-title {
|
.section-title {
|
||||||
|
width: 120px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: 2px solid #ffffff;
|
||||||
|
border-image: linear-gradient(to right, rgb(245, 173, 7), rgb(160, 5, 216)) 1;
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 1px 10px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
font-weight: 600;
|
font-weight: bold;
|
||||||
color: #2c3e50;
|
color: #ffffff;
|
||||||
margin: 0 0 20px 0;
|
margin-bottom: 20px;
|
||||||
padding-bottom: 10px;
|
|
||||||
border-bottom: 2px solid #e4e7ed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-actions {
|
.footer-actions {
|
||||||
height: 80px;
|
height: 142px;
|
||||||
background: #fff;
|
background: #000000;
|
||||||
border-top: 1px solid #e4e7ed;
|
/* border-top: 1px solid #e4e7ed; */
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -487,12 +412,14 @@ const handleSaveAndDetect = async () => {
|
|||||||
padding: 0 20px;
|
padding: 0 20px;
|
||||||
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
:deep(.footer-actions .el-button){
|
||||||
.footer-actions .el-button {
|
background: linear-gradient(to right,#F135A6,#A005D8,#A005D8);
|
||||||
min-width: 120px;
|
border: none;
|
||||||
height: 40px;
|
color: #ffffff;
|
||||||
font-size: 16px;
|
height: 60px;
|
||||||
font-weight: 600;
|
width: 320px;
|
||||||
|
border-radius: 50px;
|
||||||
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-form-item__label) {
|
:deep(.el-form-item__label) {
|
||||||
@ -531,4 +458,72 @@ const handleSaveAndDetect = async () => {
|
|||||||
color: #f56c6c;
|
color: #f56c6c;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
background-color: rgba(51, 51, 51, 1);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: rgba(127, 127, 127, 1);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select__wrapper) {
|
||||||
|
background-color: rgba(51, 51, 51, 1);
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: rgba(127, 127, 127, 1);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-form-item__label) {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: '苹方 粗体', '苹方 中等', '苹方', sans-serif;
|
||||||
|
font-weight: 700;
|
||||||
|
font-style: normal;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-col-12) {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__inner) {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-select__placeholder) {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input.is-disabled .el-input__wrapper) {
|
||||||
|
background-color: rgba(127, 127, 127, 1);
|
||||||
|
box-shadow: none;
|
||||||
|
border-width: 1px;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: rgba(215, 215, 215, 1);
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style>
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input-tag__wrapper,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input-tag__wrapper.is-focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input-tag__wrapper:focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input-tag__wrapper:hover,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input__wrapper,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input__wrapper.is-focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input__wrapper:focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-input__wrapper:hover,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-select__wrapper,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-select__wrapper.is-focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-select__wrapper:focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-select__wrapper:hover,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-textarea__inner,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-textarea__inner.is-focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-textarea__inner:focus,
|
||||||
|
.el-form-item.is-error .el-form-item__content .el-textarea__inner:hover {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #f56c6c;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user