更新
This commit is contained in:
@@ -45,7 +45,7 @@ const wxcode = async (code) => {
|
||||
}, false) // 不显示加载中
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('userData', res.data)
|
||||
if(res.code==1){
|
||||
if(res.code==1 &&res.data.diagnosis){
|
||||
video(res.data)
|
||||
}
|
||||
console.log('请求结果:', res.data)
|
||||
|
||||
@@ -46,6 +46,12 @@
|
||||
<!-- 表情消息 -->
|
||||
<text v-if="msg.type === 'face'" class="message-emoji">{{ msg.emoji }}</text>
|
||||
|
||||
<!-- 语音消息 -->
|
||||
<view v-if="msg.type === 'audio'" class="message-audio" @click="playAudio(msg)">
|
||||
<text class="audio-icon">{{ playingAudioId === msg.audioId ? '⏸' : '▶' }}</text>
|
||||
<text class="audio-duration">{{ msg.duration || 0 }}秒</text>
|
||||
</view>
|
||||
|
||||
<!-- 消息时间 -->
|
||||
<view class="message-meta">
|
||||
<text class="message-time">{{ formatTime(msg.time) }}</text>
|
||||
@@ -73,22 +79,27 @@
|
||||
<uni-icons type="tool " size="30" color="#999"></uni-icons>
|
||||
<text class="tool-label">表情</text>
|
||||
</view> -->
|
||||
<view class="tool-item tool-item-left" @click="toggleInputMode">
|
||||
<uni-icons :type="inputMode === 'voice' ? 'compose' : 'mic'" size="38" color="#576b95"></uni-icons>
|
||||
<text class="tool-label" v-if="inputMode === 'voice'">文字</text>
|
||||
<text class="tool-label" v-else>语音</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="chooseImage">
|
||||
<uni-icons type="image " size="30" color="#999"></uni-icons>
|
||||
<uni-icons type="image " size="40" color="#576b95"></uni-icons>
|
||||
<text class="tool-label">图片</text>
|
||||
</view>
|
||||
<view class="tool-item" @click="chooseFile">
|
||||
<uni-icons type="paperclip " size="30" color="#999"></uni-icons>
|
||||
<uni-icons type="paperclip " size="40" color="#576b95"></uni-icons>
|
||||
<text class="tool-label">文件</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 输入框 -->
|
||||
<view class="input-wrapper">
|
||||
<!-- 输入区域:文字模式 -->
|
||||
<view v-if="inputMode === 'text'" class="input-wrapper">
|
||||
<input
|
||||
class="message-input"
|
||||
v-model="inputText"
|
||||
placeholder="输入消息..."
|
||||
placeholder="请输入消息内容..."
|
||||
:adjust-position="false"
|
||||
:hold-keyboard="true"
|
||||
@focus="onInputFocus"
|
||||
@@ -99,6 +110,37 @@
|
||||
<text class="send-text">发送</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 语音模式:按住说话 -->
|
||||
<view
|
||||
v-else
|
||||
class="voice-input-wrapper"
|
||||
:class="{ 'voice-input-recording': isRecording }"
|
||||
@touchstart="onVoiceTouchStart"
|
||||
@touchmove="onVoiceTouchMove"
|
||||
@touchend="onVoiceTouchEnd"
|
||||
@touchcancel="onVoiceTouchCancel"
|
||||
>
|
||||
<text class="voice-input-text">{{ isRecording ? (willCancel ? '松开 取消' : '松开 发送') : '按住 说话' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 录音浮层 - 微信风格 -->
|
||||
<view v-if="isRecording" class="recording-overlay">
|
||||
<view class="recording-popup" :class="{ 'recording-cancel': willCancel }">
|
||||
<view class="recording-icon">
|
||||
<view v-if="!willCancel" class="recording-waves">
|
||||
<view class="wave"></view>
|
||||
<view class="wave"></view>
|
||||
<view class="wave"></view>
|
||||
<view class="wave"></view>
|
||||
<view class="wave"></view>
|
||||
</view>
|
||||
<text v-else class="cancel-icon">✕</text>
|
||||
</view>
|
||||
<text class="recording-hint">{{ willCancel ? '松开手指,取消发送' : '上滑取消' }}</text>
|
||||
<text class="recording-duration">{{ recordingDuration }}"</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 表情选择器 -->
|
||||
@@ -137,7 +179,15 @@
|
||||
const showEmoji = ref(false);
|
||||
const keyboardHeight = ref(0);
|
||||
const userAvatar = ref(''); // 当前用户头像
|
||||
const inputMode = ref('text'); // 'text' | 'voice'
|
||||
const isRecording = ref(false);
|
||||
const recordingDuration = ref(0);
|
||||
const willCancel = ref(false); // 上滑取消
|
||||
const playingAudioId = ref('');
|
||||
let innerAudioContext = null;
|
||||
let chat = null;
|
||||
let recorderManager = null;
|
||||
let recordingTimer = null;
|
||||
let conversationID = '';
|
||||
let targetUserID = '';
|
||||
let currentUserID = ''; // 当前登录用户ID
|
||||
@@ -158,6 +208,174 @@
|
||||
'👏', '🙌', '👐', '🤲', '🤝', '🙏', '💪', '❤️'
|
||||
];
|
||||
|
||||
// 切换输入模式(文字/语音)
|
||||
function toggleInputMode() {
|
||||
inputMode.value = inputMode.value === 'text' ? 'voice' : 'text';
|
||||
}
|
||||
|
||||
// 初始化录音管理器
|
||||
function initRecorderManager() {
|
||||
// #ifdef MP-WEIXIN
|
||||
recorderManager = uni.getRecorderManager();
|
||||
recorderManager.onStop((res) => {
|
||||
if (willCancel.value) {
|
||||
willCancel.value = false;
|
||||
} else if (res.tempFilePath && res.duration >= 1000) {
|
||||
sendAudioMessage(res);
|
||||
} else if (res.duration < 1000) {
|
||||
uni.showToast({ title: '录音时间太短', icon: 'none' });
|
||||
}
|
||||
isRecording.value = false;
|
||||
recordingDuration.value = 0;
|
||||
if (recordingTimer) clearInterval(recordingTimer);
|
||||
});
|
||||
recorderManager.onError((err) => {
|
||||
console.error('录音错误:', err);
|
||||
isRecording.value = false;
|
||||
recordingDuration.value = 0;
|
||||
if (recordingTimer) clearInterval(recordingTimer);
|
||||
uni.showToast({ title: '录音失败', icon: 'none' });
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 按住说话 - 开始
|
||||
function onVoiceTouchStart(e) {
|
||||
// #ifdef MP-WEIXIN
|
||||
e.preventDefault();
|
||||
willCancel.value = false;
|
||||
touchStartY = e.touches[0]?.clientY || 0;
|
||||
if (!recorderManager) initRecorderManager();
|
||||
startRecord();
|
||||
// #endif
|
||||
// #ifndef MP-WEIXIN
|
||||
uni.showToast({ title: '当前平台暂不支持语音', icon: 'none' });
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 松开 - 发送或取消
|
||||
function onVoiceTouchEnd(e) {
|
||||
// #ifdef MP-WEIXIN
|
||||
e.preventDefault();
|
||||
if (isRecording.value && recorderManager) {
|
||||
recorderManager.stop();
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
|
||||
// 触摸取消(如滑出区域)
|
||||
function onVoiceTouchCancel(e) {
|
||||
onVoiceTouchEnd(e);
|
||||
}
|
||||
|
||||
let touchStartY = 0;
|
||||
// 监听上滑取消
|
||||
function onVoiceTouchMove(e) {
|
||||
if (!isRecording.value) return;
|
||||
const touch = e.touches[0];
|
||||
if (touch && touchStartY - touch.clientY > 80) {
|
||||
willCancel.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
function startRecord() {
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.authorize({
|
||||
scope: 'scope.record',
|
||||
success: () => {
|
||||
isRecording.value = true;
|
||||
recordingDuration.value = 0;
|
||||
recorderManager.start({
|
||||
duration: 60000,
|
||||
sampleRate: 44100,
|
||||
numberOfChannels: 1,
|
||||
encodeBitRate: 192000,
|
||||
format: 'aac'
|
||||
});
|
||||
recordingTimer = setInterval(() => {
|
||||
recordingDuration.value++;
|
||||
}, 1000);
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
title: '需要录音权限',
|
||||
content: '请在设置中开启录音权限以发送语音消息',
|
||||
confirmText: '去设置',
|
||||
success: (res) => {
|
||||
if (res.confirm) uni.openSetting();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
}
|
||||
|
||||
async function sendAudioMessage(recordRes) {
|
||||
try {
|
||||
uni.showLoading({ title: '发送中...' });
|
||||
const durationSec = Math.max(1, Math.round(recordRes.duration / 1000));
|
||||
const message = chat.createAudioMessage({
|
||||
to: targetUserID,
|
||||
conversationType: TencentCloudChat.TYPES.CONV_C2C,
|
||||
payload: { file: recordRes },
|
||||
onProgress: () => {}
|
||||
});
|
||||
const sendResult = await chat.sendMessage(message);
|
||||
const payload = sendResult?.data?.message?.payload || {};
|
||||
const audioUrl = payload.url || payload.file?.url || recordRes.tempFilePath;
|
||||
messages.value.push({
|
||||
type: 'audio',
|
||||
audioUrl,
|
||||
duration: durationSec,
|
||||
audioId: sendResult?.data?.message?.ID || 'local-' + Date.now(),
|
||||
time: Date.now(),
|
||||
flow: 'out',
|
||||
avatar: userAvatar.value
|
||||
});
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '发送成功', icon: 'success' });
|
||||
scrollToBottom();
|
||||
setTimeout(() => scrollToBottom(), 150);
|
||||
} catch (error) {
|
||||
console.error('发送语音失败:', error);
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '发送失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
|
||||
function playAudio(msg) {
|
||||
if (!msg.audioUrl) {
|
||||
uni.showToast({ title: '无法播放', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (playingAudioId.value === msg.audioId) {
|
||||
if (innerAudioContext) {
|
||||
innerAudioContext.stop();
|
||||
innerAudioContext.destroy();
|
||||
innerAudioContext = null;
|
||||
}
|
||||
playingAudioId.value = '';
|
||||
return;
|
||||
}
|
||||
if (innerAudioContext) {
|
||||
innerAudioContext.stop();
|
||||
innerAudioContext.destroy();
|
||||
}
|
||||
innerAudioContext = uni.createInnerAudioContext();
|
||||
innerAudioContext.src = msg.audioUrl;
|
||||
innerAudioContext.play();
|
||||
playingAudioId.value = msg.audioId;
|
||||
innerAudioContext.onEnded(() => {
|
||||
playingAudioId.value = '';
|
||||
innerAudioContext = null;
|
||||
});
|
||||
innerAudioContext.onError(() => {
|
||||
playingAudioId.value = '';
|
||||
innerAudioContext = null;
|
||||
uni.showToast({ title: '播放失败', icon: 'none' });
|
||||
});
|
||||
}
|
||||
|
||||
onLoad(async (options) => {
|
||||
try {
|
||||
const app = getApp();
|
||||
@@ -236,6 +454,13 @@
|
||||
onUnload(() => {
|
||||
if (chat) chat.off(TencentCloudChat.EVENT.MESSAGE_RECEIVED, onMessageReceived);
|
||||
if (scrollTimer) clearTimeout(scrollTimer);
|
||||
if (innerAudioContext) {
|
||||
innerAudioContext.stop();
|
||||
innerAudioContext.destroy();
|
||||
}
|
||||
if (isRecording.value && recorderManager) {
|
||||
recorderManager.stop();
|
||||
}
|
||||
});
|
||||
|
||||
async function loadHistoryMessages() {
|
||||
@@ -335,8 +560,11 @@
|
||||
return null; // 解析失败的消息不显示
|
||||
}
|
||||
|
||||
case TencentCloudChat.TYPES.MSG_AUDIO:
|
||||
return { ...baseMsg, type: 'text', text: '[语音消息]' };
|
||||
case TencentCloudChat.TYPES.MSG_AUDIO: {
|
||||
const audioUrl = msg.payload?.url || msg.payload?.file?.url || '';
|
||||
const audioDuration = msg.payload?.second ?? (msg.payload?.duration ? Math.round(msg.payload.duration / 1000) : 0);
|
||||
return { ...baseMsg, type: 'audio', audioUrl, duration: Math.round(audioDuration), audioId: msg.ID || msg.id || '' };
|
||||
}
|
||||
|
||||
case TencentCloudChat.TYPES.MSG_VIDEO:
|
||||
return { ...baseMsg, type: 'text', text: '[视频消息]' };
|
||||
@@ -625,37 +853,36 @@
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 容器 */
|
||||
/* 适老化设计:50-80岁 - 大字号、高对比、大触控区 */
|
||||
.chat-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: #f7f8fa;
|
||||
background: #e8eaed;
|
||||
}
|
||||
|
||||
/* 顶部导航栏 */
|
||||
.chat-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 88rpx;
|
||||
padding: 0 20rpx;
|
||||
height: 100rpx;
|
||||
padding: 0 28rpx;
|
||||
background: #fff;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
border-bottom: 4rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.back-icon {
|
||||
font-size: 48rpx;
|
||||
color: #576b95;
|
||||
font-size: 52rpx;
|
||||
color: #1890ff;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@@ -667,51 +894,50 @@
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 34rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.header-status {
|
||||
font-size: 22rpx;
|
||||
color: #888;
|
||||
margin-top: 2rpx;
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
margin-top: 4rpx;
|
||||
}
|
||||
|
||||
.header-right {
|
||||
width: 88rpx;
|
||||
width: 100rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.video-call-btn {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.video-icon {
|
||||
font-size: 44rpx;
|
||||
color: #576b95;
|
||||
font-size: 52rpx;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
/* 消息列表 */
|
||||
.message-list {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.message-container {
|
||||
padding: 20rpx 24rpx;
|
||||
padding-bottom: 280rpx;
|
||||
padding: 28rpx 32rpx;
|
||||
padding-bottom: 320rpx;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.message-wrapper {
|
||||
display: flex;
|
||||
margin-bottom: 24rpx;
|
||||
margin-bottom: 32rpx;
|
||||
animation: fadeIn 0.25s ease;
|
||||
}
|
||||
|
||||
@@ -728,45 +954,45 @@
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
/* 头像 */
|
||||
/* 头像 - 更大 */
|
||||
.avatar {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 8rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
font-weight: 500;
|
||||
background: #e8e8e8;
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.avatar-in {
|
||||
background: #e8e8e8;
|
||||
margin-right: 16rpx;
|
||||
background: #e0e0e0;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.avatar-out {
|
||||
background: #95ec69;
|
||||
margin-left: 16rpx;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.avatar-text {
|
||||
font-size: 28rpx;
|
||||
font-size: 36rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 8rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
/* 消息气泡 */
|
||||
/* 消息气泡 - 更大内边距 */
|
||||
.message-bubble {
|
||||
max-width: 500rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
border-radius: 8rpx;
|
||||
max-width: 540rpx;
|
||||
padding: 28rpx 32rpx;
|
||||
border-radius: 16rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -778,113 +1004,110 @@
|
||||
background: #95ec69;
|
||||
}
|
||||
|
||||
/* 文本消息 */
|
||||
/* 文本消息 - 大字号 */
|
||||
.message-text {
|
||||
font-size: 30rpx;
|
||||
line-height: 1.5;
|
||||
color: #000;
|
||||
font-size: 38rpx;
|
||||
line-height: 1.6;
|
||||
color: #1a1a1a;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.bubble-out .message-text {
|
||||
color: #000;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
/* 图片消息 */
|
||||
.message-image {
|
||||
max-width: 100%;
|
||||
border-radius: 8rpx;
|
||||
border-radius: 12rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 文件消息 */
|
||||
/* 文件消息 - 大触控区 */
|
||||
.message-file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
padding: 12rpx;
|
||||
background: rgba(0, 0, 0, 0.04);
|
||||
border-radius: 8rpx;
|
||||
gap: 24rpx;
|
||||
padding: 20rpx;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.bubble-out .message-file {
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.file-icon-wrapper {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
background: #576b95;
|
||||
border-radius: 8rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
background: #1890ff;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.bubble-out .file-icon-wrapper {
|
||||
background: rgba(0, 0, 0, 0.15);
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.file-icon {
|
||||
font-size: 40rpx;
|
||||
font-size: 48rpx;
|
||||
}
|
||||
|
||||
.file-details {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6rpx;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.file-name {
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
font-weight: 400;
|
||||
font-size: 34rpx;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bubble-out .file-name {
|
||||
color: #000;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.file-size {
|
||||
font-size: 22rpx;
|
||||
color: #888;
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.bubble-out .file-size {
|
||||
color: #666;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.download-icon {
|
||||
font-size: 28rpx;
|
||||
color: #576b95;
|
||||
font-size: 36rpx;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.bubble-out .download-icon {
|
||||
color: #000;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
/* 表情消息 */
|
||||
.message-emoji {
|
||||
font-size: 96rpx;
|
||||
font-size: 112rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 消息元信息 */
|
||||
.message-meta {
|
||||
margin-top: 8rpx;
|
||||
margin-top: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 20rpx;
|
||||
color: #b2b2b2;
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.bubble-out .message-time {
|
||||
color: #888;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
@@ -894,92 +1117,220 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 600rpx;
|
||||
gap: 16rpx;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
font-size: 100rpx;
|
||||
opacity: 0.25;
|
||||
font-size: 120rpx;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #b2b2b2;
|
||||
font-weight: 400;
|
||||
font-size: 38rpx;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.empty-hint {
|
||||
font-size: 24rpx;
|
||||
color: #d0d0d0;
|
||||
font-size: 32rpx;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/* 底部占位 */
|
||||
.bottom-placeholder {
|
||||
height: 40rpx;
|
||||
height: 56rpx;
|
||||
}
|
||||
|
||||
/* 输入区域 */
|
||||
/* 输入区域 - 大触控区 */
|
||||
.input-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #f7f8fa;
|
||||
border-top: 1rpx solid #e7e7e7;
|
||||
padding: 16rpx 20rpx;
|
||||
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
||||
background: #ededed;
|
||||
border-top: 1rpx solid #d9d9d9;
|
||||
padding: 20rpx 24rpx;
|
||||
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
|
||||
z-index: 100;
|
||||
transition: padding-bottom 0.3s ease;
|
||||
}
|
||||
|
||||
/* 工具栏 */
|
||||
.toolbar {
|
||||
display: flex;
|
||||
gap: 32rpx;
|
||||
margin-bottom: 16rpx;
|
||||
padding: 0 8rpx;
|
||||
gap: 48rpx;
|
||||
margin-bottom: 24rpx;
|
||||
padding: 0 12rpx;
|
||||
}
|
||||
|
||||
.tool-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6rpx;
|
||||
gap: 12rpx;
|
||||
min-height: 100rpx;
|
||||
}
|
||||
|
||||
.tool-item-left {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.tool-icon {
|
||||
font-size: 48rpx;
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
.tool-label {
|
||||
font-size: 20rpx;
|
||||
color: #888;
|
||||
font-size: 30rpx;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 语音输入 - 微信风格 */
|
||||
.voice-input-wrapper {
|
||||
height: 96rpx;
|
||||
background: #f7f7f7;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 56rpx;
|
||||
border: 2rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.voice-input-recording {
|
||||
background: #e8e8e8;
|
||||
border-color: #c0c0c0;
|
||||
}
|
||||
|
||||
.voice-input-text {
|
||||
font-size: 34rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
/* 录音浮层 - 微信风格 */
|
||||
.recording-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.recording-popup {
|
||||
width: 320rpx;
|
||||
padding: 48rpx;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
}
|
||||
|
||||
.recording-popup.recording-cancel {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.recording-icon {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.recording-waves {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
gap: 8rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.recording-waves .wave {
|
||||
width: 12rpx;
|
||||
height: 24rpx;
|
||||
background: #07c160;
|
||||
border-radius: 6rpx;
|
||||
animation: waveAnim 0.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.recording-waves .wave:nth-child(1) { animation-delay: 0s; }
|
||||
.recording-waves .wave:nth-child(2) { animation-delay: 0.1s; }
|
||||
.recording-waves .wave:nth-child(3) { animation-delay: 0.2s; }
|
||||
.recording-waves .wave:nth-child(4) { animation-delay: 0.3s; }
|
||||
.recording-waves .wave:nth-child(5) { animation-delay: 0.4s; }
|
||||
|
||||
@keyframes waveAnim {
|
||||
0%, 100% { height: 24rpx; }
|
||||
50% { height: 60rpx; }
|
||||
}
|
||||
|
||||
.cancel-icon {
|
||||
font-size: 80rpx;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
.recording-hint {
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.recording-popup .recording-duration {
|
||||
font-size: 32rpx;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.message-audio {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
padding: 20rpx 28rpx;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 12rpx;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.bubble-out .message-audio {
|
||||
background: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.audio-icon {
|
||||
font-size: 36rpx;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.audio-duration {
|
||||
font-size: 34rpx;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 输入框 */
|
||||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
margin-bottom: 45rpx;
|
||||
gap: 20rpx;
|
||||
margin-bottom: 56rpx;
|
||||
}
|
||||
|
||||
.message-input {
|
||||
flex: 1;
|
||||
height: 72rpx;
|
||||
padding: 0 24rpx;
|
||||
height: 96rpx;
|
||||
padding: 0 32rpx;
|
||||
background: #fff;
|
||||
border-radius: 8rpx;
|
||||
border: 1rpx solid #e7e7e7;
|
||||
font-size: 28rpx;
|
||||
color: #000;
|
||||
border-radius: 16rpx;
|
||||
border: 4rpx solid #e0e0e0;
|
||||
font-size: 36rpx;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.send-button {
|
||||
width: 112rpx;
|
||||
height: 72rpx;
|
||||
background: #ededed;
|
||||
border-radius: 8rpx;
|
||||
width: 140rpx;
|
||||
height: 96rpx;
|
||||
background: #e0e0e0;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -991,16 +1342,15 @@
|
||||
}
|
||||
|
||||
.send-text {
|
||||
font-size: 28rpx;
|
||||
font-size: 36rpx;
|
||||
color: #888;
|
||||
font-weight: 400;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.send-button-active .send-text {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 表情选择器 */
|
||||
.emoji-panel {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
@@ -1017,8 +1367,8 @@
|
||||
.emoji-content {
|
||||
width: 100%;
|
||||
max-height: 65vh;
|
||||
background: #f7f8fa;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
background: #e8eaed;
|
||||
border-radius: 28rpx 28rpx 0 0;
|
||||
animation: slideUp 0.25s ease;
|
||||
}
|
||||
|
||||
@@ -1031,20 +1381,20 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 28rpx 28rpx 20rpx;
|
||||
border-bottom: 1rpx solid #e7e7e7;
|
||||
padding: 36rpx 36rpx 28rpx;
|
||||
border-bottom: 4rpx solid #e0e0e0;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.emoji-title {
|
||||
font-size: 30rpx;
|
||||
font-size: 38rpx;
|
||||
font-weight: 500;
|
||||
color: #000;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.emoji-close {
|
||||
width: 52rpx;
|
||||
height: 52rpx;
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
background: #f0f0f0;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
@@ -1053,27 +1403,27 @@
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
font-size: 28rpx;
|
||||
color: #888;
|
||||
font-size: 36rpx;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.emoji-scroll {
|
||||
max-height: 55vh;
|
||||
padding: 20rpx;
|
||||
background: #f7f8fa;
|
||||
padding: 28rpx;
|
||||
background: #e8eaed;
|
||||
}
|
||||
|
||||
.emoji-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.emoji-cell {
|
||||
width: 96rpx;
|
||||
height: 96rpx;
|
||||
width: 112rpx;
|
||||
height: 112rpx;
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -1086,6 +1436,6 @@
|
||||
}
|
||||
|
||||
.emoji-icon {
|
||||
font-size: 52rpx;
|
||||
font-size: 60rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 加载中 -->
|
||||
<view v-if="loading" class="loading-wrap">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
<block v-else-if="article">
|
||||
<!-- 封面图 -->
|
||||
<image v-if="article.image" :src="article.image" class="cover-image" mode="aspectFill" />
|
||||
|
||||
<!-- 内容区 -->
|
||||
<view class="content-wrap">
|
||||
<text class="article-title">{{ article.title }}</text>
|
||||
|
||||
<view class="meta-row">
|
||||
<text class="meta-text">{{ article.author || '健康科普' }}</text>
|
||||
<text class="meta-dot">·</text>
|
||||
<text class="meta-text">{{ article.create_time }}</text>
|
||||
<text class="meta-dot">·</text>
|
||||
<text class="meta-text">{{ article.click }} 阅读</text>
|
||||
</view>
|
||||
|
||||
<!-- 富文本内容 -->
|
||||
<rich-text :nodes="article.content" class="article-content" />
|
||||
</view>
|
||||
</block>
|
||||
|
||||
<!-- 加载失败 -->
|
||||
<view v-else class="empty-wrap">
|
||||
<text class="empty-text">文章不存在或已下架</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const article = ref(null)
|
||||
const loading = ref(false)
|
||||
|
||||
const fetchDetail = async (id) => {
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await proxy.apiUrl({
|
||||
url: '/api/article/detail',
|
||||
method: 'GET',
|
||||
data: { id }
|
||||
})
|
||||
if (response && response.code === 1) {
|
||||
article.value = response.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取文章详情失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const pages = getCurrentPages()
|
||||
const currentPage = pages[pages.length - 1]
|
||||
const id = currentPage?.options?.id
|
||||
if (id) fetchDetail(id)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.loading-wrap, .empty-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-top: 200rpx;
|
||||
}
|
||||
|
||||
.loading-text, .empty-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.cover-image {
|
||||
width: 100%;
|
||||
height: 420rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
background: #fff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
margin-top: -24rpx;
|
||||
padding: 40rpx 32rpx 60rpx;
|
||||
min-height: calc(100vh - 396rpx);
|
||||
}
|
||||
|
||||
.article-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.5;
|
||||
display: block;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 32rpx;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.meta-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.meta-dot {
|
||||
font-size: 24rpx;
|
||||
color: #ccc;
|
||||
margin: 0 12rpx;
|
||||
}
|
||||
|
||||
.article-content {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
line-height: 1.8;
|
||||
}
|
||||
</style>
|
||||
@@ -105,7 +105,7 @@
|
||||
<text class="error-text">{{ error }}</text>
|
||||
<view class="retry-btn" @click="loadDetail">重试</view>
|
||||
</view>
|
||||
|
||||
<view v-if="doctor">
|
||||
<!-- 底部操作栏 -->
|
||||
<view v-if="doctor.enable_image_consult || doctor.enable_video_consult" class="bottom-bar">
|
||||
<view class="btn-chat" @click="goChat" v-if="doctor.enable_image_consult">
|
||||
@@ -117,6 +117,7 @@
|
||||
<text class="btn-text">视频问诊</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 顶部标题 -->
|
||||
<view class="page-header">
|
||||
<text class="page-title">名医推荐</text>
|
||||
</view>
|
||||
|
||||
<!-- 医生列表 -->
|
||||
<view class="doctors-list">
|
||||
<view
|
||||
v-for="doctor in doctors"
|
||||
:key="doctor.id"
|
||||
class="doctor-card"
|
||||
@click="selectDoctor(doctor)"
|
||||
>
|
||||
<image :src="doctor.avatar || defaultAvatar" class="doctor-photo" mode="aspectFill"></image>
|
||||
<view class="doctor-info">
|
||||
<view class="doctor-top">
|
||||
<text class="doctor-name">{{ doctor.name }}</text>
|
||||
<text class="doctor-rating">★ {{ doctor.rating || '4.9' }}</text>
|
||||
</view>
|
||||
<text class="doctor-specialty">{{ doctor.specialty || doctor.title || '中医' }}</text>
|
||||
<view class="doctor-price-row">
|
||||
<text class="doctor-price">{{ doctor.price || '' }}</text>
|
||||
<text class="doctor-unit" v-if="doctor.title">{{doctor.title}}</text>
|
||||
</view>
|
||||
<view class="doctor-actions">
|
||||
<view class="appointment-btn" @click.stop="selectDoctor(doctor)">预约</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<view class="load-more" v-if="hasMore" @click="loadMore">
|
||||
<text class="load-more-text">{{ loading ? '加载中...' : '加载更多' }}</text>
|
||||
</view>
|
||||
<view class="no-more" v-else-if="doctors.length > 0">
|
||||
<text class="no-more-text">没有更多了</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty" v-if="!loading && doctors.length === 0">
|
||||
<text class="empty-text">暂无医生信息</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const doctors = ref([])
|
||||
const loading = ref(false)
|
||||
const pageNo = ref(1)
|
||||
const pageSize = 10
|
||||
const hasMore = ref(true)
|
||||
const defaultAvatar = '/static/user/user.png'
|
||||
|
||||
const selectDoctor = (doctor) => {
|
||||
uni.navigateTo({
|
||||
url: `/doctor/pages/doctor/doctor?id=${doctor.id}`
|
||||
})
|
||||
}
|
||||
|
||||
const fetchDoctors = async (reset = false) => {
|
||||
if (loading.value) return
|
||||
loading.value = true
|
||||
try {
|
||||
const response = await proxy.apiUrl({
|
||||
url: '/api/doctor/lists',
|
||||
method: 'GET',
|
||||
data: {
|
||||
page_no: pageNo.value,
|
||||
page_size: pageSize
|
||||
}
|
||||
})
|
||||
|
||||
if (response && response.code === 1) {
|
||||
const list = response.data?.lists || []
|
||||
if (reset) {
|
||||
doctors.value = list
|
||||
} else {
|
||||
doctors.value.push(...list)
|
||||
}
|
||||
hasMore.value = list.length === pageSize
|
||||
} else {
|
||||
console.warn('获取医生列表失败:', response?.msg)
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('请求异常:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const loadMore = () => {
|
||||
if (!hasMore.value || loading.value) return
|
||||
pageNo.value++
|
||||
fetchDoctors()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchDoctors(true)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
$background: #faf9f5;
|
||||
$primary: #204e2b;
|
||||
$on-primary: #ffffff;
|
||||
$on-primary-container: #afe2b3;
|
||||
$surface-container-lowest: #ffffff;
|
||||
$surface-container-high: #e9e8e4;
|
||||
$surface-container-highest: #e3e2df;
|
||||
$on-surface: #1b1c1a;
|
||||
$on-surface-variant: #414941;
|
||||
$outline: #727970;
|
||||
|
||||
.container {
|
||||
background: $background;
|
||||
min-height: 100vh;
|
||||
padding: 24rpx 32rpx 120rpx;
|
||||
font-family: 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', sans-serif;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: $on-surface;
|
||||
font-family: 'Noto Serif', 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', serif;
|
||||
}
|
||||
|
||||
.doctors-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.doctor-card {
|
||||
background: $surface-container-lowest;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.doctor-photo {
|
||||
width: 160rpx;
|
||||
height: 230rpx;
|
||||
border-radius: 16rpx;
|
||||
flex-shrink: 0;
|
||||
background: $surface-container-highest;
|
||||
}
|
||||
|
||||
.doctor-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-height: 192rpx;
|
||||
}
|
||||
|
||||
.doctor-top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.doctor-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: $on-surface;
|
||||
font-family: 'Noto Serif', 'Noto Sans SC', 'PingFang SC', 'Microsoft YaHei', serif;
|
||||
}
|
||||
|
||||
.doctor-rating {
|
||||
font-size: 24rpx;
|
||||
color: #805533;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.doctor-specialty {
|
||||
font-size: 28rpx;
|
||||
color: $on-surface-variant;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.doctor-price-row {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.doctor-price {
|
||||
font-size: 28rpx;
|
||||
color: $primary;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.doctor-unit {
|
||||
font-size: 24rpx;
|
||||
font-weight: normal;
|
||||
color: $on-surface-variant;
|
||||
}
|
||||
|
||||
.doctor-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.appointment-btn {
|
||||
background: $primary;
|
||||
color: $on-primary;
|
||||
font-size: 24rpx;
|
||||
font-weight: bold;
|
||||
padding: 16rpx 32rpx;
|
||||
border-radius: 9999rpx;
|
||||
}
|
||||
|
||||
.load-more {
|
||||
text-align: center;
|
||||
padding: 40rpx 0 20rpx;
|
||||
}
|
||||
|
||||
.load-more-text {
|
||||
font-size: 28rpx;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
padding: 40rpx 0 20rpx;
|
||||
}
|
||||
|
||||
.no-more-text {
|
||||
font-size: 26rpx;
|
||||
color: $outline;
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
padding: 120rpx 0;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 30rpx;
|
||||
color: $outline;
|
||||
}
|
||||
</style>
|
||||
@@ -9,7 +9,7 @@
|
||||
{
|
||||
"path": "pages/login/login",
|
||||
"style": {
|
||||
"navigationBarTitleText": "登录"
|
||||
"navigationBarTitleText": "视频问诊"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -27,7 +27,7 @@
|
||||
{
|
||||
"path": "TUICallKit/src/Components/TUICallKit",
|
||||
"style": {
|
||||
"navigationBarTitleText": "视频面诊",
|
||||
"navigationBarTitleText": "视频问诊",
|
||||
"navigationBarHidden": true,
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
@@ -76,7 +76,7 @@
|
||||
{
|
||||
"path": "pages/chat/chat",
|
||||
"style": {
|
||||
"navigationBarTitleText": "聊天"
|
||||
"navigationBarTitleText": "图文问诊"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -89,6 +89,18 @@
|
||||
"style": {
|
||||
"navigationBarTitleText": "医生信息"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/doctor/list/list",
|
||||
"style": {
|
||||
"navigationBarTitleText": "执业医生列表"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/article/article",
|
||||
"style": {
|
||||
"navigationBarTitleText": "健康百科"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -112,7 +124,7 @@
|
||||
},
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "甄养堂",
|
||||
"navigationBarTitleText": "甄养堂互联网医院",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="!loading && cardList.length === 0" class="empty-state">
|
||||
<uni-icons type="wallet" size="60" color="#999"></uni-icons>
|
||||
<uni-icons type="wallet" size="80" color="#1890ff"></uni-icons>
|
||||
<text class="empty-text">暂无就诊卡</text>
|
||||
<view class="add-card-btn" @click="createCard">新建就诊卡</view>
|
||||
</view>
|
||||
@@ -204,39 +204,41 @@ const formatDate = (timestamp) => {
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
/* 适老化设计:50-80岁 - 大字号、高对比、大触控区 */
|
||||
.card-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #f0f7ff 0%, #ffffff 100%);
|
||||
padding-bottom: 40rpx;
|
||||
background: linear-gradient(180deg, #e8f0fa 0%, #ffffff 100%);
|
||||
padding-bottom: 56rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #ffffff;
|
||||
padding: 40rpx 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
padding: 48rpx 40rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
|
||||
.header-title {
|
||||
font-size: 40rpx;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
padding: 30rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.card-item {
|
||||
background: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
border-radius: 28rpx;
|
||||
padding: 44rpx;
|
||||
margin-bottom: 36rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s;
|
||||
min-height: 200rpx;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,100 +246,100 @@ const formatDate = (timestamp) => {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
margin-bottom: 32rpx;
|
||||
padding-bottom: 28rpx;
|
||||
border-bottom: 4rpx solid #e8eaed;
|
||||
}
|
||||
|
||||
.card-id {
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
font-size: 34rpx;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
padding: 12rpx 28rpx;
|
||||
border-radius: 28rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.status-confirmed {
|
||||
background: #f6ffed;
|
||||
color: #204e2b;
|
||||
border: 2rpx solid #204e2b;
|
||||
border: 4rpx solid #204e2b;
|
||||
}
|
||||
|
||||
&.status-pending {
|
||||
background: #fff7e6;
|
||||
color: #fa8c16;
|
||||
border: 2rpx solid #ffd591;
|
||||
border: 4rpx solid #ffd591;
|
||||
}
|
||||
}
|
||||
|
||||
.card-info {
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 28rpx;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
margin-bottom: 24rpx;
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
min-width: 160rpx;
|
||||
font-size: 34rpx;
|
||||
color: #555;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-size: 36rpx;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding-top: 20rpx;
|
||||
border-top: 2rpx solid #f0f0f0;
|
||||
padding-top: 28rpx;
|
||||
border-top: 4rpx solid #e8eaed;
|
||||
}
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.time-label {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
min-width: 140rpx;
|
||||
font-size: 30rpx;
|
||||
color: #555;
|
||||
min-width: 180rpx;
|
||||
}
|
||||
|
||||
.time-value {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
font-size: 32rpx;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
|
||||
.view-count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 8rpx;
|
||||
margin-top: 12rpx;
|
||||
|
||||
.count-icon {
|
||||
font-size: 28rpx;
|
||||
margin-right: 8rpx;
|
||||
font-size: 34rpx;
|
||||
margin-right: 12rpx;
|
||||
}
|
||||
|
||||
.count-text {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
font-size: 30rpx;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,37 +348,38 @@ const formatDate = (timestamp) => {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
padding: 160rpx 0;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: 30rpx;
|
||||
font-size: 140rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
margin-bottom: 40rpx;
|
||||
font-size: 40rpx;
|
||||
color: #555;
|
||||
margin-bottom: 56rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.add-card-btn {
|
||||
padding: 24rpx 64rpx;
|
||||
padding: 36rpx 88rpx;
|
||||
background: #1890ff;
|
||||
color: #ffffff;
|
||||
font-size: 30rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: 500;
|
||||
border-radius: 48rpx;
|
||||
border-radius: 56rpx;
|
||||
min-height: 100rpx;
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 80rpx 0;
|
||||
padding: 120rpx 0;
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
font-size: 36rpx;
|
||||
color: #555;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1837,7 +1837,7 @@ const goBack = () => {
|
||||
color: #333333;
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
min-height: 60rpx;
|
||||
min-height: 80rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,59 +1,59 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-section">
|
||||
<!-- <view class="search-section">
|
||||
<view class="search-bar">
|
||||
<text class="search-icon">🔍</text>
|
||||
<input class="search-input" placeholder="搜索药材、医生或症状..." type="text" />
|
||||
<text class="search-filter">⚙</text>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
|
||||
<!-- 科室分类 -->
|
||||
<view class="department-section">
|
||||
<!-- 平台资质 -->
|
||||
<view class="qualification-section">
|
||||
<view class="section-header">
|
||||
<text class="section-title">科室分类</text>
|
||||
<text class="more-link" @click="navigateToDepartments">查看全部</text>
|
||||
<text class="section-title">平台资质</text>
|
||||
<!-- <text class="more-link" @click="navigateToQualifications">查看详情</text> -->
|
||||
</view>
|
||||
<view class="department-grid">
|
||||
<view class="dept-col-left">
|
||||
<view class="qualification-grid">
|
||||
<view class="qual-col-left">
|
||||
<view
|
||||
class="department-card large"
|
||||
@click="navigateToDepartment(departments[0])"
|
||||
class="qualification-card large"
|
||||
@click="navigateToQualification(qualifications[0])"
|
||||
>
|
||||
<view class="dept-card-inner dept-green">
|
||||
<view class="dept-icon"><text class="icon-text">✦</text></view>
|
||||
<text class="dept-name text-white">针灸</text>
|
||||
<text class="dept-desc text-white-sub">调理气血</text>
|
||||
<view class="qual-card-inner qual-primary">
|
||||
<view class="qual-icon"><image src="/static/wjw.png" style="width: 100rpx; margin-left: -5px;" mode="widthFix"></image></view>
|
||||
<text class="qual-name text-white">卫健委认证机构</text>
|
||||
<text class="qual-desc text-white-sub">互联网诊疗资质备案</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="dept-col-right">
|
||||
<view class="qual-col-right">
|
||||
<view
|
||||
class="department-card small"
|
||||
@click="navigateToDepartment(departments[1])"
|
||||
class="qualification-card small"
|
||||
@click="navigateToQualification(qualifications[1])"
|
||||
>
|
||||
<view class="dept-card-inner dept-beige">
|
||||
<view class="dept-icon-wrap">
|
||||
<view class="dept-icon"><text class="icon-text">●</text></view>
|
||||
<view class="qual-card-inner qual-beige">
|
||||
<view class="qual-icon-wrap">
|
||||
<view class="qual-icon"><image src="/static/yy.png" style="width: 100rpx; margin-left: -10px;" mode="widthFix"></image></view>
|
||||
</view>
|
||||
<view>
|
||||
<text class="dept-name">中药</text>
|
||||
<text class="dept-desc">古法方剂</text>
|
||||
<text class="qual-name">互联网医院</text>
|
||||
<text class="qual-desc">持证合规运营</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view
|
||||
class="department-card small"
|
||||
@click="navigateToDepartment(departments[2])"
|
||||
class="qualification-card small"
|
||||
@click="navigateToAllDoctors"
|
||||
>
|
||||
<view class="dept-card-inner dept-grey">
|
||||
<view class="dept-icon-wrap">
|
||||
<view class="dept-icon"><text class="icon-text">☯</text></view>
|
||||
<view class="qual-card-inner qual-grey">
|
||||
<view class="qual-icon-wrap">
|
||||
<view class="qual-icon"><image src="/static/ys.png" style="width: 90rpx; margin-left: -5px;" mode="widthFix"></image></view>
|
||||
</view>
|
||||
<view>
|
||||
<text class="dept-name">推拿</text>
|
||||
<text class="dept-desc">中医按摩</text>
|
||||
<text class="qual-name">执业医师认证</text>
|
||||
<text class="qual-desc">持证医师在线问诊</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -84,7 +84,7 @@
|
||||
<text class="doctor-specialty">{{ doctor.specialty || doctor.title || '中医' }}</text>
|
||||
<view class="doctor-price-row">
|
||||
<text class="doctor-price">{{ doctor.price || '' }}</text>
|
||||
<text class="doctor-unit">/次</text>
|
||||
<text class="doctor-unit" v-if="doctor.title">{{doctor.title}}</text>
|
||||
</view>
|
||||
<view class="doctor-actions">
|
||||
<view class="appointment-btn" @click.stop="selectDoctor(doctor)">预约</view>
|
||||
@@ -102,18 +102,18 @@
|
||||
</view>
|
||||
<scroll-view class="encyclopedia-scroll no-scrollbar" scroll-x :show-scrollbar="false">
|
||||
<view
|
||||
v-for="article in articles"
|
||||
v-for="(article, index) in articles"
|
||||
:key="article.id"
|
||||
class="article-card"
|
||||
:class="{ 'article-card-secondary': article.id === 2 }"
|
||||
:class="{ 'article-card-secondary': index % 2 === 1 }"
|
||||
@click="navigateToArticle(article)"
|
||||
>
|
||||
<view class="article-image-wrap">
|
||||
<image :src="article.cover" class="article-image" mode="aspectFill"></image>
|
||||
<view class="article-gradient" :class="{ 'gradient-secondary': article.id === 2 }"></view>
|
||||
<view class="article-tag" :class="{ 'tag-secondary': article.id === 2 }">{{ article.tag }}</view>
|
||||
<view class="article-gradient" :class="{ 'gradient-secondary': index % 2 === 1 }"></view>
|
||||
<view class="article-tag" :class="{ 'tag-secondary': index % 2 === 1 }">{{ article.tag }}</view>
|
||||
</view>
|
||||
<text class="article-title" :class="{ 'title-secondary': article.id === 2 }">{{ article.title }}</text>
|
||||
<text class="article-title" :class="{ 'title-secondary': index % 2 === 1 }">{{ article.title }}</text>
|
||||
<text class="article-desc">{{ article.desc }}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -124,26 +124,41 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getCurrentInstance } from 'vue'
|
||||
|
||||
import { onShow, onShareAppMessage } from '@dcloudio/uni-app'
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
const doctors = ref([])
|
||||
const loading = ref(false)
|
||||
const defaultAvatar = '/static/user/user.png'
|
||||
|
||||
// 科室分类
|
||||
const departments = ref([
|
||||
{ id: 1, name: '针灸', desc: '调理气血', icon: '✦', iconClass: 'icon-acupuncture', bgColor: 'linear-gradient(135deg, #2d5a3d 0%, #3d7a4d 100%)', dark: true, size: 'large', pattern: true },
|
||||
{ id: 2, name: '中药', desc: '古法方剂', icon: '◉', iconClass: 'icon-herb', bgColor: '#F5E6D3', dark: false, size: 'small' },
|
||||
{ id: 3, name: '推拿', desc: '中医按摩', icon: '☯', iconClass: 'icon-massage', bgColor: '#E8E4DF', dark: false, size: 'small' }
|
||||
// 平台资质
|
||||
const qualifications = ref([
|
||||
{ id: 1, name: '卫健委认证机构', desc: '互联网诊疗资质备案', icon: '✓', dark: true, size: 'large' },
|
||||
{ id: 2, name: '互联网医院', desc: '持证合规运营', icon: '', dark: false, size: 'small' },
|
||||
{ id: 3, name: '执业医师认证', desc: '持证医师在线问诊', icon: '★', dark: false, size: 'small' }
|
||||
])
|
||||
|
||||
// 健康百科
|
||||
const articles = ref([
|
||||
{ id: 1, title: '晨间生姜:脾胃健康的催化剂', desc: '了解每天早晨一片生姜如何改善您的新陈代谢...', tag: '膳食营养', cover: 'https://picsum.photos/seed/herb/300/180' },
|
||||
{ id: 2, title: '四时呼吸:顺应节气养生', desc: '顺应节气,调养身心...', tag: '正念冥想', cover: 'https://picsum.photos/seed/nature/300/180' },
|
||||
{ id: 3, title: '中医养生之道', desc: '传统智慧,现代健康...', tag: '养生保健', cover: 'https://picsum.photos/seed/health/300/180' }
|
||||
])
|
||||
const articles = ref([])
|
||||
|
||||
const fetchArticles = async () => {
|
||||
try {
|
||||
const response = await proxy.apiUrl({
|
||||
url: '/api/article/lists',
|
||||
method: 'GET',
|
||||
data: { page_no: 1, page_size: 10 }
|
||||
})
|
||||
if (response && response.code === 1) {
|
||||
articles.value = (response.data.lists || []).map(item => ({
|
||||
...item,
|
||||
cover: item.image,
|
||||
tag: item.cid || ''
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取文章列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const selectDoctor = (doctor) => {
|
||||
uni.navigateTo({
|
||||
@@ -151,16 +166,21 @@ const selectDoctor = (doctor) => {
|
||||
})
|
||||
}
|
||||
|
||||
const navigateToDepartments = () => {
|
||||
uni.showToast({ title: '科室列表', icon: 'none' })
|
||||
const navigateToQualifications = () => {
|
||||
uni.showToast({ title: '资质详情', icon: 'none' })
|
||||
}
|
||||
|
||||
const navigateToDepartment = (item) => {
|
||||
uni.showToast({ title: item.name, icon: 'none' })
|
||||
const navigateToQualification = (item) => {
|
||||
// 根据类型打开不同的协议页面
|
||||
uni.navigateTo({
|
||||
url: '/pages/Card/contact?type=health'
|
||||
})
|
||||
}
|
||||
|
||||
const navigateToAllDoctors = () => {
|
||||
uni.showToast({ title: '更多医生', icon: 'none' })
|
||||
uni.navigateTo({
|
||||
url: '/doctor/pages/doctor/list/list'
|
||||
})
|
||||
}
|
||||
|
||||
const navigateToEncyclopedia = () => {
|
||||
@@ -168,7 +188,7 @@ const navigateToEncyclopedia = () => {
|
||||
}
|
||||
|
||||
const navigateToArticle = (article) => {
|
||||
uni.showToast({ title: article.title, icon: 'none' })
|
||||
uni.navigateTo({ url: `/doctor/pages/article/article?id=${article.id}` })
|
||||
}
|
||||
|
||||
const fetchDoctors = async () => {
|
||||
@@ -196,9 +216,28 @@ const fetchDoctors = async () => {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
const userinfo = async (code) => {
|
||||
|
||||
try {
|
||||
// 通过 proxy 调用全局的 apiUrl
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/user/info',
|
||||
method: 'POST',
|
||||
}, false) // 不显示加载中
|
||||
|
||||
uni.setStorageSync('userData', res.data)
|
||||
|
||||
|
||||
} catch (err) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
onMounted(() => {
|
||||
fetchDoctors()
|
||||
fetchArticles()
|
||||
userinfo()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -289,28 +328,28 @@ $outline: #727970;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
// 科室分类 - grid 布局
|
||||
.department-section {
|
||||
// 平台资质 - grid 布局
|
||||
.qualification-section {
|
||||
margin-bottom: 64rpx;
|
||||
}
|
||||
|
||||
.department-grid {
|
||||
.qualification-grid {
|
||||
display: flex;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.dept-col-left {
|
||||
.qual-col-left {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.dept-col-right {
|
||||
.qual-col-right {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.department-card {
|
||||
.qualification-card {
|
||||
&.large {
|
||||
height: 100%;
|
||||
min-height: 320rpx;
|
||||
@@ -322,7 +361,7 @@ $outline: #727970;
|
||||
}
|
||||
}
|
||||
|
||||
.dept-card-inner {
|
||||
.qual-card-inner {
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
height: 100%;
|
||||
@@ -335,24 +374,24 @@ $outline: #727970;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 针灸 - primary-container */
|
||||
.dept-green {
|
||||
/* 卫健委认证 - primary-container */
|
||||
.qual-primary {
|
||||
background: $primary-container;
|
||||
color: $on-primary;
|
||||
}
|
||||
|
||||
.dept-green .dept-icon .icon-text,
|
||||
.dept-green .dept-name {
|
||||
.qual-primary .qual-icon .icon-text,
|
||||
.qual-primary .qual-name {
|
||||
color: $on-primary;
|
||||
}
|
||||
|
||||
.dept-green .dept-desc {
|
||||
.qual-primary .qual-desc {
|
||||
color: $on-primary-container;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
/* 中药 - secondary-container */
|
||||
.dept-beige {
|
||||
/* 互联网医院 - secondary-container */
|
||||
.qual-beige {
|
||||
background: $secondary-container;
|
||||
color: $on-secondary-container;
|
||||
flex-direction: row;
|
||||
@@ -361,32 +400,28 @@ $outline: #727970;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.dept-beige .dept-icon-wrap {
|
||||
background: rgba(255, 255, 255, 0.4);
|
||||
padding: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.dept-beige .dept-icon .icon-text {
|
||||
|
||||
.qual-beige .qual-icon .icon-text {
|
||||
font-size: 40rpx;
|
||||
color: $on-secondary-container;
|
||||
}
|
||||
|
||||
.dept-beige .dept-name {
|
||||
.qual-beige .qual-name {
|
||||
color: $on-secondary-container;
|
||||
margin-bottom: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dept-beige .dept-desc {
|
||||
.qual-beige .qual-desc {
|
||||
color: $on-secondary-container;
|
||||
opacity: 0.8;
|
||||
font-size: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* 推拿 - surface-container-high */
|
||||
.dept-grey {
|
||||
/* 执业医师认证 - surface-container-high */
|
||||
.qual-grey {
|
||||
background: $surface-container-high;
|
||||
color: $on-surface;
|
||||
flex-direction: row;
|
||||
@@ -395,43 +430,39 @@ $outline: #727970;
|
||||
padding: 32rpx;
|
||||
}
|
||||
|
||||
.dept-grey .dept-icon-wrap {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
padding: 16rpx;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.dept-grey .dept-icon .icon-text {
|
||||
|
||||
.qual-grey .qual-icon .icon-text {
|
||||
font-size: 40rpx;
|
||||
color: $primary;
|
||||
}
|
||||
|
||||
.dept-grey .dept-name {
|
||||
.qual-grey .qual-name {
|
||||
color: $on-surface;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dept-grey .dept-desc {
|
||||
.qual-grey .qual-desc {
|
||||
color: $on-surface-variant;
|
||||
font-size: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.dept-icon {
|
||||
.qual-icon {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.dept-beige .dept-icon,
|
||||
.dept-grey .dept-icon {
|
||||
.qual-beige .qual-icon,
|
||||
.qual-grey .qual-icon {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.dept-icon .icon-text {
|
||||
.qual-icon .icon-text {
|
||||
font-size: 56rpx;
|
||||
color: $on-primary;
|
||||
}
|
||||
|
||||
.dept-name {
|
||||
.qual-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: $on-surface;
|
||||
@@ -443,7 +474,7 @@ $outline: #727970;
|
||||
}
|
||||
}
|
||||
|
||||
.dept-desc {
|
||||
.qual-desc {
|
||||
font-size: 26rpx;
|
||||
color: $on-surface-variant;
|
||||
|
||||
@@ -512,11 +543,13 @@ $outline: #727970;
|
||||
font-size: 28rpx;
|
||||
color: $on-surface-variant;
|
||||
margin-bottom: 16rpx;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.doctor-price-row {
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
|
||||
.doctor-price {
|
||||
font-size: 28rpx;
|
||||
@@ -533,6 +566,9 @@ $outline: #727970;
|
||||
.doctor-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
position: relative;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.appointment-btn {
|
||||
|
||||
@@ -83,8 +83,8 @@ onShareAppMessage((res) =>{
|
||||
return {
|
||||
title: '视频问诊通话邀请',
|
||||
path: '/pages/index/video',
|
||||
imageUrl: '/static/share-img.png',
|
||||
desc: '自定义分享描述',
|
||||
imageUrl: '',
|
||||
desc: '视频问诊通话邀请',
|
||||
success() {
|
||||
uni.showToast({ title: '分享成功', icon: 'success' });
|
||||
},
|
||||
|
||||
@@ -356,6 +356,7 @@
|
||||
|
||||
<script setup>
|
||||
import { ref,onMounted,getCurrentInstance } from "vue";
|
||||
import { onShow, onShareAppMessage } from '@dcloudio/uni-app'
|
||||
// 2. 获取组件实例,通过 proxy 访问全局属性
|
||||
const { proxy } = getCurrentInstance()
|
||||
const formData = ref({
|
||||
@@ -433,7 +434,21 @@ onMounted(() => {
|
||||
getDictOptions();
|
||||
loadDiagnosisDetail();
|
||||
});
|
||||
|
||||
onShareAppMessage((res) =>{
|
||||
return {
|
||||
title: '诊单确认',
|
||||
path: '/pages/order/monad/monad?id='+diagnosisId+'&share_user_id='+share_user_id,
|
||||
imageUrl: '',
|
||||
desc: '诊单确认',
|
||||
success() {
|
||||
uni.showToast({ title: '分享成功', icon: 'success' });
|
||||
},
|
||||
fail(err) {
|
||||
console.log('分享失败:', err);
|
||||
uni.showToast({ title: '分享失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
});
|
||||
// 获取字典数据
|
||||
const getDictOptions = async () => {
|
||||
try {
|
||||
@@ -518,7 +533,8 @@ const getDictData = async (type) => {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
let diagnosisId=''
|
||||
let share_user_id='';
|
||||
// 加载诊单详情
|
||||
const loadDiagnosisDetail = async () => {
|
||||
// 从页面参数获取诊单ID
|
||||
@@ -526,7 +542,8 @@ const loadDiagnosisDetail = async () => {
|
||||
const currentPage = pages[pages.length - 1];
|
||||
const params = proxy.$parsePageParams(currentPage.options);
|
||||
dingdan_ok.value=uni.getStorageSync('dingdan_ok');
|
||||
const diagnosisId = params.id;
|
||||
diagnosisId = params.id;
|
||||
share_user_id = params.share_user_id;
|
||||
console.log('进入onMounted:', params, '诊单ID:', diagnosisId);
|
||||
|
||||
if (!diagnosisId) {
|
||||
|
||||
@@ -6,23 +6,23 @@
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill" />
|
||||
<div class="user-info">
|
||||
<text class="nickname">{{ userInfo.nickname || '未登录' }}</text>
|
||||
<text class="vip-tag">VIP会员</text>
|
||||
<!-- <text class="vip-tag">VIP会员</text> -->
|
||||
</div>
|
||||
<div class="qr-code" @click.stop="showQRCode">
|
||||
<!-- <div class="qr-code" @click.stop="showQRCode">
|
||||
<uni-icons type="scan" size="20" color="#333"></uni-icons>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="stat-row">
|
||||
<div class="stat-item">
|
||||
<text class="value">{{ userInfo.balance ||0}}</text>
|
||||
<text class="value">{{ userInfo.balance || 0 }}</text>
|
||||
<text class="label">钱包(元)</text>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<text class="value">{{ userInfo.points ||0}}</text>
|
||||
<text class="value">{{ userInfo.points || 0 }}</text>
|
||||
<text class="label">积分</text>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<text class="value">{{ userInfo.coupons ||0}}</text>
|
||||
<text class="value">{{ userInfo.coupons || 0 }}</text>
|
||||
<text class="label">优惠券</text>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,23 +68,23 @@
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 服务菜单列表 -->
|
||||
<!-- 服务菜单列表(适老化:显示全部,大触控区) -->
|
||||
<div class="service-list">
|
||||
<div
|
||||
class="service-item"
|
||||
v-for="(item, index) in allServices.slice(4)"
|
||||
v-for="(item, index) in allServices"
|
||||
:key="index"
|
||||
@click="navigateTo(item.path)"
|
||||
>
|
||||
<div class="left">
|
||||
<div class="service-icon" :class="item.class">
|
||||
<uni-icons :type="item.icon" size="20" color="#fff"></uni-icons>
|
||||
<uni-icons :type="item.icon" size="28" color="#fff"></uni-icons>
|
||||
</div>
|
||||
<text class="service-name">{{ item.name }}</text>
|
||||
</div>
|
||||
<div class="right">
|
||||
<text v-if="item.desc" class="desc">{{ item.desc }}</text>
|
||||
<uni-icons type="right" size="14" color="#999"></uni-icons>
|
||||
<uni-icons type="right" size="20" color="#666"></uni-icons>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -92,6 +92,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onShow, onShareAppMessage } from '@dcloudio/uni-app'
|
||||
export default {
|
||||
name: 'profileB',
|
||||
data() {
|
||||
@@ -137,19 +138,15 @@ export default {
|
||||
}
|
||||
],
|
||||
allServices: [
|
||||
{ name: '收藏夹', icon: 'star', path: '/pages/favorite/index', class: 'bg-red' },
|
||||
{ name: '浏览记录', icon: 'eye', path: '/pages/history/index', class: 'bg-blue' },
|
||||
{ name: '收货地址', icon: 'location', path: '/pages/address/list', class: 'bg-green' },
|
||||
{ name: '优惠券', icon: 'gift', path: '/pages/coupon/list', class: 'bg-purple' },
|
||||
{ name: '就诊卡', icon: 'folder-add', path: '/pages/Card/Card', class: 'bg-cyan' },
|
||||
{ name: '设置', icon: 'gear', path: '/pages/user/userinfo', class: 'bg-gray' }// ,
|
||||
{ name: '设置', icon: 'gear', path: '/pages/user/userinfo', class: 'bg-gray' }// ,
|
||||
// { name: '客服中心', icon: 'headphones', path: '/pages/service/index', class: 'bg-orange', desc: '在线客服' }
|
||||
]
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.userInfo=uni.getStorageSync('userData')
|
||||
|
||||
this.user()
|
||||
},
|
||||
methods: {
|
||||
navigateTo(path) {
|
||||
@@ -163,56 +160,59 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 适老化设计:50-80岁老人 - 大字号、高对比、大触控区 */
|
||||
.mine-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f6fa;
|
||||
padding: 30rpx;
|
||||
background: #e8eaed;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
border-radius: 28rpx;
|
||||
padding: 48rpx;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
|
||||
.user-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
margin-bottom: 48rpx;
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
margin-right: 30rpx;
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 80rpx;
|
||||
margin-right: 36rpx;
|
||||
border: 4rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
|
||||
.nickname {
|
||||
font-size: 36rpx;
|
||||
font-size: 48rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 12rpx;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.vip-tag {
|
||||
background: linear-gradient(90deg, #FFD700 0%, #FFA500 100%);
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 28rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
border-radius: 24rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 36rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
background: #f5f6fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -222,24 +222,26 @@ export default {
|
||||
|
||||
.stat-row {
|
||||
display: flex;
|
||||
padding-top: 30rpx;
|
||||
border-top: 2rpx solid #f5f6fa;
|
||||
padding-top: 40rpx;
|
||||
border-top: 4rpx solid #e8eaed;
|
||||
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
min-height: 120rpx;
|
||||
|
||||
.value {
|
||||
font-size: 40rpx;
|
||||
font-size: 52rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 12rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
font-size: 32rpx;
|
||||
color: #555;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -354,16 +356,17 @@ export default {
|
||||
|
||||
.service-list {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 10rpx 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
border-radius: 28rpx;
|
||||
padding: 20rpx 40rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0,0,0,0.06);
|
||||
|
||||
.service-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 2rpx solid #f5f6fa;
|
||||
padding: 44rpx 0;
|
||||
border-bottom: 4rpx solid #e8eaed;
|
||||
min-height: 120rpx;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
@@ -374,18 +377,19 @@ export default {
|
||||
align-items: center;
|
||||
|
||||
.service-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 32rpx;
|
||||
margin-right: 24rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
border-radius: 44rpx;
|
||||
margin-right: 32rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
font-size: 38rpx;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,9 +398,9 @@ export default {
|
||||
align-items: center;
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
font-size: 30rpx;
|
||||
color: #555;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="avatar-upload" @click="uploadAvatar">
|
||||
|
||||
<uni-icons type="upload-filled" size="14" color="#999" class="upload-icon"></uni-icons>
|
||||
<uni-icons type="upload-filled" size="24" color="#FFA500" class="upload-icon"></uni-icons>
|
||||
<text class="upload-text">更换头像</text>
|
||||
</view>
|
||||
</view>
|
||||
@@ -281,9 +280,10 @@ const goBack = () => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 适老化设计:50-80岁 - 大字号、高对比、大触控区 */
|
||||
.userinfo-container {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
background: #e8eaed;
|
||||
}
|
||||
|
||||
.header {
|
||||
@@ -291,30 +291,30 @@ const goBack = () => {
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #ffffff;
|
||||
padding: 20rpx 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
padding: 24rpx 40rpx;
|
||||
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.header-back {
|
||||
font-size: 40rpx;
|
||||
font-size: 48rpx;
|
||||
color: #FFA500;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
width: 88rpx;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-size: 44rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
color: #1a1a1a;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-placeholder {
|
||||
width: 60rpx;
|
||||
width: 88rpx;
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
@@ -322,34 +322,34 @@ const goBack = () => {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
font-size: 36rpx;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
padding: 30rpx;
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 36rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #FFA500;
|
||||
margin-bottom: 24rpx;
|
||||
margin-bottom: 32rpx;
|
||||
display: block;
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
padding-bottom: 24rpx;
|
||||
border-bottom: 4rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 24rpx;
|
||||
margin-bottom: 36rpx;
|
||||
}
|
||||
|
||||
.form-group:last-child {
|
||||
@@ -358,111 +358,116 @@ const goBack = () => {
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
font-size: 36rpx;
|
||||
color: #1a1a1a;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16rpx;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e8e8e8;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.5;
|
||||
color: #333333;
|
||||
padding: 28rpx;
|
||||
border: 4rpx solid #e0e0e0;
|
||||
border-radius: 16rpx;
|
||||
font-size: 36rpx;
|
||||
line-height: 1.6;
|
||||
color: #1a1a1a;
|
||||
background: #ffffff;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
height: auto;
|
||||
min-height: 60rpx;
|
||||
min-height: 96rpx;
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: #cccccc;
|
||||
color: #999;
|
||||
font-size: 34rpx;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
gap: 32rpx;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 80rpx;
|
||||
background: #f0f0f0;
|
||||
border: 4rpx solid #e0e0e0;
|
||||
}
|
||||
|
||||
.avatar-upload {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border: 2rpx dashed #FFA500;
|
||||
border-radius: 12rpx;
|
||||
padding: 36rpx;
|
||||
border: 4rpx dashed #FFA500;
|
||||
border-radius: 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
gap: 16rpx;
|
||||
min-height: 120rpx;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 40rpx;
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
font-size: 24rpx;
|
||||
font-size: 34rpx;
|
||||
color: #FFA500;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.sex-group {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
gap: 28rpx;
|
||||
}
|
||||
|
||||
.sex-btn {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e8e8e8;
|
||||
border-radius: 12rpx;
|
||||
padding: 32rpx;
|
||||
border: 4rpx solid #e0e0e0;
|
||||
border-radius: 16rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
font-size: 38rpx;
|
||||
line-height: 1.5;
|
||||
color: #666666;
|
||||
color: #555;
|
||||
background: #ffffff;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 60rpx;
|
||||
min-height: 96rpx;
|
||||
}
|
||||
|
||||
.sex-btn.active {
|
||||
border-color: #FFA500;
|
||||
background: #e6f7ff;
|
||||
background: #fff7e6;
|
||||
color: #FFA500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
margin-bottom: 40rpx;
|
||||
gap: 28rpx;
|
||||
margin-top: 56rpx;
|
||||
margin-bottom: 56rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
padding: 36rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
min-height: 100rpx;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
@@ -476,7 +481,7 @@ const goBack = () => {
|
||||
|
||||
.btn-cancel {
|
||||
background: #f0f0f0;
|
||||
color: #666666;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
@@ -485,6 +490,6 @@ const goBack = () => {
|
||||
}
|
||||
|
||||
.btn-submit:active:not(:disabled) {
|
||||
background: #0050b3;
|
||||
background: #e69500;
|
||||
}
|
||||
</style>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Reference in New Issue
Block a user