902 lines
20 KiB
Vue
902 lines
20 KiB
Vue
<template>
|
||
<view class="page">
|
||
<view class="card">
|
||
<view class="header">
|
||
<view class="avatar">
|
||
<image v-if="archive.avatar" class="avatar-img" :src="archive.avatar" mode="aspectFill" />
|
||
</view>
|
||
|
||
<view class="header-main">
|
||
<view class="name-row">
|
||
<text class="name">{{ archive.name || '-' }}</text>
|
||
<text v-if="sexOrAge" class="meta">{{ sexOrAge }}</text>
|
||
</view>
|
||
|
||
<view v-if="archive.mobile" class="sub-line">{{ archive.mobile }}</view>
|
||
|
||
<view v-if="idRows.length" class="id-rows">
|
||
<view v-for="row in idRows" :key="row.label" class="id-row">
|
||
<text class="id-label">{{ row.label }}:</text>
|
||
<text class="id-value">{{ row.value }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view v-if="createText" class="create-row">
|
||
<text class="create-text">{{ createText }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="header-right" @click="goEdit">
|
||
<uni-icons type="right" size="18" color="#bbb" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="cells">
|
||
<!-- 联系电话 -->
|
||
<view class="info-row border-bottom">
|
||
<text class="input-label">联系电话</text>
|
||
<view class="info-right">
|
||
<template v-if="archive.mobile">
|
||
<view class="phone-area" @click="makeCall">
|
||
<uni-icons type="phone-filled" size="18" color="#4f6ef7" class="mr-4" />
|
||
<text class="phone-text">{{ archive.mobile }}</text>
|
||
</view>
|
||
<view class="edit-icon" @click.stop="openContact">
|
||
<uni-icons type="compose" size="20" color="#4f6ef7" />
|
||
</view>
|
||
</template>
|
||
<view v-else class="empty-click" @click="openContact">
|
||
<text class="placeholder">添加联系电话</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 备注 -->
|
||
<view class="info-block border-bottom">
|
||
<view class="block-header">
|
||
<text class="input-label">备注</text>
|
||
<view class="edit-icon" @click.stop="openNotes">
|
||
<uni-icons type="compose" size="20" color="#4f6ef7" />
|
||
</view>
|
||
</view>
|
||
<view class="block-content">
|
||
<text v-if="archive.notes" class="note-content">{{ archive.notes }}</text>
|
||
<view v-else class="empty-click" @click="openNotes">
|
||
<text class="placeholder">添加备注</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 分组 -->
|
||
<view class="info-block">
|
||
<view class="block-header">
|
||
<text class="input-label">分组</text>
|
||
<view class="edit-icon" @click.stop="openGroups">
|
||
<uni-icons type="compose" size="20" color="#4f6ef7" />
|
||
</view>
|
||
</view>
|
||
<view class="block-content">
|
||
<view v-if="archive.groups && archive.groups.length" class="tags-wrap">
|
||
<view v-for="tag in archive.groups" :key="tag" class="tag-item">
|
||
{{ tag }}
|
||
</view>
|
||
</view>
|
||
<view v-else class="empty-click" @click="openGroups">
|
||
<text class="placeholder">添加分组</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="tabs">
|
||
<view
|
||
v-for="t in tabs"
|
||
:key="t.key"
|
||
class="tab"
|
||
:class="{ active: currentTab === t.key }"
|
||
@click="currentTab = t.key"
|
||
>
|
||
{{ t.title }}
|
||
</view>
|
||
</view>
|
||
|
||
<view class="content">
|
||
<HealthProfileTab
|
||
v-if="currentTab === 'visitRecord'"
|
||
:data="archive"
|
||
:archiveId="archiveId"
|
||
:floatingBottom="floatingBottom"
|
||
/>
|
||
<ServiceInfoTab
|
||
v-else-if="currentTab === 'serviceRecord'"
|
||
:data="archive"
|
||
:archiveId="archiveId"
|
||
:reachBottomTime="reachBottomTime"
|
||
:floatingBottom="floatingBottom"
|
||
/>
|
||
<FollowUpManageTab
|
||
v-else
|
||
:data="archive"
|
||
:archiveId="archiveId"
|
||
:reachBottomTime="reachBottomTime"
|
||
:floatingBottom="floatingBottom"
|
||
/>
|
||
</view>
|
||
|
||
<view v-if="showBindWechat" class="footer">
|
||
<button class="bind-btn" @click="bindWechat">
|
||
<uni-icons type="email" size="18" color="#fff" />
|
||
<text class="bind-text">关联患者微信</text>
|
||
</button>
|
||
</view>
|
||
|
||
<!-- 修改联系电话(居中弹窗) -->
|
||
<uni-popup ref="contactPopup" type="center">
|
||
<view class="modal">
|
||
<view class="modal-title">修改联系电话</view>
|
||
<view class="modal-body">
|
||
<input class="modal-input" v-model="contactInput" type="number" placeholder="请输入联系电话" />
|
||
</view>
|
||
<view class="modal-actions">
|
||
<view class="modal-btn cancel" @click="closeContact">取消</view>
|
||
<view class="modal-btn save" @click="saveContact">保存</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 修改备注(底部弹层) -->
|
||
<uni-popup ref="notesPopup" type="bottom">
|
||
<view class="sheet">
|
||
<view class="sheet-header">
|
||
<view class="sheet-header-left" />
|
||
<view class="sheet-title">修改备注</view>
|
||
<view class="sheet-close" @click="closeNotes">
|
||
<uni-icons type="closeempty" size="18" color="#333" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="sheet-body">
|
||
<textarea
|
||
v-model="notesInput"
|
||
class="notes-textarea"
|
||
placeholder="请输入备注"
|
||
:maxlength="100"
|
||
/>
|
||
<view class="counter">{{ notesInput.length }}/100</view>
|
||
</view>
|
||
|
||
<view class="sheet-footer">
|
||
<button class="primary-btn" @click="saveNotes">保存</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 选择分组(底部弹层) -->
|
||
<uni-popup ref="groupPopup" type="bottom">
|
||
<view class="sheet">
|
||
<view class="sheet-header">
|
||
<view class="sheet-close" @click="closeGroups">
|
||
<uni-icons type="closeempty" size="18" color="#333" />
|
||
</view>
|
||
<view class="sheet-title">选择分组</view>
|
||
<view class="sheet-link" @click="openAddGroup">添加分组</view>
|
||
</view>
|
||
|
||
<view class="group-list">
|
||
<view v-for="g in groupOptions" :key="g" class="group-item" @click="toggleGroup(g)">
|
||
<uni-icons
|
||
:type="selectedGroupMap[g] ? 'checkbox-filled' : 'checkbox'"
|
||
size="20"
|
||
:color="selectedGroupMap[g] ? '#4f6ef7' : '#c7c7c7'"
|
||
/>
|
||
<text class="group-name">{{ g }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="sheet-footer">
|
||
<button class="primary-btn" @click="saveGroups">保存</button>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
|
||
<!-- 添加新分组(居中弹窗) -->
|
||
<uni-popup ref="addGroupPopup" type="center">
|
||
<view class="modal">
|
||
<view class="modal-title">添加新分组</view>
|
||
<view class="modal-body">
|
||
<input class="modal-input" v-model="newGroupName" placeholder="请输入分组名称" />
|
||
</view>
|
||
<view class="modal-actions">
|
||
<view class="modal-btn cancel" @click="closeAddGroup">取消</view>
|
||
<view class="modal-btn save" @click="saveAddGroup">保存</view>
|
||
</view>
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { computed, ref } from 'vue';
|
||
import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app';
|
||
|
||
import HealthProfileTab from '@/components/archive-detail/health-profile-tab.vue';
|
||
import ServiceInfoTab from '@/components/archive-detail/service-info-tab.vue';
|
||
import FollowUpManageTab from '@/components/archive-detail/follow-up-manage-tab.vue';
|
||
import { ensureSeed } from '@/components/archive-detail/mock';
|
||
|
||
const STORAGE_KEY = 'ykt_case_archive_detail';
|
||
|
||
const tabs = [
|
||
{ key: 'visitRecord', title: '病历记录' },
|
||
{ key: 'followUp', title: '回访任务' },
|
||
{ key: 'serviceRecord', title: '服务记录' }
|
||
];
|
||
|
||
const currentTab = ref('visitRecord');
|
||
const reachBottomTime = ref(0);
|
||
const archiveId = ref('');
|
||
|
||
const archive = ref({
|
||
name: '',
|
||
sex: '',
|
||
age: '',
|
||
avatar: '',
|
||
mobile: '',
|
||
outpatientNo: '',
|
||
inpatientNo: '',
|
||
medicalRecordNo: '',
|
||
createTime: '',
|
||
creator: '',
|
||
createdByDoctor: true,
|
||
hasBindWechat: false,
|
||
notes: '',
|
||
groups: [],
|
||
groupOptions: ['高血压', '糖尿病', '高血脂']
|
||
});
|
||
|
||
onLoad((options) => {
|
||
archiveId.value = options?.id ? String(options.id) : String(archive.value.medicalRecordNo || archive.value.outpatientNo || archive.value.inpatientNo || '');
|
||
|
||
const cached = uni.getStorageSync(STORAGE_KEY);
|
||
if (cached && typeof cached === 'object') {
|
||
archive.value = {
|
||
...archive.value,
|
||
...cached,
|
||
groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups,
|
||
groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions
|
||
};
|
||
}
|
||
|
||
if (!archive.value.mobile) {
|
||
const mobiles = cached && Array.isArray(cached.mobiles) ? cached.mobiles : [];
|
||
if (mobiles.length) archive.value.mobile = String(mobiles[0]);
|
||
}
|
||
|
||
if (!archiveId.value) {
|
||
archiveId.value = String(archive.value.medicalRecordNo || archive.value.outpatientNo || archive.value.inpatientNo || `mock_${Date.now()}`);
|
||
}
|
||
ensureSeed(archiveId.value, archive.value);
|
||
});
|
||
|
||
onShow(() => {
|
||
const cached = uni.getStorageSync(STORAGE_KEY);
|
||
if (cached && typeof cached === 'object') {
|
||
archive.value = {
|
||
...archive.value,
|
||
...cached,
|
||
groups: Array.isArray(cached.groups) ? cached.groups : archive.value.groups,
|
||
groupOptions: Array.isArray(cached.groupOptions) ? cached.groupOptions : archive.value.groupOptions,
|
||
};
|
||
}
|
||
});
|
||
|
||
onReachBottom(() => {
|
||
reachBottomTime.value = Date.now();
|
||
});
|
||
|
||
const sexOrAge = computed(() => {
|
||
const sex = archive.value.sex ? String(archive.value.sex) : '';
|
||
const age = archive.value.age || archive.value.age === 0 ? `${archive.value.age}岁` : '';
|
||
if (sex && age) return `${sex} ${age}`;
|
||
return sex || age;
|
||
});
|
||
|
||
const idRows = computed(() => {
|
||
const rows = [];
|
||
if (archive.value.outpatientNo) rows.push({ label: '门诊号', value: String(archive.value.outpatientNo) });
|
||
if (archive.value.inpatientNo) rows.push({ label: '住院号', value: String(archive.value.inpatientNo) });
|
||
if (archive.value.medicalRecordNo) rows.push({ label: '病案号', value: String(archive.value.medicalRecordNo) });
|
||
return rows;
|
||
});
|
||
|
||
const createText = computed(() => {
|
||
const time = archive.value.createTime ? String(archive.value.createTime) : '';
|
||
const creator = archive.value.creator ? String(archive.value.creator) : '';
|
||
if (time && creator) return `${time} ${creator}创建`;
|
||
if (time) return `${time} 创建`;
|
||
return '';
|
||
});
|
||
|
||
const showBindWechat = computed(() => Boolean(archive.value.createdByDoctor && !archive.value.hasBindWechat));
|
||
const floatingBottom = computed(() => (showBindWechat.value ? 90 : 16));
|
||
|
||
// const contactTitle = computed(() => (archive.value.mobile ? '联系方式' : '添加联系电话'));
|
||
// const notesTitle = computed(() => (archive.value.notes ? '备注' : '添加备注'));
|
||
// const groupTitle = computed(() => (Array.isArray(archive.value.groups) && archive.value.groups.length ? '分组' : '添加分组'));
|
||
|
||
const saveToStorage = () => {
|
||
uni.setStorageSync(STORAGE_KEY, { ...archive.value });
|
||
};
|
||
|
||
const goEdit = () => {
|
||
uni.navigateTo({ url: `/pages/case/archive-edit?archiveId=${encodeURIComponent(archiveId.value || '')}` });
|
||
};
|
||
|
||
const bindWechat = () => {
|
||
uni.showToast({ title: '关联患者微信功能待接入', icon: 'none' });
|
||
};
|
||
|
||
const makeCall = () => {
|
||
if (archive.value.mobile) {
|
||
uni.makePhoneCall({ phoneNumber: archive.value.mobile });
|
||
}
|
||
};
|
||
|
||
// ===== 联系电话 =====
|
||
const contactPopup = ref(null);
|
||
const contactInput = ref('');
|
||
|
||
const openContact = () => {
|
||
contactInput.value = archive.value.mobile ? String(archive.value.mobile) : '';
|
||
contactPopup.value?.open();
|
||
};
|
||
|
||
const closeContact = () => {
|
||
contactPopup.value?.close();
|
||
};
|
||
|
||
const saveContact = () => {
|
||
const v = String(contactInput.value || '').trim();
|
||
if (!v) {
|
||
uni.showToast({ title: '请输入联系电话', icon: 'none' });
|
||
return;
|
||
}
|
||
archive.value.mobile = v;
|
||
saveToStorage();
|
||
closeContact();
|
||
};
|
||
|
||
// ===== 备注 =====
|
||
const notesPopup = ref(null);
|
||
const notesInput = ref('');
|
||
|
||
const openNotes = () => {
|
||
notesInput.value = archive.value.notes ? String(archive.value.notes) : '';
|
||
notesPopup.value?.open();
|
||
};
|
||
|
||
const closeNotes = () => {
|
||
notesPopup.value?.close();
|
||
};
|
||
|
||
const saveNotes = () => {
|
||
archive.value.notes = String(notesInput.value || '').trim();
|
||
saveToStorage();
|
||
closeNotes();
|
||
};
|
||
|
||
// ===== 分组 =====
|
||
const groupPopup = ref(null);
|
||
const addGroupPopup = ref(null);
|
||
|
||
const groupOptions = computed(() => (Array.isArray(archive.value.groupOptions) ? archive.value.groupOptions : []));
|
||
|
||
const selectedGroupMap = ref({});
|
||
|
||
const syncSelectedMapFromArchive = () => {
|
||
const current = Array.isArray(archive.value.groups) ? archive.value.groups : [];
|
||
selectedGroupMap.value = current.reduce((acc, name) => {
|
||
acc[name] = true;
|
||
return acc;
|
||
}, {});
|
||
};
|
||
|
||
const openGroups = () => {
|
||
syncSelectedMapFromArchive();
|
||
groupPopup.value?.open();
|
||
};
|
||
|
||
const closeGroups = () => {
|
||
groupPopup.value?.close();
|
||
};
|
||
|
||
const toggleGroup = (name) => {
|
||
selectedGroupMap.value[name] = !selectedGroupMap.value[name];
|
||
};
|
||
|
||
const saveGroups = () => {
|
||
archive.value.groups = Object.keys(selectedGroupMap.value).filter(k => selectedGroupMap.value[k]);
|
||
saveToStorage();
|
||
closeGroups();
|
||
};
|
||
|
||
// 添加新分组
|
||
const newGroupName = ref('');
|
||
|
||
const openAddGroup = () => {
|
||
newGroupName.value = '';
|
||
addGroupPopup.value?.open();
|
||
};
|
||
|
||
const closeAddGroup = () => {
|
||
addGroupPopup.value?.close();
|
||
};
|
||
|
||
const saveAddGroup = () => {
|
||
const name = String(newGroupName.value || '').trim();
|
||
if (!name) {
|
||
uni.showToast({ title: '请输入分组名称', icon: 'none' });
|
||
return;
|
||
}
|
||
const exists = groupOptions.value.some(g => String(g).trim() === name);
|
||
if (exists) {
|
||
uni.showToast({ title: '该分组已存在', icon: 'none' });
|
||
return;
|
||
}
|
||
|
||
archive.value.groupOptions = [...groupOptions.value, name];
|
||
selectedGroupMap.value[name] = true;
|
||
saveToStorage();
|
||
closeAddGroup();
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.page {
|
||
min-height: 100vh;
|
||
background: #f5f6f8;
|
||
padding-bottom: calc(80px + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.card {
|
||
background: #fff;
|
||
}
|
||
|
||
.header {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
padding: 14px 14px 10px;
|
||
border-bottom: 1px solid #f2f2f2;
|
||
}
|
||
|
||
.avatar {
|
||
width: 56px;
|
||
height: 56px;
|
||
border-radius: 6px;
|
||
border: 1px solid #e8e8e8;
|
||
background: #fafafa;
|
||
overflow: hidden;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.avatar-img {
|
||
width: 56px;
|
||
height: 56px;
|
||
}
|
||
|
||
.header-main {
|
||
flex: 1;
|
||
min-width: 0;
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.name-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
padding-top: 2px;
|
||
}
|
||
|
||
.name {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #1f1f1f;
|
||
max-width: 220px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.meta {
|
||
font-size: 13px;
|
||
color: #666;
|
||
}
|
||
|
||
.sub-line {
|
||
margin-top: 6px;
|
||
font-size: 12px;
|
||
color: #666;
|
||
}
|
||
|
||
.id-rows {
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.id-row {
|
||
display: flex;
|
||
align-items: center;
|
||
font-size: 12px;
|
||
color: #666;
|
||
line-height: 18px;
|
||
}
|
||
|
||
.id-label {
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.id-value {
|
||
min-width: 0;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.create-row {
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.create-text {
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
.header-right {
|
||
width: 28px;
|
||
height: 28px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.cells {
|
||
background: #fff;
|
||
padding: 0 14px;
|
||
}
|
||
|
||
.border-bottom {
|
||
border-bottom: 1px solid #f2f2f2;
|
||
}
|
||
|
||
.info-row {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 16px 0;
|
||
min-height: 24px;
|
||
}
|
||
|
||
.info-block {
|
||
padding: 16px 0;
|
||
}
|
||
|
||
.block-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.block-content {
|
||
min-height: 20px;
|
||
}
|
||
|
||
.input-label {
|
||
font-size: 15px;
|
||
color: #666;
|
||
}
|
||
|
||
.info-right {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.phone-area {
|
||
display: flex;
|
||
align-items: center;
|
||
margin-right: 12px;
|
||
}
|
||
|
||
.mr-4 {
|
||
margin-right: 4px;
|
||
}
|
||
|
||
.phone-text {
|
||
font-size: 16px;
|
||
color: #4f6ef7;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.edit-icon {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
|
||
.placeholder {
|
||
font-size: 14px;
|
||
color: #999;
|
||
}
|
||
|
||
.note-content {
|
||
font-size: 14px;
|
||
color: #333;
|
||
line-height: 1.5;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.tags-wrap {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.tag-item {
|
||
height: 24px;
|
||
line-height: 22px;
|
||
padding: 0 10px;
|
||
border: 1px solid #4f6ef7;
|
||
border-radius: 12px;
|
||
font-size: 12px;
|
||
color: #4f6ef7;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.empty-click {
|
||
/* To ensure empty area is clickable */
|
||
display: inline-block;
|
||
}
|
||
|
||
.tabs {
|
||
margin-top: 10px;
|
||
background: #fff;
|
||
display: flex;
|
||
border-top: 1px solid #f2f2f2;
|
||
border-bottom: 1px solid #f2f2f2;
|
||
}
|
||
|
||
.tab {
|
||
flex: 1;
|
||
text-align: center;
|
||
height: 44px;
|
||
line-height: 44px;
|
||
font-size: 14px;
|
||
color: #333;
|
||
position: relative;
|
||
}
|
||
|
||
.tab.active {
|
||
color: #4f6ef7;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.tab.active::after {
|
||
content: '';
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: 0;
|
||
width: 32px;
|
||
height: 3px;
|
||
background: #4f6ef7;
|
||
transform: translateX(-50%);
|
||
border-radius: 2px;
|
||
}
|
||
|
||
.content {
|
||
padding: 0;
|
||
}
|
||
|
||
.empty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.empty-img {
|
||
width: 160px;
|
||
height: 160px;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
.empty-text {
|
||
margin-top: 10px;
|
||
font-size: 13px;
|
||
color: #9aa0a6;
|
||
}
|
||
|
||
.footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background: #fff;
|
||
padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
|
||
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.bind-btn {
|
||
width: 100%;
|
||
height: 44px;
|
||
background: #4f6ef7;
|
||
color: #fff;
|
||
border-radius: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
font-size: 15px;
|
||
}
|
||
|
||
.bind-text {
|
||
color: #fff;
|
||
}
|
||
|
||
/* ===== 弹窗样式(居中) ===== */
|
||
.modal {
|
||
width: 320px;
|
||
background: #fff;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
padding: 14px 12px;
|
||
color: #333;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 14px 14px 8px;
|
||
}
|
||
|
||
.modal-input {
|
||
width: 100%;
|
||
height: 40px;
|
||
border: 1px solid #e6e6e6;
|
||
border-radius: 4px;
|
||
padding: 0 10px;
|
||
font-size: 14px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.modal-actions {
|
||
display: flex;
|
||
gap: 12px;
|
||
padding: 12px 14px 14px;
|
||
}
|
||
|
||
.modal-btn {
|
||
flex: 1;
|
||
height: 40px;
|
||
line-height: 40px;
|
||
text-align: center;
|
||
border-radius: 4px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.modal-btn.cancel {
|
||
border: 1px solid #4f6ef7;
|
||
color: #4f6ef7;
|
||
background: #fff;
|
||
}
|
||
|
||
.modal-btn.save {
|
||
background: #4f6ef7;
|
||
color: #fff;
|
||
}
|
||
|
||
/* ===== 底部弹层样式 ===== */
|
||
.sheet {
|
||
background: #fff;
|
||
border-top-left-radius: 10px;
|
||
border-top-right-radius: 10px;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.sheet-header {
|
||
height: 48px;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 14px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.sheet-title {
|
||
flex: 1;
|
||
text-align: center;
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
.sheet-close {
|
||
width: 24px;
|
||
height: 24px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.sheet-header-left {
|
||
width: 24px;
|
||
}
|
||
|
||
.sheet-link {
|
||
min-width: 60px;
|
||
text-align: right;
|
||
font-size: 14px;
|
||
color: #4f6ef7;
|
||
}
|
||
|
||
.sheet-body {
|
||
padding: 14px;
|
||
}
|
||
|
||
.notes-textarea {
|
||
width: 100%;
|
||
height: 140px;
|
||
border: 1px solid #e6e6e6;
|
||
border-radius: 4px;
|
||
padding: 10px;
|
||
font-size: 14px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.counter {
|
||
text-align: right;
|
||
margin-top: 8px;
|
||
font-size: 12px;
|
||
color: #999;
|
||
}
|
||
|
||
.group-list {
|
||
padding: 8px 14px 14px;
|
||
max-height: 55vh;
|
||
overflow: auto;
|
||
}
|
||
|
||
.group-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 12px 0;
|
||
}
|
||
|
||
.group-name {
|
||
margin-left: 10px;
|
||
font-size: 14px;
|
||
color: #333;
|
||
}
|
||
|
||
.sheet-footer {
|
||
padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.primary-btn {
|
||
width: 100%;
|
||
height: 44px;
|
||
background: #4f6ef7;
|
||
color: #fff;
|
||
border-radius: 4px;
|
||
font-size: 15px;
|
||
line-height: 44px;
|
||
}
|
||
</style>
|