Merge branch 'master' of https://gitea.igandanyiyuan.com/gdxz/uniapp-app
# Conflicts: # pages/my/my.vue
This commit is contained in:
commit
71136a03a6
15
api/api.js
15
api/api.js
@ -556,6 +556,21 @@ const api = {
|
|||||||
toAddNickname(data){
|
toAddNickname(data){
|
||||||
return request('/expertAPI/toAddNickname', data, 'post', false);
|
return request('/expertAPI/toAddNickname', data, 'post', false);
|
||||||
},
|
},
|
||||||
|
caseDetail(data){
|
||||||
|
return request('/expertAPI/caseDetail', data, 'post', false);
|
||||||
|
},
|
||||||
|
conditionRecordList(data){
|
||||||
|
return request('/expertAPI/conditionRecordList', data, 'post', false);
|
||||||
|
},
|
||||||
|
addConditionRecord(data){
|
||||||
|
return request('/expertAPI/addConditionRecord', data, 'post', false);
|
||||||
|
},
|
||||||
|
updateConditionRecord(data){
|
||||||
|
return request('/expertAPI/upConditionRecord', data, 'post', false);
|
||||||
|
},
|
||||||
|
deleteConditionRecord(data){
|
||||||
|
return request('/expertAPI/delConditionRecord', data, 'post', false);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default api
|
export default api
|
||||||
@ -8,14 +8,15 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"description": "",
|
"description": "",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@xkit-yx/im-store-v2": "^0.8.3",
|
||||||
|
"@xkit-yx/utils": "^0.7.2",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"@xkit-yx/im-store-v2": "^0.8.3",
|
|
||||||
"@xkit-yx/utils": "^0.7.2",
|
|
||||||
"mobx": "^6.6.1",
|
|
||||||
"nim-web-sdk-ng": "^10.9.30",
|
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
|
"image-tools": "^1.4.0",
|
||||||
"js-base64": "^3.7.8",
|
"js-base64": "^3.7.8",
|
||||||
"js-md5": "^0.8.3",
|
"js-md5": "^0.8.3",
|
||||||
|
"mobx": "^6.6.1",
|
||||||
|
"nim-web-sdk-ng": "^10.9.30",
|
||||||
"pinyin": "^4.0.0",
|
"pinyin": "^4.0.0",
|
||||||
"uview-plus": "^3.4.73"
|
"uview-plus": "^3.4.73"
|
||||||
}
|
}
|
||||||
|
|||||||
53
pages.json
53
pages.json
@ -606,6 +606,58 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "caseRecord/caseRecord",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "uni-app分页",
|
||||||
|
"app": {
|
||||||
|
"bounce": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "searchPatient/searchPatient",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "uni-app分页",
|
||||||
|
"app": {
|
||||||
|
"bounce": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"path": "visitPlan/visitPlan",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "uni-app分页",
|
||||||
|
"app": {
|
||||||
|
"bounce": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"path": "caseList/caseList",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "uni-app分页",
|
||||||
|
"app": {
|
||||||
|
"bounce": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "checkRecord/checkRecord",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "uni-app分页",
|
||||||
|
"app": {
|
||||||
|
"bounce": "none"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "qikan/qikan",
|
"path": "qikan/qikan",
|
||||||
"style": {
|
"style": {
|
||||||
@ -1011,6 +1063,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"path": "productDetail/productDetail",
|
"path": "productDetail/productDetail",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@ -472,6 +472,11 @@
|
|||||||
url='/pages_course/course/course'
|
url='/pages_course/course/course'
|
||||||
}else if(name=='积分商城'){
|
}else if(name=='积分商城'){
|
||||||
url='/pages_goods/pointMall/pointMall'
|
url='/pages_goods/pointMall/pointMall'
|
||||||
|
}else if(name=='我的福利'){
|
||||||
|
url='/pages_app/myWelfare/myWelfare'
|
||||||
|
}else if(name=='专题e站'){
|
||||||
|
const encoded = encodeURIComponent('https://wx.igandan.com/Esite/index.htm#/home?fromtype=doctor')
|
||||||
|
url=`/pages_app/webview/webview?url=${encoded}`
|
||||||
}else{
|
}else{
|
||||||
url='/pages_app/myApplication/myApplication'
|
url='/pages_app/myApplication/myApplication'
|
||||||
}
|
}
|
||||||
|
|||||||
121
pages/my/my.vue
121
pages/my/my.vue
@ -215,12 +215,35 @@
|
|||||||
<!-- 底部导航栏 -->
|
<!-- 底部导航栏 -->
|
||||||
<CustomTabbar></CustomTabbar>
|
<CustomTabbar></CustomTabbar>
|
||||||
</view>
|
</view>
|
||||||
|
<unidialog :visible="hasSign" content="今日已签到,每天只能签到一次。<br>请明日继续哦~" @close="hasSign=false" :showCancel="true" cancelText="关闭"></unidialog>
|
||||||
|
<up-overlay :show="showSign" >
|
||||||
|
<view class="signwrap">
|
||||||
|
<view class="signbox">
|
||||||
|
<view class="close" @click="showSign=false"></view>
|
||||||
|
<view class="signbg">
|
||||||
|
<up-image :src="signImg" width="604rpx" height="964rpx" ></up-image>
|
||||||
|
</view>
|
||||||
|
<view class="signcontent">
|
||||||
|
<view class="day">今天是我们相识的第{{signInfo.gdxzday}}天</view>
|
||||||
|
<view class="signtotal">本周共签到{{signInfo.totalDay}}次</view>
|
||||||
|
<view class="signcontinue">已经连续签到{{signInfo.continuous_day}}天</view>
|
||||||
|
<view class="tip">连续签到获取更多积分</view>
|
||||||
|
<view class="news" @click.stop="goNews">
|
||||||
|
{{signInfo.news.summary}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</up-overlay>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import unidialog from '@/components/dialog/dialog.vue'
|
||||||
|
import signImg from "@/static/sign_in_bng_big.png"
|
||||||
import CustomTabbar from '@/components/tabBar/tabBar.vue';
|
import CustomTabbar from '@/components/tabBar/tabBar.vue';
|
||||||
import {
|
import {
|
||||||
ref
|
ref,reactive
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
import {
|
import {
|
||||||
onShow
|
onShow
|
||||||
@ -246,7 +269,7 @@
|
|||||||
import ghsjhImg from "@/static/ghsjh.png"
|
import ghsjhImg from "@/static/ghsjh.png"
|
||||||
import tzykImg from "@/static/xxtx.png"
|
import tzykImg from "@/static/xxtx.png"
|
||||||
import versionImg from "@/static/fxxbb.png"
|
import versionImg from "@/static/fxxbb.png"
|
||||||
|
import jifenImg from "@/static/point_buy.png"
|
||||||
|
|
||||||
import fulicard from "@/static/fulicard.png"
|
import fulicard from "@/static/fulicard.png"
|
||||||
import fpgl from "@/static/fpgl.png"
|
import fpgl from "@/static/fpgl.png"
|
||||||
@ -258,7 +281,13 @@
|
|||||||
import linkUrl from "@/utils/docUrl"
|
import linkUrl from "@/utils/docUrl"
|
||||||
// 响应式数据
|
// 响应式数据
|
||||||
const isLargeFont = ref(false);
|
const isLargeFont = ref(false);
|
||||||
|
const hasSign = ref(false)
|
||||||
|
const showSign = ref(false)
|
||||||
|
const signInfo=reactive({
|
||||||
|
news:{
|
||||||
|
summary:''
|
||||||
|
}
|
||||||
|
})
|
||||||
// 新增:我的信息数据
|
// 新增:我的信息数据
|
||||||
const avatar = ref('')
|
const avatar = ref('')
|
||||||
const username = ref('')
|
const username = ref('')
|
||||||
@ -269,7 +298,26 @@
|
|||||||
const totalPoints = ref(0)
|
const totalPoints = ref(0)
|
||||||
const sign_in = ref(0)
|
const sign_in = ref(0)
|
||||||
const honor_list = ref([])
|
const honor_list = ref([])
|
||||||
|
|
||||||
const notice_on = ref(false)
|
const notice_on = ref(false)
|
||||||
|
const goNews=()=>{
|
||||||
|
let url=docUrl+signInfo.news.path;
|
||||||
|
// #ifdef H5
|
||||||
|
window.open(url, '_blank');
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
plus.runtime.openURL(url);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP
|
||||||
|
const encoded = encodeURIComponent(url);
|
||||||
|
navTo({
|
||||||
|
url: `/pages_app/webview/webview?url=${encoded}`
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
|
||||||
// 从storage获取用户信息
|
// 从storage获取用户信息
|
||||||
const getUserInfoFromStorage = () => {
|
const getUserInfoFromStorage = () => {
|
||||||
try {
|
try {
|
||||||
@ -300,6 +348,7 @@
|
|||||||
title: '签到成功,获得'+res.bonuspoints+'积分',
|
title: '签到成功,获得'+res.bonuspoints+'积分',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
});
|
});
|
||||||
|
Object.assign(signInfo,res);
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: res?.msg || '签到失败',
|
title: res?.msg || '签到失败',
|
||||||
@ -647,7 +696,66 @@ const switchPushPermissions = () => {
|
|||||||
padding-bottom: 100rpx;
|
padding-bottom: 100rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.signwrap{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height:100%;
|
||||||
|
.signbox{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
z-index:0;
|
||||||
|
.close{
|
||||||
|
position:absolute;
|
||||||
|
right:0;
|
||||||
|
height:60rpx;
|
||||||
|
width:60rpx;
|
||||||
|
opacity: 0;
|
||||||
|
background:#fff;
|
||||||
|
z-index:2;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.signwrap .signcontent{
|
||||||
|
width:100%;
|
||||||
|
top:0;
|
||||||
|
position: absolute;
|
||||||
|
z-index:1;
|
||||||
|
}
|
||||||
|
.signwrap .signcontent .day{
|
||||||
|
margin-top: 384rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.signwrap .signtotal{
|
||||||
|
margin-top: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
.signwrap .signcontinue{
|
||||||
|
font-size: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signwrap .signcontent .tip{
|
||||||
|
margin-top: 40rpx;
|
||||||
|
color:red;
|
||||||
|
font-size: 28rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.signwrap .signcontent .news{
|
||||||
|
margin: 196rpx 60rpx 0;
|
||||||
|
height: 116rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
.signwrap .signbg{
|
||||||
|
width:604rpx;
|
||||||
|
height:964rpx;
|
||||||
|
}
|
||||||
// 用户信息卡片
|
// 用户信息卡片
|
||||||
.user-card {
|
.user-card {
|
||||||
|
|
||||||
@ -747,7 +855,7 @@ const switchPushPermissions = () => {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 54rpx;
|
top: 54rpx;
|
||||||
width: 160rpx;
|
width: 150rpx;
|
||||||
height: 56rpx;
|
height: 56rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -769,10 +877,11 @@ const switchPushPermissions = () => {
|
|||||||
right: 0;
|
right: 0;
|
||||||
top: 54rpx;
|
top: 54rpx;
|
||||||
width: 160rpx;
|
width: 160rpx;
|
||||||
height: 56rpx;
|
height: 54rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border: 1rpx solid #fc564a;
|
border: 1rpx solid #fc564a;
|
||||||
|
border-right: none;
|
||||||
border-radius: 30rpx 0 0 30rpx;
|
border-radius: 30rpx 0 0 30rpx;
|
||||||
background: #fff url("@/static/qd_bg.9.png")no-repeat 0 0;
|
background: #fff url("@/static/qd_bg.9.png")no-repeat 0 0;
|
||||||
background-size: 57rpx 56rpx;
|
background-size: 57rpx 56rpx;
|
||||||
|
|||||||
450
pages_app/caseList/caseList.vue
Normal file
450
pages_app/caseList/caseList.vue
Normal file
@ -0,0 +1,450 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<!-- 头部导航 -->
|
||||||
|
<uni-nav-bar
|
||||||
|
left-icon="left"
|
||||||
|
title="病情记录"
|
||||||
|
@clickLeft="goBack"
|
||||||
|
fixed
|
||||||
|
color="#8B2316"
|
||||||
|
height="140rpx"
|
||||||
|
:border="false"
|
||||||
|
backgroundColor="#eee"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="nav-right">
|
||||||
|
<uni-icons type="plus" size="24" color="#8B2316" @click="goAddRecord" style="margin-left: 30rpx;"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-nav-bar>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<scroll-view
|
||||||
|
class="main-content"
|
||||||
|
scroll-y
|
||||||
|
refresher-enabled
|
||||||
|
:refresher-triggered="refreshing"
|
||||||
|
@refresherrefresh="onRefresh"
|
||||||
|
@scrolltolower="onLoadMore"
|
||||||
|
:lower-threshold="100"
|
||||||
|
>
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<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 class="timeline-container" v-else>
|
||||||
|
<!-- 时间线 -->
|
||||||
|
<view class="timeline-line"></view>
|
||||||
|
|
||||||
|
<!-- 记录条目 -->
|
||||||
|
<view
|
||||||
|
class="record-item"
|
||||||
|
v-for="(record, index) in recordList"
|
||||||
|
:key="record.uuid"
|
||||||
|
@click="goToDetail(record)"
|
||||||
|
>
|
||||||
|
<!-- 时间线节点 -->
|
||||||
|
<view class="timeline-node">
|
||||||
|
<view class="node-circle"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 记录内容 -->
|
||||||
|
<view class="record-content">
|
||||||
|
<!-- 日期气泡 -->
|
||||||
|
<view class="date-bubble">
|
||||||
|
<text class="date-text">{{ record.create_date }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 记录描述 -->
|
||||||
|
<view class="record-description" v-if="record.des">
|
||||||
|
<text class="description-text">{{ record.des }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 记录图片 -->
|
||||||
|
<view class="record-images" v-if="record.photo && record.photo.length > 0">
|
||||||
|
<view class="image-grid">
|
||||||
|
<view
|
||||||
|
class="image-item"
|
||||||
|
v-for="(imagePath, imgIndex) in record.photo"
|
||||||
|
:key="imgIndex"
|
||||||
|
@click.stop="previewImages(record.photo, imgIndex)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="docUrl + imagePath"
|
||||||
|
class="content-image"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载更多状态 -->
|
||||||
|
<view class="load-more" v-if="recordList.length > 0">
|
||||||
|
<view class="loading-text" v-if="loadingMore">
|
||||||
|
<uni-load-more status="loading" content-text="{ contentText: { contentdown: '上拉显示更多', contentrefresh: '正在加载...', contentnomore: '没有更多数据了' } }"></uni-load-more>
|
||||||
|
</view>
|
||||||
|
<!-- <view class="no-more-text" v-else-if="currentPage >= totalPage">
|
||||||
|
<text>没有更多数据了</text>
|
||||||
|
</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// Vue3 Composition API
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue'
|
||||||
|
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'
|
||||||
|
|
||||||
|
const patientUuid = ref('')
|
||||||
|
const getRecordList = (isRefresh = false) => {
|
||||||
|
let usrInfo = uni.getStorageSync('userInfo')
|
||||||
|
|
||||||
|
// 如果是刷新,重置页码
|
||||||
|
if (isRefresh) {
|
||||||
|
currentPage.value = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置加载状态
|
||||||
|
if (isRefresh) {
|
||||||
|
refreshing.value = true
|
||||||
|
} else if (currentPage.value === 1) {
|
||||||
|
loading.value = true
|
||||||
|
} else {
|
||||||
|
loadingMore.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
api.conditionRecordList({
|
||||||
|
patient_uuid: patientUuid.value,
|
||||||
|
expert_uuid: usrInfo.uuid,
|
||||||
|
page: currentPage.value
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
if(res.code == 200){
|
||||||
|
const newList = res.data.list || []
|
||||||
|
|
||||||
|
if (isRefresh || currentPage.value === 1) {
|
||||||
|
// 刷新或首次加载,替换数据
|
||||||
|
recordList.value = newList
|
||||||
|
} else {
|
||||||
|
// 加载更多,追加数据
|
||||||
|
recordList.value = [...recordList.value, ...newList]
|
||||||
|
}
|
||||||
|
|
||||||
|
totalPage.value = res.data.totalPage || 1
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('获取病情记录失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '获取数据失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}).finally(() => {
|
||||||
|
// 重置加载状态
|
||||||
|
loading.value = false
|
||||||
|
refreshing.value = false
|
||||||
|
loadingMore.value = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goToDetail = (record) => {
|
||||||
|
uni.setStorageSync('caseRecord', record)
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages_app/caseRecord/caseRecord?uuid=' + record.uuid + '&patientUuid=' + patientUuid.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const goAddRecord = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages_app/caseRecord/caseRecord?patientUuid=' + patientUuid.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onLoad((options) => {
|
||||||
|
patientUuid.value = options.uuid
|
||||||
|
})
|
||||||
|
onShow(() => {
|
||||||
|
getRecordList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const recordList = ref([])
|
||||||
|
const totalPage = ref(1)
|
||||||
|
const currentPage = ref(1)
|
||||||
|
const loading = ref(false)
|
||||||
|
const refreshing = ref(false)
|
||||||
|
const loadingMore = ref(false)
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1,
|
||||||
|
fail() {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addRecord = () => {
|
||||||
|
// 跳转到添加记录页面
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages_app/addRecord/addRecord?patientUuid=' + patientUuid.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const managePatients = () => {
|
||||||
|
// 管理患者功能
|
||||||
|
addRecord()
|
||||||
|
}
|
||||||
|
|
||||||
|
const previewImages = (imageList, currentIndex) => {
|
||||||
|
const urls = imageList.map(img => docUrl + img)
|
||||||
|
uni.previewImage({
|
||||||
|
current: currentIndex,
|
||||||
|
urls: urls
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
const onRefresh = () => {
|
||||||
|
console.log('下拉刷新')
|
||||||
|
getRecordList(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上拉加载更多
|
||||||
|
const onLoadMore = () => {
|
||||||
|
console.log('上拉加载更多')
|
||||||
|
|
||||||
|
// 如果正在加载或没有更多数据,则不执行
|
||||||
|
if (loadingMore.value || loading.value || refreshing.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果已经是最后一页,不执行
|
||||||
|
if (currentPage.value >= totalPage.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 页码加1
|
||||||
|
currentPage.value++
|
||||||
|
|
||||||
|
// 加载更多数据
|
||||||
|
getRecordList(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
console.log('病情记录页面已加载')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
background-color: #ffffff;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头部导航样式 */
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #8B2316;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #8B2316;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-btn {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-icon {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #8B2316;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主要内容区域 */
|
||||||
|
.main-content {
|
||||||
|
height: calc(100vh - 140rpx);
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-container {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-line {
|
||||||
|
position: absolute;
|
||||||
|
left: 30rpx;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 4rpx;
|
||||||
|
background-color: #8B2316;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-item {
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-node {
|
||||||
|
position: relative;
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.node-circle {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: #8B2316;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 4rpx solid #ffffff;
|
||||||
|
box-shadow: 0 0 0 2rpx #8B2316;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-content {
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-bubble {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: 2rpx solid #8B2316;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-description {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.record-images {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空状态样式 */
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #999999;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-first-btn {
|
||||||
|
background-color: #8B2316;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
padding: 20rpx 40rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载更多样式 */
|
||||||
|
.load-more {
|
||||||
|
padding: 40rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 响应式调整 */
|
||||||
|
@media (max-width: 750rpx) {
|
||||||
|
.content-image {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 400rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
460
pages_app/caseRecord/caseRecord.vue
Normal file
460
pages_app/caseRecord/caseRecord.vue
Normal file
@ -0,0 +1,460 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<!-- 头部导航 -->
|
||||||
|
<uni-nav-bar
|
||||||
|
left-icon="left"
|
||||||
|
title="病情记录"
|
||||||
|
@clickLeft="goBack"
|
||||||
|
fixed
|
||||||
|
color="#8B2316"
|
||||||
|
height="140rpx"
|
||||||
|
:border="false"
|
||||||
|
backgroundColor="#eee"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="nav-right">
|
||||||
|
<text class="modify-btn" @click="saveRecord" v-if="recordUuid"
|
||||||
|
>修改</text
|
||||||
|
>
|
||||||
|
<text class="save-btn" @click="saveRecord" v-else>保存</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-nav-bar>
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<view class="main-content">
|
||||||
|
<!-- 日期选择区域 -->
|
||||||
|
<view class="form-item row">
|
||||||
|
<view class="form-label">日期</view>
|
||||||
|
<view class="form-value" @click="openDateTime">
|
||||||
|
<text class="date-text">{{ dateTime }}</text>
|
||||||
|
<uni-icons type="right" size="16" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="divider"></view>
|
||||||
|
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="form-label">描述</view>
|
||||||
|
<view class="form-value">
|
||||||
|
<textarea
|
||||||
|
class="description-input"
|
||||||
|
v-model="des"
|
||||||
|
placeholder="请输入患者病情"
|
||||||
|
></textarea>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="divider"></view>
|
||||||
|
|
||||||
|
<!-- 图片上传区域 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="form-label">图片</view>
|
||||||
|
<view class="image-upload-area">
|
||||||
|
<!-- 已上传的图片 -->
|
||||||
|
<view
|
||||||
|
class="image-item"
|
||||||
|
v-for="(image, index) in tempImageList"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="image"
|
||||||
|
class="uploaded-image"
|
||||||
|
mode="aspectFill"
|
||||||
|
@click="previewImage(index)"
|
||||||
|
/>
|
||||||
|
<view class="delete-btn" @click="deleteImage(index)">
|
||||||
|
<uni-icons type="closeempty" size="15" color="#fff"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 添加图片按钮 -->
|
||||||
|
<view
|
||||||
|
class="add-image-btn"
|
||||||
|
v-if="imageList.length < 9"
|
||||||
|
@click="chooseImage"
|
||||||
|
>
|
||||||
|
<uni-icons type="plus" size="24" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部删除按钮 -->
|
||||||
|
<view class="bottom-actions" v-if="recordUuid">
|
||||||
|
<button class="delete-btn" @click="deleteRecord">删除该条记录</button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-datetime-picker
|
||||||
|
:show="showDate"
|
||||||
|
v-model="selectedDate"
|
||||||
|
@cancel="showDate = false"
|
||||||
|
@confirm="confirmDate"
|
||||||
|
mode="date"
|
||||||
|
></up-datetime-picker>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// Vue3 Composition API
|
||||||
|
import { ref, reactive, onMounted, computed } from "vue";
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import api from "@/api/api.js";
|
||||||
|
import docUrl from "@/utils/docUrl.js";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import { pathToBase64, base64ToPath } from "image-tools";
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const des = ref("");
|
||||||
|
const showDate = ref(false);
|
||||||
|
const recordUuid = ref("");
|
||||||
|
const patientUuid = ref("");
|
||||||
|
const dateTime = ref(dayjs().format("YYYY年MM月DD日"));
|
||||||
|
const selectedDate = ref(dayjs());
|
||||||
|
const description = ref("");
|
||||||
|
const imageList = ref([]);
|
||||||
|
const tempImageList = ref([]);
|
||||||
|
const originalData = ref({});
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1,
|
||||||
|
fail() {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: "/pages/index/index",
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const confirmDate = ({ value, mode }) => {
|
||||||
|
console.log(value);
|
||||||
|
dateTime.value = dayjs(value).format("YYYY年MM月DD日");
|
||||||
|
selectedDate.value = dayjs(value).format("YYYY-MM-DD");
|
||||||
|
showDate.value = false;
|
||||||
|
};
|
||||||
|
const openDateTime = () => {
|
||||||
|
console.log("openDateTime");
|
||||||
|
showDate.value = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const chooseImage = () => {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 8 - imageList.value.length,
|
||||||
|
sizeType: ["original", "compressed"],
|
||||||
|
sourceType: ["album", "camera"],
|
||||||
|
success: (res) => {
|
||||||
|
// 这里应该上传图片到服务器
|
||||||
|
// imageList.value = [...imageList.value, ...res.tempFilePaths]
|
||||||
|
tempImageList.value = [...tempImageList.value, ...res.tempFilePaths];
|
||||||
|
const fileManager = uni.getFileSystemManager();
|
||||||
|
for (let i = 0; i < res.tempFilePaths.length; i++) {
|
||||||
|
fileManager.readFile({
|
||||||
|
filePath: res.tempFilePaths[i],
|
||||||
|
encoding: "base64",
|
||||||
|
success: (res) => {
|
||||||
|
imageList.value.push(res.data);
|
||||||
|
},
|
||||||
|
fail: (error) => {
|
||||||
|
console.log("chooseImage", error);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteImage = (index) => {
|
||||||
|
// 显示模态框
|
||||||
|
uni.showModal({
|
||||||
|
title: "确认删除",
|
||||||
|
content: "确定要删除这张图片吗?",
|
||||||
|
// 设置模态框点击确定按钮后的回调函数
|
||||||
|
success: (res) => {
|
||||||
|
// 如果用户点击了确认按钮
|
||||||
|
if (res.confirm) {
|
||||||
|
// 从imageList数组中删除指定索引的图片
|
||||||
|
imageList.value.splice(index, 1);
|
||||||
|
tempImageList.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const previewImage = (index) => {
|
||||||
|
uni.previewImage({
|
||||||
|
current: index,
|
||||||
|
urls: imageList.value,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const addRecord = async () => {
|
||||||
|
if (!des.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "请输入患者病情",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let usrInfo = uni.getStorageSync("userInfo");
|
||||||
|
const res = await api.addConditionRecord({
|
||||||
|
patient_uuid: patientUuid.value,
|
||||||
|
expert_uuid: usrInfo.uuid,
|
||||||
|
des: des.value,
|
||||||
|
create_date: dayjs(selectedDate.value).format("YYYY-MM-DD"),
|
||||||
|
img1: imageList.value[0] || "",
|
||||||
|
img2: imageList.value[1] || "",
|
||||||
|
img3: imageList.value[2] || "",
|
||||||
|
img4: imageList.value[3] || "",
|
||||||
|
img5: imageList.value[4] || "",
|
||||||
|
img6: imageList.value[5] || "",
|
||||||
|
img7: imageList.value[6] || "",
|
||||||
|
img8: imageList.value[7] || "",
|
||||||
|
});
|
||||||
|
if (res.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "添加成功",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const updateRecord = async () => {
|
||||||
|
if (!des.value) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "请输入患者病情",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let usrInfo = uni.getStorageSync("userInfo");
|
||||||
|
const res = await api.updateConditionRecord({
|
||||||
|
uuid: recordUuid.value,
|
||||||
|
patient_uuid: patientUuid.value,
|
||||||
|
expert_uuid: usrInfo.uuid,
|
||||||
|
des: des.value,
|
||||||
|
create_date: dayjs(selectedDate.value).format("YYYY-MM-DD"),
|
||||||
|
img1: imageList.value[0] || "",
|
||||||
|
img2: imageList.value[1] || "",
|
||||||
|
img3: imageList.value[2] || "",
|
||||||
|
img4: imageList.value[3] || "",
|
||||||
|
img5: imageList.value[4] || "",
|
||||||
|
img6: imageList.value[5] || "",
|
||||||
|
img7: imageList.value[6] || "",
|
||||||
|
img8: imageList.value[7] || "",
|
||||||
|
});
|
||||||
|
if (res.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "修改成功",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
uni.setStorageSync("caseRecord",null);
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const deleteConditionRecord = async () => {
|
||||||
|
const res = await api.deleteConditionRecord({
|
||||||
|
uuid: recordUuid.value,
|
||||||
|
});
|
||||||
|
if (res.code == 200) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "删除成功",
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
goBack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteRecord = () => {
|
||||||
|
uni.showModal({
|
||||||
|
title: "确认删除",
|
||||||
|
content: "确定要删除这条记录吗?",
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
deleteConditionRecord();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onLoad((options) => {
|
||||||
|
console.log(options);
|
||||||
|
recordUuid.value = options.uuid || "";
|
||||||
|
patientUuid.value = options.patientUuid || "";
|
||||||
|
if (recordUuid.value) {
|
||||||
|
imageList.value = [];
|
||||||
|
let record = uni.getStorageSync("caseRecord");
|
||||||
|
des.value = record.des;
|
||||||
|
tempImageList.value = record.photo.map((item) => docUrl + item);
|
||||||
|
// imageList.value = record.photo.map(item=>docUrl+item);
|
||||||
|
dateTime.value = dayjs(record.create_date).format("YYYY年MM月DD日");
|
||||||
|
selectedDate.value = dayjs(record.create_date);
|
||||||
|
for (let i = 0; i < record.photo.length; i++) {
|
||||||
|
console.log("url", docUrl + record.photo[i]);
|
||||||
|
uni.request({
|
||||||
|
url: docUrl + record.photo[i],
|
||||||
|
method: 'GET',
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
success: (res) => {
|
||||||
|
const base64 = `${uni.arrayBufferToBase64(res.data)}`
|
||||||
|
console.log(base64);
|
||||||
|
imageList.value.push(base64);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const saveRecord = () => {
|
||||||
|
if (recordUuid.value) {
|
||||||
|
updateRecord();
|
||||||
|
} else {
|
||||||
|
addRecord();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background-color: #ffffff;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头部导航样式 */
|
||||||
|
.nav-right {
|
||||||
|
padding-right: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modify-btn,
|
||||||
|
.save-btn {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #8b2316;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主要内容区域 */
|
||||||
|
.main-content {
|
||||||
|
padding: 0rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-value {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-input {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 200rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.6;
|
||||||
|
background-color: 2rpx solid #f5f5f5;
|
||||||
|
border: none;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-input:disabled {
|
||||||
|
color: #999999;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图片上传区域 */
|
||||||
|
.image-upload-area {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
position: relative;
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item .delete-btn {
|
||||||
|
position: absolute;
|
||||||
|
top: 10rpx;
|
||||||
|
right: 10rpx;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.6);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-image-btn {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
border: 2rpx dashed #cccccc;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.divider {
|
||||||
|
height: 1rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin: 0 -30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部操作区域 */
|
||||||
|
.bottom-actions {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-actions .delete-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 88rpx;
|
||||||
|
background-color: #8b2316;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
341
pages_app/checkRecord/checkRecord.vue
Normal file
341
pages_app/checkRecord/checkRecord.vue
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<!-- 头部导航 -->
|
||||||
|
<navBar :title="headerTitle" />
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<view class="main-content">
|
||||||
|
<!-- 疾病诊断部分 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-header">
|
||||||
|
<view class="red-bar"></view>
|
||||||
|
<text class="section-title">疾病诊断</text>
|
||||||
|
</view>
|
||||||
|
<view class="section-content">
|
||||||
|
<text class="diagnosis-text">疾病诊断: {{ pageData.diseaseName }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 化验报告部分 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-header">
|
||||||
|
<text class="section-title">化验报告</text>
|
||||||
|
</view>
|
||||||
|
<view class="section-content">
|
||||||
|
<text class="no-report-text" v-if="!pageData.hasLabReport">无检查化验报告</text>
|
||||||
|
<view v-else class="lab-report-container">
|
||||||
|
<view class="image-grid">
|
||||||
|
<view
|
||||||
|
class="image-item"
|
||||||
|
v-for="(image, index) in caseImages"
|
||||||
|
:key="image.uuid"
|
||||||
|
@click="previewImage(index)"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
:src="docUrl+image.path"
|
||||||
|
class="report-image"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
|
<!-- <view class="image-date">{{ formatDate(image.createDate) }}</view> -->
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 疾病描述部分 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-header">
|
||||||
|
<text class="section-title">疾病描述</text>
|
||||||
|
</view>
|
||||||
|
<view class="section-content">
|
||||||
|
<text class="description-text">{{ pageData.des || '暂无描述' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部线条 -->
|
||||||
|
<view class="bottom-line"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// Vue3 Composition API
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue'
|
||||||
|
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'
|
||||||
|
const uuid = ref('')
|
||||||
|
onLoad((options) => {
|
||||||
|
uuid.value = options.uuid
|
||||||
|
})
|
||||||
|
onShow(() => {
|
||||||
|
getDetail()
|
||||||
|
})
|
||||||
|
// 响应式数据
|
||||||
|
const pageData = ref({
|
||||||
|
date: '',
|
||||||
|
diseaseName: '',
|
||||||
|
diagnosis: '',
|
||||||
|
hasLabReport: false,
|
||||||
|
labReport: '',
|
||||||
|
description: '',
|
||||||
|
photo: '',
|
||||||
|
age: 0,
|
||||||
|
title: '',
|
||||||
|
patientUuid: '',
|
||||||
|
diseaseUuid: '',
|
||||||
|
state: 0,
|
||||||
|
createDate: '',
|
||||||
|
modifyDate: null
|
||||||
|
})
|
||||||
|
|
||||||
|
// 案例图片数据
|
||||||
|
const caseImages = ref([])
|
||||||
|
|
||||||
|
const getDetail = () => {
|
||||||
|
api.caseDetail({
|
||||||
|
caseUuid: uuid.value
|
||||||
|
}).then(res => {
|
||||||
|
console.log(res)
|
||||||
|
if(res.code == 200){
|
||||||
|
// 更新案例数据
|
||||||
|
pageData.value = res.data.case
|
||||||
|
// 更新案例图片
|
||||||
|
caseImages.value = res.data.caseImg || []
|
||||||
|
// 设置是否有化验报告(根据图片数量判断)
|
||||||
|
pageData.value.hasLabReport = caseImages.value.length > 0
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('获取案例详情失败:', err)
|
||||||
|
uni.showToast({
|
||||||
|
title: '获取数据失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const headerTitle = computed(() => {
|
||||||
|
return pageData.value.title || `${pageData.value.createDate}${pageData.value.diseaseName}`
|
||||||
|
})
|
||||||
|
|
||||||
|
// 格式化日期
|
||||||
|
const formatDate = (dateStr) => {
|
||||||
|
if (!dateStr) return ''
|
||||||
|
const date = new Date(dateStr)
|
||||||
|
return date.toLocaleDateString('zh-CN', {
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit'
|
||||||
|
}).replace(/\//g, '-')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 预览图片
|
||||||
|
const previewImage = (index) => {
|
||||||
|
const urls = caseImages.value.map(img => docUrl+img.path)
|
||||||
|
uni.previewImage({
|
||||||
|
current: index,
|
||||||
|
urls: urls
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
// 页面加载时的逻辑
|
||||||
|
console.log('检查记录页面已加载')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
background-color: #ffffff;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 状态栏样式 */
|
||||||
|
.status-bar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10rpx 30rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-left {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-center {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.network-icons {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bluetooth-icon, .wifi-icon {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speed {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signal {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-right {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 头部导航样式 */
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #ff4444;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #ff4444;
|
||||||
|
font-weight: bold;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 主要内容区域 */
|
||||||
|
.main-content {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-header {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-bar {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
width: 8rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #ff4444;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-content {
|
||||||
|
padding-left: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.diagnosis-text {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-report-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lab-report-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lab-report-container {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-item {
|
||||||
|
position: relative;
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-date {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background: linear-gradient(transparent, rgba(0, 0, 0, 0.7));
|
||||||
|
color: white;
|
||||||
|
font-size: 20rpx;
|
||||||
|
padding: 20rpx 10rpx 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部线条 */
|
||||||
|
.bottom-line {
|
||||||
|
height: 2rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin: 40rpx 30rpx 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
<uni-icons type="right" color="#999" size="18"></uni-icons>
|
<uni-icons type="right" color="#999" size="18"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="cell" @click="editDesc">
|
<view class="cell" @click="openGroup">
|
||||||
<text class="cell-label">描述</text>
|
<text class="cell-label">描述</text>
|
||||||
<view class="cell-right">
|
<view class="cell-right">
|
||||||
<text class="hint">补充患者关键信息,方便随访患者</text>
|
<text class="hint">补充患者关键信息,方便随访患者</text>
|
||||||
@ -62,10 +62,22 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 患者病史 -->
|
<!-- 患者病史 -->
|
||||||
<view class="section-title">患者病史</view>
|
<view class="history-section" v-if="patientDetail.medicalHistoryContent">
|
||||||
<view class="card history-card">
|
<view class="section-title">患者病史</view>
|
||||||
<text class="history-text" :class="{ fold: !showAllHistory }">{{ patientDetail.medicalHistoryContent }}</text>
|
<view class="card history-card">
|
||||||
<text class="toggle" @click="toggleHistory" v-if="patientDetail.patientHistoryText">{{ showAllHistory ? '收起' : '展开全部' }}</text>
|
<text class="history-text" :class="{ fold: !showAllHistory }">{{ patientDetail.medicalHistoryContent }}</text>
|
||||||
|
<text class="toggle" @click="toggleHistory" v-if="patientDetail.medicalHistoryContent">{{ showAllHistory ? '收起' : '展开全部' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 检查报告 -->
|
||||||
|
<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>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部操作 -->
|
<!-- 底部操作 -->
|
||||||
@ -116,8 +128,8 @@
|
|||||||
|
|
||||||
// 计算属性:完整地址
|
// 计算属性:完整地址
|
||||||
const fullAddress = computed(() => {
|
const fullAddress = computed(() => {
|
||||||
const { provName, cityName, countyName, detailed_address } = patientInfo.value;
|
const { provName, cityName, countyName } = patientInfo.value;
|
||||||
const addressParts = [provName, cityName, countyName, detailed_address].filter(Boolean);
|
const addressParts = [provName, cityName, countyName].filter(Boolean);
|
||||||
return addressParts.length > 0 ? addressParts.join('') : '未设置';
|
return addressParts.length > 0 ? addressParts.join('') : '未设置';
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -127,13 +139,29 @@
|
|||||||
patient_uuid.value = options.uuid;
|
patient_uuid.value = options.uuid;
|
||||||
});
|
});
|
||||||
const goBack = ()=> uni.navigateBack()
|
const goBack = ()=> uni.navigateBack()
|
||||||
const editPatient = ()=> uni.showToast({ title:'编辑资料', icon:'none' })
|
const openCase = (uuid)=>{
|
||||||
const openGroup = ()=> uni.showToast({ title:'分组', icon:'none' })
|
|
||||||
const editDesc = ()=> uni.showToast({ title:'编辑描述', icon:'none' })
|
|
||||||
const sendMessage = ()=>{
|
|
||||||
navTo({
|
navTo({
|
||||||
url: '/pages_app/chat/chat?patient_uuid='+patient_uuid,
|
url:'/pages_app/checkRecord/checkRecord?uuid='+uuid
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
const editPatient = ()=> {
|
||||||
|
navTo({
|
||||||
|
url:'/pages_app/patientSetting/patientSetting?uuid=' + patient_uuid.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const openGroup = ()=>{
|
||||||
|
navTo({
|
||||||
|
url:'/pages_app/patientRemark/patientRemark?uuid=' + patientInfo.value.uuid
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const editDesc = ()=> uni.showToast({ title:'编辑描述', icon:'none' })
|
||||||
|
const sendMessage = async()=>{
|
||||||
|
let userId=uni.getStorageSync('userInfo').uuid.toLowerCase();
|
||||||
|
let conversationId=userId+'|1|'+patientInfo.value.uuid.toLowerCase();
|
||||||
|
await uni.$UIKitStore.uiStore.selectConversation(conversationId)
|
||||||
|
navTo({
|
||||||
|
url:'/pages_chat/chat/index'
|
||||||
|
})
|
||||||
};
|
};
|
||||||
const nickname = ref('');
|
const nickname = ref('');
|
||||||
const group = ref({});
|
const group = ref({});
|
||||||
@ -186,17 +214,48 @@
|
|||||||
getToAddNickname();
|
getToAddNickname();
|
||||||
getPatientCard();
|
getPatientCard();
|
||||||
});
|
});
|
||||||
const goMakePlan = ()=> uni.navigateTo({ url:'/pages_app/visit/visit' })
|
const goMakePlan = ()=> {
|
||||||
const recordIllness = ()=> uni.showToast({ title:'记录病情', icon:'none' })
|
navTo({
|
||||||
|
url:'/pages_app/visitPlan/visitPlan'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const recordIllness = ()=> {
|
||||||
|
navTo({
|
||||||
|
url:'/pages_app/caseList/caseList?uuid='+patient_uuid.value
|
||||||
|
})
|
||||||
|
}
|
||||||
const toggleHistory = ()=> showAllHistory.value = !showAllHistory.value
|
const toggleHistory = ()=> showAllHistory.value = !showAllHistory.value
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.report-card{
|
||||||
|
display: flex;
|
||||||
|
gap: 55rpx;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
.report-item{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10rpx;
|
||||||
|
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 20rpx;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
.report-item-title{
|
||||||
|
font-size: 28rpx;
|
||||||
|
color:#666;
|
||||||
|
}
|
||||||
|
.report-item-content{
|
||||||
|
font-size: 28rpx;
|
||||||
|
color:#333;
|
||||||
|
}
|
||||||
|
}
|
||||||
.content { background:#f5f5f5; min-height:100vh; }
|
.content { background:#f5f5f5; min-height:100vh; }
|
||||||
.nav-right { padding-right: 20rpx; }
|
.nav-right { padding-right: 20rpx; }
|
||||||
|
|
||||||
.card { background:#ffffff; padding: 20rpx; }
|
.card { background:#ffffff; padding: 20rpx; padding-top: 0;}
|
||||||
.header-card { display:flex; }
|
.header-card { display:flex; padding-top: 20rpx;}
|
||||||
.avatar { width: 140rpx; height: 140rpx; border-radius: 12rpx; margin-right: 20rpx; }
|
.avatar { width: 140rpx; height: 140rpx; border-radius: 12rpx; margin-right: 20rpx; }
|
||||||
.base-info { flex:1; }
|
.base-info { flex:1; }
|
||||||
.name-row { display:flex; align-items:center; margin-bottom: 10rpx; }
|
.name-row { display:flex; align-items:center; margin-bottom: 10rpx; }
|
||||||
@ -215,11 +274,11 @@
|
|||||||
.hint { font-size: 28rpx; color:#999; margin-right: 12rpx; }
|
.hint { font-size: 28rpx; color:#999; margin-right: 12rpx; }
|
||||||
.phone { font-size: 32rpx; color:#b10000; }
|
.phone { font-size: 32rpx; color:#b10000; }
|
||||||
|
|
||||||
.section-title { padding: 16rpx 30rpx; color:#8B2316; font-size: 30rpx; margin-top: 20rpx; }
|
.section-title { padding: 16rpx 30rpx; color:#8B2316; font-size: 30rpx; margin-top: 20rpx; background: #fff;}
|
||||||
.history-card { position: relative; }
|
.history-card { position: relative; }
|
||||||
.history-text { font-size: 28rpx; color:#666; line-height: 1.7; display:block; }
|
.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; }
|
.history-text.fold { display:-webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
|
||||||
.toggle { position:absolute; right: 20rpx; bottom: 16rpx; color:#b10000; font-size: 28rpx; }
|
.toggle { position:absolute; right: 20rpx; bottom: 25rpx; color:#b10000; font-size: 28rpx;background: #fff; z-index: 10;}
|
||||||
|
|
||||||
.actions { background:#ffffff; margin-top: 20rpx;}
|
.actions { background:#ffffff; margin-top: 20rpx;}
|
||||||
.action { display:flex; align-items:center;justify-content: center; padding: 28rpx 30rpx; border-top:1rpx solid #f0f0f0; }
|
.action { display:flex; align-items:center;justify-content: center; padding: 28rpx 30rpx; border-top:1rpx solid #f0f0f0; }
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
<!-- 顶部导航栏 -->
|
<!-- 顶部导航栏 -->
|
||||||
<uni-nav-bar
|
<uni-nav-bar
|
||||||
left-icon="left"
|
left-icon="left"
|
||||||
title="患者消息"
|
:title="title"
|
||||||
@clickLeft="goBack"
|
@clickLeft="goBack"
|
||||||
fixed
|
fixed
|
||||||
color="#8B2316"
|
color="#8B2316"
|
||||||
@ -12,10 +12,18 @@
|
|||||||
backgroundColor="#eee"
|
backgroundColor="#eee"
|
||||||
>
|
>
|
||||||
<template #right>
|
<template #right>
|
||||||
<view class="nav-right">
|
<view class="nav-right" v-if="activeTab === 'message'">
|
||||||
<uni-icons type="search" size="24" color="#8B2316" @click="searchPatients"></uni-icons>
|
<uni-icons type="search" size="24" color="#8B2316" @click="searchPatients"></uni-icons>
|
||||||
<uni-icons type="staff" size="24" color="#8B2316" @click="managePatients" style="margin-left: 30rpx;"></uni-icons>
|
<uni-icons type="staff" size="24" color="#8B2316" @click="managePatients" style="margin-left: 30rpx;"></uni-icons>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="nav-right" v-else-if="activeTab === 'list'">
|
||||||
|
<uni-icons type="search" size="24" color="#8B2316" @click="searchPatients"></uni-icons>
|
||||||
|
<uni-icons type="plusempty" size="24" color="#8B2316" @click="goCode" style="margin-left: 30rpx;" ></uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="nav-right" v-else-if="activeTab === 'plan'" @click="showAddMenu">
|
||||||
|
<view class="save-btn">保存</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
</uni-nav-bar>
|
</uni-nav-bar>
|
||||||
|
|
||||||
@ -167,10 +175,10 @@
|
|||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<!-- 悬浮添加按钮 -->
|
<!-- 悬浮添加按钮 -->
|
||||||
<view class="floating-add-btn" @click="showAddMenu">
|
<!-- <view class="floating-add-btn" @click="showAddMenu">
|
||||||
<uni-icons type="plus" size="24" color="#ffffff"></uni-icons>
|
<uni-icons type="plus" size="24" color="#ffffff"></uni-icons>
|
||||||
<text class="btn-text">添加</text>
|
<text class="btn-text">添加</text>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- 添加菜单弹窗 -->
|
<!-- 添加菜单弹窗 -->
|
||||||
<view class="add-menu-popup" v-if="showAddMenuFlag" @click="hideAddMenu">
|
<view class="add-menu-popup" v-if="showAddMenuFlag" @click="hideAddMenu">
|
||||||
@ -191,13 +199,11 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view
|
||||||
|
|
||||||
<!-- 底部标签栏 -->
|
<!-- 底部标签栏 -->
|
||||||
<view class="tab-bar">
|
<view class="tab-bar">
|
||||||
<view class="tab-item" :class="{active: activeTab === 'message'}" @click="switchTab('message')">
|
<view class="tab-item" :class="{active: activeTab === 'message'}" @click="switchTab('message')">
|
||||||
<text class="tab-text">患者消息</text>
|
<text class="tab-text">患者消息</text>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
<view class="tab-item" :class="{active: activeTab === 'list'}" @click="switchTab('list')">
|
<view class="tab-item" :class="{active: activeTab === 'list'}" @click="switchTab('list')">
|
||||||
<text class="tab-text">患者列表</text>
|
<text class="tab-text">患者列表</text>
|
||||||
@ -223,7 +229,7 @@
|
|||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import lineImg from "@/static/item_visitplan_fg.png"
|
import lineImg from "@/static/item_visitplan_fg.png"
|
||||||
import ConversationList from './conversation-list/index.vue'
|
import ConversationList from './conversation-list/index.vue'
|
||||||
|
const title = ref('患者消息');
|
||||||
const goPatientDetail = (uuid) => {
|
const goPatientDetail = (uuid) => {
|
||||||
navTo({
|
navTo({
|
||||||
url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}`
|
url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}`
|
||||||
@ -235,6 +241,11 @@
|
|||||||
url: `/pages_app/patientSetting/patientSetting?uuid=${uuid}`
|
url: `/pages_app/patientSetting/patientSetting?uuid=${uuid}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
const goCode = () => {
|
||||||
|
navTo({
|
||||||
|
url: `/pages_app/myCode/myCode`
|
||||||
|
})
|
||||||
|
}
|
||||||
// 仅保留年月日
|
// 仅保留年月日
|
||||||
const formatYMD = (input) => {
|
const formatYMD = (input) => {
|
||||||
if (!input) return '';
|
if (!input) return '';
|
||||||
@ -489,10 +500,9 @@
|
|||||||
|
|
||||||
// 搜索患者
|
// 搜索患者
|
||||||
const searchPatients = () => {
|
const searchPatients = () => {
|
||||||
uni.showToast({
|
navTo({
|
||||||
title: '搜索患者',
|
url: `/pages_app/searchPatient/searchPatient`
|
||||||
icon: 'none'
|
})
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 管理患者
|
// 管理患者
|
||||||
@ -519,15 +529,19 @@
|
|||||||
const switchTab = (tab) => {
|
const switchTab = (tab) => {
|
||||||
activeTab.value = tab;
|
activeTab.value = tab;
|
||||||
|
|
||||||
|
|
||||||
switch(tab) {
|
switch(tab) {
|
||||||
case 'message':
|
case 'message':
|
||||||
// 患者消息页面逻辑 - 刷新申请列表
|
// 患者消息页面逻辑 - 刷新申请列表
|
||||||
getApplyList();
|
getApplyList();
|
||||||
|
title.value = '患者消息';
|
||||||
break;
|
break;
|
||||||
case 'list':
|
case 'list':
|
||||||
|
title.value = '患者列表';
|
||||||
// 显示患者列表
|
// 显示患者列表
|
||||||
break;
|
break;
|
||||||
case 'plan':
|
case 'plan':
|
||||||
|
title.value = '随访计划';
|
||||||
// 随访计划页面 - 加载随访计划数据
|
// 随访计划页面 - 加载随访计划数据
|
||||||
if (followUpList.value.length === 0) {
|
if (followUpList.value.length === 0) {
|
||||||
getFollowUpList(true);
|
getFollowUpList(true);
|
||||||
@ -618,6 +632,11 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.save-btn {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #8b2316;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
.content {
|
.content {
|
||||||
background-color: #f5f5f5;
|
background-color: #f5f5f5;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -893,7 +912,7 @@
|
|||||||
.group-section {
|
.group-section {
|
||||||
.group-header {
|
.group-header {
|
||||||
padding: 20rpx 30rpx;
|
padding: 20rpx 30rpx;
|
||||||
background-color: #f8f8f8;
|
background-color: #e4e4e4;
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
color: #666666;
|
color: #666666;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
@ -1044,7 +1063,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.plan-list{
|
.plan-list{
|
||||||
margin-top: 20rpx;
|
|
||||||
padding-bottom: 20rpx;
|
padding-bottom: 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
98
pages_app/searchPatient/searchPatient.vue
Normal file
98
pages_app/searchPatient/searchPatient.vue
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
<template>
|
||||||
|
<view class="select-page">
|
||||||
|
|
||||||
|
<navBar title="搜索患者" />
|
||||||
|
|
||||||
|
<!-- 搜索框 -->
|
||||||
|
<view class="search-bar">
|
||||||
|
<view class="input-wrap">
|
||||||
|
<input class="search-input" v-model.trim="keyword" placeholder="搜索患者的备注名、昵称或手机号" placeholder-class="ph" @input="$u.debounce(onSearch, 500)" />
|
||||||
|
</view>
|
||||||
|
<view class="search-btn" @click="onSearch">
|
||||||
|
<uni-icons type="search" size="50rpx" color="#999" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<scroll-view class="list" scroll-y>
|
||||||
|
<view class="item" @click="goDetail(p.uuid)" v-for="p in availablePatientList" :key="p.uuid">
|
||||||
|
<image class="avatar" :src="docUrl + (p.photo || '')" mode="aspectFill" />
|
||||||
|
<view class="name">{{ p.nickname || p.realName }}</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import docUrl from '@/utils/docUrl.js'
|
||||||
|
import { onShow,onLoad} from "@dcloudio/uni-app";
|
||||||
|
import api from '@/api/api.js'
|
||||||
|
import navTo from '@/utils/navTo.js'
|
||||||
|
import navBar from '@/components/navBar/navBar.vue'
|
||||||
|
const from = ref('');
|
||||||
|
const keyword = ref('')
|
||||||
|
const patientList = ref([])
|
||||||
|
// 计算属性:显示所有患者,但标记已选中的状态
|
||||||
|
const availablePatientList = computed(() => {
|
||||||
|
return patientList.value
|
||||||
|
})
|
||||||
|
const patientListByGBK = async () => {
|
||||||
|
|
||||||
|
const res = await api.patientListByGBK();
|
||||||
|
if(res.code == 1){
|
||||||
|
patientList.value = res.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onLoad((options) => {
|
||||||
|
if(options.from == 'chatMsg'){
|
||||||
|
from.value = 'chatMsg';
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
onShow(() => {
|
||||||
|
patientListByGBK();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const goDetail = (uuid) => {
|
||||||
|
navTo({ url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}` })
|
||||||
|
}
|
||||||
|
|
||||||
|
const onSearch = () => {
|
||||||
|
patientList.value = patientList.value.filter(p => p.realName.indexOf(keyword.value) !== -1 || (p.nickname && p.nickname.indexOf(keyword.value) !== -1) || p.mobile.indexOf(keyword.value) !== -1)
|
||||||
|
}
|
||||||
|
const goBack = () => uni.navigateBack()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.select-page{
|
||||||
|
min-height: 100vh; background:#fefefe;
|
||||||
|
}
|
||||||
|
.confirm-text{ color:#fff; font-size: 28rpx;white-space: nowrap; }
|
||||||
|
.confirm-btn{ background:#7f7f7f; padding: 10rpx 18rpx; border-radius: 26rpx; }
|
||||||
|
.confirm-btn.active{ background:#8B2316; }
|
||||||
|
.search-bar{
|
||||||
|
border: 2rpx solid #eee;
|
||||||
|
margin: 20rpx 30rpx; display:flex; align-items:center; gap: 16rpx;
|
||||||
|
.input-wrap{ flex:1; background:#fff; border-radius: 12rpx; padding: 16rpx 20rpx; }
|
||||||
|
.search-input{ font-size: 28rpx; color:#333; }
|
||||||
|
.ph{ color:#bfbfbf; }
|
||||||
|
.search-btn{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 88rpx; height: 72rpx; background:#fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list{ border-radius: 12rpx; }
|
||||||
|
.item{background:#fff; display:flex; align-items:center;padding: 24rpx 30rpx; border-bottom: 2rpx solid #eee; }
|
||||||
|
.avatar{ width: 96rpx; height:96rpx; border-radius: 16rpx; background:#ffe; }
|
||||||
|
.name{ flex:1; margin-left: 20rpx; font-size: 32rpx; color:#333; }
|
||||||
|
.check{ padding-left: 12rpx; }
|
||||||
|
.circle{ width: 40rpx; height: 40rpx; border-radius: 50%; border: 2rpx solid #cfcfcf; }
|
||||||
|
.circle.active{ background:#8B2316; border-color:#8B2316; position: relative; }
|
||||||
|
.circle.active::after{ content:''; position:absolute; left: 14rpx; top: 6rpx; width: 10rpx; height: 18rpx; border: 4rpx solid #fff; border-top: 0; border-left: 0; transform: rotate(45deg); }
|
||||||
|
</style>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<!-- 搜索框 -->
|
<!-- 搜索框 -->
|
||||||
<view class="search-bar">
|
<view class="search-bar">
|
||||||
<view class="input-wrap">
|
<view class="input-wrap">
|
||||||
<input class="search-input" v-model.trim="keyword" placeholder="搜索患者的备注名、昵称或手机号" placeholder-class="ph" @confirm="onSearch" />
|
<input class="search-input" v-model.trim="keyword" placeholder="搜索患者的备注名、昵称或手机号" placeholder-class="ph" @input="$u.debounce(onSearch, 500)" />
|
||||||
</view>
|
</view>
|
||||||
<view class="search-btn" @click="onSearch">
|
<view class="search-btn" @click="onSearch">
|
||||||
<uni-icons type="search" size="50rpx" color="#999" />
|
<uni-icons type="search" size="50rpx" color="#999" />
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<scroll-view class="list" scroll-y>
|
<scroll-view class="list" scroll-y>
|
||||||
<view class="item" @click="toggle(p.uuid)" v-for="p in availablePatientList" :key="p.uuid">
|
<view class="item" @click="toggle(p.uuid)" v-for="p in availablePatientList" :key="p.uuid">
|
||||||
<image class="avatar" :src="docUrl + (p.photo || '')" mode="aspectFill" />
|
<image class="avatar" :src="docUrl + (p.photo || '')" mode="aspectFill" />
|
||||||
<view class="name">{{ p.realName || '-' }}</view>
|
<view class="name">{{ p.nickname || p.realName }}</view>
|
||||||
<view class="check" >
|
<view class="check" >
|
||||||
<view class="circle" :class="{ active: selectedIds.includes(p.uuid) }"></view>
|
<view class="circle" :class="{ active: selectedIds.includes(p.uuid) }"></view>
|
||||||
</view>
|
</view>
|
||||||
@ -111,7 +111,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSearch = () => {}
|
const onSearch = () => {
|
||||||
|
patientList.value = patientList.value.filter(p => p.realName.indexOf(keyword.value) !== -1 || (p.nickname && p.nickname.indexOf(keyword.value) !== -1) || p.mobile.indexOf(keyword.value) !== -1)
|
||||||
|
}
|
||||||
const goBack = () => uni.navigateBack()
|
const goBack = () => uni.navigateBack()
|
||||||
const confirmSelect = () => {
|
const confirmSelect = () => {
|
||||||
const payload = { ids: selectedIds.value, list: selectedDetail.value }
|
const payload = { ids: selectedIds.value, list: selectedDetail.value }
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
<!-- 搜索框 -->
|
<!-- 搜索框 -->
|
||||||
<view class="search-bar">
|
<view class="search-bar">
|
||||||
<view class="input-wrap">
|
<view class="input-wrap">
|
||||||
<input class="search-input" v-model.trim="keyword" placeholder="搜索患者的备注名、昵称或手机号" placeholder-class="ph" @confirm="onSearch" />
|
<input class="search-input" v-model.trim="keyword" placeholder="搜索患者的备注名、昵称或手机号" placeholder-class="ph" @input="$u.debounce(onSearch, 500)" />
|
||||||
</view>
|
</view>
|
||||||
<view class="search-btn" @click="onSearch">
|
<view class="search-btn" @click="onSearch">
|
||||||
<uni-icons type="search" size="50rpx" color="#999" />
|
<uni-icons type="search" size="50rpx" color="#999" />
|
||||||
@ -31,7 +31,7 @@
|
|||||||
<scroll-view class="list" scroll-y>
|
<scroll-view class="list" scroll-y>
|
||||||
<view class="item" @click="toggle(p.uuid)" v-for="p in availablePatientList" :key="p.uuid">
|
<view class="item" @click="toggle(p.uuid)" v-for="p in availablePatientList" :key="p.uuid">
|
||||||
<image class="avatar" :src="docUrl + (p.photo || '')" mode="aspectFill" />
|
<image class="avatar" :src="docUrl + (p.photo || '')" mode="aspectFill" />
|
||||||
<view class="name">{{ p.realName || '-' }}</view>
|
<view class="name">{{ p.nickname || p.realName }}</view>
|
||||||
<view class="check" >
|
<view class="check" >
|
||||||
<view class="circle" :class="{ active: selectedIds.includes(p.uuid) }"></view>
|
<view class="circle" :class="{ active: selectedIds.includes(p.uuid) }"></view>
|
||||||
</view>
|
</view>
|
||||||
@ -114,7 +114,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSearch = () => {}
|
const onSearch = () => {
|
||||||
|
patientList.value = patientList.value.filter(p => p.realName.indexOf(keyword.value) !== -1 || (p.nickname && p.nickname.indexOf(keyword.value) !== -1) || p.mobile.indexOf(keyword.value) !== -1)
|
||||||
|
}
|
||||||
const goBack = () => uni.navigateBack()
|
const goBack = () => uni.navigateBack()
|
||||||
const confirmSelect = (id) => {
|
const confirmSelect = (id) => {
|
||||||
const payload =patientList.value.find(x => x.uuid === id)
|
const payload =patientList.value.find(x => x.uuid === id)
|
||||||
|
|||||||
209
pages_app/visitPlan/visitPlan.vue
Normal file
209
pages_app/visitPlan/visitPlan.vue
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<uni-nav-bar
|
||||||
|
left-icon="left"
|
||||||
|
title="随访计划"
|
||||||
|
@clickLeft="goBack"
|
||||||
|
fixed
|
||||||
|
color="#8B2316"
|
||||||
|
height="140rpx"
|
||||||
|
:border="false"
|
||||||
|
backgroundColor="#eee"
|
||||||
|
>
|
||||||
|
<template #right>
|
||||||
|
<view class="nav-right">
|
||||||
|
|
||||||
|
<text class="save-btn" @click="showAddMenu" >添加</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-nav-bar>
|
||||||
|
<view class="plan">
|
||||||
|
<scroll-view
|
||||||
|
class="plan-scroll"
|
||||||
|
scroll-y="true"
|
||||||
|
refresher-enabled="true"
|
||||||
|
:refresher-triggered="followUpRefreshing"
|
||||||
|
@refresherrefresh="onFollowUpRefresh"
|
||||||
|
@scrolltolower="onFollowUpLoadMore"
|
||||||
|
:lower-threshold="100"
|
||||||
|
>
|
||||||
|
<view class="plan-list" v-if="groupedFollowUpList.length > 0">
|
||||||
|
<view class="plan-group" v-for="group in groupedFollowUpList" :key="group.yearMonth">
|
||||||
|
<view class="group-header">{{ group.yearMonth }}</view>
|
||||||
|
<view class="plan-card" v-for="item in group.items" :key="item.uuid" @click="goFollowDetail(item)">
|
||||||
|
<view class="left-rail">
|
||||||
|
<text class="day">{{ formatDay(item.datetime) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="linebox">
|
||||||
|
<up-image :src="lineImg" width="14rpx" height="140rpx" ></up-image>
|
||||||
|
</view>
|
||||||
|
<view class="right-content">
|
||||||
|
<view class="leftcontent">
|
||||||
|
<view class="note">{{ item.note }}</view>
|
||||||
|
<view class="name">{{ item.patientname }}</view>
|
||||||
|
</view>
|
||||||
|
<uni-icons type="forward" size="20" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="load-more" v-if="followUpLoading">
|
||||||
|
<uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
|
||||||
|
<text class="load-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<view class="no-more" v-if="!followUpHasMore && followUpList.length > 0">
|
||||||
|
<text class="no-more-text">没有更多数据了</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<empty v-else></empty>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
<!-- <view class="floating-add-btn" @click="showAddMenu">
|
||||||
|
<uni-icons type="plus" size="24" color="#ffffff"></uni-icons>
|
||||||
|
<text class="btn-text">添加</text>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<view class="add-menu-popup" v-if="showAddMenuFlag" @click="hideAddMenu">
|
||||||
|
<view class="menu-content" @click.stop>
|
||||||
|
<view class="menu-item" @click="addSchedule">
|
||||||
|
<up-image :src="dayImg" width="34rpx" height="34rpx" ></up-image>
|
||||||
|
<text class="menu-text">添加日程</text>
|
||||||
|
</view>
|
||||||
|
<view class="menu-divider"></view>
|
||||||
|
<view class="menu-item" @click="addFollowUpPlan">
|
||||||
|
<up-image :src="planImg" width="34rpx" height="34rpx" ></up-image>
|
||||||
|
<text class="menu-text">添加随访计划</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import { onShow } from '@dcloudio/uni-app'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import api from '@/api/api.js'
|
||||||
|
import navTo from '@/utils/navTo.js'
|
||||||
|
import dayImg from '@/static/visit_data11.png'
|
||||||
|
import planImg from '@/static/visitplan.png'
|
||||||
|
import lineImg from '@/static/item_visitplan_fg.png'
|
||||||
|
|
||||||
|
const formatYearMonth = (input) => {
|
||||||
|
if (!input) return ''
|
||||||
|
const d = dayjs(input)
|
||||||
|
return d.isValid() ? d.format('YYYY年MM月') : ''
|
||||||
|
}
|
||||||
|
const formatDay = (input) => {
|
||||||
|
if (!input) return ''
|
||||||
|
const d = dayjs(input)
|
||||||
|
return d.isValid() ? d.format('DD日') : ''
|
||||||
|
}
|
||||||
|
|
||||||
|
const followUpList = ref([])
|
||||||
|
const followUpLoading = ref(false)
|
||||||
|
const followUpRefreshing = ref(false)
|
||||||
|
const followUpHasMore = ref(true)
|
||||||
|
const followUpPageSize = ref(10)
|
||||||
|
const page = ref(1)
|
||||||
|
|
||||||
|
const groupedFollowUpList = computed(() => {
|
||||||
|
if (!followUpList.value || followUpList.value.length === 0) return []
|
||||||
|
const groups = new Map()
|
||||||
|
followUpList.value.forEach(item => {
|
||||||
|
const yearMonth = formatYearMonth(item.datetime)
|
||||||
|
if (!groups.has(yearMonth)) groups.set(yearMonth, [])
|
||||||
|
groups.get(yearMonth).push(item)
|
||||||
|
})
|
||||||
|
return Array.from(groups.entries()).map(([yearMonth, items]) => ({
|
||||||
|
yearMonth,
|
||||||
|
items: items.sort((a, b) => new Date(a.datetime) - new Date(b.datetime))
|
||||||
|
})).sort((a, b) => new Date(a.items[0].datetime) - new Date(b.items[0].datetime))
|
||||||
|
})
|
||||||
|
|
||||||
|
const getFollowUpList = async (isRefresh = false) => {
|
||||||
|
if (followUpLoading.value) return
|
||||||
|
followUpLoading.value = true
|
||||||
|
try {
|
||||||
|
const currentPage = isRefresh ? 1 : page.value
|
||||||
|
const res = await api.followUpList({ page: currentPage, pageSize: followUpPageSize.value })
|
||||||
|
if (res.code === 200) {
|
||||||
|
const newData = res.data.list || []
|
||||||
|
if (isRefresh) {
|
||||||
|
followUpList.value = newData
|
||||||
|
page.value = 1
|
||||||
|
} else {
|
||||||
|
followUpList.value = [...followUpList.value, ...newData]
|
||||||
|
}
|
||||||
|
followUpHasMore.value = newData.length >= followUpPageSize.value
|
||||||
|
if (!isRefresh) page.value++
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
uni.showToast({ title: '获取数据失败', icon: 'error' })
|
||||||
|
} finally {
|
||||||
|
followUpLoading.value = false
|
||||||
|
followUpRefreshing.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onFollowUpRefresh = async () => {
|
||||||
|
followUpRefreshing.value = true
|
||||||
|
await getFollowUpList(true)
|
||||||
|
uni.showToast({ title: '刷新成功', icon: 'none' })
|
||||||
|
}
|
||||||
|
const onFollowUpLoadMore = async () => {
|
||||||
|
if (!followUpHasMore.value || followUpLoading.value) return
|
||||||
|
await getFollowUpList(false)
|
||||||
|
}
|
||||||
|
const goBack = () => uni.navigateBack()
|
||||||
|
const showAddMenuFlag = ref(false)
|
||||||
|
const showAddMenu = () => { showAddMenuFlag.value = true }
|
||||||
|
const hideAddMenu = () => { showAddMenuFlag.value = false }
|
||||||
|
const addFollowUpPlan = () => { showAddMenuFlag.value = false; uni.navigateTo({ url: '/pages_app/visit/visit?from=visitPlan' }) }
|
||||||
|
const addSchedule = () => { showAddMenuFlag.value = false; uni.navigateTo({ url: '/pages_app/schedule/schedule' }) }
|
||||||
|
const goFollowDetail = (raw) => { if (!raw) return; navTo({ url: `/pages_app/followDetail/followDetail?followUpUuid=${encodeURIComponent(raw.uuid || '')}&patient_name=${raw.patientname}` }) }
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
followUpList.value = []
|
||||||
|
page.value = 1
|
||||||
|
followUpHasMore.value = true
|
||||||
|
followUpLoading.value = false
|
||||||
|
followUpRefreshing.value = false
|
||||||
|
getFollowUpList(true)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.save-btn {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #8b2316;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content { background-color: #f5f5f5; height: 100vh; overflow-y: hidden; }
|
||||||
|
.linebox{ margin:0 20rpx; }
|
||||||
|
.plan{ position: fixed; top: 140rpx; left: 0; right: 0; bottom:0rpx; }
|
||||||
|
.plan-scroll { height: 100%; }
|
||||||
|
.plan-list{ padding-bottom: 20rpx; }
|
||||||
|
.plan-group{ background:#f5f5f5; }
|
||||||
|
.group-header{ text-align: center; background:#e4e4e4; color:#333; font-size: 30rpx; padding: 20rpx 30rpx; }
|
||||||
|
.plan-card{ display:flex; align-items:center; background:#fff; padding: 26rpx 30rpx; border-bottom:1rpx solid #f0f0f0; }
|
||||||
|
.left-rail{ display:flex; align-items:center; color:#8B2316; }
|
||||||
|
.left-rail .day{ font-size: 36rpx; margin-right: 12rpx; }
|
||||||
|
.right-content{ flex:1; display:flex; align-items:center; justify-content:space-between; }
|
||||||
|
.right-content .note{ font-size: 30rpx; color:#333; }
|
||||||
|
.right-content .name{ margin-top: 30rpx; font-size: 28rpx; color:#8B2316; }
|
||||||
|
.load-more { display:flex; align-items:center; justify-content:center; padding:30rpx; color:#999; }
|
||||||
|
.load-more .load-text { margin-left:10rpx; font-size:28rpx; }
|
||||||
|
.no-more { display:flex; align-items:center; justify-content:center; padding:30rpx; }
|
||||||
|
.no-more .no-more-text{ font-size:28rpx; color:#999; }
|
||||||
|
.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-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; }
|
||||||
|
.menu-divider{ height:1rpx; background:#f0f0f0; margin:0 40rpx; }
|
||||||
|
</style>
|
||||||
|
|
||||||
BIN
static/point_buy.png
Normal file
BIN
static/point_buy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
Loading…
x
Reference in New Issue
Block a user