373 lines
8.0 KiB
Vue
373 lines
8.0 KiB
Vue
<template>
|
||
<view class="page" @touchstart="handleTapContent">
|
||
<!-- 顶部导航 -->
|
||
<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="toggleModal"></uni-icons>
|
||
</view>
|
||
</template>
|
||
</uni-nav-bar>
|
||
|
||
<!-- 警告提示区域 -->
|
||
<view class="warning-section">
|
||
<view class="warning-icon">🔔</view>
|
||
<text class="warning-text"
|
||
>若群发消息选择患者过多(建议少于200人), 部分患者可能将延迟收到消息</text
|
||
>
|
||
</view>
|
||
|
||
<!-- 消息预览卡片 -->
|
||
<view class="message-preview-card" v-if="selectedPatients.length > 0">
|
||
<view class="card-header">
|
||
<text class="label"
|
||
>消息将发送给{{ selectedPatients.length }}位患者:</text
|
||
>
|
||
<!-- <view class="close" @click="onClear">
|
||
<text>×</text>
|
||
</view> -->
|
||
</view>
|
||
<view class="card-body">
|
||
<view class="patient-list">
|
||
<text
|
||
class="patient-name"
|
||
v-for="(patient, index) in selectedPatients"
|
||
:key="patient.uuid"
|
||
>
|
||
{{ patient.nickname || patient.realName
|
||
}}{{ index < selectedPatients.length - 1 ? "、" : "" }}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态区域 -->
|
||
<view class="empty-area" v-else>
|
||
<view class="empty-content">
|
||
<text class="empty-text">请选择要发送消息的患者</text>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
|
||
<!-- 弹窗与遮罩 -->
|
||
<view v-if="showModal" class="mask" @click="closeModal"></view>
|
||
<view v-if="showModal" class="center-modal">
|
||
<view class="modal-title">温馨提示</view>
|
||
<view class="modal-divider"></view>
|
||
<view class="modal-item" @click="onSelect('single')">
|
||
<text>单独选择</text>
|
||
</view>
|
||
<view class="modal-divider"></view>
|
||
<view class="modal-item" @click="onSelect('group')">
|
||
<text>分组选择</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 底部按钮 -->
|
||
<view class="bottom-bar">
|
||
<view style="height:auto;width:100%">
|
||
<MessageInput
|
||
:isGroupSend="true"
|
||
@send="send"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from "vue";
|
||
import navBar from "@/components/navBar/navBar.vue";
|
||
import api from "@/api/api.js";
|
||
import { events } from "@/utils/im/constants";
|
||
import { onShow,onLoad,onUnload } from "@dcloudio/uni-app";
|
||
import navTo from "@/utils/navTo.js";
|
||
import MessageInput from "@/pages_chat/chat/message/message-input.vue";
|
||
const showModal = ref(false);
|
||
const selectedPatients = ref([]);
|
||
const from = ref('');
|
||
const replyMsgsMap = ref({});
|
||
const conversationType = ref("1");
|
||
const msg_content = ref("");
|
||
const msg_type = ref("1");
|
||
const to = ref("");
|
||
onLoad((options) => {
|
||
if(options.from == 'chatMsg'){
|
||
from.value = 'chatMsg';
|
||
}
|
||
})
|
||
const toggleModal = () => {
|
||
showModal.value = !showModal.value;
|
||
}
|
||
const goBack = () => {
|
||
uni.navigateBack({
|
||
delta: 1,
|
||
fail: (err) => {
|
||
navTo({
|
||
url: "/pages/index/index"
|
||
})
|
||
}
|
||
});
|
||
}
|
||
const send = (data) => {
|
||
console.log(data);
|
||
msg_content.value = data.content;
|
||
msg_type.value = data.msg_type;
|
||
addGroupSendMsg4YunXin();
|
||
}
|
||
const addGroupSendMsg4YunXin=async()=>{
|
||
const res=await api.addGroupSendMsg4YunXin({
|
||
patient_user_uuid: selectedPatients.value.map(item => item.uuid).join(','),
|
||
msg_content: msg_content.value,
|
||
msg_type: msg_type.value,
|
||
});
|
||
if(res.code==200){
|
||
uni.showToast({ title: "发送成功", icon: "none" });
|
||
navTo({
|
||
url: "/pages_chat/groupMessage/groupMessage"
|
||
})
|
||
}else{
|
||
uni.showToast({ title: res.msg, icon: "none" });
|
||
}
|
||
}
|
||
onMounted(() => {
|
||
// 初始化数据
|
||
});
|
||
const handleTapContent= () => {
|
||
uni.$emit(events.CLOSE_PANEL)
|
||
setTimeout(() => {
|
||
uni.$emit(events.CLOSE_PANEL)
|
||
}, 300)
|
||
}
|
||
|
||
onShow(() => {
|
||
try {
|
||
uni.$on('selectedChatPatients',(data)=>{
|
||
console.log(data)
|
||
selectedPatients.value = data.patients;
|
||
});
|
||
if(from.value == 'chatMsg'){
|
||
console.log(uni.getStorageSync('selectedChatPatientsSingle'))
|
||
selectedPatients.value = uni.getStorageSync('selectedChatPatientsSingle').patients;
|
||
}else{
|
||
uni.$on('selectedChatPatientsSingle',(data)=>{
|
||
console.log(data)
|
||
selectedPatients.value = data.patients;
|
||
});
|
||
}
|
||
|
||
} catch (e) {
|
||
console.error('接收已选患者失败', e);
|
||
}
|
||
});
|
||
onUnload(() => {
|
||
uni.$off('selectedChatPatients');
|
||
uni.$off('selectedChatPatientsSingle');
|
||
});
|
||
const openModal = () => {
|
||
showModal.value = true;
|
||
};
|
||
|
||
const closeModal = () => {
|
||
showModal.value = false;
|
||
};
|
||
|
||
const onSelect = (type) => {
|
||
showModal.value = false;
|
||
if (type === "single") {
|
||
navTo({
|
||
url: "/pages_app/selectPatient/selectPatient?from=chat"
|
||
})
|
||
// 这里可以跳转到患者选择页面
|
||
} else if (type === "group") {
|
||
navTo({
|
||
url: "/pages_chat/patientGroup/patientGroup"
|
||
})
|
||
// 这里可以跳转到分组选择页面
|
||
}
|
||
};
|
||
|
||
const onClear = () => {
|
||
selectedPatients.value = [];
|
||
uni.showToast({ title: "已清空选择", icon: "success" });
|
||
try { uni.removeStorageSync('GROUP_SEND_SELECTED_PATIENTS'); } catch (e) {}
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
$page-bg: #f5f5f5;
|
||
$brand: #8b2316;
|
||
$brand-deep: #8b2316;
|
||
$primary: #00cbc0;
|
||
$red: #d32f2f;
|
||
|
||
.page {
|
||
background: $page-bg;
|
||
min-height: 100vh;
|
||
position: relative;
|
||
}
|
||
|
||
// 警告提示区域
|
||
.warning-section {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
padding: 24rpx 30rpx;
|
||
background: #fff8e1;
|
||
border-left: 6rpx solid #ff9800;
|
||
margin: 20rpx 30rpx;
|
||
border-radius: 8rpx;
|
||
|
||
.warning-icon {
|
||
font-size: 28rpx;
|
||
margin-right: 16rpx;
|
||
margin-top: 4rpx;
|
||
}
|
||
|
||
.warning-text {
|
||
font-size: 26rpx;
|
||
color: #e65100;
|
||
line-height: 1.5;
|
||
flex: 1;
|
||
}
|
||
}
|
||
|
||
// 消息预览卡片
|
||
.message-preview-card {
|
||
margin: 30rpx;
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||
overflow: hidden;
|
||
border-top: 6rpx solid $red;
|
||
|
||
.card-header {
|
||
position: relative;
|
||
padding: 28rpx 28rpx 12rpx 28rpx;
|
||
|
||
.label {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.close {
|
||
position: absolute;
|
||
right: -15rpx;
|
||
top: -18rpx;
|
||
width: 100rpx;
|
||
height: 100rpx;
|
||
border-bottom-left-radius: 100rpx;
|
||
background: $red;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
text {
|
||
color: #fff;
|
||
font-size: 40rpx;
|
||
font-weight: 500;
|
||
}
|
||
}
|
||
}
|
||
|
||
.card-body {
|
||
padding: 20rpx 28rpx 28rpx 28rpx;
|
||
|
||
.patient-list {
|
||
.patient-name {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
line-height: 1.6;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// 空状态区域
|
||
.empty-area {
|
||
flex: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 100rpx 30rpx;
|
||
|
||
.empty-content {
|
||
text-align: center;
|
||
|
||
.empty-text {
|
||
font-size: 28rpx;
|
||
color: #999;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 底部按钮
|
||
.bottom-bar {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
min-height: 100rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
|
||
.btn-primary {
|
||
color: #fff;
|
||
font-size: 34rpx;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
// 遮罩与弹窗
|
||
.mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: rgba(0, 0, 0, 0.6);
|
||
z-index: 10;
|
||
}
|
||
|
||
.center-modal {
|
||
position: fixed;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 650rpx;
|
||
background: #ffffff;
|
||
border-radius: 16rpx;
|
||
z-index: 11;
|
||
overflow: hidden;
|
||
box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.modal-title {
|
||
text-align: center;
|
||
font-size: 34rpx;
|
||
color: $red;
|
||
padding: 28rpx 20rpx;
|
||
}
|
||
|
||
.modal-item {
|
||
padding: 36rpx 28rpx;
|
||
font-size: 30rpx;
|
||
color: #333333;
|
||
background: #ffffff;
|
||
}
|
||
|
||
.modal-divider {
|
||
height: 2rpx;
|
||
background: #eeeeee;
|
||
}
|
||
</style>
|