fix: 优化健康咨询模块员工端与管理端页面原型

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 18:02:59 +08:00
co-authored by Claude Opus 4.6
parent f4a368ecc8
commit 1f528faa8b
4 changed files with 181 additions and 30 deletions
@@ -107,6 +107,7 @@
.form-label { font-size: 13px; color: #666; margin-bottom: 6px; display: block; }
.form-input { width: 100%; padding: 10px 12px; border: 1.5px solid #e0e0e0; border-radius: 10px; font-size: 14px; outline: none; }
.form-input:focus { border-color: #1677ff; }
.form-label.required::before { content: '*'; color: #ff4d4f; margin-right: 4px; }
.form-section { font-size: 14px; font-weight: 600; color: #333; margin: 18px 0 10px; padding-bottom: 6px; border-bottom: 1px solid #f0f0f0; }
.gender-group { display: flex; gap: 8px; margin-bottom: 14px; }
.gender-btn { flex: 1; padding: 9px; border: 1.5px solid #e0e0e0; border-radius: 10px; font-size: 14px; background: #fff; cursor: pointer; text-align: center; }
@@ -221,16 +222,16 @@
<button class="close-btn" onclick="closeAddPerson()">&times;</button>
</div>
<div class="fullsheet-body">
<div class="form-group"><label class="form-label">姓名</label><input class="form-input" id="fname" placeholder="请输入姓名"></div>
<div class="form-group"><label class="form-label required">姓名</label><input class="form-input" id="fname" placeholder="请输入姓名"></div>
<div class="form-group">
<label class="form-label">性别</label>
<label class="form-label required">性别</label>
<div class="gender-group" data-field="gender">
<div class="gender-btn active" onclick="toggleBtn(this)"></div>
<div class="gender-btn" onclick="toggleBtn(this)"></div>
</div>
</div>
<div class="form-group"><label class="form-label">出生日期</label><input class="form-input" type="date" id="fbirthdate"></div>
<div class="form-group"><label class="form-label">与本人关系</label><input class="form-input" id="frelation" placeholder="如:配偶、朋友等"></div>
<div class="form-group"><label class="form-label required">出生日期</label><input class="form-input" type="date" id="fbirthdate"></div>
<div class="form-group"><label class="form-label required">与本人关系</label><input class="form-input" id="frelation" placeholder="如:配偶、朋友等"></div>
<div class="form-section">生活习惯</div>
<div class="form-group">
<label class="form-label">是否吸烟</label>
@@ -251,7 +252,7 @@
<div class="form-section">身体情况</div>
<div class="form-group" style="display:flex;gap:8px;">
<div style="flex:1"><label class="form-label">身高(cm)</label><input class="form-input" id="fheight" placeholder="170"></div>
<div style="flex:1"><label class="form-label">体重(kg)</label><input class="form-input" id="fweight" placeholder="65"></div>
<div style="flex:1"><label class="form-label ">体重(kg)</label><input class="form-input" id="fweight" placeholder="65"></div>
</div>
<div class="form-group"><label class="form-label">过敏史</label><input class="form-input" id="fallergy" placeholder="如:青霉素过敏"></div>
<div class="form-group"><label class="form-label">遗传史</label><input class="form-input" id="fgenetic" placeholder="如:高血压家族史"></div>
+1 -1
View File
@@ -242,7 +242,7 @@
<div class="modal-overlay" id="endConfirmModal">
<div class="modal-box">
<h3>结束咨询</h3>
<p>确认结束本次咨询吗?结束后将跳转至评价页面。</p>
<p>确认结束本次咨询吗?</p>
<div class="modal-btns">
<!-- [交互] 关闭弹窗继续咨询 -->
<button class="btn-cancel" onclick="closeModal('endConfirmModal')">继续咨询</button>
@@ -284,7 +284,7 @@
咨询人档案
</button>
<!-- [交互] 点击结束当前咨询;已结束时置灰不可点 -->
<button class="btn btn-default btn-sm" id="btnEndConsult" style="color:var(--danger);border-color:var(--danger);">
<button class="btn btn-default btn-sm" id="btnEndConsult" style="color:var(--danger);border-color:var(--danger);" onclick="showEndConfirm()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.2"/><path d="M5 5l4 4M9 5l-4 4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
结束咨询
</button>
@@ -420,6 +420,21 @@
</main>
<!-- 结束咨询确认弹窗 -->
<div class="modal" id="endConfirmModal" onclick="if(event.target===this)closeEndConfirm()">
<div style="background:#fff;border-radius:var(--radius-md);padding:32px 32px 24px;width:380px;box-shadow:0 4px 16px rgba(0,0,0,0.15);text-align:center;">
<div style="width:48px;height:48px;border-radius:50%;background:#FFF1F0;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="#FF4D4F" stroke-width="1.8"/><path d="M12 8v5" stroke="#FF4D4F" stroke-width="1.8" stroke-linecap="round"/><circle cx="12" cy="16" r="1" fill="#FF4D4F"/></svg>
</div>
<div style="font-size:var(--font-lg);font-weight:600;margin-bottom:8px;">确认结束咨询?</div>
<div style="font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:24px;">结束后该对话将不可继续回复,员工将收到咨询结束通知。</div>
<div style="display:flex;gap:12px;justify-content:center;">
<button class="btn btn-default" onclick="closeEndConfirm()" style="min-width:88px;">取消</button>
<button class="btn" onclick="confirmEndConsult()" style="min-width:88px;background:var(--danger);color:#fff;">确认结束</button>
</div>
</div>
</div>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
@@ -600,6 +615,40 @@ function refreshConvList(btn) {
btn.classList.add('spinning');
setTimeout(function(){ btn.classList.remove('spinning'); }, 500);
}
/* 结束咨询确认弹窗 */
function showEndConfirm() {
var status = convStatus[currentConvIdx];
if (status && status.ended) return;
document.getElementById('endConfirmModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeEndConfirm() {
document.getElementById('endConfirmModal').classList.remove('open');
document.body.style.overflow = '';
}
function confirmEndConsult() {
closeEndConfirm();
/* 更新状态 */
convStatus[currentConvIdx].ended = true;
convStatus[currentConvIdx].text = '已结束';
var tag = document.getElementById('chatTag');
tag.textContent = '已结束';
tag.classList.add('chat-header__tag--ended');
var btnEnd = document.getElementById('btnEndConsult');
btnEnd.disabled = true;
btnEnd.style.color = '#bbb';
btnEnd.style.borderColor = '#E8E8E8';
btnEnd.style.cursor = 'not-allowed';
btnEnd.style.background = '#fafafa';
/* 在聊天区追加结束卡片 */
var body = document.getElementById('chatBody');
var now = new Date();
var timeStr = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0') + ' ' + String(now.getHours()).padStart(2,'0') + ':' + String(now.getMinutes()).padStart(2,'0');
var endHtml = '<div class="msg right"><div class="msg__avatar asst">助</div><div class="msg__content"><div class="msg__name">健康小助手</div><div class="end-card"><div class="end-card__icon"><svg viewBox="0 0 24 24" fill="none"><path d="M6 12.5l4 4 8-8" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div><div class="end-card__text">已结束本次咨询</div><div class="end-card__time">' + timeStr + '</div></div><div class="msg__time">' + timeStr.split(' ')[1] + '</div></div></div>';
body.insertAdjacentHTML('beforeend', endHtml);
body.scrollTop = body.scrollHeight;
}
</script>
</body>
</html>
+124 -23
View File
@@ -140,6 +140,15 @@
.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}
.btn-default:hover{color:var(--primary);border-color:var(--primary);}
/* 可搜索下拉 */
.search-select{position:relative;}
.search-select__input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 32px 0 12px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;}
.search-select__input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.search-select__dropdown{position:absolute;top:44px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.1);max-height:220px;overflow-y:auto;z-index:10;display:none;}
.search-select__dropdown.show{display:block;}
.search-select__option{padding:10px 12px;font-size:var(--font-sm);cursor:pointer;transition:background .15s;}
.search-select__option:hover,.search-select__option.active{background:var(--primary-light);color:var(--primary);}
.search-select__empty{padding:10px 12px;font-size:var(--font-sm);color:var(--text-placeholder);text-align:center;}
</style>
</head>
<body>
@@ -197,15 +206,11 @@
<div class="drawer__body">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 选择医院</div>
<select class="form-select" id="hospital-select" onchange="onHospitalChange()">
<option value="">请选择医院</option>
<option value="1">西安交通大学第一附属医院</option>
<option value="2">长庆油田职工医院</option>
<option value="3">陕西省人民医院</option>
<option value="4">西北妇女儿童医院</option>
<option value="5">庆阳市人民医院</option>
<option value="6">延安大学附属医院</option>
</select>
<div class="search-select" id="hospital-search-select">
<input type="text" class="search-select__input" id="hospital-search-input" placeholder="请输入医院名称搜索" autocomplete="off">
<input type="hidden" id="hospital-select-value">
<div class="search-select__dropdown" id="hospital-dropdown"></div>
</div>
</div>
<div class="hospital-info" id="hospital-info">
<div class="hospital-info__item">
@@ -457,14 +462,19 @@ function openDrawer(mode,triggerEl){
var tr=triggerEl.closest('tr');
var cells=tr.querySelectorAll('td');
var name=cells[1].textContent.trim();
var select=document.getElementById('hospital-select');
for(var i=0;i<select.options.length;i++){
if(select.options[i].text===name){select.selectedIndex=i;break;}
// 找到匹配的医院并设置
for(let key in hospitalData){
if(hospitalData[key].name===name){
document.getElementById('hospital-select-value').value=key;
document.getElementById('hospital-search-input').value=name;
onHospitalChange();
break;
}
}
onHospitalChange();
}else{
title.textContent='新增医院';
document.getElementById('hospital-select').selectedIndex=0;
document.getElementById('hospital-select-value').value='';
document.getElementById('hospital-search-input').value='';
document.getElementById('hospital-info').classList.remove('show');
}
}
@@ -477,9 +487,8 @@ function closeDrawer(){
}
function onHospitalChange(){
const select=document.getElementById('hospital-select');
const value=document.getElementById('hospital-select-value').value;
const info=document.getElementById('hospital-info');
const value=select.value;
if(value && hospitalData[value]){
const data=hospitalData[value];
@@ -491,6 +500,61 @@ function onHospitalChange(){
}
}
// 可搜索下拉逻辑
(function(){
const input=document.getElementById('hospital-search-input');
const dropdown=document.getElementById('hospital-dropdown');
const hiddenInput=document.getElementById('hospital-select-value');
function renderOptions(keyword){
dropdown.innerHTML='';
const kw=keyword.trim().toLowerCase();
let hasMatch=false;
for(let key in hospitalData){
const name=hospitalData[key].name;
if(!kw || name.toLowerCase().includes(kw)){
hasMatch=true;
const opt=document.createElement('div');
opt.className='search-select__option';
if(hiddenInput.value===key) opt.classList.add('active');
opt.textContent=name;
opt.dataset.value=key;
opt.onclick=function(){
hiddenInput.value=key;
input.value=name;
dropdown.classList.remove('show');
onHospitalChange();
};
dropdown.appendChild(opt);
}
}
if(!hasMatch){
const empty=document.createElement('div');
empty.className='search-select__empty';
empty.textContent='无匹配医院';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus',function(){
renderOptions(this.value);
dropdown.classList.add('show');
});
input.addEventListener('input',function(){
hiddenInput.value='';
renderOptions(this.value);
dropdown.classList.add('show');
onHospitalChange();
});
document.addEventListener('click',function(e){
if(!e.target.closest('#hospital-search-select')){
dropdown.classList.remove('show');
}
});
})();
function initCascadeSelect(){
renderPanel1();
}
@@ -501,11 +565,34 @@ function renderPanel1(){
deptData.forEach(dept=>{
const item=document.createElement('div');
item.className='cascade-item';
if(selectedDepts.has(dept.id)){
item.classList.add('active');
}
item.innerHTML=`
<input type="checkbox" class="cascade-item__checkbox" ${selectedDepts.has(dept.id)?'checked':''}>
<label class="cascade-item__label">${dept.name}</label>
<span class="cascade-item__arrow"></span>
`;
item.onclick=()=>renderPanel2(dept);
const checkbox=item.querySelector('input[type="checkbox"]');
checkbox.onclick=(e)=>{
e.stopPropagation();
if(checkbox.checked){
selectedDepts.add(dept.id);
item.classList.add('active');
}else{
selectedDepts.delete(dept.id);
item.classList.remove('active');
}
updateSelectedTags();
};
item.querySelector('.cascade-item__label').onclick=(e)=>{
e.stopPropagation();
renderPanel2(dept);
};
item.querySelector('.cascade-item__arrow').onclick=(e)=>{
e.stopPropagation();
renderPanel2(dept);
};
panel.appendChild(item);
});
}
@@ -549,11 +636,18 @@ function updateSelectedTags(){
selectedDepts.forEach(deptId=>{
let deptName='';
for(let category of deptData){
const found=category.children.find(c=>c.id===deptId);
if(found){
deptName=found.name;
break;
// 先查一级科室
const topLevel=deptData.find(d=>d.id===deptId);
if(topLevel){
deptName=topLevel.name;
}else{
// 再查二级科室
for(let category of deptData){
const found=category.children.find(c=>c.id===deptId);
if(found){
deptName=found.name;
break;
}
}
}
@@ -572,7 +666,14 @@ function updateSelectedTags(){
function removeTag(deptId){
selectedDepts.delete(deptId);
updateSelectedTags();
renderPanel2(deptData.find(d=>d.children.some(c=>c.id===deptId)));
// 判断是一级还是二级科室,刷新对应面板
const topLevel=deptData.find(d=>d.id===deptId);
if(topLevel){
renderPanel1();
}else{
const parent=deptData.find(d=>d.children.some(c=>c.id===deptId));
if(parent) renderPanel2(parent);
}
}
</script>
</body>