9.4上午提交
This commit is contained in:
parent
b068fb00cc
commit
e86f8e77a7
34
api/api.js
34
api/api.js
@ -340,6 +340,40 @@ const api = {
|
||||
groupList(data){
|
||||
return request('/expertAPI/groupListU', data, 'post', false);
|
||||
},
|
||||
patientListByGroup(data){
|
||||
return request('/expertAPI/patientListByGroupU', data, 'post', false);
|
||||
},
|
||||
groupDelete(data){
|
||||
return request('/expertAPI/deleteGroupU', data, 'post', false);
|
||||
},
|
||||
groupAdd(data){
|
||||
return request('/expertAPI/addGroupU', data, 'post', false);
|
||||
},
|
||||
groupUpdate(data){
|
||||
return request('/expertAPI/updateGroupU', data, 'post', false);
|
||||
},
|
||||
updateNicknameNote(data){
|
||||
return request('/expertAPI/updateNicknameNote', data, 'post', false);
|
||||
},
|
||||
patientCard(data){
|
||||
return request('/expertAPI/patientCard', data, 'post', false);
|
||||
},
|
||||
patientCardUpdateGroup(data){
|
||||
return request('/expertAPI/patientCardUpdateGroup', data, 'post', false);
|
||||
},
|
||||
addFollowUps(data){
|
||||
return request('/expertAPI/addFollowUps', data, 'post', false);
|
||||
},
|
||||
getFollowUp(data){
|
||||
return request('/expertAPI/getFollowUp', data, 'post', false);
|
||||
},
|
||||
deleteFollowUp(data){
|
||||
return request('/expertAPI/deleteFollowUp', data, 'post', false);
|
||||
},
|
||||
cancelRes(data){
|
||||
return request('/expertAPI/cancelRes', data, 'post', false);
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
export default api
|
||||
@ -100,7 +100,7 @@
|
||||
console.log('格式化后的内容数组:', lines);
|
||||
return lines;
|
||||
}
|
||||
const emit = defineEmits(['close'])
|
||||
const emit = defineEmits(['close','confirm'])
|
||||
|
||||
|
||||
|
||||
@ -109,7 +109,9 @@
|
||||
|
||||
}
|
||||
const onconfirm=()=>{
|
||||
emit('close')
|
||||
emit('confirm')
|
||||
emit('close');
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
61
pages.json
61
pages.json
@ -212,6 +212,7 @@
|
||||
"path": "login/login",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -222,6 +223,7 @@
|
||||
"path": "video/video",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -232,6 +234,7 @@
|
||||
"path": "myPatient/myPatient",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -242,6 +245,7 @@
|
||||
"path": "patientSetting/patientSetting",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -252,6 +256,7 @@
|
||||
"path": "patientRemark/patientRemark",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -262,6 +267,18 @@
|
||||
"path": "groupEdit/groupEdit",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "groupManage/groupManage",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -272,17 +289,40 @@
|
||||
"path": "selectPatient/selectPatient",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "visitNote/visitNote",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "followDetail/followDetail",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "videoDetail/videoDetail",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -293,6 +333,7 @@
|
||||
"path": "myFlower/myFlower",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -543,6 +584,7 @@
|
||||
{
|
||||
"path": "setting/setting",
|
||||
"style": {
|
||||
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
@ -564,6 +606,7 @@
|
||||
"path": "visit/visit",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -574,6 +617,7 @@
|
||||
"path": "patientDetail/patientDetail",
|
||||
"style": {
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarRightButton":{ "hide": true},
|
||||
"navigationBarTitleText": "uni-app分页",
|
||||
"app": {
|
||||
"bounce": "none"
|
||||
@ -817,6 +861,21 @@
|
||||
"backgroundColor": "#F8F8F8",
|
||||
"app-plus": {
|
||||
"background": "#efeff4"
|
||||
},
|
||||
"mp-weixin": {
|
||||
"navigationStyle": "custom"
|
||||
},
|
||||
"mp-alipay": {
|
||||
"navigationStyle": "custom"
|
||||
},
|
||||
"mp-baidu": {
|
||||
"navigationStyle": "custom"
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"navigationStyle": "custom"
|
||||
},
|
||||
"mp-qq": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
"condition" : { //模式配置,仅开发期间生效
|
||||
|
||||
@ -216,12 +216,12 @@
|
||||
<up-image :src="signImg" width="604rpx" height="964rpx" ></up-image>
|
||||
</view>
|
||||
<view class="signcontent">
|
||||
<view class="day">今天是我们相识的第211天</view>
|
||||
<view class="signtotal">本周共签到2次</view>
|
||||
<view class="signcontinue">已经连续签到2天</view>
|
||||
<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="showSign=false">
|
||||
我是新闻内容
|
||||
<view class="news" @click.stop="goNews">
|
||||
{{signInfo.news.summary}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@ -253,6 +253,7 @@
|
||||
import sign from "@/static/home_qiandao_icon.png"
|
||||
import signImg from "@/static/sign_in_bng_big.png"
|
||||
import dayjs from 'dayjs'
|
||||
import docUrl from "@/utils/docUrl.js"
|
||||
const expertDetail=reactive({})
|
||||
const showSign=ref(false)
|
||||
// 定义refs
|
||||
@ -512,7 +513,23 @@
|
||||
url: '/pages/guide/list'
|
||||
});
|
||||
};
|
||||
|
||||
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);
|
||||
uni.navigateTo({
|
||||
url: `/pages_app/webview/webview?url=${encoded}`
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
// 点击顶部轮播图
|
||||
const onBannerClick = (item,index) => {
|
||||
if (!item) return;
|
||||
@ -833,7 +850,7 @@
|
||||
url: '/pages_course/course/course'
|
||||
});
|
||||
};
|
||||
|
||||
const signInfo=reactive({})
|
||||
// 签到点击事件
|
||||
const onSignClick = async () => {
|
||||
// 如果已经签到,显示提示
|
||||
@ -848,13 +865,15 @@
|
||||
score_type:1
|
||||
});
|
||||
|
||||
if (res && res.code === 200) {
|
||||
if (res && res.code ==1) {
|
||||
// 签到成功
|
||||
isSignedIn.value = true;
|
||||
uni.showToast({
|
||||
title: '签到成功,获得10积分',
|
||||
icon: 'success'
|
||||
title: '签到成功,获得'+res.bonuspoints+'积分',
|
||||
icon: 'none'
|
||||
});
|
||||
Object.assign(signInfo,res);
|
||||
|
||||
|
||||
// 显示签到弹窗
|
||||
showSign.value = true;
|
||||
|
||||
116
pages_app/followDetail/followDetail.vue
Normal file
116
pages_app/followDetail/followDetail.vue
Normal file
@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<view class="visit-note-page">
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="随访详情"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eee"
|
||||
>
|
||||
|
||||
</uni-nav-bar>
|
||||
|
||||
<!-- 患者行 -->
|
||||
<view class="row" @click="noop">
|
||||
<text class="row-label">患者</text>
|
||||
<text class="row-value">{{ patientName }}</text>
|
||||
</view>
|
||||
<view class="row" @click="noop">
|
||||
<text class="row-label">日期</text>
|
||||
<text class="row-value">{{ datetime }}</text>
|
||||
</view>
|
||||
<!-- 标题栏 -->
|
||||
<view class="section-title">随访内容</view>
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<view class="note-box">
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" />
|
||||
</view>
|
||||
<!-- 底部删除按钮 -->
|
||||
<view class="fixed-footer">
|
||||
<view class="fixed-btn" @click="deleteFollowUp">删除该条记录</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad,onShow } from '@dcloudio/uni-app'
|
||||
import api from '@/api/api.js'
|
||||
const patientName = ref('')
|
||||
const note = ref('请近日来医院复诊、复查')
|
||||
const datetime = ref('')
|
||||
const followUpUuid = ref('')
|
||||
onLoad((options) => {
|
||||
patientName.value = options?.patient_name
|
||||
if (options?.followUpUuid) followUpUuid.value = options.followUpUuid
|
||||
})
|
||||
onShow(() => {
|
||||
getFollowUp();
|
||||
})
|
||||
const deleteFollowUp = () => {
|
||||
api.deleteFollowUp({
|
||||
uuid: followUpUuid.value
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if(res.code == 200){
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
setTimeout(() => goBack(), 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
const getFollowUp = () => {
|
||||
api.getFollowUp({
|
||||
uuid: followUpUuid.value
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if(res.code == 200){
|
||||
note.value = res.data.note
|
||||
datetime.value = res.data.datetime
|
||||
}
|
||||
})
|
||||
}
|
||||
const goBack = () => uni.navigateBack()
|
||||
const submit = () => {
|
||||
try {
|
||||
const pages = getCurrentPages()
|
||||
const curr = pages[pages.length - 1]
|
||||
const ec = curr?.getOpenerEventChannel?.()
|
||||
ec?.emit && ec.emit('onVisitNoteSubmit', { note: note.value, idx: Number(idx.value) })
|
||||
} catch (e) {}
|
||||
uni.showToast({ title: '已添加', icon: 'success' })
|
||||
setTimeout(() => goBack(), 600)
|
||||
}
|
||||
const noop = () => {}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.visit-note-page{
|
||||
min-height: 100vh; background:#f5f5f5; padding-bottom: 120rpx;
|
||||
}
|
||||
.nav-right{ display:flex; align-items:center; }
|
||||
.submit-text{ color:#8B2316; font-size: 30rpx; }
|
||||
|
||||
.row{
|
||||
margin-top: 20rpx; background:#fff; padding: 26rpx 30rpx; display:flex; align-items:center; justify-content:space-between; border-bottom: 1rpx solid #eee;
|
||||
.row-label{ font-size: 32rpx; color:#8B2316; font-weight: 500; }
|
||||
.row-value{ font-size: 32rpx; color:#333; }
|
||||
}
|
||||
|
||||
.section-title{ background:#fff; padding: 22rpx 30rpx; color:#8B2316; font-size: 30rpx; border-top: 1rpx solid #eee; border-bottom: 1rpx solid #eee; }
|
||||
|
||||
.note-box{ background:#fff; padding: 20rpx 24rpx; }
|
||||
.note-textarea{
|
||||
box-sizing: border-box;
|
||||
width: 100%; min-height: 260rpx; background:#e5e5e5; border-radius: 0; padding: 20rpx; font-size: 32rpx; color:#111;
|
||||
}
|
||||
.fixed-footer{ position: fixed; left: 0; right: 0; bottom: 0; padding: 20rpx; background: transparent; }
|
||||
.fixed-btn{ background:#8B2316; border-radius: 12rpx; padding: 24rpx 30rpx; text-align:center; color:#fff; font-size:30rpx; margin: 0 20rpx; }
|
||||
</style>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<view class="group-edit-page">
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="编辑分组"
|
||||
:title="groupUuid ? '编辑分组' : '新建分组'"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
@ -11,7 +11,7 @@
|
||||
backgroundColor="#eee"
|
||||
>
|
||||
<template #right>
|
||||
<text class="save-text" @click="saveGroup">保存</text>
|
||||
<view class="save-text" @click="saveGroup">保存</view>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
|
||||
@ -26,30 +26,35 @@
|
||||
|
||||
<!-- 分组成员 -->
|
||||
<view class="section-header">分组成员</view>
|
||||
|
||||
<view class="add-member" @click="addMember">
|
||||
<view class="add-circle">
|
||||
<up-icon name="plus" size="34" color="#bfbfbf" />
|
||||
</view>
|
||||
<text class="add-text">添加组患者</text>
|
||||
</view>
|
||||
|
||||
<view class="member-list">
|
||||
<view class="member-item" v-for="(m, idx) in members" :key="m.uuid || idx">
|
||||
<image class="avatar" :src="docUrl + (m.photo || '')" mode="aspectFill" />
|
||||
<text class="member-name">{{ m.realName || '未知' }}</text>
|
||||
<view class="remove-btn" @click="removeMember(idx)">
|
||||
<view class="remove-circle">
|
||||
<up-icon name="minus" color="#fff" size="28rpx" bold></up-icon>
|
||||
</view>
|
||||
<!-- 已选中的成员 -->
|
||||
<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>
|
||||
<view class="remove-selected" @click="removeMember(idx)">
|
||||
<text class="remove-text">——</text>
|
||||
<!-- <up-icon name="minus" size="43rpx" color="#fff" bold /> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- 底部删除按钮 -->
|
||||
<view class="bottom-danger">
|
||||
<button class="danger-btn" @click="deleteGroup">删除分组</button>
|
||||
<button class="danger-btn" @click="visible=true">删除分组</button>
|
||||
</view>
|
||||
<unidialog :visible="visible" :content="'删除分析组?'" @close="visible=false" @confirm="confirmDelete"></unidialog>
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -58,19 +63,24 @@
|
||||
import navTo from '@/utils/navTo.js'
|
||||
import docUrl from '@/utils/docUrl.js'
|
||||
import delImg from "@/static/iv_delete.png"
|
||||
|
||||
import api from '@/api/api.js'
|
||||
import unidialog from '@/components/dialog/dialog.vue'
|
||||
const groupUuid = ref('')
|
||||
const groupName = ref('')
|
||||
const members = ref([])
|
||||
|
||||
const visible = ref(false)
|
||||
const confirmDelete = () => {
|
||||
deleteGroup();
|
||||
}
|
||||
onLoad((query) => {
|
||||
groupUuid.value = query?.uuid || ''
|
||||
console.log(query)
|
||||
groupUuid.value = query?.uuid || '';
|
||||
if(groupUuid.value){
|
||||
patientListByGroup()
|
||||
}
|
||||
// TODO: 根据 uuid 拉取分组详情
|
||||
// 预置示例
|
||||
groupName.value = '看看'
|
||||
members.value = [
|
||||
{ uuid: 'u1', realName: '测试', photo: '' }
|
||||
]
|
||||
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
@ -89,9 +99,17 @@
|
||||
|
||||
const saveGroup = () => {
|
||||
// TODO: 调用保存接口: { uuid: groupUuid, name: groupName, members }
|
||||
uni.showToast({ title: '已保存', icon: 'success' })
|
||||
if(groupUuid.value){
|
||||
groupUpdate()
|
||||
}else{
|
||||
groupAdd()
|
||||
}
|
||||
}
|
||||
const addMember = () => {
|
||||
// 传递已选中的成员ID到选择页面,让选择页面知道哪些已经选中
|
||||
const selectedIds = members.value.map(m => m.uuid)
|
||||
uni.setStorageSync('preSelectedIds', selectedIds)
|
||||
|
||||
// 跳转选择患者页并监听事件通道返回
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/selectPatient/selectPatient',
|
||||
@ -106,15 +124,49 @@
|
||||
members.value.splice(idx, 1)
|
||||
}
|
||||
const deleteGroup = () => {
|
||||
uni.showModal({
|
||||
title: '删除分组',
|
||||
content: '确定要删除该分组吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
// TODO: 调用删除接口
|
||||
uni.showToast({ title: '已删除', icon: 'success' })
|
||||
setTimeout(() => goBack(), 700)
|
||||
}
|
||||
api.groupDelete({
|
||||
group_uuid: groupUuid.value
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
uni.showToast({ title: '删除成功', icon: 'none' })
|
||||
setTimeout(() => goBack(), 700)
|
||||
}
|
||||
})
|
||||
}
|
||||
const groupAdd = () => {
|
||||
if(!groupName.value){
|
||||
uni.showToast({
|
||||
title: '请输入分组名称',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
api.groupAdd({
|
||||
name: groupName.value,
|
||||
patient_uuid: members.value.map(m => m.uuid).join(','),
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
uni.showToast({ title: '保存成功', icon: 'none' })
|
||||
setTimeout(() => goBack(), 700)
|
||||
}
|
||||
})
|
||||
}
|
||||
const groupUpdate = () => {
|
||||
if(!groupName.value){
|
||||
uni.showToast({
|
||||
title: '请输入分组名称',
|
||||
icon: 'none'
|
||||
})
|
||||
return
|
||||
}
|
||||
api.groupUpdate({
|
||||
uuid: groupUuid.value,
|
||||
name: groupName.value,
|
||||
patient_uuid: members.value.map(m => m.uuid).join(','),
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
uni.showToast({ title: '保存成功', icon: 'none' })
|
||||
setTimeout(() => goBack(), 700)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -129,6 +181,16 @@
|
||||
}
|
||||
})
|
||||
}
|
||||
const patientListByGroup = async () => {
|
||||
const res = await api.patientListByGroup({
|
||||
group_uuid: groupUuid.value,
|
||||
list_sort:0
|
||||
})
|
||||
if(res.code == 200){
|
||||
members.value = res.data.patient_list
|
||||
groupName.value = res.data.group.name
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -137,7 +199,16 @@
|
||||
background: #f5f5f5;
|
||||
padding-bottom: 160rpx;
|
||||
}
|
||||
.save-text{ color:#8B2316; font-size: 30rpx; }
|
||||
.save-text{
|
||||
background:#8B2316;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 15rpx 25rpx;
|
||||
color:#fff;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.section-header{
|
||||
background:#d9d9d9;
|
||||
@ -160,6 +231,18 @@
|
||||
.icon-btn{ padding-left: 20rpx; }
|
||||
}
|
||||
|
||||
.selected-members{
|
||||
background:#fff;
|
||||
.selected-item{
|
||||
display:flex; align-items:center; justify-content:space-between;
|
||||
padding: 20rpx 30rpx; border-bottom: 1rpx solid #eee;
|
||||
.selected-avatar{ width: 80rpx; height: 80rpx; border-radius: 12rpx; background:#ffe; }
|
||||
.selected-name{ flex:1; margin-left: 20rpx; font-size: 30rpx; color:#333; }
|
||||
.remove-selected{ width: 48rpx; height: 48rpx; border-radius: 50%; background:#8B2316; display:flex; align-items:center; justify-content:center; }
|
||||
}
|
||||
.remove-text{ font-size: 14rpx; color:#fff;font-weight: bold; }
|
||||
}
|
||||
|
||||
.add-member{
|
||||
background:#fff;
|
||||
display:flex;
|
||||
@ -176,18 +259,6 @@
|
||||
.add-text{ font-size: 32rpx; color:#666; }
|
||||
}
|
||||
|
||||
.member-list{
|
||||
background:#fff;
|
||||
.member-item{
|
||||
display:flex; align-items:center; justify-content:space-between;
|
||||
padding: 26rpx 30rpx; border-bottom: 1rpx solid #eee;
|
||||
.avatar{ width: 100rpx; height: 100rpx; border-radius: 16rpx; background:#ffe; }
|
||||
.member-name{ flex:1; margin-left: 20rpx; font-size: 32rpx; color:#333; }
|
||||
.remove-btn{ padding-left: 20rpx; }
|
||||
.remove-circle{ width: 48rpx; height:48rpx; background:#8B2316; border-radius:50%; display:flex; align-items:center; justify-content:center; }
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-danger{
|
||||
position: fixed; left:30rpx; right:30rpx; bottom: 30rpx;
|
||||
background:#fff; border-top: 1rpx solid #eee;
|
||||
|
||||
251
pages_app/groupManage/groupManage.vue
Normal file
251
pages_app/groupManage/groupManage.vue
Normal file
@ -0,0 +1,251 @@
|
||||
<template>
|
||||
<view class="group-manage-page">
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="分组管理"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eee"
|
||||
>
|
||||
<template #right>
|
||||
<view class="save-text" @click="saveGroups">保存</view>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
|
||||
<!-- 已选中的分组 -->
|
||||
<view class="selected-section">
|
||||
<view class="tag-list">
|
||||
<view
|
||||
class="tag-item selected"
|
||||
v-for="(group, index) in selectedGroups"
|
||||
:key="group.uuid"
|
||||
>
|
||||
<text class="tag-text">{{ group.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 所有分组 -->
|
||||
<view class="all-groups-section">
|
||||
<view class="section-title">所有分组(选择分组)</view>
|
||||
<view class="tag-list">
|
||||
<view
|
||||
class="tag-item"
|
||||
:class="{ selected: isGroupSelected(group) }"
|
||||
v-for="group in allGroups"
|
||||
:key="group.uuid"
|
||||
@click="selectGroup(group)"
|
||||
>
|
||||
<text class="tag-text">{{ group.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部添加按钮 -->
|
||||
<view class="bottom-bar">
|
||||
<button class="add-btn" @click="show=true">添加分组</button>
|
||||
</view>
|
||||
</view>
|
||||
<up-modal :show="show" :title="'添加分组'" showCancelButton confirmColor="#8B2316" @confirm="addGroup" @cancel="show=false">
|
||||
<view class="slot-content">
|
||||
<input class="input" v-model="groupName" placeholder="请输入分组名称" />
|
||||
</view>
|
||||
</up-modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import api from "@/api/api.js";
|
||||
|
||||
const selectedGroups = ref([]);
|
||||
const allGroups = ref([]);
|
||||
const groupName = ref('');
|
||||
const show = ref(false);
|
||||
const patientUuid = ref('');
|
||||
onLoad((options) => {
|
||||
patientUuid.value = options.uuid
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
loadAllGroups();
|
||||
});
|
||||
|
||||
const goBack = () => uni.navigateBack();
|
||||
|
||||
const loadAllGroups = async () => {
|
||||
try {
|
||||
const res = await api.groupList();
|
||||
if (res.code === 200) {
|
||||
allGroups.value = res.data || [];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("加载分组列表失败:", e);
|
||||
}
|
||||
};
|
||||
|
||||
const selectGroup = (group) => {
|
||||
// 检查是否已经选中
|
||||
const isSelected = selectedGroups.value.some((g) => g.uuid === group.uuid);
|
||||
if (isSelected) {
|
||||
// 如果已选中,则取消选中
|
||||
const index = selectedGroups.value.findIndex((g) => g.uuid === group.uuid);
|
||||
selectedGroups.value.splice(index, 1);
|
||||
return;
|
||||
}
|
||||
// 限制最多选择三个
|
||||
if (selectedGroups.value.length >= 3) {
|
||||
uni.showToast({ title: '最多选择三个分组', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
// 如果未选中,则选中
|
||||
selectedGroups.value.push(group);
|
||||
};
|
||||
|
||||
const removeSelectedGroup = (index) => {
|
||||
selectedGroups.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const isGroupSelected = (group) => {
|
||||
return selectedGroups.value.some((g) => g.uuid === group.uuid);
|
||||
};
|
||||
|
||||
const addGroup = () => {
|
||||
if(!groupName.value){
|
||||
uni.showToast({ title: '请输入分组名称', icon: 'none' })
|
||||
return;
|
||||
}
|
||||
let userInfo=uni.getStorageSync('userInfo')
|
||||
api.groupAdd({
|
||||
patient_uuid:patientUuid.value,
|
||||
name: groupName.value,
|
||||
expert_uuid:userInfo.uuid,
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
loadAllGroups();
|
||||
show.value = false;
|
||||
groupName.value = '';
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
const saveGroups = () => {
|
||||
api.patientCardUpdateGroup({
|
||||
name:selectedGroups.value.map(g => g.name).join(','),
|
||||
group_uuid: selectedGroups.value.map(g => g.uuid).join(','),
|
||||
patient_uuid: patientUuid.value
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
uni.showToast({ title: '保存成功', icon: 'none' })
|
||||
setTimeout(() => goBack(), 700);
|
||||
}
|
||||
})
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.group-manage-page {
|
||||
min-height: 100vh;
|
||||
background: #fff;
|
||||
padding-bottom: 160rpx;
|
||||
}
|
||||
|
||||
.save-text {
|
||||
color: #8b2316;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.input{
|
||||
width:450rpx;
|
||||
background: #f8f8f8;
|
||||
border-radius: 12rpx;
|
||||
padding: 16rpx 24rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
.selected-section {
|
||||
min-height: 300rpx;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.all-groups-section {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.tag-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.tag-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: #fff;
|
||||
border: 2rpx solid #999;
|
||||
border-radius: 40rpx;
|
||||
padding: 12rpx 20rpx;
|
||||
position: relative;
|
||||
&.selected {
|
||||
border-color: #8b2316;
|
||||
.tag-text {
|
||||
color: #8b2316;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tag-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.tag-close {
|
||||
width: 32rpx;
|
||||
height: 32rpx;
|
||||
border-radius: 50%;
|
||||
background: #8b2316;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
font-size: 20rpx;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bottom-bar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
border-top: 1rpx solid #f0f0f0;
|
||||
padding: 20rpx 30rpx env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: #20b2aa;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
@ -11,9 +11,11 @@
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eeeeee"
|
||||
/>
|
||||
|
||||
|
||||
>
|
||||
<template #right>
|
||||
<view class="save-text" @click="addGroup">新建</view>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
<!-- 筛选排序栏 -->
|
||||
<view class="filter-sort-bar">
|
||||
<view class="sort-section" @click="toggleGroupSort">
|
||||
@ -65,7 +67,7 @@
|
||||
<view class="groupcell" v-for="(group, gi) in groups" :key="group.uuid || gi">
|
||||
<view class="section-title" @click="toggleGroup(gi)">
|
||||
<view class="left">
|
||||
<view class="imgbox">
|
||||
<view class="imgbox" :class="{ 'active':openGroups[gi] }">
|
||||
<up-image v-if="!openGroups[gi]" :src="groupRightImg" width="19rpx" height="32rpx" ></up-image>
|
||||
<up-image v-else :src="groupDownImg" width="32rpx" height="19rpx" ></up-image>
|
||||
</view>
|
||||
@ -102,6 +104,7 @@ import groupDownImg from "@/static/groupup_big.png"
|
||||
import api from '@/api/api.js';
|
||||
import docUrl from '@/utils/docUrl'
|
||||
import dayjs from 'dayjs'
|
||||
import navTo from '@/utils/navTo.js'
|
||||
const list_sort = ref(0);
|
||||
const group_sort = ref(0);
|
||||
|
||||
@ -143,8 +146,9 @@ const toggleGroup = (idx) => {
|
||||
};
|
||||
|
||||
const editGroup = (group) => {
|
||||
// TODO: 跳转到分组编辑页或弹窗编辑
|
||||
uni.showToast({ title: `编辑:${group.name || '未命名分组'}`, icon: 'none' });
|
||||
navTo({
|
||||
url: `/pages_app/groupEdit/groupEdit?uuid=${group.uuid}`
|
||||
})
|
||||
};
|
||||
|
||||
// 分组排序弹窗状态
|
||||
@ -173,7 +177,11 @@ const chooseGroupSort = (type) => {
|
||||
closeGroupSort();
|
||||
fetchGroupList();
|
||||
};
|
||||
|
||||
const addGroup = () => {
|
||||
navTo({
|
||||
url: `/pages_app/groupEdit/groupEdit`
|
||||
})
|
||||
}
|
||||
const toggleInnerSort = () => {
|
||||
showInnerSort.value = !showInnerSort.value;
|
||||
if (showInnerSort.value) showGroupSort.value = false;
|
||||
@ -250,6 +258,14 @@ const createNew = () => {
|
||||
.popup-item.active .item-text {
|
||||
color: #8B2316;
|
||||
}
|
||||
.save-text{
|
||||
color:#8B2316;
|
||||
font-size: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
}
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@ -454,7 +470,9 @@ const createNew = () => {
|
||||
align-items:center;
|
||||
}
|
||||
.imgbox{
|
||||
margin-top: 4rpx;
|
||||
&.active{
|
||||
margin-top: -20rpx;
|
||||
}
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
.right-edit{
|
||||
|
||||
@ -87,7 +87,7 @@
|
||||
|
||||
<view class="listbox">
|
||||
<!-- 使用 up-index-list 索引组件,数据动态渲染 -->
|
||||
<up-index-list :index-list="indexList" custom-nav-height="140rpx">
|
||||
<up-index-list :index-list="indexList" custom-nav-height="140rpx" v-if="patientList.length > 0">
|
||||
<template v-for="group in patientGroups" :key="group.letter">
|
||||
<up-index-item >
|
||||
<up-index-anchor :text="group.letter" />
|
||||
@ -117,18 +117,49 @@
|
||||
</up-index-item>
|
||||
</template>
|
||||
</up-index-list>
|
||||
<empty v-else></empty>
|
||||
</view>
|
||||
</view>
|
||||
<view class="plan" v-if="activeTab === 'plan'">
|
||||
|
||||
<view class="apply-list" v-if="applyList.length > 0">
|
||||
<view class="apply-item" v-for="item in applyList" :key="item.id">
|
||||
<view class="apply-content">
|
||||
<text class="apply-text">{{ item.messagePreview }}</text>
|
||||
<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="note">{{ item.note }}</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>
|
||||
</view>
|
||||
<empty v-else></empty>
|
||||
<empty v-else></empty>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 悬浮添加按钮 -->
|
||||
<view class="floating-add-btn" @click="showAddMenu">
|
||||
@ -175,7 +206,7 @@
|
||||
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance } from 'vue';
|
||||
import { ref, getCurrentInstance, computed } from 'vue';
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import dayImg from "@/static/visit_data11.png"
|
||||
import planImg from "@/static/visitplan.png"
|
||||
@ -185,6 +216,8 @@
|
||||
const patientList = ref([]);
|
||||
import pinyin from 'pinyin';
|
||||
import dayjs from 'dayjs'
|
||||
import lineImg from "@/static/item_visitplan_fg.png"
|
||||
|
||||
const goPatientDetail = (uuid) => {
|
||||
navTo({
|
||||
url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}`
|
||||
@ -202,6 +235,18 @@
|
||||
const d = dayjs(input);
|
||||
return d.isValid() ? d.format('YYYY-MM-DD') : '';
|
||||
}
|
||||
|
||||
const formatYearMonth = (input) => {
|
||||
if (!input) return '';
|
||||
const d = dayjs(input);
|
||||
return d.isValid() ? d.format('YYYY年MM月') : '';
|
||||
}
|
||||
// 格式化显示日(如:03)
|
||||
const formatDay = (input) => {
|
||||
if (!input) return '';
|
||||
const d = dayjs(input);
|
||||
return d.isValid() ? d.format('DD日') : '';
|
||||
}
|
||||
// 申请列表数据
|
||||
const messageList = ref([
|
||||
{
|
||||
@ -283,7 +328,51 @@
|
||||
|
||||
// 刷新状态
|
||||
const isRefreshing = ref(false);
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
console.log('随访计划数据:', followUpList.value);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取随访计划失败:', error);
|
||||
uni.showToast({
|
||||
title: '获取数据失败',
|
||||
icon: 'error',
|
||||
duration: 2000
|
||||
});
|
||||
} finally {
|
||||
followUpLoading.value = false;
|
||||
followUpRefreshing.value = false;
|
||||
}
|
||||
};
|
||||
const getApplyList = async () => { // 申请列表
|
||||
|
||||
try {
|
||||
@ -321,17 +410,36 @@
|
||||
|
||||
};
|
||||
const page=ref(1)
|
||||
const followUpList = async () => {
|
||||
let userInfo=uni.getStorageSync('userInfo')
|
||||
const res = await api.followUpList({
|
||||
page:page.value,
|
||||
pageSize:10
|
||||
});
|
||||
if(res.code === '1'){
|
||||
followUpList.value = res.data;
|
||||
const followUpList = ref([]);
|
||||
|
||||
// 随访计划相关状态
|
||||
const followUpLoading = ref(false);
|
||||
const followUpRefreshing = ref(false);
|
||||
const followUpHasMore = ref(true);
|
||||
const followUpPageSize = ref(10);
|
||||
|
||||
// 按年月分组的随访计划数据
|
||||
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 onRefresh = async () => {
|
||||
@ -356,6 +464,23 @@
|
||||
}
|
||||
};
|
||||
|
||||
// 随访计划下拉刷新
|
||||
const onFollowUpRefresh = async () => {
|
||||
followUpRefreshing.value = true;
|
||||
await getFollowUpList(true);
|
||||
uni.showToast({
|
||||
title: '刷新成功',
|
||||
icon: 'success',
|
||||
duration: 1500
|
||||
});
|
||||
};
|
||||
|
||||
// 随访计划上拉加载
|
||||
const onFollowUpLoadMore = async () => {
|
||||
if (!followUpHasMore.value || followUpLoading.value) return;
|
||||
await getFollowUpList(false);
|
||||
};
|
||||
|
||||
// 搜索患者
|
||||
const searchPatients = () => {
|
||||
uni.showToast({
|
||||
@ -397,11 +522,10 @@
|
||||
// 显示患者列表
|
||||
break;
|
||||
case 'plan':
|
||||
// 跳转到随访计划页面
|
||||
uni.showToast({
|
||||
title: '随访计划',
|
||||
icon: 'none'
|
||||
});
|
||||
// 随访计划页面 - 加载随访计划数据
|
||||
if (followUpList.value.length === 0) {
|
||||
getFollowUpList(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -432,12 +556,13 @@
|
||||
const addFollowUpPlan = () => {
|
||||
showAddMenuFlag.value = false;
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/visit/visit'
|
||||
url: '/pages_app/visit/visit?from=patientMsg'
|
||||
});
|
||||
};
|
||||
|
||||
// 添加日程
|
||||
const addSchedule = () => {
|
||||
showAddMenuFlag.value = false;
|
||||
uni.navigateTo({
|
||||
url: '/pages_app/schedule/schedule'
|
||||
});
|
||||
@ -457,17 +582,25 @@
|
||||
|
||||
// 页面显示时加载数据
|
||||
onShow(() => {
|
||||
activeTab.value='message';
|
||||
loadMessageList();
|
||||
computeListHeight();
|
||||
getApplyList();
|
||||
patientListByGBK();
|
||||
followUpList();
|
||||
getFollowUpList();
|
||||
});
|
||||
|
||||
// 加载消息列表
|
||||
const loadMessageList = () => {
|
||||
// 这里可以调用API获取消息列表
|
||||
};
|
||||
|
||||
const goFollowDetail = (raw) => {
|
||||
if(!raw) return;
|
||||
navTo({
|
||||
url: `/pages_app/followDetail/followDetail?followUpUuid=${encodeURIComponent(raw.uuid || '')}&patient_name=${encodeURIComponent(raw.patient_name || '')}`
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@ -476,7 +609,9 @@
|
||||
min-height: 100vh;
|
||||
|
||||
}
|
||||
|
||||
.linebox{
|
||||
margin:0 20rpx;
|
||||
}
|
||||
// 导航栏右侧按钮样式
|
||||
.nav-right {
|
||||
display: flex;
|
||||
@ -878,5 +1013,99 @@
|
||||
background-color: #f0f0f0;
|
||||
margin: 0 40rpx;
|
||||
}
|
||||
|
||||
/* 随访计划样式 */
|
||||
.plan{
|
||||
position: fixed;
|
||||
top: 140rpx;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom:110rpx;
|
||||
}
|
||||
|
||||
.plan-scroll {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.plan-list{
|
||||
margin-top: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.plan-group{
|
||||
background:#f5f5f5;
|
||||
}
|
||||
|
||||
.group-header{
|
||||
text-align: center;
|
||||
background:#eee;
|
||||
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;
|
||||
}
|
||||
|
||||
.left-rail .rail-dot{
|
||||
width: 4rpx;
|
||||
height: 60rpx;
|
||||
background:#8B2316;
|
||||
border-radius: 2rpx;
|
||||
}
|
||||
|
||||
.right-content{
|
||||
flex:1;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
}
|
||||
|
||||
.right-content .note{
|
||||
font-size: 30rpx;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
/* 加载状态样式 */
|
||||
.load-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx;
|
||||
color: #999;
|
||||
|
||||
.load-text {
|
||||
margin-left: 10rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.no-more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx;
|
||||
|
||||
.no-more-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -12,34 +12,79 @@
|
||||
/>
|
||||
<view class="form-block">
|
||||
<view class="label">备注</view>
|
||||
<input class="input" v-model.trim="remark" placeholder="给患者添加备注名" placeholder-class="ph" maxlength="20"/>
|
||||
<input class="input" v-model.trim="remark" :placeholder="groupInfo.nickname || '给患者添加备注名'" placeholder-class="ph" maxlength="20"/>
|
||||
</view>
|
||||
<view class="form-block">
|
||||
<view class="form-block" @click="goGroup">
|
||||
<view class="label">分组</view>
|
||||
<view class="iptbox">
|
||||
<input class="input" v-model.trim="remark" placeholder="通过分组给患者分类" placeholder-class="ph" maxlength="20" readonly/>
|
||||
<view class="iptbox readonly">
|
||||
<input class="input readonly-input" v-model.trim="groupName" :placeholder="groupInfo.name || '通过分组给患者分类'" placeholder-class="ph" maxlength="20" readonly disabled/>
|
||||
<uni-icons type="right" size="20" color="#666"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-block">
|
||||
<view class="label">描述</view>
|
||||
<textarea class="textarea" v-model.trim="note" placeholder="补充患者关键信息,方便随访患者" placeholder-class="ph" auto-height maxlength="140"/>
|
||||
<textarea class="textarea" v-model.trim="note" :placeholder="groupInfo.note || '补充患者关键信息,方便随访患者'" placeholder-class="ph" auto-height maxlength="140"/>
|
||||
</view>
|
||||
|
||||
<view class="bottom-bar">
|
||||
<button class="save-btn" @click="saveRemark">保存</button>
|
||||
<button class="save-btn" @click="updateNicknameNote">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import api from '@/api/api.js'
|
||||
import navTo from '@/utils/navTo.js'
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
const remark = ref('')
|
||||
const note = ref('')
|
||||
|
||||
const groupName = ref('')
|
||||
const patientUuid = ref('')
|
||||
const patientCardData = ref({})
|
||||
const groupInfo = ref({})
|
||||
|
||||
const goBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
const goGroup = () => {
|
||||
navTo({
|
||||
url: `/pages_app/groupManage/groupManage?uuid=${patientUuid.value}`
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
patientUuid.value = options.uuid || ''
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
patientCard()
|
||||
})
|
||||
const patientCard = () =>{
|
||||
api.patientCard({
|
||||
patient_uuid: patientUuid.value
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
patientCardData.value = res
|
||||
groupInfo.value = res.group || {}
|
||||
// 初始化表单数据
|
||||
remark.value = res.group?.nickname || ''
|
||||
note.value = res.group?.note || ''
|
||||
groupName.value = res.group?.name || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
const updateNicknameNote = async() => {
|
||||
const res = await api.updateNicknameNote({
|
||||
patient_uuid: patientUuid.value,
|
||||
nickname: remark.value,
|
||||
note: note.value,
|
||||
})
|
||||
if(res.code == 200){
|
||||
uni.showToast({ title: '保存成功', icon: 'none' })
|
||||
setTimeout(() => goBack(), 700)
|
||||
}
|
||||
}
|
||||
|
||||
const saveRemark = () => {
|
||||
if (!remark.value) {
|
||||
@ -63,6 +108,10 @@
|
||||
background: #f8f8f8;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
&.readonly {
|
||||
background: #f5f5f5;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
background: #fff;
|
||||
@ -79,6 +128,10 @@
|
||||
padding: 24rpx;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
&.readonly-input {
|
||||
background: transparent;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.textarea{
|
||||
background: #f8f8f8;
|
||||
@ -101,6 +154,9 @@
|
||||
padding: 20rpx 24rpx env(safe-area-inset-bottom);
|
||||
.save-btn{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 92rpx;
|
||||
background: #8B2316;
|
||||
color: #fff;
|
||||
|
||||
@ -17,15 +17,15 @@
|
||||
<view class="cell" @click="goRemark">
|
||||
<text class="cell-left">设置备注</text>
|
||||
<view class="cell-right">
|
||||
<text class="cell-desc">给患者添加备注名</text>
|
||||
<text class="cell-desc">{{ groupInfo.nickname || '给患者添加备注名' }}</text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="cell" @click="goRemark">
|
||||
<view class="cell" @click="goGroup">
|
||||
<text class="cell-left">设置分组</text>
|
||||
<view class="cell-right">
|
||||
<text class="cell-desc">通过分组给患者分类</text>
|
||||
<text class="cell-desc">{{ groupInfo.name || '通过分组给患者分类' }}</text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@ -33,7 +33,7 @@
|
||||
<view class="cell" @click="goRemark">
|
||||
<text class="cell-left">患者描述</text>
|
||||
<view class="cell-right">
|
||||
<text class="cell-desc">补充患者关键信息,方便随访患者</text>
|
||||
<text class="cell-desc">{{ groupInfo.note || '补充患者关键信息,方便随访患者' }}</text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@ -41,7 +41,7 @@
|
||||
<view class="cell" @click="setNextFollow">
|
||||
<text class="cell-left">下次随访时间</text>
|
||||
<view class="cell-right">
|
||||
<text class="cell-desc">添加随访提醒</text>
|
||||
<text class="cell-desc">{{patientCardData.FollowUpDate? patientCardData.FollowUpDate : '添加随访提醒' }}</text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@ -55,40 +55,80 @@
|
||||
</view>
|
||||
|
||||
<view class="danger-block">
|
||||
<text class="danger-text" @click="unbindPatient">解除随访</text>
|
||||
<text class="danger-text" @click="visible=true">解除随访</text>
|
||||
</view>
|
||||
</view>
|
||||
<unidialog :visible="visible" :content="message" @close="visible=false" @confirm="deleteFollowUp" ></unidialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import navTo from '@/utils/navTo.js'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||
import api from '@/api/api.js'
|
||||
import unidialog from '@/components/dialog/dialog.vue'
|
||||
const patientUuid = ref('')
|
||||
const patientName = ref('')
|
||||
const patientCardData = ref({})
|
||||
const groupInfo = ref({})
|
||||
const visible = ref(false)
|
||||
const message = ref('')
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
}
|
||||
const goRemark = () => {
|
||||
navTo({ url: '/pages_app/patientRemark/patientRemark' })
|
||||
navTo({ url: '/pages_app/patientRemark/patientRemark?uuid=' + patientUuid.value })
|
||||
}
|
||||
|
||||
const goGroup = () => {
|
||||
navTo({ url: '/pages_app/groupManage/groupManage?uuid=' + patientUuid.value })
|
||||
}
|
||||
onLoad((options) => {
|
||||
patientUuid.value = options.uuid;
|
||||
console.log(patientUuid.value)
|
||||
})
|
||||
onShow(() => {
|
||||
patientCard();
|
||||
})
|
||||
const setNextFollow = () => {
|
||||
navTo({ url: '/pages_app/visit/visit' })
|
||||
if(patientCardData.value.FollowUpUuid){
|
||||
navTo({ url: '/pages_app/followDetail/followDetail?followUpUuid=' +patientCardData.value.FollowUpUuid+'&patient_name=' + patientName.value })
|
||||
}else{
|
||||
navTo({ url: '/pages_app/visit/visit?uuid=' + patientUuid.value+'&patient_name=' + patientName.value })
|
||||
}
|
||||
|
||||
}
|
||||
const goFeedback = () => {
|
||||
navTo({ url: '/pages_app/feedback/feedback' })
|
||||
}
|
||||
const unbindPatient = () => {
|
||||
uni.showModal({
|
||||
title: '确认解除',
|
||||
content: '确定要解除随访关系吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.showToast({ title: '已提交解除', icon: 'success' })
|
||||
// TODO: 调用解除随访接口
|
||||
}
|
||||
const patientCard = () =>{
|
||||
api.patientCard({
|
||||
patient_uuid: patientUuid.value
|
||||
}).then(res => {
|
||||
if(res.code == 200){
|
||||
patientName.value = res.group.nickname || res.patient.realName
|
||||
message.value = `解除[${patientName.value}]的随访关系?`
|
||||
patientCardData.value = res
|
||||
groupInfo.value = res.group || {}
|
||||
}
|
||||
})
|
||||
}
|
||||
const deleteFollowUp = () => {
|
||||
api.cancelRes({
|
||||
patientUuid: patientUuid.value
|
||||
}).then(res => {
|
||||
if(res.code == 1){
|
||||
uni.showToast({
|
||||
title: '解除成功',
|
||||
icon: 'none'
|
||||
})
|
||||
uni.redirectTo({
|
||||
url: '/pages_app/patientMsg/patientMsg'
|
||||
})
|
||||
}
|
||||
visible.value = false
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@ -22,14 +22,14 @@
|
||||
<!-- 排序和筛选栏 -->
|
||||
<view class="filter-bar">
|
||||
<view class="filter-item" @click="toggleSort">
|
||||
<text class="filter-text">{{sort==0?'最新':'最热'}}</text>
|
||||
<text class="filter-text active">{{sort==0?'最新':'最热'}}</text>
|
||||
<view class="newbox">
|
||||
<up-image :src="upImg" width="20rpx" height="26rpx" ></up-image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="divider"></view>
|
||||
<view class="filter-item" @click="showFilterPopup">
|
||||
<text class="filter-text">筛选</text>
|
||||
<text class="filter-text" :class="{active:isFilterActive}">筛选</text>
|
||||
<view class="filterbox">
|
||||
<up-image :src="isFilterActive ? filterOn : filter" width="30rpx" height="30rpx" ></up-image>
|
||||
</view>
|
||||
@ -119,6 +119,7 @@
|
||||
import downLoadImg from "@/static/wdxz.png"
|
||||
import api from '@/api/api.js';
|
||||
const isFilterActive=ref(false)
|
||||
const keywords=ref('')
|
||||
const sort = ref(0); // 默认最新排序
|
||||
// 响应式数据
|
||||
const refreshing = ref(false);
|
||||
@ -256,7 +257,7 @@
|
||||
page: page.value,
|
||||
sort: sort.value,
|
||||
// 可以根据需要添加其他筛选参数
|
||||
keywords: '',
|
||||
keywords:keywords.value,
|
||||
title: '',
|
||||
// fileType: selectedFileType.value,
|
||||
// sortBy: sortType.value
|
||||
@ -355,18 +356,27 @@
|
||||
|
||||
const toggleTag = (index) => {
|
||||
filterTags.value[index].selected = !filterTags.value[index].selected;
|
||||
isFilterActive.value = filterTags.value.some(tag => tag.selected);
|
||||
//isFilterActive.value = filterTags.value.some(tag => tag.selected);
|
||||
};
|
||||
|
||||
const resetFilter = () => {
|
||||
filterTags.value.forEach(tag => tag.selected = false);
|
||||
isFilterActive.value = false;
|
||||
//isFilterActive.value = false;
|
||||
};
|
||||
|
||||
const confirmFilter = () => {
|
||||
const selectedTags = filterTags.value.filter(tag => tag.selected);
|
||||
console.log('选中的筛选标签:', selectedTags);
|
||||
for (var i = 0; i < selectedTags.length; i++) {
|
||||
if(keywords.value){
|
||||
keywords.value+=","+selectedTags[i].DES
|
||||
}else{
|
||||
keywords.value=selectedTags[i].DES
|
||||
}
|
||||
}
|
||||
isFilterActive.value =true;
|
||||
hideFilterPopup();
|
||||
loadData(true);
|
||||
// 这里可以根据选中的标签进行数据筛选
|
||||
};
|
||||
const fromatPrice=(price)=>{
|
||||
@ -496,6 +506,12 @@
|
||||
.filterbox{
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
.filter-text{
|
||||
color:#666;
|
||||
}
|
||||
.filter-text.active{
|
||||
color:#8B2316
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -84,8 +84,8 @@
|
||||
<view class="calendartop">
|
||||
<view class="title">时间日期</view>
|
||||
<view class="datebox">
|
||||
<view class="year">2025年</view>
|
||||
<view class="day">11月22日周六</view>
|
||||
<view class="year">{{ headerYear }}</view>
|
||||
<view class="day">{{ headerDay }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-calendar class="uni-calendar--hook" @change="change" @monthSwitch="monthSwitch" />
|
||||
@ -110,6 +110,8 @@
|
||||
const followUpContent = ref('请于近日来院复诊、复查');
|
||||
const remindMe = ref(false);
|
||||
const remindPatient = ref(true);
|
||||
const headerYear = ref('');
|
||||
const headerDay = ref('');
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
@ -170,7 +172,17 @@
|
||||
});
|
||||
const change=(e)=>{
|
||||
console.log('change 返回:', e)
|
||||
|
||||
if(e && e.fulldate){
|
||||
const d = new Date(e.fulldate);
|
||||
const y = d.getFullYear();
|
||||
const m = d.getMonth()+1;
|
||||
const dd = d.getDate();
|
||||
const weekdays = ['日','一','二','三','四','五','六'];
|
||||
const w = weekdays[d.getDay()];
|
||||
headerYear.value = `${y}年`;
|
||||
headerDay.value = `${m}月${dd}日周${w}`;
|
||||
selectedDate.value = `${y}年${m}月${dd}日(星期${w})`;
|
||||
}
|
||||
};
|
||||
|
||||
const monthSwitch=(e)=>{
|
||||
@ -179,7 +191,6 @@
|
||||
|
||||
// 初始化页面
|
||||
const initPage = () => {
|
||||
// 设置默认日期为今天
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = today.getMonth() + 1;
|
||||
@ -187,6 +198,8 @@
|
||||
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
const weekday = weekdays[today.getDay()];
|
||||
selectedDate.value = `${year}年${month}月${day}日(星期${weekday})`;
|
||||
headerYear.value = `${year}年`;
|
||||
headerDay.value = `${month}月${day}日周${weekday}`;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
|
||||
<!-- 列表 -->
|
||||
<scroll-view class="list" scroll-y>
|
||||
<view class="item" @click="toggle(p.uuid)" v-for="p in patientList" :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" />
|
||||
<view class="name">{{ p.realName || '-' }}</view>
|
||||
<view class="check" >
|
||||
@ -50,6 +50,11 @@
|
||||
const selectedIds = ref([])
|
||||
const patientList = ref([])
|
||||
const selectedDetail = ref([])
|
||||
|
||||
// 计算属性:显示所有患者,但标记已选中的状态
|
||||
const availablePatientList = computed(() => {
|
||||
return patientList.value
|
||||
})
|
||||
const patientListByGBK = async () => {
|
||||
|
||||
const res = await api.patientListByGBK();
|
||||
@ -61,27 +66,47 @@
|
||||
|
||||
};
|
||||
onLoad(() => {
|
||||
|
||||
// 读取已选中的成员ID
|
||||
try {
|
||||
const preSelected = uni.getStorageSync('preSelectedIds')
|
||||
if (Array.isArray(preSelected)) {
|
||||
selectedIds.value = [...preSelected]
|
||||
// 清理缓存
|
||||
uni.removeStorageSync('preSelectedIds')
|
||||
}
|
||||
} catch (e) {}
|
||||
})
|
||||
onShow(() => {
|
||||
patientListByGBK();
|
||||
// 根据已选中的ID更新selectedDetail
|
||||
updateSelectedDetail();
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 根据已选中的ID更新selectedDetail
|
||||
const updateSelectedDetail = () => {
|
||||
selectedDetail.value = selectedIds.value.map(id => {
|
||||
const p = patientList.value.find(x => x.uuid === id)
|
||||
return { uuid: id, realName: p?.realName || '', photo: p?.photo || '' }
|
||||
})
|
||||
}
|
||||
|
||||
const toggle = (id) => {
|
||||
const i = selectedIds.value.indexOf(id)
|
||||
if (i > -1) {
|
||||
// 如果已选中,则取消选中
|
||||
selectedIds.value.splice(i, 1)
|
||||
const di = selectedDetail.value.findIndex(it => it.uuid === id)
|
||||
if (di > -1) selectedDetail.value.splice(di, 1)
|
||||
} else {
|
||||
// 如果未选中,则选中
|
||||
selectedIds.value.push(id)
|
||||
const p = patientList.value.find(x => x.uuid === id)
|
||||
selectedDetail.value.push({ uuid: id, realName: p?.realName || '', photo: p?.photo || '' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const onSearch = () => {}
|
||||
const goBack = () => uni.navigateBack()
|
||||
const confirmSelect = () => {
|
||||
|
||||
@ -22,20 +22,24 @@
|
||||
<view class="form-section" @click="selectPatient">
|
||||
<view class="section-label"><text class="label-text">患者</text></view>
|
||||
<view class="section-content">
|
||||
<text class="content-text">{{ selectedPatient || '请选择患者' }}</text>
|
||||
<uni-icons type="right" size="20" color="#999"></uni-icons>
|
||||
<text class="content-text">{{patientName}}</text>
|
||||
<uni-icons type="right" size="20" color="#999" v-if="from"></uni-icons>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 随访内容列表 -->
|
||||
<view class="title-bar">随访内容</view>
|
||||
<scroll-view class="visit-list" scroll-y scroll-with-animation :scroll-into-view="scrollIntoViewId">
|
||||
<view class="visitbox">
|
||||
<view class="divider"></view>
|
||||
<scroll-view class="visit-list" scroll-y scroll-with-animation :scroll-into-view="scrollIntoViewId">
|
||||
|
||||
<view class="visit-item" v-for="(item, idx) in visits" :key="item.id" :id="`visit-${item.id}`">
|
||||
<view class="left">
|
||||
<uni-icons type="close" size="20" :color="idx===0 ? '#cfcfcf' : '#c0392b'" @click="removeVisit(idx)"></uni-icons>
|
||||
</view>
|
||||
<view class="mid">
|
||||
<text class="visit-text">{{ idx+1 }}.{{ defaultContent }}</text>
|
||||
<view class="mid" @click="goVisitNote(idx,item.note)">
|
||||
<text class="visit-text">{{ idx+1 }}.{{ item.note}}</text>
|
||||
</view>
|
||||
<view class="right" @click="pickDate(idx)">
|
||||
<text class="date-text">{{ item.date }}</text>
|
||||
@ -43,6 +47,7 @@
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 添加随访日程按钮 -->
|
||||
<view class="add-row" @click="addVisit">
|
||||
@ -66,24 +71,85 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<up-overlay :show="show">
|
||||
<view class="warp">
|
||||
|
||||
<view class="calendarbox">
|
||||
<view class="calendartop">
|
||||
<!-- <view class="title">时间日期</view> -->
|
||||
<view class="datebox">
|
||||
<view class="year">{{ headerYear }}</view>
|
||||
<view class="day">{{ headerDay }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-calendar class="uni-calendar--hook" :date="calendarDate" @change="change" @monthSwitch="monthSwitch" />
|
||||
<view class="calendarbottom">
|
||||
<view class="cancel" @click="show=false">取消</view>
|
||||
<view class="ok" @click="confirmDate">确定</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</up-overlay>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref,nextTick } from 'vue';
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
|
||||
import { onShow,onLoad } from "@dcloudio/uni-app";
|
||||
import navTo from '@/utils/navTo.js';
|
||||
const patientUuid = ref('');
|
||||
const patientName = ref('');
|
||||
const show = ref(false);
|
||||
const dealIndex=ref(0);
|
||||
import api from '@/api/api.js'
|
||||
const from = ref('');
|
||||
onLoad((options) => {
|
||||
patientUuid.value = options.uuid;
|
||||
patientName.value = options.patient_name;
|
||||
from.value = options.from;
|
||||
});
|
||||
const selectedPatient = ref('');
|
||||
const defaultContent = '请近日来医院复诊、复查';
|
||||
const visits = ref([
|
||||
{ id: 1, date: formatDate(new Date()) },
|
||||
{ id: 2, date: formatDate(addMonths(new Date(), 6)) },
|
||||
{ id: 3, date: formatDate(addMonths(new Date(), 12)) },
|
||||
{ id: 4, date: formatDate(addMonths(new Date(), 24)) }
|
||||
{ id: 1, date: formatDate(addDays(new Date(), 1)),note:defaultContent},
|
||||
{ id: 2, date: formatDate(addMonths(new Date(), 6)),note:defaultContent },
|
||||
{ id: 3, date: formatDate(addMonths(new Date(), 9)),note:defaultContent },
|
||||
{ id: 4, date: formatDate(addMonths(new Date(), 12)),note:defaultContent }
|
||||
]);
|
||||
const remindMe = ref(false);
|
||||
const remindPatient = ref(true);
|
||||
const scrollIntoViewId = ref('');
|
||||
|
||||
const tempDate=ref('');
|
||||
const headerYear=ref('');
|
||||
const headerDay=ref('');
|
||||
const calendarDate=ref('');
|
||||
const setHeaderByDate=(d)=>{
|
||||
const y=d.getFullYear();
|
||||
const m=d.getMonth()+1;
|
||||
const dd=d.getDate();
|
||||
const w=['日','一','二','三','四','五','六'][d.getDay()];
|
||||
headerYear.value=`${y}年`;
|
||||
headerDay.value=`${m}月${dd}日周${w}`;
|
||||
}
|
||||
const change=(e)=>{
|
||||
tempDate.value = formatDate(new Date(e.fulldate));
|
||||
setHeaderByDate(new Date(e.fulldate));
|
||||
calendarDate.value = e.fulldate;
|
||||
}
|
||||
const confirmDate=()=>{
|
||||
visits.value[dealIndex.value].date = tempDate.value;
|
||||
show.value=false;
|
||||
}
|
||||
const goVisitNote=(idx,note)=>{
|
||||
navTo({
|
||||
url: '/pages_app/visitNote/visitNote?idx='+idx+'¬e='+encodeURIComponent(note)+'&patient_name='+encodeURIComponent(patientName.value),
|
||||
events: {
|
||||
onVisitNoteSubmit: ({ note, idx }) => {
|
||||
console.log('onVisitNoteSubmit', note, idx)
|
||||
visits.value[Number(idx)].note = note
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
function formatDate(d){
|
||||
const y=d.getFullYear();
|
||||
const m=`${d.getMonth()+1}`.padStart(2,'0');
|
||||
@ -96,22 +162,52 @@
|
||||
nd.setMonth(nd.getMonth()+m);
|
||||
return nd;
|
||||
}
|
||||
|
||||
function addDays(d, days){
|
||||
const nd = new Date(d);
|
||||
nd.setDate(nd.getDate() + days);
|
||||
return nd;
|
||||
}
|
||||
const addFollowUps=()=>{
|
||||
api.addFollowUps({
|
||||
patient_uuid: patientUuid.value,
|
||||
note: visits.value.map(item=>item.note).join('☆'),
|
||||
datetime: visits.value.map(item=>String(item.date).split('(')[0]).join('☆').replace(/\./g,'-'),
|
||||
isremindpatient: remindPatient.value?1:0,
|
||||
isremindme:remindMe.value?1:0,
|
||||
type:2
|
||||
}).then(res=>{
|
||||
console.log(res)
|
||||
if(res.code==200){
|
||||
uni.showToast({ title: '已提交', icon: 'success' });
|
||||
setTimeout(()=>uni.navigateBack(),700);
|
||||
}
|
||||
})
|
||||
}
|
||||
const goBack=()=>uni.navigateBack();
|
||||
const submitPlan=()=>{
|
||||
addFollowUps();
|
||||
uni.showToast({ title: '已提交', icon: 'success' });
|
||||
setTimeout(()=>uni.navigateBack(),1000);
|
||||
};
|
||||
const selectPatient=()=>{
|
||||
uni.showActionSheet({
|
||||
itemList:['张三','李四','王五','赵六'],
|
||||
success:(res)=>{ selectedPatient.value=['张三','李四','王五','赵六'][res.tapIndex]; }
|
||||
});
|
||||
if(from.value=='patientMsg'){
|
||||
navTo({url:'/pages_app/selectPatient/selectPatient'})
|
||||
}
|
||||
};
|
||||
|
||||
const addVisit=()=>{
|
||||
const id= Date.now();
|
||||
visits.value.push({ id, date: formatDate(new Date()) });
|
||||
// 以最后一条的日期为基准,加3个月
|
||||
let baseDate = new Date();
|
||||
const last = visits.value[visits.value.length - 1];
|
||||
if (last && last.date) {
|
||||
// last.date 形如 2025.09.02(星期二),取括号前并替换为日期
|
||||
const pure = String(last.date).split('(')[0].replace(/\./g, '-');
|
||||
const parsed = new Date(pure);
|
||||
if (!isNaN(parsed.getTime())) baseDate = parsed;
|
||||
}
|
||||
const nextDate = addMonths(baseDate, 3);
|
||||
visits.value.push({ id, date: formatDate(nextDate) });
|
||||
// 下一帧滚动到新项
|
||||
nextTick(()=>{ scrollIntoViewId.value = `visit-${id}`; });
|
||||
};
|
||||
@ -120,13 +216,16 @@
|
||||
visits.value.splice(idx,1);
|
||||
};
|
||||
const pickDate=(idx)=>{
|
||||
uni.showDatePicker({
|
||||
mode:'date',
|
||||
value:new Date().toISOString().split('T')[0],
|
||||
success:(res)=>{
|
||||
visits.value[idx].date = formatDate(new Date(res.value));
|
||||
}
|
||||
});
|
||||
show.value=true;
|
||||
dealIndex.value=idx;
|
||||
// 打开时始终显示今天
|
||||
const base=new Date();
|
||||
tempDate.value=formatDate(base);
|
||||
setHeaderByDate(base);
|
||||
const y=base.getFullYear();
|
||||
const m=`${base.getMonth()+1}`.padStart(2,'0');
|
||||
const d=`${base.getDate()}`.padStart(2,'0');
|
||||
calendarDate.value=`${y}-${m}-${d}`;
|
||||
};
|
||||
|
||||
const toggleRemindMe=()=>{ remindMe.value=!remindMe.value; };
|
||||
@ -136,6 +235,70 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.warp {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
.calendarbox{
|
||||
margin-top: 140rpx;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
:deep(.uni-calendar-item--checked){
|
||||
background:#ff3346!important;
|
||||
border-radius: 50%;
|
||||
color:#fff;
|
||||
}
|
||||
:deep(.uni-calendar-item--isDay){
|
||||
border-radius: 50%;
|
||||
background:#ff3346!important;
|
||||
}
|
||||
|
||||
|
||||
.calendartop {
|
||||
width:100%;
|
||||
.title{
|
||||
font-size:34rpx;
|
||||
padding:20rpx 30rpx 8rpx;
|
||||
}
|
||||
.datebox{
|
||||
background:#ff3346;
|
||||
display: flex;
|
||||
width:100%;
|
||||
color:#fff;
|
||||
font-size: 46rpx;
|
||||
padding:20rpx 30rpx;
|
||||
box-sizing:border-box;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
.calendarbottom{
|
||||
color:#ff3346;
|
||||
display: flex;
|
||||
box-sizing:border-box;
|
||||
padding:30rpx 40rpx 40rpx;
|
||||
width:100%;
|
||||
justify-content: flex-end;
|
||||
.ok{
|
||||
font-size: 28rpx;
|
||||
margin-left: 40rpx;
|
||||
}
|
||||
.cancel{
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
|
||||
}
|
||||
.content {
|
||||
background-color: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
@ -154,15 +317,28 @@
|
||||
.content-text { font-size: 32rpx; color:#333; }
|
||||
}
|
||||
.title-bar { padding: 20rpx 30rpx; color:#8B2316; font-size: 32rpx; background:#ffffff; margin-top: 20rpx; border-top: 1rpx solid #f0f0f0; border-bottom: 1rpx solid #f0f0f0; }
|
||||
|
||||
.visitbox{
|
||||
position: relative;
|
||||
.divider{
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 100%;
|
||||
width: 2rpx;
|
||||
background: #f0f0f0;
|
||||
z-index:2;
|
||||
}
|
||||
}
|
||||
.visit-list {
|
||||
position: relative;
|
||||
/* 让列表在可视区域内滚动 */
|
||||
height: 400rpx;
|
||||
background-color: #ffffff;
|
||||
|
||||
}
|
||||
.visit-item { box-sizing:border-box;display:flex; align-items:center; padding: 26rpx 30rpx; border-bottom:1rpx solid #f0f0f0; }
|
||||
.visit-item .left { width: 60rpx; display:flex; justify-content:center; }
|
||||
.visit-item .mid { flex:1; }
|
||||
.visit-item .mid { flex:1;width:354rpx; }
|
||||
.visit-text { font-size: 30rpx; color:#333; display: inline-block;white-space: nowrap;width:80%;overflow: hidden;}
|
||||
.visit-item .right { flex:1;display:flex; align-items:center; }
|
||||
.date-text { display: inline-block;white-space: nowrap; font-size: 30rpx; color:#333; margin-right: 10rpx; }
|
||||
|
||||
84
pages_app/visitNote/visitNote.vue
Normal file
84
pages_app/visitNote/visitNote.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<view class="visit-note-page">
|
||||
<uni-nav-bar
|
||||
left-icon="left"
|
||||
title="添加随访计划"
|
||||
@clickLeft="goBack"
|
||||
fixed
|
||||
color="#8B2316"
|
||||
height="140rpx"
|
||||
:border="false"
|
||||
backgroundColor="#eee"
|
||||
>
|
||||
<template #right>
|
||||
<view class="nav-right" @click="submit" v-if="!followUpUuid">
|
||||
<text class="submit-text">添加</text>
|
||||
</view>
|
||||
</template>
|
||||
</uni-nav-bar>
|
||||
|
||||
<!-- 患者行 -->
|
||||
<view class="row" @click="noop">
|
||||
<text class="row-label">患者</text>
|
||||
<text class="row-value">{{ patientName }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<view class="section-title">随访内容</view>
|
||||
|
||||
<!-- 输入框区域 -->
|
||||
<view class="note-box">
|
||||
<textarea class="note-textarea" v-model.trim="note" placeholder="请填写随访内容" auto-height :maxlength="200" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
const patientName = ref('')
|
||||
const note = ref('请近日来医院复诊、复查')
|
||||
const idx = ref(0)
|
||||
onLoad((options) => {
|
||||
patientName.value =decodeURIComponent( options?.patient_name )
|
||||
if (options?.note) note.value = decodeURIComponent(options.note)
|
||||
if (options?.idx) idx.value = options.idx
|
||||
|
||||
})
|
||||
|
||||
const goBack = () => uni.navigateBack()
|
||||
const submit = () => {
|
||||
try {
|
||||
const pages = getCurrentPages()
|
||||
const curr = pages[pages.length - 1]
|
||||
const ec = curr?.getOpenerEventChannel?.()
|
||||
ec?.emit && ec.emit('onVisitNoteSubmit', { note: note.value, idx: Number(idx.value) })
|
||||
} catch (e) {}
|
||||
uni.showToast({ title: '已添加', icon: 'success' })
|
||||
setTimeout(() => goBack(), 600)
|
||||
}
|
||||
const noop = () => {}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.visit-note-page{
|
||||
min-height: 100vh; background:#f5f5f5;
|
||||
}
|
||||
.nav-right{ display:flex; align-items:center; }
|
||||
.submit-text{ color:#8B2316; font-size: 30rpx; }
|
||||
|
||||
.row{
|
||||
margin-top: 20rpx; background:#fff; padding: 26rpx 30rpx; display:flex; align-items:center; justify-content:space-between; border-bottom: 1rpx solid #eee;
|
||||
.row-label{ font-size: 32rpx; color:#8B2316; font-weight: 500; }
|
||||
.row-value{ font-size: 32rpx; color:#333; }
|
||||
}
|
||||
|
||||
.section-title{box-sizing: border-box; margin-top: 20rpx; background:#fff; padding: 22rpx 30rpx; color:#8B2316; font-size: 30rpx; border-top: 1rpx solid #eee; border-bottom: 1rpx solid #eee; }
|
||||
|
||||
.note-box{ background:#fff; padding: 20rpx 24rpx; }
|
||||
.note-textarea{
|
||||
width: 100%; min-height: 260rpx; background:#e5e5e5; border-radius: 0; padding: 20rpx; font-size: 32rpx; color:#111;
|
||||
}
|
||||
</style>
|
||||
|
||||
BIN
static/item_visitplan_fg.png
Normal file
BIN
static/item_visitplan_fg.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Loading…
x
Reference in New Issue
Block a user