更新
This commit is contained in:
@@ -0,0 +1,359 @@
|
||||
<template>
|
||||
<view class="card-container">
|
||||
<!-- 顶部标题栏 -->
|
||||
<view class="header">
|
||||
<text class="header-title">我的就诊卡</text>
|
||||
</view>
|
||||
|
||||
<!-- 就诊卡列表 -->
|
||||
<view class="card-list">
|
||||
<view
|
||||
v-for="card in cardList"
|
||||
:key="card.id"
|
||||
class="card-item"
|
||||
@click="viewCardDetail(card)"
|
||||
>
|
||||
<!-- 卡片头部 -->
|
||||
<view class="card-header">
|
||||
<view class="card-id">
|
||||
<text class="label">诊单编号:</text>
|
||||
<text class="value">{{ card.id }}</text>
|
||||
</view>
|
||||
<view :class="['status-badge', getStatusClass(card.status)]">
|
||||
{{ card.status_desc || getStatusText(card.status) }}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 患者信息 -->
|
||||
<view class="card-info">
|
||||
<view class="info-row">
|
||||
<text class="info-label">患者姓名:</text>
|
||||
<text class="info-value">{{ card.patient_name || '-' }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">性别年龄:</text>
|
||||
<text class="info-value">{{ card.gender_desc || '-' }} / {{ card.age }}岁</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">诊断类型:</text>
|
||||
<text class="info-value">{{ getDiagnosisTypeName(card.diagnosis_type) }}</text>
|
||||
</view>
|
||||
<view class="info-row">
|
||||
<text class="info-label">证型:</text>
|
||||
<text class="info-value">{{ getSyndromeTypeName(card.syndrome_type) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 时间信息 -->
|
||||
<view class="card-footer">
|
||||
<view class="time-info">
|
||||
<text class="time-label">诊断日期:</text>
|
||||
<text class="time-value">{{ card.diagnosis_date_text || formatDate(card.diagnosis_date) }}</text>
|
||||
</view>
|
||||
<view class="time-info">
|
||||
<text class="time-label">创建时间:</text>
|
||||
<text class="time-value">{{ card.create_time || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="!loading && cardList.length === 0" class="empty-state">
|
||||
<uni-icons type="wallet" size="60" color="#999"></uni-icons>
|
||||
<text class="empty-text">暂无就诊卡</text>
|
||||
</view>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view v-if="loading" class="loading-state">
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
|
||||
// 数据
|
||||
const cardList = ref([])
|
||||
const loading = ref(false)
|
||||
|
||||
// 页面加载时获取数据
|
||||
onMounted(() => {
|
||||
loadCardList()
|
||||
})
|
||||
|
||||
// 加载就诊卡列表
|
||||
const loadCardList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
// 检查token是否存在
|
||||
const token = uni.getStorageSync('token')
|
||||
if (!token) {
|
||||
uni.showToast({ title: '请先登录', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.redirectTo({ url: '/pages/login/login' })
|
||||
}, 1500)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取当前用户的patient_id
|
||||
const userData = uni.getStorageSync('userData')
|
||||
const patientId = userData?.diagnosis?.patient_id
|
||||
|
||||
if (!patientId) {
|
||||
uni.showToast({ title: '患者信息不存在', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 调用后端接口获取就诊卡列表
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/getCardList',
|
||||
method: 'GET',
|
||||
data: {
|
||||
patient_id: patientId
|
||||
}
|
||||
})
|
||||
|
||||
if (res.code === 1) {
|
||||
cardList.value = res.data || []
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '获取失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载就诊卡列表失败:', err)
|
||||
//uni.showToast({ title: '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 查看卡片详情
|
||||
const viewCardDetail = (card) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/Card/edit_card?id=${card.id}`
|
||||
})
|
||||
}
|
||||
|
||||
// 获取状态文本
|
||||
const getStatusText = (status) => {
|
||||
return status === 1 ? '启用' : '禁用'
|
||||
}
|
||||
|
||||
// 获取状态样式类
|
||||
const getStatusClass = (status) => {
|
||||
return status === 1 ? 'status-confirmed' : 'status-pending'
|
||||
}
|
||||
|
||||
// 诊断类型字典
|
||||
const diagnosisTypeMap = {
|
||||
'first_visit': '初诊',
|
||||
'follow_up': '复诊',
|
||||
'consultation': '会诊'
|
||||
}
|
||||
|
||||
// 证型字典
|
||||
const syndromeTypeMap = {
|
||||
'qi_deficiency': '气虚',
|
||||
'blood_deficiency': '血虚',
|
||||
'yin_deficiency': '阴虚',
|
||||
'yang_deficiency': '阳虚',
|
||||
'qi_stagnation': '气滞',
|
||||
'blood_stasis': '血瘀',
|
||||
'phlegm_dampness': '痰湿',
|
||||
'damp_heat': '湿热',
|
||||
'cold_dampness': '寒湿',
|
||||
'wind_cold': '风寒',
|
||||
'wind_heat': '风热'
|
||||
}
|
||||
|
||||
// 获取诊断类型名称
|
||||
const getDiagnosisTypeName = (type) => {
|
||||
return diagnosisTypeMap[type] || type || '-'
|
||||
}
|
||||
|
||||
// 获取证型名称
|
||||
const getSyndromeTypeName = (type) => {
|
||||
return syndromeTypeMap[type] || type || '-'
|
||||
}
|
||||
|
||||
// 格式化日期(时间戳转日期)
|
||||
const formatDate = (timestamp) => {
|
||||
if (!timestamp) return '-'
|
||||
const date = new Date(timestamp * 1000)
|
||||
const year = date.getFullYear()
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0')
|
||||
const day = String(date.getDate()).padStart(2, '0')
|
||||
return `${year}-${month}-${day}`
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.card-container {
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #f0f7ff 0%, #ffffff 100%);
|
||||
padding-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.header {
|
||||
background: #ffffff;
|
||||
padding: 40rpx 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.header-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.card-item {
|
||||
background: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 24rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.card-id {
|
||||
.label {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
padding: 8rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
|
||||
&.status-confirmed {
|
||||
background: #f6ffed;
|
||||
color: #52c41a;
|
||||
border: 2rpx solid #b7eb8f;
|
||||
}
|
||||
|
||||
&.status-pending {
|
||||
background: #fff7e6;
|
||||
color: #fa8c16;
|
||||
border: 2rpx solid #ffd591;
|
||||
}
|
||||
}
|
||||
|
||||
.card-info {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
.info-label {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
min-width: 160rpx;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding-top: 20rpx;
|
||||
border-top: 2rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
|
||||
.time-label {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
min-width: 140rpx;
|
||||
}
|
||||
|
||||
.time-value {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.view-count {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 8rpx;
|
||||
|
||||
.count-icon {
|
||||
font-size: 28rpx;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
|
||||
.count-text {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 120rpx 0;
|
||||
|
||||
.empty-icon {
|
||||
font-size: 120rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
font-size: 32rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 80rpx 0;
|
||||
|
||||
.loading-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -137,7 +137,7 @@ const loginHandler = async (patient_id) => {
|
||||
|
||||
|
||||
|
||||
const {userId } = res.data;
|
||||
const {userId } = res.data;
|
||||
|
||||
const { userSig, SDKAppID } = GenerateTestUserSig.genTestUserSig({
|
||||
userID:userId,
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
|
||||
<!-- 等待视频通话页面 - 老年人友好版 -->
|
||||
<view class="waiting-container">
|
||||
<view class="waiting-content">
|
||||
<!-- 大号医生图标动画 -->
|
||||
<view class="waiting-animation">
|
||||
<view class="pulse-ring"></view>
|
||||
<view class="pulse-ring delay-1"></view>
|
||||
<view class="pulse-ring delay-2"></view>
|
||||
<view class="doctor-icon">
|
||||
<text class="icon-text">👨⚕️</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 超大标题 -->
|
||||
<view class="waiting-title">正在等待医生</view>
|
||||
<view class="waiting-subtitle">视频通话即将开始</view>
|
||||
|
||||
<!-- 大字号提示卡片 -->
|
||||
<view class="tips-card">
|
||||
<view class="tips-header">
|
||||
<text class="tips-icon">💡</text>
|
||||
<text class="tips-header-text">温馨提示</text>
|
||||
</view>
|
||||
<view class="tips-list">
|
||||
<view class="tips-item">
|
||||
<text class="tips-number">1</text>
|
||||
<text class="tips-text">请保持手机摄像头清洁</text>
|
||||
</view>
|
||||
<view class="tips-item">
|
||||
<text class="tips-number">2</text>
|
||||
<text class="tips-text">选择光线明亮的位置</text>
|
||||
</view>
|
||||
<view class="tips-item">
|
||||
<text class="tips-number">3</text>
|
||||
<text class="tips-text">保持环境安静</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 大号帮助按钮 -->
|
||||
<view class="help-button" @click="url">
|
||||
<text class="help-text">需要帮助?点击这里</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, getCurrentInstance } from "vue";
|
||||
import { onShow, onShareAppMessage } from '@dcloudio/uni-app'
|
||||
const { proxy } = getCurrentInstance()
|
||||
import * as GenerateTestUserSig from "@/debug/GenerateTestUserSig-es.js";
|
||||
import { CallManager } from "@/TUICallKit/src/TUICallService/serve/callManager";
|
||||
let userId = ref("");
|
||||
let userSig= ref("");
|
||||
let SDKAppID=ref("");
|
||||
uni.CallManager = new CallManager();
|
||||
|
||||
onShow(() => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success: function (loginRes) {
|
||||
console.log('---------进入onShow',loginRes.code)
|
||||
wxcode(loginRes.code)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
onShareAppMessage((res) =>{
|
||||
return {
|
||||
title: '视频问诊通话邀请',
|
||||
path: '/pages/index/video',
|
||||
imageUrl: '/static/share-img.png',
|
||||
desc: '自定义分享描述',
|
||||
success() {
|
||||
uni.showToast({ title: '分享成功', icon: 'success' });
|
||||
},
|
||||
fail(err) {
|
||||
console.log('分享失败:', err);
|
||||
uni.showToast({ title: '分享失败', icon: 'none' });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const wxcode = async (code) => {
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/login/mnpLogin',
|
||||
method: 'POST',
|
||||
data: { code: code },
|
||||
}, false)
|
||||
console.log('---------------',res.data)
|
||||
uni.setStorageSync('token', res.data.token)
|
||||
uni.setStorageSync('userData', res.data)
|
||||
loginHandler(res.data.diagnosis.patient_id)
|
||||
} catch (err) {
|
||||
uni.showToast({ title: '请求失败', icon: 'none' })
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
const url=()=>{
|
||||
const doctor='doctor_'+uni.getStorageSync('userData').diagnosis.diagnosis_id
|
||||
// 跳转到聊天页面
|
||||
uni.navigateTo({
|
||||
url: `/TUIKit/pages/chat/chat?userID=${encodeURIComponent(userId)}&userSig=${encodeURIComponent(userSig)}&SDKAppID=${SDKAppID}&targetUserID=${doctor}`
|
||||
});
|
||||
}
|
||||
const loginHandler = async (patient_id) => {
|
||||
console.log('获取签名开始:',patient_id);
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/tcm/getPatientSignature',
|
||||
method: 'GET',
|
||||
data: { patient_id: patient_id },
|
||||
}, false)
|
||||
|
||||
const {userId } = res.data;
|
||||
const { userSig, SDKAppID } = GenerateTestUserSig.genTestUserSig({
|
||||
userID:userId,
|
||||
});
|
||||
console.log('获取签名成功:',userSig);
|
||||
|
||||
getApp().globalData.userID = userId;
|
||||
getApp().globalData.userSig = userSig;
|
||||
getApp().globalData.SDKAppID = SDKAppID;
|
||||
getApp().globalData.isIMInitialized = false; // 标记IM未初始化
|
||||
|
||||
// 初始化视频通话
|
||||
await uni.CallManager.init({
|
||||
sdkAppID: SDKAppID,
|
||||
userID: userId,
|
||||
userSig: userSig,
|
||||
globalCallPagePath: "TUICallKit/src/Components/TUICallKit",
|
||||
});
|
||||
|
||||
console.log('初始化完成,跳转到聊天页面');
|
||||
|
||||
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #f4f5f9;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* ========== 老年人友好等待界面样式 ========== */
|
||||
.waiting-container {
|
||||
width: 100vw;
|
||||
min-height: 100vh;
|
||||
background: linear-gradient(180deg, #f0f7ff 0%, #ffffff 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 40rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.waiting-content {
|
||||
width: 100%;
|
||||
max-width: 700rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 动画区域 - 更大更明显 */
|
||||
.waiting-animation {
|
||||
position: relative;
|
||||
width: 280rpx;
|
||||
height: 280rpx;
|
||||
margin-bottom: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pulse-ring {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 6rpx solid #1890ff;
|
||||
border-radius: 50%;
|
||||
animation: pulse 2s ease-out infinite;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.pulse-ring.delay-1 {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
.pulse-ring.delay-2 {
|
||||
animation-delay: 1.2s;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% {
|
||||
transform: scale(0.5);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1.3);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.doctor-icon {
|
||||
width: 180rpx;
|
||||
height: 180rpx;
|
||||
background: linear-gradient(135deg, #1890ff 0%, #096dd9 100%);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 8rpx 24rpx rgba(24, 144, 255, 0.3);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.icon-text {
|
||||
font-size: 100rpx;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 超大标题 - 老年人易读 */
|
||||
.waiting-title {
|
||||
font-size: 56rpx;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
margin-bottom: 20rpx;
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.waiting-subtitle {
|
||||
font-size: 40rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 60rpx;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 提示卡片 - 大字号清晰 */
|
||||
.tips-card {
|
||||
width: 100%;
|
||||
background: #fffbe6;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 40rpx;
|
||||
border: 3rpx solid #fadb14;
|
||||
}
|
||||
|
||||
.tips-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 2rpx solid #ffd666;
|
||||
}
|
||||
|
||||
.tips-icon {
|
||||
font-size: 48rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.tips-header-text {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #d48806;
|
||||
}
|
||||
|
||||
.tips-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30rpx;
|
||||
}
|
||||
|
||||
.tips-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 24rpx;
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.tips-number {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: #faad14;
|
||||
color: #ffffff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 24rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.tips-text {
|
||||
font-size: 36rpx;
|
||||
color: #333333;
|
||||
line-height: 1.6;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 帮助按钮 - 大号易点击 */
|
||||
.help-button {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
background: #ffffff;
|
||||
border: 3rpx solid #1890ff;
|
||||
border-radius: 50rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 12rpx rgba(24, 144, 255, 0.15);
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
font-size: 38rpx;
|
||||
color: #1890ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,414 @@
|
||||
<template>
|
||||
<div class="mine-page">
|
||||
<!-- 顶部用户信息卡片 -->
|
||||
<div class="user-card" @click="navigateTo('/pages/user/userinfo')">
|
||||
<div class="user-header">
|
||||
<image class="avatar" :src="userInfo.avatar" mode="aspectFill" />
|
||||
<div class="user-info">
|
||||
<text class="nickname">{{ userInfo.nickname || '未登录' }}</text>
|
||||
<text class="vip-tag">VIP会员</text>
|
||||
</div>
|
||||
<div class="qr-code" @click.stop="showQRCode">
|
||||
<uni-icons type="scan" size="20" color="#333"></uni-icons>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat-row">
|
||||
<div class="stat-item">
|
||||
<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="label">积分</text>
|
||||
</div>
|
||||
<div class="stat-item">
|
||||
<text class="value">{{ userInfo.coupons ||0}}</text>
|
||||
<text class="label">优惠券</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 订单卡片 -->
|
||||
<div class="order-card">
|
||||
<div class="card-header">
|
||||
<text class="title">我的订单</text>
|
||||
<div class="more" @click="navigateTo('/pages/order/list')">
|
||||
<text>查看全部</text>
|
||||
<uni-icons type="right" size="14" color="#999"></uni-icons>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-list">
|
||||
<div
|
||||
class="order-item"
|
||||
v-for="(item, index) in orderTypes"
|
||||
:key="index"
|
||||
@click="navigateTo(item.path)"
|
||||
>
|
||||
<div class="icon-wrapper">
|
||||
<image :src="item.image" mode="aspectFit" class="order-icon" />
|
||||
<text v-if="item.count" class="count-badge">{{ item.count }}</text>
|
||||
</div>
|
||||
<text class="order-name">{{ item.name }}</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 快捷功能区 -->
|
||||
<!-- <div class="quick-actions">
|
||||
<div
|
||||
class="action-item"
|
||||
v-for="(item, index) in allServices.slice(0, 4)"
|
||||
:key="index"
|
||||
@click="navigateTo(item.path)"
|
||||
>
|
||||
<div class="action-icon" :class="item.class">
|
||||
<uni-icons :type="item.icon" size="24" color="#fff"></uni-icons>
|
||||
</div>
|
||||
<text class="action-name">{{ item.name }}</text>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<!-- 服务菜单列表 -->
|
||||
<div class="service-list">
|
||||
<div
|
||||
class="service-item"
|
||||
v-for="(item, index) in allServices.slice(4)"
|
||||
: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>
|
||||
</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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'profileB',
|
||||
data() {
|
||||
return {
|
||||
userInfo: {
|
||||
avatar: '',
|
||||
nickname: '',
|
||||
userId: '',
|
||||
balance: '0',
|
||||
points: '0',
|
||||
coupons: '5'
|
||||
},
|
||||
orderTypes: [
|
||||
{
|
||||
name: '待付款',
|
||||
image: '/static/images/my/payment.png',
|
||||
path: '/pages/order/list?type=1',
|
||||
count: 2
|
||||
},
|
||||
{
|
||||
name: '待发货',
|
||||
image: '/static/images/my/delivery.png',
|
||||
path: '/pages/order/list?type=2',
|
||||
count: 1
|
||||
},
|
||||
{
|
||||
name: '待收货',
|
||||
image: '/static/images/my/shipping.png',
|
||||
path: '/pages/order/list?type=3',
|
||||
count: 0
|
||||
},
|
||||
{
|
||||
name: '待评价',
|
||||
image: '/static/images/my/review.png',
|
||||
path: '/pages/order/list?type=4',
|
||||
count: 3
|
||||
},
|
||||
{
|
||||
name: '退换/售后',
|
||||
image: '/static/images/my/after-sale.png',
|
||||
path: '/pages/order/list?type=5',
|
||||
count: 0
|
||||
}
|
||||
],
|
||||
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: 'headphones', path: '/pages/service/index', class: 'bg-orange', desc: '在线客服' }
|
||||
]
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.userInfo=uni.getStorageSync('userData')
|
||||
|
||||
},
|
||||
methods: {
|
||||
navigateTo(path) {
|
||||
uni.navigateTo({ url: path })
|
||||
},
|
||||
showQRCode() {
|
||||
// 显示二维码
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.mine-page {
|
||||
min-height: 100vh;
|
||||
background: #f5f6fa;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.user-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
margin-right: 30rpx;
|
||||
}
|
||||
|
||||
.user-info {
|
||||
flex: 1;
|
||||
|
||||
.nickname {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 12rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.vip-tag {
|
||||
background: linear-gradient(90deg, #FFD700 0%, #FFA500 100%);
|
||||
color: #fff;
|
||||
font-size: 24rpx;
|
||||
padding: 4rpx 16rpx;
|
||||
border-radius: 20rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
width: 72rpx;
|
||||
height: 72rpx;
|
||||
border-radius: 36rpx;
|
||||
background: #f5f6fa;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.stat-row {
|
||||
display: flex;
|
||||
padding-top: 30rpx;
|
||||
border-top: 2rpx solid #f5f6fa;
|
||||
|
||||
.stat-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
.value {
|
||||
font-size: 40rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-card {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 40rpx;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
.title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.more {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
text {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 8rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.order-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
|
||||
.icon-wrapper {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
margin: 0 auto 0;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.count-badge {
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
right: -10rpx;
|
||||
background: #ff4d4f;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
min-width: 32rpx;
|
||||
height: 32rpx;
|
||||
line-height: 32rpx;
|
||||
text-align: center;
|
||||
border-radius: 16rpx;
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
|
||||
.order-icon {
|
||||
width: 56rpx;
|
||||
height: 56rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.order-name {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.quick-actions {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.action-item {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 30rpx 20rpx;
|
||||
text-align: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.action-icon {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 40rpx;
|
||||
margin: 0 auto 16rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.action-name {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.service-list {
|
||||
background: #fff;
|
||||
border-radius: 24rpx;
|
||||
padding: 10rpx 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.04);
|
||||
|
||||
.service-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 2rpx solid #f5f6fa;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.service-icon {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 32rpx;
|
||||
margin-right: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.service-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 背景色
|
||||
.bg-red { background: #ff4d4f; }
|
||||
.bg-blue { background: #1890ff; }
|
||||
.bg-green { background: #52c41a; }
|
||||
.bg-purple { background: #722ed1; }
|
||||
.bg-orange { background: #fa8c16; }
|
||||
.bg-cyan { background: #13c2c2; }
|
||||
.bg-pink { background: #eb2f96; }
|
||||
.bg-gray { background: #666666; }
|
||||
</style>
|
||||
@@ -0,0 +1,490 @@
|
||||
<template>
|
||||
<view class="userinfo-container">
|
||||
<!-- 顶部标题栏 -->
|
||||
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<view v-if="loading" class="loading-state">
|
||||
<text>加载中...</text>
|
||||
</view>
|
||||
|
||||
<!-- 编辑表单 -->
|
||||
<view v-else class="form-wrapper">
|
||||
<!-- 头像 -->
|
||||
<view class="form-section">
|
||||
<view class="form-group">
|
||||
<text class="form-label">头像</text>
|
||||
<view class="avatar-container">
|
||||
<image
|
||||
:src="formData.avatar"
|
||||
class="avatar-image"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="avatar-upload" @click="uploadAvatar">
|
||||
|
||||
<uni-icons type="upload-filled" size="14" color="#999" class="upload-icon"></uni-icons>
|
||||
<text class="upload-text">更换头像</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<view class="form-section">
|
||||
<text class="section-title">基本信息</text>
|
||||
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">昵称</text>
|
||||
<input
|
||||
v-model="formData.nickname"
|
||||
class="form-input"
|
||||
placeholder="请输入昵称"
|
||||
maxlength="50"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">性别</text>
|
||||
<view class="sex-group">
|
||||
<view
|
||||
class="sex-btn"
|
||||
:class="{ active: formData.sex === 1}"
|
||||
@click="formData.sex = 1"
|
||||
>
|
||||
男
|
||||
</view>
|
||||
<view
|
||||
class="sex-btn"
|
||||
:class="{ active: formData.sex === 2}"
|
||||
@click="formData.sex = 2"
|
||||
>
|
||||
女
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-group">
|
||||
<text class="form-label">年龄</text>
|
||||
<input
|
||||
v-model.number="formData.age"
|
||||
class="form-input"
|
||||
type="number"
|
||||
placeholder="请输入年龄"
|
||||
min="0"
|
||||
max="150"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="button-group">
|
||||
|
||||
<button class="btn btn-submit" @click="submitForm" :disabled="submitting">
|
||||
{{ submitting ? '保存中...' : '保存修改' }}
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, getCurrentInstance } from 'vue'
|
||||
|
||||
const { proxy } = getCurrentInstance()
|
||||
const instance = getCurrentInstance();
|
||||
// 2. 从实例中获取全局 $url
|
||||
const $url = instance.appContext.config.globalProperties.$url;
|
||||
|
||||
// 数据
|
||||
const loading = ref(false)
|
||||
const submitting = ref(false)
|
||||
|
||||
// 表单数据
|
||||
const formData = ref({
|
||||
avatar: '',
|
||||
patient_name: '',
|
||||
phone: '',
|
||||
nickname: '',
|
||||
sex: 1,
|
||||
age: ''
|
||||
})
|
||||
|
||||
// 页面加载
|
||||
onMounted(() => {
|
||||
|
||||
loadUserInfo()
|
||||
})
|
||||
|
||||
// 加载用户信息
|
||||
const loadUserInfo = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/user/info',
|
||||
method: 'GET',
|
||||
data: {}
|
||||
})
|
||||
|
||||
if (res.code === 1) {
|
||||
const userInfo = res.data
|
||||
formData.value = {
|
||||
avatar: userInfo.avatar || '',
|
||||
patient_name: userInfo.patient_name || userInfo.nickname || '',
|
||||
phone: userInfo.phone || '',
|
||||
nickname: userInfo.nickname || '',
|
||||
sex: userInfo.sex =='男'?1:2,
|
||||
age: userInfo.age || ''
|
||||
}
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '加载失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载用户信息失败:', err)
|
||||
uni.showToast({ title: '加载失败', icon: 'none' })
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 上传头像
|
||||
const uploadAvatar = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera'],
|
||||
success: async (res) => {
|
||||
const tempFilePath = res.tempFilePaths[0]
|
||||
|
||||
try {
|
||||
uni.showLoading({ title: '上传中...' })
|
||||
|
||||
// 获取token
|
||||
const token = uni.getStorageSync('token')
|
||||
|
||||
// 调用后端上传接口
|
||||
const uploadRes = await new Promise((resolve, reject) => {
|
||||
uni.uploadFile({
|
||||
url: $url+'/api/upload/image',
|
||||
filePath: tempFilePath,
|
||||
name: 'file',
|
||||
header: {
|
||||
token: token,
|
||||
'content-type': 'multipart/form-data'
|
||||
},
|
||||
success: (res) => {
|
||||
const data = JSON.parse(res.data)
|
||||
resolve(data)
|
||||
},
|
||||
fail: (err) => {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
uni.hideLoading()
|
||||
|
||||
if (uploadRes.code === 1) {
|
||||
// 上传成功,更新头像
|
||||
formData.value.avatar = uploadRes.data.uri || uploadRes.data
|
||||
uni.showToast({ title: '头像上传成功', icon: 'success' })
|
||||
} else {
|
||||
uni.showToast({ title: uploadRes.msg || '上传失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
uni.hideLoading()
|
||||
console.error('上传头像失败:', err)
|
||||
uni.showToast({ title: '上传失败', icon: 'none' })
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('选择图片失败:', err)
|
||||
uni.showToast({ title: '选择图片失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 验证手机号
|
||||
const validatePhone = (phone) => {
|
||||
if (!phone) return true // 可选字段
|
||||
return /^1[3-9]\d{9}$/.test(phone)
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const submitForm = async () => {
|
||||
// 验证必填字段
|
||||
if (!formData.value.patient_name) {
|
||||
uni.showToast({ title: '姓名不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
// 验证手机号格式
|
||||
if (formData.value.phone && !validatePhone(formData.value.phone)) {
|
||||
uni.showToast({ title: '手机号格式不正确', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
submitting.value = true
|
||||
try {
|
||||
// 调用后端API更新用户信息
|
||||
const res = await proxy.apiUrl({
|
||||
url: '/api/user/setInfo',
|
||||
method: 'POST',
|
||||
data: {
|
||||
avatar: formData.value.avatar,
|
||||
phone: formData.value.phone,
|
||||
nickname: formData.value.nickname,
|
||||
sex: formData.value.sex,
|
||||
age: formData.value.age,
|
||||
patient_name: formData.value.patient_name
|
||||
}
|
||||
})
|
||||
|
||||
if (res.code === 1) {
|
||||
// 更新本地存储
|
||||
const userData = uni.getStorageSync('userData')
|
||||
const updatedData = {
|
||||
...userData,
|
||||
avatar: formData.value.avatar,
|
||||
phone: formData.value.phone,
|
||||
nickname: formData.value.nickname,
|
||||
sex: formData.value.sex,
|
||||
age: formData.value.age,
|
||||
patient_name: formData.value.patient_name,
|
||||
diagnosis: {
|
||||
...userData.diagnosis,
|
||||
patient_name: formData.value.patient_name
|
||||
}
|
||||
}
|
||||
|
||||
uni.setStorageSync('userData', updatedData)
|
||||
|
||||
uni.showToast({ title: '保存成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1500)
|
||||
} else {
|
||||
uni.showToast({ title: res.msg || '保存失败', icon: 'none' })
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('保存失败:', err)
|
||||
uni.showToast({ title: '保存失败', icon: 'none' })
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.userinfo-container {
|
||||
min-height: 100vh;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #ffffff;
|
||||
padding: 20rpx 30rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.header-back {
|
||||
font-size: 40rpx;
|
||||
color: #FFA500;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.header-placeholder {
|
||||
width: 60rpx;
|
||||
}
|
||||
|
||||
.loading-state {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
.form-wrapper {
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.form-section {
|
||||
background: #ffffff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
color: #FFA500;
|
||||
margin-bottom: 24rpx;
|
||||
display: block;
|
||||
padding-bottom: 16rpx;
|
||||
border-bottom: 2rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.form-group:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16rpx;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.form-input {
|
||||
width: 100%;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e8e8e8;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.5;
|
||||
color: #333333;
|
||||
background: #ffffff;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
height: auto;
|
||||
min-height: 60rpx;
|
||||
}
|
||||
|
||||
.form-input::placeholder {
|
||||
color: #cccccc;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.avatar-upload {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border: 2rpx dashed #FFA500;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.upload-icon {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.upload-text {
|
||||
font-size: 24rpx;
|
||||
color: #FFA500;
|
||||
}
|
||||
|
||||
.sex-group {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.sex-btn {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border: 2rpx solid #e8e8e8;
|
||||
border-radius: 12rpx;
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.5;
|
||||
color: #666666;
|
||||
background: #ffffff;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 60rpx;
|
||||
}
|
||||
|
||||
.sex-btn.active {
|
||||
border-color: #FFA500;
|
||||
background: #e6f7ff;
|
||||
color: #FFA500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.button-group {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
margin-top: 40rpx;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 1;
|
||||
padding: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.btn:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
background: #f0f0f0;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.btn-submit {
|
||||
background: #FFA500;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-submit:active:not(:disabled) {
|
||||
background: #0050b3;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user