Compare commits
4 Commits
66aa21085e
...
1dde942ff1
| Author | SHA1 | Date |
|---|---|---|
|
|
1dde942ff1 | |
|
|
6678bce527 | |
|
|
befb1dd8f9 | |
|
|
7bc3d491b8 |
|
|
@ -1,249 +0,0 @@
|
|||
// HTTP API使用示例
|
||||
// 注意:鉴权配置已简化,只需要在 http/config/config.js 中配置不需要鉴权的接口即可
|
||||
|
||||
// 导入API模块
|
||||
import { petsApi, assistantApi, adoptionApi, profileApi, commonApi, addNoAuthApis, setEnvironment } from '@/http/index.js'
|
||||
|
||||
// 或者导入所有API
|
||||
// import api from '@/http/index.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
petsList: [],
|
||||
userInfo: {},
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 示例1:获取宠物列表(自动鉴权)
|
||||
async loadPets() {
|
||||
try {
|
||||
// 使用默认配置,自动根据接口判断是否需要鉴权
|
||||
const pets = await petsApi.getPetsList()
|
||||
this.petsList = pets
|
||||
} catch (error) {
|
||||
console.error('获取宠物列表失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例2:添加不需要鉴权的接口
|
||||
addCustomNoAuthApis() {
|
||||
// 如果有自定义的接口不需要鉴权,可以这样添加
|
||||
addNoAuthApis([
|
||||
'/custom/public-api',
|
||||
'/special/no-auth-endpoint'
|
||||
])
|
||||
},
|
||||
|
||||
// 示例3:切换环境
|
||||
switchEnvironment() {
|
||||
// 根据需要切换环境
|
||||
// #ifdef H5
|
||||
setEnvironment('development') // H5开发环境
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
setEnvironment('production') // 小程序生产环境
|
||||
// #endif
|
||||
|
||||
// 或者根据条件动态切换
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
setEnvironment(isDev ? 'development' : 'production')
|
||||
},
|
||||
|
||||
// 示例2:添加宠物
|
||||
async addNewPet() {
|
||||
try {
|
||||
const petData = {
|
||||
name: '小白',
|
||||
breed: '金毛',
|
||||
age: 2,
|
||||
gender: '公'
|
||||
}
|
||||
|
||||
const result = await petsApi.addPet(petData, {
|
||||
custom: {
|
||||
auth: true,
|
||||
loading: true,
|
||||
toast: true // 显示成功/失败提示
|
||||
}
|
||||
})
|
||||
|
||||
uni.showToast({
|
||||
title: '添加成功',
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// 重新加载列表
|
||||
this.loadPets()
|
||||
} catch (error) {
|
||||
// 错误已在拦截器中处理,这里可以做额外处理
|
||||
console.error('添加宠物失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例3:AI助手对话
|
||||
async sendMessageToAI() {
|
||||
try {
|
||||
const messageData = {
|
||||
message: '我的猫咪最近不爱吃饭,怎么办?',
|
||||
petId: 123
|
||||
}
|
||||
|
||||
const response = await assistantApi.sendMessage(messageData, {
|
||||
custom: {
|
||||
auth: true,
|
||||
loading: true,
|
||||
loadingText: 'AI正在思考中...'
|
||||
}
|
||||
})
|
||||
|
||||
console.log('AI回复:', response.reply)
|
||||
} catch (error) {
|
||||
console.error('AI对话失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例4:用户登录
|
||||
async userLogin() {
|
||||
try {
|
||||
const loginData = {
|
||||
username: 'user@example.com',
|
||||
password: '123456'
|
||||
}
|
||||
|
||||
const result = await profileApi.userLogin(loginData, {
|
||||
custom: {
|
||||
auth: false, // 登录接口不需要token
|
||||
loading: true,
|
||||
loadingText: '正在登录...'
|
||||
}
|
||||
})
|
||||
|
||||
// 保存token和用户信息
|
||||
uni.setStorageSync('token', result.token)
|
||||
uni.setStorageSync('userInfo', result.userInfo)
|
||||
|
||||
uni.showToast({
|
||||
title: '登录成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('登录失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例5:上传图片
|
||||
async uploadPetImage() {
|
||||
try {
|
||||
// 选择图片
|
||||
const chooseResult = await uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album', 'camera']
|
||||
})
|
||||
|
||||
const imageData = {
|
||||
filePath: chooseResult.tempFilePaths[0],
|
||||
name: 'petImage',
|
||||
formData: {
|
||||
type: 'pet',
|
||||
petId: 123
|
||||
}
|
||||
}
|
||||
|
||||
const uploadResult = await commonApi.uploadImage(imageData, {
|
||||
custom: {
|
||||
auth: true,
|
||||
loading: true,
|
||||
loadingText: '正在上传图片...'
|
||||
}
|
||||
})
|
||||
|
||||
console.log('上传成功:', uploadResult.url)
|
||||
|
||||
uni.showToast({
|
||||
title: '上传成功',
|
||||
icon: 'success'
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('上传失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例6:搜索领养宠物
|
||||
async searchAdoptionPets() {
|
||||
try {
|
||||
const searchParams = {
|
||||
keyword: '金毛',
|
||||
type: 'dog',
|
||||
age: '1-3',
|
||||
location: '北京'
|
||||
}
|
||||
|
||||
const pets = await adoptionApi.searchPets(searchParams, {
|
||||
custom: {
|
||||
auth: false, // 搜索不需要登录
|
||||
loading: true
|
||||
}
|
||||
})
|
||||
|
||||
console.log('搜索结果:', pets)
|
||||
} catch (error) {
|
||||
console.error('搜索失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例7:批量操作
|
||||
async batchOperations() {
|
||||
try {
|
||||
// 并发执行多个请求
|
||||
const [pets, userInfo, adoptionPets] = await Promise.all([
|
||||
petsApi.getPetsList(),
|
||||
profileApi.getUserInfo(),
|
||||
adoptionApi.getAdoptionPets()
|
||||
])
|
||||
|
||||
console.log('批量获取数据成功:', { pets, userInfo, adoptionPets })
|
||||
} catch (error) {
|
||||
console.error('批量操作失败:', error)
|
||||
}
|
||||
},
|
||||
|
||||
// 示例8:自定义错误处理
|
||||
async customErrorHandling() {
|
||||
try {
|
||||
const result = await petsApi.getPetsList({}, {
|
||||
custom: {
|
||||
auth: true,
|
||||
loading: true,
|
||||
toast: false, // 不显示默认错误提示
|
||||
catch: true // 允许catch捕获错误
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
// 自定义错误处理
|
||||
if (error.code === 401) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '登录已过期,请重新登录',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/login'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: error.message || '操作失败',
|
||||
icon: 'none'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<view class="adoption-container page-container-with-bg">
|
||||
<view class="adoption-container page-container-unified">
|
||||
<!-- 头部搜索栏 -->
|
||||
<view class="header-section">
|
||||
<view class="search-wrapper">
|
||||
|
|
@ -1192,7 +1192,7 @@ export default {
|
|||
/* 头部搜索栏 */
|
||||
.header-section {
|
||||
background: transparent;
|
||||
padding: 24rpx 20rpx;
|
||||
padding: 0 0 24rpx 0;
|
||||
|
||||
.search-wrapper {
|
||||
display: flex;
|
||||
|
|
@ -1287,7 +1287,7 @@ export default {
|
|||
.filter-panel {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
padding: 24rpx 20rpx;
|
||||
padding: 24rpx 0;
|
||||
border-bottom: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
|
|
@ -1514,7 +1514,7 @@ export default {
|
|||
/* 宠物列表区域 */
|
||||
.pets-scroll {
|
||||
height: calc(100vh - 100rpx);
|
||||
padding: 0 20rpx;
|
||||
padding: 0;
|
||||
overflow-x: hidden;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<view class="assistant-container page-container-with-bg">
|
||||
<view class="assistant-container page-container-unified">
|
||||
<!-- 宠物助手信息卡片 -->
|
||||
<view class="assistant-info-card">
|
||||
<view class="assistant-avatar-wrapper">
|
||||
|
|
@ -191,31 +191,54 @@ export default {
|
|||
sendMessage() {
|
||||
if (!this.inputMessage.trim() || this.isThinking) return
|
||||
|
||||
// 保存用户输入内容
|
||||
const userInput = this.inputMessage
|
||||
|
||||
// 添加用户消息
|
||||
const userMessage = {
|
||||
type: 'user',
|
||||
content: this.inputMessage,
|
||||
content: userInput,
|
||||
time: this.getCurrentTime()
|
||||
}
|
||||
this.messageList.push(userMessage)
|
||||
|
||||
// 清空输入框
|
||||
this.inputMessage = ''
|
||||
|
||||
// 开始AI思考
|
||||
this.isThinking = true
|
||||
this.scrollToBottom()
|
||||
|
||||
// 确保DOM更新后再滚动到思考状态
|
||||
this.$nextTick(() => {
|
||||
this.forceScrollToBottom()
|
||||
// 在思考过程中持续滚动,确保思考动画可见
|
||||
setTimeout(() => {
|
||||
this.forceScrollToBottom()
|
||||
}, 200)
|
||||
setTimeout(() => {
|
||||
this.forceScrollToBottom()
|
||||
}, 500)
|
||||
})
|
||||
|
||||
// 模拟AI回复
|
||||
setTimeout(() => {
|
||||
const aiMessage = {
|
||||
type: 'ai',
|
||||
content: this.getAIResponse(this.inputMessage),
|
||||
content: this.getAIResponse(userInput),
|
||||
time: this.getCurrentTime()
|
||||
}
|
||||
this.messageList.push(aiMessage)
|
||||
this.isThinking = false
|
||||
this.scrollToBottom()
|
||||
}, 1500 + Math.random() * 1000) // 1.5-2.5秒随机延迟
|
||||
|
||||
this.inputMessage = ''
|
||||
// AI回复完成后强制滚动到底部
|
||||
this.$nextTick(() => {
|
||||
this.forceScrollToBottom()
|
||||
// 延迟再次滚动,确保消息完全显示
|
||||
setTimeout(() => {
|
||||
this.forceScrollToBottom()
|
||||
}, 100)
|
||||
})
|
||||
}, 1500 + Math.random() * 1000) // 1.5-2.5秒随机延迟
|
||||
},
|
||||
|
||||
getAIResponse(question) {
|
||||
|
|
@ -245,6 +268,17 @@ export default {
|
|||
})
|
||||
},
|
||||
|
||||
// 强制滚动到底部,用于确保消息可见
|
||||
forceScrollToBottom() {
|
||||
this.$nextTick(() => {
|
||||
// 使用时间戳确保每次滚动都能触发
|
||||
this.scrollTop = Date.now()
|
||||
setTimeout(() => {
|
||||
this.scrollTop = 999999
|
||||
}, 50)
|
||||
})
|
||||
},
|
||||
|
||||
startVoiceInput() {
|
||||
uni.showToast({
|
||||
title: '语音功能开发中',
|
||||
|
|
@ -273,7 +307,7 @@ export default {
|
|||
.assistant-info-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 20rpx 30rpx 0 30rpx;
|
||||
margin: 0 0 0 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
|
|
@ -359,7 +393,7 @@ export default {
|
|||
.quick-questions {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 20rpx 30rpx;
|
||||
margin: 20rpx 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
|
|
@ -400,7 +434,7 @@ export default {
|
|||
}
|
||||
|
||||
.chat-messages {
|
||||
margin-top: 20rpx;
|
||||
margin-top: 24rpx;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
@ -425,21 +459,31 @@ export default {
|
|||
|
||||
.message-item.user {
|
||||
justify-content: flex-end;
|
||||
padding: 0 10rpx 0 80rpx;
|
||||
padding: 0 0 0 60rpx;
|
||||
}
|
||||
|
||||
.message-item.ai {
|
||||
justify-content: flex-start;
|
||||
padding: 0 80rpx 0 10rpx;
|
||||
padding: 0 60rpx 0 0;
|
||||
}
|
||||
|
||||
.message-avatar {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
margin: 0 16rpx;
|
||||
margin: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* AI消息头像 - 右边距 */
|
||||
.message-item.ai .message-avatar {
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
/* 用户消息头像 - 左边距 */
|
||||
.message-item.user .message-avatar {
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
|
||||
.assistant-avatar, .user-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
|
@ -555,10 +599,8 @@ export default {
|
|||
}
|
||||
|
||||
.chat-input-area {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
padding: 16rpx 20rpx;
|
||||
//padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
||||
padding: 16rpx 0;
|
||||
border-top: 1rpx solid rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
|
|
@ -566,48 +608,131 @@ export default {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16rpx;
|
||||
margin-bottom: 0 !important;
|
||||
|
||||
.input-wrapper {
|
||||
flex: 1;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 28rpx;
|
||||
padding: 0 20rpx;
|
||||
backdrop-filter: blur(10rpx);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
backdrop-filter: blur(15rpx);
|
||||
border: 3rpx solid rgba(255, 255, 255, 0.98);
|
||||
height: 56rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow:
|
||||
0 0 0 1rpx rgba(255, 255, 255, 0.4),
|
||||
0 2rpx 8rpx rgba(255, 255, 255, 0.15),
|
||||
0 4rpx 16rpx rgba(255, 255, 255, 0.1),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.2);
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 25rpx;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.05) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:focus-within {
|
||||
border-color: rgba(255, 255, 255, 1);
|
||||
box-shadow:
|
||||
0 0 0 2rpx rgba(255, 255, 255, 0.6),
|
||||
0 0 20rpx rgba(255, 255, 255, 0.3),
|
||||
0 4rpx 12rpx rgba(255, 255, 255, 0.2),
|
||||
0 8rpx 24rpx rgba(255, 255, 255, 0.15),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.3);
|
||||
transform: translateY(-2rpx);
|
||||
}
|
||||
|
||||
.message-input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
color: #ffffff;
|
||||
border: none;
|
||||
outline: none;
|
||||
background: transparent;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
||||
&::placeholder {
|
||||
color: rgba(255, 255, 255, 0.95);
|
||||
font-weight: 400;
|
||||
text-shadow: 0 1rpx 2rpx rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.send-button {
|
||||
padding: 12rpx 20rpx;
|
||||
height: 56rpx;
|
||||
padding: 0 20rpx;
|
||||
border-radius: 24rpx;
|
||||
background: rgba(200, 200, 200, 0.5);
|
||||
transition: all 0.3s ease;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%);
|
||||
border: 3rpx solid rgba(255, 255, 255, 0.85);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
backdrop-filter: blur(10rpx);
|
||||
box-shadow:
|
||||
0 0 0 1rpx rgba(255, 255, 255, 0.3),
|
||||
0 2rpx 6rpx rgba(255, 255, 255, 0.12),
|
||||
0 4rpx 12rpx rgba(255, 255, 255, 0.08),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.15);
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 21rpx;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, transparent 50%, rgba(255, 255, 255, 0.03) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.96) translateY(1rpx);
|
||||
}
|
||||
|
||||
.send-text {
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
text-shadow: 0 1rpx 2rpx rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
.send-button.active {
|
||||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 100%);
|
||||
box-shadow: 0 4rpx 16rpx rgba(255, 138, 128, 0.4);
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%);
|
||||
border: 3rpx solid rgba(255, 255, 255, 0.98);
|
||||
box-shadow:
|
||||
0 0 0 2rpx rgba(255, 255, 255, 0.5),
|
||||
0 0 16rpx rgba(255, 255, 255, 0.25),
|
||||
0 4rpx 10rpx rgba(255, 255, 255, 0.18),
|
||||
0 6rpx 20rpx rgba(255, 255, 255, 0.12),
|
||||
inset 0 1rpx 0 rgba(255, 255, 255, 0.25);
|
||||
transform: translateY(-2rpx);
|
||||
|
||||
&::before {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, transparent 50%, rgba(255, 255, 255, 0.06) 100%);
|
||||
}
|
||||
|
||||
.send-text {
|
||||
color: #ffffff;
|
||||
color: rgba(255, 255, 255, 0.98);
|
||||
font-weight: 600;
|
||||
text-shadow: 0 1rpx 3rpx rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,21 +7,25 @@
|
|||
<view class="category-tabs">
|
||||
<u-tabs :list="categories" @click="switchCategory" :current="currentCategory"></u-tabs>
|
||||
</view>
|
||||
|
||||
<scroll-view class="knowledge-list" scroll-y="true">
|
||||
<view v-for="item in filteredKnowledge" :key="item.id" class="knowledge-card" @click="viewDetail(item)">
|
||||
<view class="knowledge-item">
|
||||
<text class="knowledge-title">{{ item.title }}</text>
|
||||
<text class="knowledge-summary">{{ item.summary }}</text>
|
||||
<view class="knowledge-meta">
|
||||
<view class="category-tag">
|
||||
<text class="tag-text">{{ item.category }}</text>
|
||||
|
||||
<view class="knowledge-list">
|
||||
<scroll-view class="knowledge-scroll" scroll-y="true">
|
||||
<view class="knowledge-content">
|
||||
<view v-for="item in filteredKnowledge" :key="item.id" class="knowledge-card" @click="viewDetail(item)">
|
||||
<view class="knowledge-item">
|
||||
<text class="knowledge-title">{{ item.title }}</text>
|
||||
<text class="knowledge-summary">{{ item.summary }}</text>
|
||||
<view class="knowledge-meta">
|
||||
<view class="category-tag">
|
||||
<text class="tag-text">{{ item.category }}</text>
|
||||
</view>
|
||||
<text class="read-count">{{ item.readCount }}次阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="read-count">{{ item.readCount }}次阅读</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
|
|
@ -107,39 +111,57 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.knowledge-container {
|
||||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||||
min-height: 100vh;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.search-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 20rpx 30rpx;
|
||||
margin: 20rpx 30rpx 0 30rpx;
|
||||
border-radius: 24rpx;
|
||||
padding: 20rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.category-tabs {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 20rpx 30rpx;
|
||||
margin: 20rpx 30rpx 0 30rpx;
|
||||
border-radius: 24rpx;
|
||||
padding: 20rpx 0;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.knowledge-list {
|
||||
height: calc(100vh - 300rpx);
|
||||
padding: 0 30rpx;
|
||||
margin-top: 20rpx;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.knowledge-scroll {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.knowledge-content {
|
||||
padding: 20rpx 30rpx;
|
||||
padding-bottom: 80rpx;
|
||||
min-height: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.knowledge-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 20rpx 0;
|
||||
margin-bottom: 24rpx;
|
||||
border-radius: 24rpx;
|
||||
padding: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<view class="pets-container gradient-bg page-container">
|
||||
<view class="pets-container page-container-unified">
|
||||
<!-- 标签切换容器 -->
|
||||
<view class="tabs-container" v-if="petsList.length > 0">
|
||||
<view class="tabs-header">
|
||||
|
|
@ -653,12 +653,12 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.pets-container {
|
||||
padding-bottom: 120rpx;
|
||||
/* 边距由外层page-container-unified统一管理 */
|
||||
}
|
||||
|
||||
.tabs-container {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
margin: 20rpx 20rpx 30rpx;
|
||||
margin: 0 0 30rpx 0;
|
||||
border-radius: 40rpx;
|
||||
backdrop-filter: blur(20rpx);
|
||||
overflow: visible;
|
||||
|
|
@ -758,7 +758,7 @@ export default {
|
|||
}
|
||||
|
||||
.tab-content {
|
||||
padding: 30rpx;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tab-panel {
|
||||
|
|
@ -941,7 +941,7 @@ export default {
|
|||
}
|
||||
|
||||
.functions-section {
|
||||
margin: 16rpx 30rpx 20rpx;
|
||||
margin: 16rpx 0 20rpx 0;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 0;
|
||||
|
|
@ -1037,7 +1037,7 @@ export default {
|
|||
}
|
||||
|
||||
.cards-section {
|
||||
padding: 0 30rpx;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<view class="profile-container page-container-with-bg">
|
||||
<view class="profile-container page-container-unified">
|
||||
<!-- 用户信息卡片 -->
|
||||
<view class="user-info-card">
|
||||
<view class="user-avatar-section" :class="{ 'logged-in': userInfo.nickName }" @click="handleUserAction">
|
||||
|
|
@ -690,14 +690,14 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.profile-container {
|
||||
padding-bottom: 40rpx;
|
||||
/* 边距由外层page-container-unified统一管理 */
|
||||
}
|
||||
|
||||
/* 用户信息卡片 */
|
||||
.user-info-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 0 30rpx 24rpx 30rpx;
|
||||
margin: 0 0 24rpx 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
display: flex;
|
||||
|
|
@ -837,7 +837,7 @@ export default {
|
|||
.stats-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 0 30rpx 24rpx 30rpx;
|
||||
margin: 0 0 24rpx 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
|
|
@ -907,7 +907,7 @@ export default {
|
|||
.family-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 0 30rpx 24rpx 30rpx;
|
||||
margin: 0 0 24rpx 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
|
|
@ -1025,7 +1025,7 @@ export default {
|
|||
.adoption-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 0 30rpx 24rpx 30rpx;
|
||||
margin: 0 0 24rpx 0;
|
||||
border-radius: 24rpx;
|
||||
padding: 32rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
|
|
@ -1122,7 +1122,7 @@ export default {
|
|||
@media (max-width: 375px) {
|
||||
.profile-container {
|
||||
.user-info-card {
|
||||
margin: 0 20rpx 20rpx 20rpx;
|
||||
margin: 0 0 20rpx 0;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
|
|
@ -1130,7 +1130,7 @@ export default {
|
|||
.family-card,
|
||||
.adoption-card,
|
||||
.settings-card {
|
||||
margin: 0 20rpx 20rpx 20rpx;
|
||||
margin: 0 0 20rpx 0;
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
|
|
@ -1245,7 +1245,7 @@ export default {
|
|||
.settings-card {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
margin: 0 30rpx 24rpx 30rpx;
|
||||
margin: 0 0 24rpx 0;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 8rpx 32rpx rgba(255, 138, 128, 0.2);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.3);
|
||||
|
|
|
|||
|
|
@ -135,6 +135,17 @@
|
|||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||||
}
|
||||
|
||||
/* 统一布局架构 - 页面容器 */
|
||||
.page-container-unified {
|
||||
@extend .page-container-with-bg;
|
||||
padding: 20rpx 30rpx 0 30rpx; /* 上边距20rpx,左右边距30rpx,下边距0 */
|
||||
|
||||
/* 响应式设计 - 小屏幕使用较小边距 */
|
||||
@media (max-width: 375px) {
|
||||
padding: 20rpx 20rpx 0 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 通用背景渐变 */
|
||||
.gradient-bg {
|
||||
background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 25%, #FECFEF 50%, #F8BBD9 100%);
|
||||
|
|
@ -175,6 +186,18 @@
|
|||
border-radius: 28rpx;
|
||||
}
|
||||
|
||||
/* 统一布局架构 - 卡片样式 */
|
||||
.card-unified {
|
||||
@extend .card;
|
||||
margin: 0 0 24rpx 0; /* 仅保留下边距用于卡片间隔 */
|
||||
|
||||
/* 响应式设计 - 小屏幕调整间距 */
|
||||
@media (max-width: 375px) {
|
||||
margin: 0 0 20rpx 0;
|
||||
padding: 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 通用按钮样式 */
|
||||
.btn {
|
||||
padding: 16rpx 32rpx;
|
||||
|
|
|
|||
Loading…
Reference in New Issue