851 lines
19 KiB
Plaintext
851 lines
19 KiB
Plaintext
<template>
|
||
<view class="compose-page">
|
||
<!-- 导航栏 -->
|
||
<view class="nav-bar">
|
||
<view class="nav-left" @click="goBack">
|
||
<text class="nav-text">取消</text>
|
||
</view>
|
||
<view class="nav-center">
|
||
<text class="nav-title">{{ pageTitle }}</text>
|
||
</view>
|
||
<view class="nav-right" @click="sendMessage">
|
||
<text class="nav-text" :class="{ 'disabled': !canSend }">发送</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 表单内容 -->
|
||
<scroll-view class="form-content">
|
||
<!-- 消息类型选择 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">消息类型</text>
|
||
</view>
|
||
<picker-view class="type-picker" :value="[typeIndex]" @change="onTypeChange">
|
||
<picker-view-column>
|
||
<view v-for="(type, index) in messageTypes" :key="type.id">
|
||
<text class="picker-text">{{ type.name }}</text>
|
||
</view>
|
||
</picker-view-column>
|
||
</picker-view>
|
||
</view>
|
||
|
||
<!-- 接收者选择 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">发送给</text>
|
||
</view>
|
||
<view class="receiver-input">
|
||
<input
|
||
class="input-field"
|
||
type="text"
|
||
placeholder="输入接收者ID或选择群组"
|
||
:value="formData.receiverId"
|
||
/>
|
||
<view class="select-btn" @click="selectReceiver">
|
||
<text class="btn-text">选择</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息标题 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">标题 (可选)</text>
|
||
</view>
|
||
<input
|
||
class="title-input"
|
||
type="text"
|
||
placeholder="请输入消息标题"
|
||
:value="formData.title"
|
||
maxlength="200"
|
||
/>
|
||
<view class="char-count">
|
||
<text class="count-text">{{ formData.title.length }}/200</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息内容 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">内容 *</text>
|
||
</view>
|
||
<textarea
|
||
class="content-textarea"
|
||
placeholder="请输入消息内容"
|
||
:value="formData.content"
|
||
maxlength="5000"
|
||
:auto-height="true"
|
||
/>
|
||
<view class="char-count">
|
||
<text class="count-text">{{ formData.content.length }}/5000</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息选项 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">消息选项</text>
|
||
</view>
|
||
|
||
<!-- 优先级设置 -->
|
||
<view class="option-item">
|
||
<text class="option-label">优先级</text>
|
||
<picker-view class="priority-picker" :value="[priorityIndex]" @change="onPriorityChange">
|
||
<picker-view-column>
|
||
<view v-for="(priority, index) in priorityOptions" :key="index">
|
||
<text class="picker-text">{{ priority.label }}</text>
|
||
</view>
|
||
</picker-view-column>
|
||
</picker-view>
|
||
</view>
|
||
|
||
<!-- 紧急标记 -->
|
||
<view class="option-item">
|
||
<text class="option-label">紧急消息</text>
|
||
<switch :value="formData.isUrgent" />
|
||
</view>
|
||
|
||
<!-- 推送通知 -->
|
||
<view class="option-item">
|
||
<text class="option-label">推送通知</text>
|
||
<switch :value="formData.pushNotification" />
|
||
</view>
|
||
|
||
<!-- 邮件通知 -->
|
||
<view class="option-item">
|
||
<text class="option-label">邮件通知</text>
|
||
<switch :value="formData.emailNotification" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 定时发送 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">定时发送</text>
|
||
</view>
|
||
<view class="option-item">
|
||
<text class="option-label">启用定时发送</text>
|
||
<switch :value="formData.enableSchedule" @change="onScheduleToggle" />
|
||
</view>
|
||
<view class="schedule-time" v-if="formData.enableSchedule">
|
||
<picker-date
|
||
:value="scheduleDate"
|
||
@change="onScheduleDateChange"
|
||
></picker-date>
|
||
<picker-time
|
||
:value="scheduleTime"
|
||
@change="onScheduleTimeChange"
|
||
></picker-time>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 过期时间 -->
|
||
<view class="form-section">
|
||
<view class="section-title">
|
||
<text class="title-text">过期时间</text>
|
||
</view>
|
||
<view class="option-item">
|
||
<text class="option-label">设置过期时间</text>
|
||
<switch :value="formData.enableExpiry" @change="onExpiryToggle" />
|
||
</view>
|
||
<view class="expiry-time" v-if="formData.enableExpiry">
|
||
<picker-date
|
||
:value="expiryDate"
|
||
@change="onExpiryDateChange"
|
||
></picker-date>
|
||
<picker-time
|
||
:value="expiryTime"
|
||
@change="onExpiryTimeChange"
|
||
></picker-time>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 原消息引用 (回复/转发时显示) -->
|
||
<view class="form-section" v-if="originalMessage !== null">
|
||
<view class="section-title">
|
||
<text class="title-text">{{ isReply ? '回复消息' : '转发消息' }}</text>
|
||
</view>
|
||
<view class="original-message">
|
||
<view class="original-header">
|
||
<text class="original-sender">{{ originalMessage?.sender_name ?? '未知发送者' }}</text>
|
||
<text class="original-time">{{ originalMessage?.created_at!=null ? formatTime(new Date(originalMessage!!.created_at!!)) : '' }}</text>
|
||
</view>
|
||
<view class="original-content">
|
||
<text class="original-text">{{ getMessageSummary(originalMessage?.content ?? '', 100) }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 接收者选择弹窗 -->
|
||
<view class="receiver-modal" v-if="showReceiverModal" @click="hideReceiverModal">
|
||
<view class="modal-content" @click.stop>
|
||
<view class="modal-header">
|
||
<text class="modal-title">选择接收者</text>
|
||
<view class="modal-close" @click="hideReceiverModal">
|
||
<text class="close-icon">×</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="modal-body">
|
||
<view class="receiver-type-tabs">
|
||
<view
|
||
class="tab-item"
|
||
:class="{ 'active': receiverTab === 'user' }"
|
||
@click="switchReceiverTab('user')"
|
||
>
|
||
<text class="tab-text">用户</text>
|
||
</view>
|
||
<view
|
||
class="tab-item"
|
||
:class="{ 'active': receiverTab === 'group' }"
|
||
@click="switchReceiverTab('group')"
|
||
>
|
||
<text class="tab-text">群组</text>
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view class="receiver-list">
|
||
<view
|
||
class="receiver-item"
|
||
v-for="receiver in receiverList"
|
||
:key="receiver.id"
|
||
@click="selectReceiverItem(receiver)"
|
||
>
|
||
<view class="receiver-info">
|
||
<text class="receiver-name">{{ receiver.name }}</text>
|
||
<text class="receiver-desc">{{ receiver.description }}</text>
|
||
</view>
|
||
</view>
|
||
</scroll-view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { MsgDataServiceReal } from '@/utils/msgDataServiceReal.uts'
|
||
import { MsgUtils } from '@/utils/msgUtils.uts'
|
||
import supa from '@/components/supadb/aksupainstance.uts'
|
||
import {
|
||
Message,
|
||
MessageType,
|
||
SendMessageParams
|
||
} from '@/utils/msgTypes.uts'
|
||
|
||
// 页面参数
|
||
const replyToId = ref<string>('')
|
||
const forwardId = ref<string>('')
|
||
|
||
// 响应式数据
|
||
const messageTypes = ref<Array<MessageType>>([])
|
||
const originalMessage = ref<Message | null>(null)
|
||
const loading = ref<boolean>(false)
|
||
const showReceiverModal = ref<boolean>(false)
|
||
const receiverTab = ref<string>('user')
|
||
const receiverList = ref<Array<MessageType>>([])
|
||
|
||
// 表单数据类型声明,兼容 UTS Android 类型推断
|
||
type FormData = {
|
||
messageTypeId: string
|
||
receiverId: string
|
||
title: string
|
||
content: string
|
||
priority: number
|
||
isUrgent: boolean
|
||
pushNotification: boolean
|
||
emailNotification: boolean
|
||
enableSchedule: boolean
|
||
enableExpiry: boolean
|
||
}
|
||
const formData = ref({
|
||
messageTypeId: '',
|
||
receiverId: '',
|
||
title: '',
|
||
content: '',
|
||
priority: 0,
|
||
isUrgent: false,
|
||
pushNotification: true,
|
||
emailNotification: false,
|
||
enableSchedule: false,
|
||
enableExpiry: false
|
||
} as FormData)
|
||
|
||
// UI状态
|
||
const typeIndex = ref<number>(0)
|
||
const priorityIndex = ref<number>(1)
|
||
const scheduleDate = ref<string>('')
|
||
const scheduleTime = ref<string>('')
|
||
const expiryDate = ref<string>('')
|
||
const expiryTime = ref<string>('')
|
||
|
||
// 优先级选项
|
||
const priorityOptions = [
|
||
{ label: '低优先级', value: 10 },
|
||
{ label: '普通', value: 50 },
|
||
{ label: '重要', value: 70 },
|
||
{ label: '紧急', value: 90 }
|
||
]
|
||
const isReply = computed(() => {
|
||
return replyToId.value !== ''
|
||
})
|
||
// 计算属性
|
||
const pageTitle = computed(() => {
|
||
if (originalMessage.value !== null) {
|
||
return isReply.value ? '回复消息' : '转发消息'
|
||
}
|
||
return '写消息'
|
||
})
|
||
|
||
|
||
|
||
const canSend = computed(() => {
|
||
return formData.value.content.trim() !== '' && formData.value.messageTypeId !== ''
|
||
})
|
||
|
||
// 日期/时间格式化函数,放在顶部,确保所有调用前可用
|
||
function formatDate(date: Date): string {
|
||
const y = date.getFullYear()
|
||
const m = (date.getMonth() + 1).toString().padStart(2, '0')
|
||
const d = date.getDate().toString().padStart(2, '0')
|
||
return y + '-' + m + '-' + d
|
||
}
|
||
function formatTime(date: Date): string {
|
||
const h = date.getHours().toString().padStart(2, '0')
|
||
const min = date.getMinutes().toString().padStart(2, '0')
|
||
return h + ':' + min
|
||
}
|
||
|
||
// 加载消息类型
|
||
async function loadMessageTypes(): Promise<void> {
|
||
const response = await MsgDataServiceReal.getMessageTypes()
|
||
if (response.data !== null) {
|
||
if (Array.isArray(response.data)) {
|
||
const dataArray = response.data as Array<any>
|
||
const types: Array<MessageType> = []
|
||
for (let i = 0; i < dataArray.length; i++) {
|
||
types.push(dataArray[i] as MessageType)
|
||
}
|
||
messageTypes.value = types
|
||
} else {
|
||
messageTypes.value = []
|
||
}
|
||
} else {
|
||
messageTypes.value = []
|
||
}
|
||
if (messageTypes.value.length > 0) {
|
||
formData.value.messageTypeId = messageTypes.value[0].id
|
||
}
|
||
}
|
||
|
||
// 加载原消息
|
||
async function loadOriginalMessage(): Promise<void> {
|
||
const messageId = replyToId.value !== '' ? replyToId.value : forwardId.value
|
||
if (messageId === '') return
|
||
const response = await MsgDataServiceReal.getMessageById(messageId)
|
||
if (response.data !== null) {
|
||
originalMessage.value = (response.data ?? null) as Message | null
|
||
// 预填充表单数据
|
||
const msg = originalMessage.value
|
||
if (isReply.value) {
|
||
formData.value.title = `回复: ${(msg != null && typeof msg.title === 'string') ? msg.title : ''}`
|
||
formData.value.receiverId = (msg != null && typeof msg.sender_id === 'string') ? (msg.sender_id as string) : ''
|
||
} else {
|
||
formData.value.title = `转发: ${(msg != null && typeof msg.title === 'string') ? msg.title : ''}`
|
||
formData.value.content = `转发消息:\n\n${(msg != null && typeof msg.content === 'string') ? msg.content : ''}`
|
||
}
|
||
}
|
||
}
|
||
// 工具函数
|
||
function goBack(): void {
|
||
uni.navigateBack()
|
||
}
|
||
|
||
// 事件处理
|
||
function onTypeChange(event: UniPickerViewChangeEvent): void {
|
||
const index = event.detail.value[0]
|
||
typeIndex.value = index
|
||
|
||
if (index < messageTypes.value.length) {
|
||
formData.value.messageTypeId = messageTypes.value[index].id
|
||
}
|
||
}
|
||
|
||
function onPriorityChange(event: UniPickerViewChangeEvent): void {
|
||
const index = event.detail.value[0]
|
||
priorityIndex.value = index
|
||
|
||
if (index < priorityOptions.length) {
|
||
formData.value.priority = parseInt(priorityOptions[index].value.toString())
|
||
}
|
||
}
|
||
function hideReceiverModal(): void {
|
||
showReceiverModal.value = false
|
||
}
|
||
|
||
function onScheduleToggle(): void {
|
||
if (formData.value.enableSchedule) {
|
||
const now = new Date()
|
||
scheduleDate.value = formatDate(now)
|
||
scheduleTime.value = formatTime(now)
|
||
}
|
||
}
|
||
|
||
function onExpiryToggle(): void {
|
||
if (formData.value.enableExpiry) {
|
||
const tomorrow = new Date()
|
||
tomorrow.setDate(tomorrow.getDate() + 1)
|
||
expiryDate.value = formatDate(tomorrow)
|
||
expiryTime.value = formatTime(tomorrow)
|
||
}
|
||
}
|
||
|
||
function onScheduleDateChange(date: string): void {
|
||
scheduleDate.value = date
|
||
}
|
||
|
||
function onScheduleTimeChange(time: string): void {
|
||
scheduleTime.value = time
|
||
}
|
||
|
||
function onExpiryDateChange(date: string): void {
|
||
expiryDate.value = date
|
||
}
|
||
|
||
function onExpiryTimeChange(time: string): void {
|
||
expiryTime.value = time
|
||
}
|
||
|
||
function loadReceiverList(): void {
|
||
// 这里应该根据receiverTab加载用户或群组列表
|
||
receiverList.value = []
|
||
}
|
||
|
||
function selectReceiverItem(receiver:MessageType): void {
|
||
formData.value.receiverId = receiver.id
|
||
hideReceiverModal()
|
||
}
|
||
|
||
// 发送消息
|
||
async function sendMessage(): Promise<void> {
|
||
if (!canSend.value) return
|
||
|
||
// 验证表单
|
||
const validationError = MsgUtils.validateSendParams(formData.value.title, formData.value.content)
|
||
if (validationError !== null) {
|
||
uni.showToast({
|
||
title: validationError,
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
|
||
loading.value = true
|
||
|
||
try {
|
||
const params: SendMessageParams = {
|
||
message_type_id: formData.value.messageTypeId,
|
||
receiver_type: 'user', // 根据实际选择确定
|
||
receiver_id: formData.value.receiverId === '' ? null : formData.value.receiverId,
|
||
title: formData.value.title === '' ? null : formData.value.title,
|
||
content: formData.value.content,
|
||
priority: formData.value.priority,
|
||
is_urgent: formData.value.isUrgent,
|
||
push_notification: formData.value.pushNotification,
|
||
email_notification: formData.value.emailNotification
|
||
}
|
||
|
||
// 设置定时发送
|
||
if (formData.value.enableSchedule && scheduleDate.value !== '' && scheduleTime.value !== '') {
|
||
params.scheduled_at = `${scheduleDate.value} ${scheduleTime.value}`
|
||
}
|
||
|
||
// 设置过期时间
|
||
if (formData.value.enableExpiry && expiryDate.value !== '' && expiryTime.value !== '') {
|
||
params.expires_at = `${expiryDate.value} ${expiryTime.value}`
|
||
}
|
||
|
||
const response = await MsgDataServiceReal.sendMessage(params)
|
||
|
||
let isSuccess = false
|
||
if ( response.status >= 200 && response.status < 300) {
|
||
isSuccess = true
|
||
}
|
||
if (isSuccess) {
|
||
uni.showToast({
|
||
title: '发送成功',
|
||
icon: 'success'
|
||
})
|
||
setTimeout(() => {
|
||
goBack()
|
||
}, 1500)
|
||
} else {
|
||
let errMsg = response.error?.message ?? '发送失败'
|
||
uni.showToast({
|
||
title: errMsg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: '发送失败',
|
||
icon: 'none'
|
||
})
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
// 接收者选择
|
||
function selectReceiver(): void {
|
||
showReceiverModal.value = true
|
||
loadReceiverList()
|
||
}
|
||
|
||
|
||
function switchReceiverTab(tab: string): void {
|
||
receiverTab.value = tab
|
||
loadReceiverList()
|
||
}
|
||
|
||
|
||
function getMessageSummary(content: string | null, maxLength: number): string {
|
||
return MsgUtils.getMessageSummary(content, maxLength)
|
||
}
|
||
|
||
// 初始化数据
|
||
async function loadInitialData(): Promise<void> {
|
||
await loadMessageTypes()
|
||
|
||
if (replyToId.value !== '' || forwardId.value !== '') {
|
||
await loadOriginalMessage()
|
||
}
|
||
}
|
||
|
||
// 生命周期
|
||
onLoad((options: OnLoadOptions) => {
|
||
if (options["replyTo"] !== null) {
|
||
const val = options.getString("replyTo")
|
||
if (val !== null) {
|
||
replyToId.value = val
|
||
}
|
||
}
|
||
if (options["forward"] !== null) {
|
||
const val = options.getString("forward")
|
||
if (val !== null) {
|
||
forwardId.value = val
|
||
}
|
||
}
|
||
loadInitialData()
|
||
})
|
||
</script>
|
||
|
||
<style>
|
||
.compose-page {
|
||
display: flex;
|
||
flex-direction: column;
|
||
height: 100vh;
|
||
background-color: #f5f5f5;
|
||
}
|
||
|
||
.nav-bar {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
height: 44px;
|
||
padding: 0 16px;
|
||
background-color: #ffffff;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
}
|
||
|
||
.nav-left, .nav-right {
|
||
width: 80px;
|
||
}
|
||
|
||
.nav-center {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.nav-text {
|
||
font-size: 16px;
|
||
color: #007AFF;
|
||
}
|
||
|
||
.nav-text.disabled {
|
||
color: #cccccc;
|
||
}
|
||
|
||
.nav-title {
|
||
font-size: 17px;
|
||
font-weight: 700;
|
||
color: #000000;
|
||
}
|
||
|
||
.form-content {
|
||
flex: 1;
|
||
padding: 16px;
|
||
}
|
||
|
||
.form-section {
|
||
background-color: #ffffff;
|
||
border-radius: 8px;
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.section-title {
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.title-text {
|
||
font-size: 16px;
|
||
font-weight: 700;
|
||
color: #333333;
|
||
}
|
||
|
||
.type-picker, .priority-picker {
|
||
height: 100px;
|
||
}
|
||
|
||
.picker-text {
|
||
font-size: 16px;
|
||
color: #333333;
|
||
text-align: center;
|
||
line-height: 40px;
|
||
}
|
||
|
||
.receiver-input {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.input-field {
|
||
flex: 1;
|
||
height: 40px;
|
||
padding: 0 12px;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 6px;
|
||
background-color: #f8f8f8;
|
||
}
|
||
|
||
.select-btn {
|
||
margin-left: 12px;
|
||
padding: 0 16px;
|
||
height: 40px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
background-color: #2196F3;
|
||
border-radius: 6px;
|
||
}
|
||
|
||
.btn-text {
|
||
color: #ffffff;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.title-input {
|
||
width: 100%;
|
||
height: 40px;
|
||
padding: 0 12px;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 6px;
|
||
background-color: #f8f8f8;
|
||
}
|
||
|
||
.content-textarea {
|
||
width: 100%;
|
||
min-height: 120px;
|
||
padding: 12px;
|
||
border: 1px solid #e0e0e0;
|
||
border-radius: 6px;
|
||
background-color: #f8f8f8;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.char-count {
|
||
margin-top: 8px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.count-text {
|
||
font-size: 12px;
|
||
color: #999999;
|
||
}
|
||
|
||
.option-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 12px 0;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.option-label {
|
||
font-size: 16px;
|
||
color: #333333;
|
||
}
|
||
|
||
.schedule-time, .expiry-time {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
margin-top: 12px;
|
||
}
|
||
|
||
.original-message {
|
||
background-color: #f8f8f8;
|
||
border-radius: 6px;
|
||
padding: 12px;
|
||
}
|
||
|
||
.original-header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.original-sender {
|
||
font-size: 14px;
|
||
font-weight: 700;
|
||
color: #333333;
|
||
}
|
||
|
||
.original-time {
|
||
font-size: 12px;
|
||
color: #999999;
|
||
}
|
||
|
||
.original-content {
|
||
padding: 8px 0;
|
||
}
|
||
|
||
.original-text {
|
||
font-size: 14px;
|
||
color: #666666;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.receiver-modal {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.3);
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.modal-content {
|
||
background-color: #ffffff;
|
||
border-radius: 12px;
|
||
width: 90%;
|
||
max-width: 400px;
|
||
max-height: 80%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.modal-header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 16px 20px;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 18px;
|
||
font-weight: 700;
|
||
color: #333333;
|
||
}
|
||
|
||
.modal-close {
|
||
width: 30px;
|
||
height: 30px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.close-icon {
|
||
font-size: 24px;
|
||
color: #999999;
|
||
}
|
||
|
||
.modal-body {
|
||
flex: 1;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.receiver-type-tabs {
|
||
display: flex;
|
||
flex-direction: row;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
}
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
height: 44px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.tab-item.active {
|
||
border-bottom: 2px solid #2196F3;
|
||
}
|
||
|
||
.tab-text {
|
||
font-size: 16px;
|
||
color: #666666;
|
||
}
|
||
|
||
.tab-item.active .tab-text {
|
||
color: #2196F3;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.receiver-list {
|
||
flex: 1;
|
||
}
|
||
|
||
.receiver-item {
|
||
padding: 16px 20px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.receiver-info {
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.receiver-name {
|
||
font-size: 16px;
|
||
color: #333333;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.receiver-desc {
|
||
font-size: 14px;
|
||
color: #999999;
|
||
}
|
||
</style>
|