3.13提交
This commit is contained in:
parent
4e3a30b863
commit
4042df6762
@ -1709,7 +1709,7 @@
|
||||
"list": [
|
||||
{
|
||||
"name": "",
|
||||
"path": "pages_app/newsList/newsList",
|
||||
"path": "pages_app/patientMsg/patientMsg",
|
||||
"query": ""
|
||||
}
|
||||
]
|
||||
|
||||
@ -33,10 +33,11 @@
|
||||
:lower-threshold="100"
|
||||
>
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="recordList.length === 0 && !loading">
|
||||
<empty v-if="recordList.length === 0 && !loading" :emptyDesc="'您暂未添加病情记录'"></empty>
|
||||
<!-- <view class="empty-state" v-if="recordList.length === 0 && !loading">
|
||||
<text class="empty-text">暂无病情记录</text>
|
||||
<button class="add-first-btn" @click="addRecord">添加第一条记录</button>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 时间线容器 -->
|
||||
<view class="timeline-container" v-else>
|
||||
@ -108,6 +109,7 @@ import { onShow, onLoad } from '@dcloudio/uni-app'
|
||||
import navBar from '@/components/navBar/navBar.vue'
|
||||
import api from '@/api/api.js'
|
||||
import docUrl from '@/utils/docUrl.js'
|
||||
import empty from '@/components/empty/empty.vue'
|
||||
|
||||
const patientUuid = ref('')
|
||||
const getRecordList = (isRefresh = false) => {
|
||||
@ -200,7 +202,7 @@ const goBack = () => {
|
||||
const addRecord = () => {
|
||||
// 跳转到添加记录页面
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/addRecord/addRecord?patientUuid=' + patientUuid.value
|
||||
url: '/pages_app/caseRecord/caseRecord?patientUuid=' + patientUuid.value
|
||||
})
|
||||
}
|
||||
|
||||
@ -396,7 +398,7 @@ onMounted(() => {
|
||||
height: 200rpx;
|
||||
border-radius: 12rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
|
||||
}
|
||||
|
||||
.content-image {
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
class="description-input"
|
||||
v-model="des"
|
||||
placeholder="请输入患者病情"
|
||||
:adjust-position="false"
|
||||
></textarea>
|
||||
</view>
|
||||
</view>
|
||||
@ -347,7 +348,7 @@ const saveRecord = () => {
|
||||
bottom:150rpx;
|
||||
z-index:1;
|
||||
overflow-y: scroll;
|
||||
padding: 30rpx;
|
||||
padding:0 30rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
<!-- 顶部导航栏 -->
|
||||
<navBar :title="'意见反馈'"></navBar>
|
||||
<navBar :title="'投诉反馈'"></navBar>
|
||||
|
||||
<!-- 反馈输入区域 -->
|
||||
<view class="feedback-input-container">
|
||||
@ -14,6 +14,7 @@
|
||||
v-model="feedbackText"
|
||||
:maxlength="200"
|
||||
placeholder="尊敬的医生您好,若在交流过程中发现患者发布不适当内容,请您及时填写相关信息,我们将第一时间处理,谢谢您的支持。"
|
||||
:adjust-position="false"
|
||||
@input="onInput"
|
||||
></textarea>
|
||||
<!-- <view class="voice-button" @click="toggleVoiceInput">
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<view class="note-box">
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" />
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" :adjust-position="false"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 底部删除按钮 -->
|
||||
|
||||
@ -38,8 +38,8 @@
|
||||
<!-- 已选中的成员 -->
|
||||
<view class="selected-members" v-if="members.length > 0">
|
||||
<view class="selected-item" v-for="(m, idx) in members" :key="m.uuid || idx">
|
||||
<image class="selected-avatar" :src="docUrl + (m.photo || '')" mode="aspectFill" />
|
||||
<text class="selected-name">{{ m.realName || '未知' }}</text>
|
||||
<image class="selected-avatar" :src="getMemberAvatar(m)" mode="aspectFill" @error="handleMemberAvatarError(m)" />
|
||||
<text class="selected-name">{{ m.nickname || m.realName }}</text>
|
||||
<view class="remove-selected" @click="removeMember(idx)">
|
||||
<text class="remove-text">——</text>
|
||||
<!-- <up-icon name="minus" size="43rpx" color="#fff" bold /> -->
|
||||
@ -68,11 +68,33 @@
|
||||
import delImg from "@/static/iv_delete.png"
|
||||
import addImg from "@/static/addpatient.png"
|
||||
import api from '@/api/api.js'
|
||||
import defaultImg from "@/static/default.png"
|
||||
import unidialog from '@/components/dialog/dialog.vue'
|
||||
const groupUuid = ref('')
|
||||
const groupName = ref('')
|
||||
const members = ref([])
|
||||
const visible = ref(false)
|
||||
const avatarErrorMap = ref({})
|
||||
const getAvatarKey = (member = {}) => String(member.uuid || member.id || member.realName || '')
|
||||
const normalizeAvatarUrl = (photo) => {
|
||||
const raw = String(photo || '').trim()
|
||||
if (!raw) return defaultImg
|
||||
if (/^https?:\/\//i.test(raw)) return raw
|
||||
return `${docUrl}${raw}`
|
||||
}
|
||||
const getMemberAvatar = (member = {}) => {
|
||||
const key = getAvatarKey(member)
|
||||
if (key && avatarErrorMap.value[key]) return defaultImg
|
||||
return normalizeAvatarUrl(member.photo)
|
||||
}
|
||||
const handleMemberAvatarError = (member) => {
|
||||
const key = getAvatarKey(member)
|
||||
if (!key) return
|
||||
avatarErrorMap.value = {
|
||||
...avatarErrorMap.value,
|
||||
[key]: true
|
||||
}
|
||||
}
|
||||
const confirmDelete = () => {
|
||||
deleteGroup();
|
||||
}
|
||||
@ -186,6 +208,7 @@
|
||||
})
|
||||
}
|
||||
const patientListByGroup = async () => {
|
||||
avatarErrorMap.value = {}
|
||||
const res = await api.patientListByGroup({
|
||||
group_uuid: groupUuid.value,
|
||||
list_sort:0
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
placeholder="请依据患者的个人信息、疾病资料及患者所咨询的问题详细解答患者的问题(信息仅提问患者及医生可见,最多输入300个字)"
|
||||
placeholder-class="ph"
|
||||
auto-height
|
||||
:adjust-position="false"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<view class="history-section" v-if="historyList.length > 0">
|
||||
<view class="section-title">申请记录(近一月)</view>
|
||||
<view class="history-list">
|
||||
<view class="history-item" v-for="(item, index) in historyList" :key="index">
|
||||
<view class="history-item" v-for="(item, index) in historyList" :key="index" @click="goPatientDetail(item.patient_uuid,item.status)">
|
||||
<view class="avatar">
|
||||
<up-image v-if="docUrl+item.patient_photo" :src="docUrl + item.patient_photo" radius="10rpx" width="120rpx" height="120rpx"></up-image>
|
||||
|
||||
@ -198,6 +198,15 @@ const getApplyList = async () => { // 申请列表
|
||||
|
||||
});
|
||||
|
||||
const goPatientDetail = (uuid,status) => {
|
||||
|
||||
if(status == 2){
|
||||
navTo({
|
||||
url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}`
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法
|
||||
// 格式化日期
|
||||
const formatDate = (dateString) => {
|
||||
|
||||
@ -13,7 +13,8 @@
|
||||
>
|
||||
<template #right>
|
||||
<view class="nav-right" @click.stop="editPatient">
|
||||
<uni-icons type="compose" size="22" color="#8B2316"></uni-icons>
|
||||
<up-image :src="editImg" width="40rpx" height="40rpx"></up-image>
|
||||
<!-- <uni-icons type="compose" size="22" color="#8B2316"></uni-icons> -->
|
||||
</view>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
@ -24,10 +25,10 @@
|
||||
<image class="avatar" :src="avatarSrc" mode="aspectFill" @error="handleAvatarError"></image>
|
||||
<view class="base-info">
|
||||
<view class="name-row">
|
||||
<text class="name">{{ patientInfo.realName || '未知' }}</text>
|
||||
<text class="name">{{nickname || patientInfo.realName }}</text>
|
||||
<up-image :src="genderIcon" width="36rpx" height="36rpx"></up-image>
|
||||
</view>
|
||||
<view class="line"><text class="label">昵称:</text><text class="value">{{nickname }}</text></view>
|
||||
<view class="line" v-if="nickname"><text class="label">昵称:</text><text class="value">{{ patientInfo.realName || '未知' }}</text></view>
|
||||
<view class="line">
|
||||
<text class="label">年龄:</text><text class="value">{{ patientDetail.age || '未知' }}</text>
|
||||
<text class="sep">|</text>
|
||||
@ -42,9 +43,16 @@
|
||||
|
||||
<!-- 功能分组条目 -->
|
||||
<view class="cell" @click="openGroup" style="margin-top: 20rpx;">
|
||||
<text class="cell-label">备注</text>
|
||||
<view class="cell-right">
|
||||
<text class="hint">{{nickname || '给患者添加备注名'}}</text>
|
||||
<uni-icons type="right" color="#999" size="18"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cell" @click="openGroup" >
|
||||
<text class="cell-label">分组</text>
|
||||
<view class="cell-right">
|
||||
<text class="hint">{{ group.name }}</text>
|
||||
<text class="hint">{{ group.name || '通过分组给患者分类' }}</text>
|
||||
<uni-icons type="right" color="#999" size="18"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@ -58,7 +66,7 @@
|
||||
<view class="cell">
|
||||
<text class="cell-label">电话号码</text>
|
||||
<view class="cell-right">
|
||||
<text class="phone">{{ patientInfo.mobile || '未设置' }}</text>
|
||||
<text class="phone" @click="alertDialog">{{ patientInfo.mobile || '未设置' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -73,12 +81,14 @@
|
||||
<!-- 检查报告 -->
|
||||
<view class="history-section" v-if="patientDetail.patientCase && patientDetail.patientCase.length>0">
|
||||
<view class="section-title">检查报告</view>
|
||||
<view class="card report-card">
|
||||
<view class="report-item" v-for="item in patientDetail.patientCase" :key="item.diseaseUuid" @click="openCase(item.uuid)">
|
||||
<view class="report-item-title">{{ $u.timeFormat(item.createDate, 'yyyy-mm-dd') }}</view>
|
||||
<view class="report-item-content">{{ item.diseaseName }}</view>
|
||||
<scroll-view class="card report-card-scroll" scroll-x>
|
||||
<view class="report-card">
|
||||
<view class="report-item" v-for="item in patientDetail.patientCase" :key="item.diseaseUuid" @click="openCase(item.uuid)">
|
||||
<view class="report-item-title">{{ $u.timeFormat(item.createDate, 'yyyy-mm-dd') }}</view>
|
||||
<view class="report-item-content">{{ item.diseaseName }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 底部操作 -->
|
||||
@ -97,6 +107,15 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<unidialog
|
||||
:visible="showDialog"
|
||||
@close="showDialog=false"
|
||||
@confirm="confirmDialog"
|
||||
:content="'复制该患者手机号码'"
|
||||
:confirmText="'确定'"
|
||||
:cancelText="'取消'"
|
||||
>
|
||||
</unidialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -111,12 +130,23 @@
|
||||
import manImg from "@/static/new_man_big.png"
|
||||
import womanImg from "@/static/new_woman_big.png"
|
||||
import defaultImg from "@/static/default.png"
|
||||
|
||||
import unidialog from '@/components/dialog/dialog.vue'
|
||||
import editImg from "@/static/edit_patitent.png"
|
||||
const showAllHistory = ref(false);
|
||||
const showDialog = ref(false);
|
||||
const patientDetail = ref({});
|
||||
const patient_uuid = ref('');
|
||||
const note = ref('');
|
||||
const avatarLoadError = ref(false);
|
||||
const confirmDialog = ()=>{
|
||||
showDialog.value = false;
|
||||
uni.setClipboardData({
|
||||
data: patientInfo.value.mobile,
|
||||
success: () => {
|
||||
uni.showToast({ title: '复制成功', icon: 'none' });
|
||||
}
|
||||
})
|
||||
}
|
||||
// 计算属性:患者基本信息
|
||||
const patientInfo = computed(() => {
|
||||
return patientDetail.value.patient || {};
|
||||
@ -164,6 +194,12 @@
|
||||
url:'/pages_app/patientRemark/patientRemark?uuid=' + patientInfo.value.uuid
|
||||
})
|
||||
}
|
||||
const alertDialog = ()=>{
|
||||
|
||||
if(patientInfo.value.mobile){
|
||||
showDialog.value = true;
|
||||
}
|
||||
}
|
||||
const editDesc = ()=> uni.showToast({ title:'编辑描述', icon:'none' })
|
||||
const sendMessage = async()=>{
|
||||
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
|
||||
@ -172,6 +208,8 @@
|
||||
// navTo({
|
||||
// url:'/pages_chat/chat/index'
|
||||
// })
|
||||
console.log(patientInfo.value.realName);
|
||||
console.log(nickname.value);
|
||||
uni.sendNativeEvent('goSendMsg', {
|
||||
msg: {
|
||||
patientuuid: patientInfo.value.uuid,
|
||||
@ -249,15 +287,18 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.report-card-scroll{
|
||||
white-space: nowrap;
|
||||
}
|
||||
.report-card{
|
||||
display: flex;
|
||||
gap: 55rpx;
|
||||
flex-wrap: wrap;
|
||||
display: inline-flex;
|
||||
gap: 24rpx;
|
||||
}
|
||||
.report-item{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rpx;
|
||||
min-width: 260rpx;
|
||||
|
||||
background: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
@ -282,7 +323,7 @@
|
||||
.avatar { width: 140rpx; height: 140rpx; border-radius: 12rpx; margin-right: 20rpx; }
|
||||
.base-info { flex:1; }
|
||||
.name-row { display:flex; align-items:center; margin-bottom: 10rpx; }
|
||||
.name { font-size: 40rpx; color:#222; margin-right: 10rpx;}
|
||||
.name { font-size: 36rpx; color:#222; margin-right: 10rpx;}
|
||||
.line { font-size: 28rpx; color:#666; margin-top: 6rpx; display:flex; align-items:center; }
|
||||
.label { color:#999;white-space: nowrap; }
|
||||
.value { color:#333; }
|
||||
@ -297,7 +338,7 @@
|
||||
.hint { font-size: 28rpx; color:#999; margin-right: 12rpx; }
|
||||
.phone { font-size: 32rpx; color:#b10000; }
|
||||
|
||||
.section-title { padding: 16rpx 30rpx; color:#8B2316; font-size: 30rpx; margin-top: 20rpx; background: #fff;}
|
||||
.section-title { padding: 16rpx 30rpx; color:#8B2316; font-size: 28rpx; margin-top: 20rpx; background: #fff;}
|
||||
.history-card { position: relative; }
|
||||
.history-text { font-size: 28rpx; color:#666; line-height: 1.7; display:block; }
|
||||
.history-text.fold { display:-webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
||||
|
||||
@ -196,7 +196,7 @@ const preprocessGroups = (rawGroups) => {
|
||||
const list = Array.isArray(group.patientList) ? group.patientList : [];
|
||||
list.forEach((patient) => {
|
||||
patient._formattedJoinDate = formatYMD(patient.join_date);
|
||||
patient._displayName = patient.realName || patient.nickname || '-';
|
||||
patient._displayName = patient.nickname || patient.realName ;
|
||||
patient._photoUrl = patient.photo ? `${docUrl}${patient.photo}` : defaultImg;
|
||||
});
|
||||
return {
|
||||
|
||||
@ -96,68 +96,73 @@
|
||||
<view class="patient-list" v-show="activeTab === 'list'">
|
||||
|
||||
<view class="listbox alertContent" v-if="showAlert">
|
||||
<image :src="alertImg" class="alert-img" mode="widthFix"></image>
|
||||
<image :src="delImg" class="del-img" mode="widthFix" @click="hideAlert"></image>
|
||||
<image :src="alertImg" class="alert-img" mode="widthFix"></image>
|
||||
</view>
|
||||
<view class="listbox" v-show="patientList.length>0">
|
||||
<!-- 使用 up-index-list 索引组件,数据动态渲染 -->
|
||||
<up-index-list :index-list="indexList" v-show="loadFinish" >
|
||||
|
||||
<!-- 特殊操作项 -->
|
||||
<template #header>
|
||||
<view class="special-actions" >
|
||||
<view class="action-item" @click="addNewPatient">
|
||||
|
||||
<view class="action-icon new-patient">
|
||||
<up-image :src="newPatientImg" width="60rpx" height="60rpx" ></up-image>
|
||||
</view>
|
||||
<text class="action-text">新的患者<text class="new-patient-count" v-if="applyList.length > 0">(待审核{{ applyList.length }}人)</text></text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
|
||||
<view class="action-item" @click="managePatientGroups">
|
||||
<view class="action-icon group-icon">
|
||||
<view class="grid-icon">
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
<scroll-view
|
||||
class="groups-scroll"
|
||||
scroll-y="true"
|
||||
:scroll-into-view="scrollIntoViewId"
|
||||
:scroll-with-animation="true"
|
||||
v-show="loadFinish"
|
||||
>
|
||||
<view class="special-actions">
|
||||
<view class="action-item" @click="addNewPatient">
|
||||
<view class="action-icon new-patient">
|
||||
<up-image :src="newPatientImg" width="60rpx" height="60rpx"></up-image>
|
||||
</view>
|
||||
<text class="action-text">新的患者<text class="new-patient-count" v-if="applyList.length > 0">(待审核{{ applyList.length }}人)</text></text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<text class="action-text">患者分组 <text class="new-patient-count" v-if="patientList.length > 0">(随访{{ patientList.length }}人)</text></text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-for="group in patientGroups" :key="group.letter" >
|
||||
<up-index-item >
|
||||
<up-index-anchor :text="group.letter" />
|
||||
<view class="group-section">
|
||||
<view class="patient-item" v-for="item in group.items" :key="item.uuid || item.id" @longpress="onPatientItemLongPress(item)">
|
||||
<!-- <template v-if="item.placeholder">
|
||||
<view class="patient-avatar-placeholder">
|
||||
<uni-icons type="person" size="32" color="#ffffff" @click="goPatientDetail(item.uuid)"></uni-icons>
|
||||
</view>
|
||||
</template> -->
|
||||
|
||||
<image class="patient-avatar" :src="item._avatarLoadError ? defaultImg : item.avatarUrl" mode="aspectFill" @error="handlePatientAvatarError(item)" @click.stop="goPatientDetail(item.uuid)"></image>
|
||||
|
||||
<view class="patient-info" >
|
||||
<text class="patient-name">{{ item.realName }}</text>
|
||||
<view class="patient-badge" v-if="item.badge">
|
||||
<text class="badge-text">{{ item.badge }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="patient-status">
|
||||
<uni-icons type="compose" size="20" color="#8B2316" @click.stop="editPatient(item.uuid)"></uni-icons>
|
||||
<text class="follow-date">随访于{{ item.joinDateYMD }}</text>
|
||||
</view>
|
||||
|
||||
<view class="action-item" @click="managePatientGroups">
|
||||
<view class="action-icon group-icon">
|
||||
<view class="grid-icon">
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
<view class="grid-item"></view>
|
||||
</view>
|
||||
</view>
|
||||
</up-index-item>
|
||||
</template>
|
||||
</up-index-list>
|
||||
|
||||
<text class="action-text">患者分组 <text class="new-patient-count" v-if="patientList.length > 0">(随访{{ patientList.length }}人)</text></text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="group-section"
|
||||
v-for="group in patientGroups"
|
||||
:key="group.letter"
|
||||
:id="`anchor-${group.letter}`"
|
||||
>
|
||||
<view class="group-header">{{ group.letter }}</view>
|
||||
<view class="patient-item" v-for="item in group.items" :key="item.uuid || item.id" @longpress="onPatientItemLongPress(item)">
|
||||
<image class="patient-avatar" :src="getPatientAvatar(item)" mode="aspectFill" @error="handlePatientAvatarError(item)" @click.stop="goPatientDetail(item.uuid)"></image>
|
||||
|
||||
<view class="patient-info">
|
||||
<text class="patient-name" @click.stop="goPatientDetail(item.uuid)">{{ item.nickname || item.realName }}</text>
|
||||
<view class="patient-badge" v-if="item.badge">
|
||||
<text class="badge-text">{{ item.badge }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="patient-status">
|
||||
<up-image :src="editImg" class="edit-img" width="40rpx" height="40rpx" @click.stop="editPatient(item.uuid)"></up-image>
|
||||
<text class="follow-date">随访于{{ item.joinDateYMD }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="letter-index" v-if="loadFinish && indexList.length > 0">
|
||||
<view
|
||||
class="letter-item"
|
||||
v-for="letter in indexList"
|
||||
:key="letter"
|
||||
:class="{ active: activeLetter === letter }"
|
||||
@click="onLetterTap(letter)"
|
||||
>{{ letter }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="listbox" v-show="patientList.length === 0">
|
||||
<view class="special-actions" >
|
||||
@ -285,6 +290,7 @@
|
||||
import defaultImg from "@/static/default.png"
|
||||
import newPatientImg from "@/static/new_patient.png"
|
||||
import delImg from "@/static/iv_delete.png"
|
||||
import editImg from "@/static/edit_patitent.png"
|
||||
const patientList = ref([]);
|
||||
const visible = ref(false)
|
||||
const message = ref('')
|
||||
@ -330,7 +336,7 @@
|
||||
const onPatientItemLongPress = (item) => {
|
||||
if (!item || !item.uuid) return
|
||||
selectedPatientUuid.value = item.uuid
|
||||
selectedPatientName.value = item.realName || ''
|
||||
selectedPatientName.value = item.nickname || item.realName
|
||||
message.value = `确认解除[${selectedPatientName.value || '该患者'}]的随访关系?`
|
||||
visible.value = true
|
||||
}
|
||||
@ -351,9 +357,27 @@
|
||||
}
|
||||
visible.value = false
|
||||
}
|
||||
const avatarErrorMap = ref({});
|
||||
const getAvatarKey = (item = {}) => String(item.uuid || item.id || item.realName || item.nickname || '');
|
||||
const normalizeAvatarUrl = (photo) => {
|
||||
const raw = String(photo || '').trim();
|
||||
if (!raw) return defaultImg;
|
||||
if (/^https?:\/\//i.test(raw)) return raw;
|
||||
return `${docUrl}${raw}`;
|
||||
};
|
||||
const getPatientAvatar = (item = {}) => {
|
||||
const key = getAvatarKey(item);
|
||||
if (key && avatarErrorMap.value[key]) return defaultImg;
|
||||
return item.avatarUrl || defaultImg;
|
||||
};
|
||||
const handlePatientAvatarError = (item) => {
|
||||
if (!item) return
|
||||
item._avatarLoadError = true
|
||||
if (!item) return;
|
||||
const key = getAvatarKey(item);
|
||||
if (!key) return;
|
||||
avatarErrorMap.value = {
|
||||
...avatarErrorMap.value,
|
||||
[key]: true
|
||||
};
|
||||
}
|
||||
const goCode = () => {
|
||||
navTo({
|
||||
@ -391,10 +415,8 @@
|
||||
|
||||
// 当前激活的标签
|
||||
const activeTab = ref('message');
|
||||
const letters = ref(['A','C','E','L']);
|
||||
const activeLetter = ref('A');
|
||||
const scrollIntoViewId = ref('');
|
||||
let scrollingByClick = false;
|
||||
|
||||
// 控制添加菜单弹窗显示
|
||||
const showAddMenuFlag = ref(false);
|
||||
@ -402,9 +424,19 @@
|
||||
// 组件实例(用于 selectorQuery 作用域)
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
// up-index-list 索引固定为 26 个大写字母
|
||||
// 索引固定为 A-Z
|
||||
const indexList = ref('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''));
|
||||
const LETTER_ORDER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
|
||||
const sortLetter = (a, b) => {
|
||||
if (a === '#') return 1;
|
||||
if (b === '#') return -1;
|
||||
const ai = LETTER_ORDER.indexOf(a);
|
||||
const bi = LETTER_ORDER.indexOf(b);
|
||||
if (ai === -1 && bi === -1) return String(a).localeCompare(String(b));
|
||||
if (ai === -1) return 1;
|
||||
if (bi === -1) return -1;
|
||||
return ai - bi;
|
||||
};
|
||||
// up-index-list 索引使用实际分组字母,避免索引与锚点数量不一致
|
||||
const indexList = ref([]);
|
||||
// 列表高度(像素):窗口高度 - 顶部导航(rpx转px) - 底部tab(约100rpx->px) - 操作区(约200rpx->px)
|
||||
const groupsListHeight = ref(0);
|
||||
const rpxToPx = (rpx) => {
|
||||
@ -420,10 +452,27 @@
|
||||
// 分组数据(可从接口返回后赋值)
|
||||
const patientGroups = shallowRef([]);
|
||||
|
||||
// 重建索引时保持固定 A-Z
|
||||
// 根据当前分组重建索引(与 up-index-anchor 一一对应)
|
||||
const rebuildIndexList = () => {
|
||||
// 固定 A-Z,不随分组变化
|
||||
indexList.value = patientGroups.value.map(g => g.letter);
|
||||
indexList.value = patientGroups.value
|
||||
.map(g => String(g?.letter || '').toUpperCase())
|
||||
.filter((letter, index, arr) => (letter === '#' || /^[A-Z]$/.test(letter)) && arr.indexOf(letter) === index)
|
||||
.sort(sortLetter);
|
||||
activeLetter.value = indexList.value[0] || '';
|
||||
};
|
||||
const onLetterTap = (letter) => {
|
||||
if (!letter) return;
|
||||
const targetId = `anchor-${letter}`;
|
||||
activeLetter.value = letter;
|
||||
// 点击同一字母时,先清空再回填,确保 scroll-into-view 能再次触发
|
||||
if (scrollIntoViewId.value === targetId) {
|
||||
scrollIntoViewId.value = '';
|
||||
nextTick(() => {
|
||||
scrollIntoViewId.value = targetId;
|
||||
});
|
||||
return;
|
||||
}
|
||||
scrollIntoViewId.value = targetId;
|
||||
};
|
||||
|
||||
// 生成模拟数据
|
||||
@ -448,6 +497,7 @@
|
||||
}
|
||||
// 根据 patientList 构建按拼音首字母的分组
|
||||
const buildGroupsFromPatients = () => {
|
||||
avatarErrorMap.value = {};
|
||||
const map = new Map();
|
||||
|
||||
const source = patientList.value || [];
|
||||
@ -455,15 +505,15 @@
|
||||
const p = source[i] || {};
|
||||
const normalized = {
|
||||
...p,
|
||||
avatarUrl: p.photo ? `${docUrl}${p.photo}` : defaultImg,
|
||||
avatarUrl: normalizeAvatarUrl(p.photo),
|
||||
joinDateYMD: formatYMD(p.join_date)
|
||||
};
|
||||
const first = getFirstLetter(normalized.realName || '');
|
||||
const first = getFirstLetter(normalized.nickname || normalized.realName);
|
||||
const letter = /^[A-Z]$/.test(first) ? first : '#';
|
||||
if (!map.has(letter)) map.set(letter, []);
|
||||
map.get(letter).push(normalized);
|
||||
}
|
||||
const letters = Array.from(map.keys()).sort((a,b) => a.localeCompare(b));
|
||||
const letters = Array.from(map.keys()).sort(sortLetter);
|
||||
patientGroups.value = letters.map(l => ({ letter: l, items: map.get(l) }));
|
||||
rebuildIndexList();
|
||||
if(patientList.value.length==0){
|
||||
@ -1020,18 +1070,12 @@
|
||||
|
||||
// 患者列表样式
|
||||
.patient-list {
|
||||
:deep(.u-index-list__letter){
|
||||
top:50%!important;
|
||||
}
|
||||
:deep(.u-index-list__scroll-view){
|
||||
height:calc(100vh - var(--status-bar-height) - 44px - 103rpx);
|
||||
}
|
||||
// position: fixed;
|
||||
// position: fixed;
|
||||
width: 100%;
|
||||
|
||||
margin-top:calc(var(--status-bar-height) + 44px);
|
||||
height:calc(100vh - var(--status-bar-height) - 44px - 103rpx);
|
||||
overflow-y: scroll;
|
||||
overflow: hidden;
|
||||
|
||||
background-color: #ffffff;
|
||||
|
||||
@ -1039,10 +1083,10 @@
|
||||
|
||||
.listbox{
|
||||
flex:1;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
.groups-scroll {
|
||||
display: none;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.special-actions {
|
||||
@ -1140,7 +1184,7 @@
|
||||
background-color: #e4e4e4;
|
||||
font-size: 36rpx;
|
||||
color: #666666;
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
.patient-item {
|
||||
@ -1156,8 +1200,8 @@
|
||||
|
||||
.patient-avatar,
|
||||
.patient-avatar-placeholder {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-right: 20rpx;
|
||||
display: flex;
|
||||
@ -1199,6 +1243,7 @@
|
||||
flex-direction: column;
|
||||
|
||||
.follow-date {
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-left: 10rpx;
|
||||
@ -1249,6 +1294,10 @@
|
||||
width: 80%;
|
||||
max-width: 400rpx;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
top: 140rpx;
|
||||
z-index: 9999;
|
||||
right: 20rpx;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
@ -1296,7 +1345,7 @@
|
||||
}
|
||||
|
||||
.group-header{
|
||||
text-align: center;
|
||||
text-align: left;
|
||||
background:#eee;
|
||||
color:#333;
|
||||
font-size: 30rpx;
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
<view class="form-block">
|
||||
<view class="label">描述</view>
|
||||
<view class="textarea-wrap">
|
||||
<textarea class="textarea" v-model.trim="note" :placeholder="groupInfo.note || '补充患者关键信息,方便随访患者'" placeholder-class="ph" auto-height maxlength="100"/>
|
||||
<textarea class="textarea" v-model.trim="note" :placeholder="groupInfo.note || '补充患者关键信息,方便随访患者'" placeholder-class="ph" auto-height maxlength="100" :adjust-position="false"/>
|
||||
<view class="textarea-count">已输入{{ noteLength }}/100</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -87,6 +87,7 @@
|
||||
<textarea
|
||||
class="form-textarea"
|
||||
type="text"
|
||||
:adjust-position="false"
|
||||
placeholder="不支持关键字/广泛查询"
|
||||
v-model="literature.literatureName"
|
||||
/>
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
<textarea
|
||||
class="reply-input"
|
||||
v-model="replyText"
|
||||
:adjust-position="false"
|
||||
:placeholder="placeholder"
|
||||
:auto-height="true"
|
||||
:maxlength="maxLength"
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
v-model="followUpContent"
|
||||
placeholder="请输入随访内容"
|
||||
:maxlength="500"
|
||||
:adjust-position="false"
|
||||
auto-height
|
||||
></textarea>
|
||||
</view>
|
||||
@ -80,7 +81,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<u-overlay :show="show">
|
||||
<up-overlay :show="show">
|
||||
<view class="warp">
|
||||
|
||||
<view class="calendarbox">
|
||||
@ -94,11 +95,11 @@
|
||||
<uni-calendar class="uni-calendar--hook" @change="change" @monthSwitch="monthSwitch" />
|
||||
<view class="calendarbottom">
|
||||
<view class="cancel" @click="show=false">取消</view>
|
||||
<view class="ok">确定</view>
|
||||
<view class="ok" @click="confirmDate">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</u-overlay>
|
||||
</up-overlay>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@ -118,6 +119,7 @@
|
||||
const headerYear = ref('');
|
||||
const headerDay = ref('');
|
||||
const patientUuid = ref('');
|
||||
let tempDate=('');
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
@ -138,6 +140,12 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const confirmDate=()=>{
|
||||
selectedDate.value = tempDate;
|
||||
//visits.value[dealIndex.value].date = tempDate.value;
|
||||
show.value=false;
|
||||
}
|
||||
// 提交日程
|
||||
const submitSchedule = () => {
|
||||
if (!selectedPatient.value) {
|
||||
@ -196,7 +204,8 @@
|
||||
headerYear.value = `${y}年`;
|
||||
headerDay.value = `${m}月${dd}日周${w}`;
|
||||
datetime.value = `${y}-${m}-${dd}`;
|
||||
selectedDate.value = `${y}年${m}月${dd}日(星期${w})`;
|
||||
//selectedDate.value = `${y}年${m}月${dd}日(星期${w})`;
|
||||
tempDate= `${y}年${m}月${dd}日(星期${w})`;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -310,19 +310,16 @@
|
||||
}
|
||||
.content {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
|
||||
}
|
||||
.content {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.nav-right { display: flex; align-items: center; }
|
||||
.submit-text { font-size: 32rpx; color: #8B2316; font-weight: 500; }
|
||||
|
||||
.form-section {
|
||||
margin-top: calc(var(--status-bar-height) + 44px);
|
||||
|
||||
// margin-top: 20rpx;
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 30rpx; background: #ffffff; border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<view class="note-box">
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" />
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" :adjust-position="false"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -44,7 +44,7 @@
|
||||
const note = ref('请近日来医院复诊、复查')
|
||||
const idx = ref(0)
|
||||
onLoad((options) => {
|
||||
console.log(options.patient_name==undefined)
|
||||
console.log(options.patient_name)
|
||||
patientName.value =options.patient_name ?decodeURIComponent(options.patient_name):'';
|
||||
console.log(patientName.value)
|
||||
if (options?.note) note.value = decodeURIComponent(options.note)
|
||||
|
||||
@ -203,7 +203,10 @@ onShow(() => {
|
||||
.floating-add-btn { position: fixed; bottom: 140rpx; right: 30rpx; background-color: #8B2316; border-radius: 50%; width: 100rpx; height: 100rpx; display:flex; flex-direction:column; align-items:center; justify-content:center; z-index:999; box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.1); }
|
||||
.floating-add-btn .btn-text{ font-size:20rpx; color:#fff; margin-top:4rpx; }
|
||||
.add-menu-popup { position: fixed; top:0; left:0; right:0; bottom:0; background-color: rgba(0,0,0,0); display:flex; align-items:center; justify-content:center; z-index:1000; }
|
||||
.menu-content { background:#fff; border-radius:20rpx; box-shadow:0 8rpx 24rpx rgba(0,0,0,0.2); width:80%; max-width:400rpx; overflow:hidden; }
|
||||
.menu-content { background:#fff; border-radius:20rpx; box-shadow:0 8rpx 24rpx rgba(0,0,0,0.2); width:80%; max-width:400rpx; overflow:hidden; position: fixed;
|
||||
top: 140rpx;
|
||||
z-index: 9999;
|
||||
right: 20rpx;}
|
||||
.menu-item { display:flex; align-items:center; padding:30rpx 40rpx; border-bottom:1rpx solid #f0f0f0; }
|
||||
.menu-item:last-child{ border-bottom:none; }
|
||||
.menu-text{ font-size:32rpx; color:#333; margin-left:20rpx; }
|
||||
|
||||
@ -34,14 +34,14 @@
|
||||
<view class="bottom-box">
|
||||
<view class="bottom-cell">
|
||||
<image class="bottom-cell-img" :src="readImg" />
|
||||
<text class="bottom-cell-text">{{ readnum }}</text>
|
||||
<text class="bottom-cell-text">{{ fromatNumber(readnum) }}</text>
|
||||
</view>
|
||||
<view class="bottom-cell" @click="toggleAgree">
|
||||
<image
|
||||
class="bottom-cell-img"
|
||||
:src="isAgree == 1 ? likeImg : dislikeImg"
|
||||
/>
|
||||
<text class="bottom-cell-text">{{ agreenum }}</text>
|
||||
<text class="bottom-cell-text">{{ fromatNumber(agreenum) }}</text>
|
||||
</view>
|
||||
<view class="bottom-cell" @click="toggleCollect">
|
||||
<image
|
||||
@ -265,6 +265,13 @@ const getNewsDetail = () => {
|
||||
}
|
||||
});
|
||||
};
|
||||
const fromatNumber = (number) => {
|
||||
if(number < 10000){
|
||||
return number;
|
||||
}else{
|
||||
return (number / 10000).toFixed(1) + 'w';
|
||||
}
|
||||
}
|
||||
const getKePuCollection = () => {
|
||||
api
|
||||
.getKePuCollection({
|
||||
|
||||
@ -23,10 +23,11 @@
|
||||
:placeholder="placeholder"
|
||||
placeholder-class="ph"
|
||||
v-model.trim="content"
|
||||
:adjust-position="false"
|
||||
|
||||
>
|
||||
</input>
|
||||
<textarea v-else v-model.trim="content" :placeholder="placeholderTextArea" placeholder-class="ph" auto-height> </textarea>
|
||||
<textarea v-else v-model.trim="content" :placeholder="placeholderTextArea" placeholder-class="ph" auto-height :adjust-position="false"> </textarea>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
@ -157,6 +157,7 @@
|
||||
<textarea
|
||||
class="form-textarea"
|
||||
type="text"
|
||||
:adjust-position="false"
|
||||
placeholder="不支持关键字/广泛查询"
|
||||
v-model="literature.literatureName"
|
||||
/>
|
||||
|
||||
@ -99,6 +99,7 @@
|
||||
<textarea
|
||||
v-show="!showEmojiInput"
|
||||
:focus="isFocus"
|
||||
:adjust-position="false"
|
||||
class="msg-input-input"
|
||||
:maxlength="-1"
|
||||
:placeholder="
|
||||
|
||||
@ -555,6 +555,7 @@ $red: #D32F2F;
|
||||
}
|
||||
.name{
|
||||
padding:20rpx 28rpx;
|
||||
word-break: break-all;
|
||||
}
|
||||
.phone {
|
||||
word-break: break-all;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
v-model="outpatientInfo"
|
||||
placeholder="请输入门诊信息..."
|
||||
:maxlength="500"
|
||||
:adjust-position="false"
|
||||
:auto-height="true"
|
||||
></textarea>
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">备注信息</text>
|
||||
<textarea class="form-textarea" placeholder="请输入备注信息" v-model="formData.remarks" />
|
||||
<textarea class="form-textarea" placeholder="请输入备注信息" v-model="formData.remarks" :adjust-position="false"/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
@ -52,7 +52,7 @@
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">备注信息</text>
|
||||
<textarea class="form-textarea" placeholder="请输入备注信息" v-model="formData.remarks" />
|
||||
<textarea class="form-textarea" placeholder="请输入备注信息" v-model="formData.remarks" :adjust-position="false"/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
@ -626,7 +626,7 @@ const handlePatientAvatarError = (patient) => {
|
||||
.patient-list-section {
|
||||
top:calc(var(--status-bar-height) + 44px);
|
||||
width:100%;
|
||||
bottom:120rpx; // 预留底部操作栏高度
|
||||
bottom:144rpx; // 预留底部操作栏高度
|
||||
position: fixed;
|
||||
background-color: #ffffff;
|
||||
|
||||
@ -740,14 +740,14 @@ const handlePatientAvatarError = (patient) => {
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
box-shadow: 0 -6rpx 20rpx rgba(0,0,0,0.06);
|
||||
padding: 20rpx 30rpx env(safe-area-inset-bottom);
|
||||
padding:30rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
.align-right{justify-content:flex-end;}
|
||||
|
||||
.clear-btn{
|
||||
width: 100%;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
:maxlength="-1"
|
||||
placeholder="请输入回复内容"
|
||||
auto-height
|
||||
:adjust-position="false"
|
||||
/>
|
||||
<view class="popup-actions">
|
||||
<view class="btn cancel" @click="onCancel">取消</view>
|
||||
|
||||
@ -49,7 +49,7 @@
|
||||
<view class="form-section">
|
||||
<view class="section-title"><text class="title-text">备注</text></view>
|
||||
<view class="remark-box">
|
||||
<textarea v-model="remark" class="remark" maxlength="300" :placeholder="remarkPh"/>
|
||||
<textarea v-model="remark" class="remark" maxlength="300" :placeholder="remarkPh" :adjust-position="false"/>
|
||||
<!-- <view class="voice-btn" @click="recordVoice">🎤</view> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@ -40,6 +40,7 @@
|
||||
v-model="reviewContent"
|
||||
placeholder="在这里提交您对精品课的建议,帮助课程继续优化改进(300字以内)"
|
||||
maxlength="300"
|
||||
:adjust-position="false"
|
||||
:show-confirm-bar="false"
|
||||
></textarea>
|
||||
<view class="word-count">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user