268 lines
7.1 KiB
Vue
268 lines
7.1 KiB
Vue
<template>
|
||
<view class="group-edit-page">
|
||
<uni-nav-bar
|
||
left-icon="left"
|
||
:title="groupUuid ? '编辑分组' : '新建分组'"
|
||
@clickLeft="goBack"
|
||
fixed
|
||
color="#8B2316"
|
||
height="140rpx"
|
||
:border="false"
|
||
backgroundColor="#eee"
|
||
>
|
||
<template #right>
|
||
<view class="save-text" @click="saveGroup">保存</view>
|
||
</template>
|
||
</uni-nav-bar>
|
||
|
||
<!-- 分组名称 -->
|
||
<view class="section-header">分组名称</view>
|
||
<view class="name-row">
|
||
<input class="name-input" v-model.trim="groupName" placeholder="请输入分组名称" maxlength="20" />
|
||
<view class="icon-btn" v-if="groupName" @click="clearName">
|
||
<up-image :src="delImg" width="48rpx" height="48rpx" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分组成员 -->
|
||
<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="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="visible=true">删除分组</button>
|
||
</view>
|
||
<unidialog :visible="visible" :content="'删除分析组?'" @close="visible=false" @confirm="confirmDelete"></unidialog>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref } from 'vue'
|
||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||
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) => {
|
||
console.log(query)
|
||
groupUuid.value = query?.uuid || '';
|
||
if(groupUuid.value){
|
||
patientListByGroup()
|
||
}
|
||
// TODO: 根据 uuid 拉取分组详情
|
||
// 预置示例
|
||
|
||
})
|
||
|
||
onShow(() => {
|
||
// 兜底读取从选择页写入的缓存
|
||
try {
|
||
const cached = uni.getStorageSync('patientsSelectedPayload')
|
||
if (cached && Array.isArray(cached.list) && cached.list.length) {
|
||
mergeSelected(cached.list)
|
||
uni.removeStorageSync('patientsSelectedPayload')
|
||
}
|
||
} catch (e) {}
|
||
})
|
||
|
||
const goBack = () => uni.navigateBack()
|
||
const clearName = () => { groupName.value = '' }
|
||
|
||
const saveGroup = () => {
|
||
// TODO: 调用保存接口: { uuid: groupUuid, name: groupName, members }
|
||
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',
|
||
events: {
|
||
onPatientsSelected: ({ ids, list }) => {
|
||
if (Array.isArray(list)) mergeSelected(list)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
const removeMember = (idx) => {
|
||
members.value.splice(idx, 1)
|
||
}
|
||
const deleteGroup = () => {
|
||
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)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 将选择结果合并到成员列表,按 uuid 去重
|
||
const mergeSelected = (selectedList) => {
|
||
const existIds = new Set(members.value.map(m => m.uuid))
|
||
selectedList.forEach(s => {
|
||
if (!existIds.has(s.uuid)) {
|
||
existIds.add(s.uuid)
|
||
members.value.push({ uuid: s.uuid, realName: s.realName, photo: s.photo || '' })
|
||
}
|
||
})
|
||
}
|
||
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>
|
||
.group-edit-page{
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
padding-bottom: 160rpx;
|
||
}
|
||
.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;
|
||
color:#333;
|
||
padding: 22rpx 30rpx;
|
||
font-size: 30rpx;
|
||
}
|
||
.name-row{
|
||
background:#fff;
|
||
display:flex;
|
||
align-items:center;
|
||
justify-content:space-between;
|
||
padding: 24rpx 30rpx;
|
||
border-bottom: 1rpx solid #eee;
|
||
.name-input{
|
||
flex:1;
|
||
font-size: 32rpx;
|
||
color:#333;
|
||
}
|
||
.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;
|
||
align-items:center;
|
||
gap:20rpx;
|
||
padding: 26rpx 30rpx;
|
||
border-bottom: 1rpx solid #eee;
|
||
.add-circle{
|
||
width: 96rpx; height: 96rpx; border-radius: 50%;
|
||
border: 4rpx solid #e5e5e5;
|
||
display:flex; align-items:center; justify-content:center;
|
||
background:#fff;
|
||
}
|
||
.add-text{ font-size: 32rpx; color:#666; }
|
||
}
|
||
|
||
.bottom-danger{
|
||
position: fixed; left:30rpx; right:30rpx; bottom: 30rpx;
|
||
background:#fff; border-top: 1rpx solid #eee;
|
||
.danger-btn{ width:100%; height: 96rpx; background:#8B2316; color:#fff; border:none; border-radius: 12rpx; font-size: 32rpx;display: flex; align-items: center; justify-content: center; }
|
||
}
|
||
</style>
|