进一步优化朋友圈、添加个人主页、优化菜单栏、初步实现知识库
This commit is contained in:
parent
952d30af78
commit
ce98f9c5d9
@ -88,6 +88,11 @@ const routes = [
|
|||||||
path: '/customer/questionnaire',
|
path: '/customer/questionnaire',
|
||||||
name: 'Questionnaire',
|
name: 'Questionnaire',
|
||||||
component: () => import('@/views/customer/Questionnaire.vue')
|
component: () => import('@/views/customer/Questionnaire.vue')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/customer/knowledge-base',
|
||||||
|
name: 'knowledgeBase',
|
||||||
|
component: () => import('@/views/customer/knowledgeBase.vue')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -420,12 +420,18 @@ export default {
|
|||||||
this.refreshState = 'ready'
|
this.refreshState = 'ready'
|
||||||
this.refreshHeight = threshold
|
this.refreshHeight = threshold
|
||||||
|
|
||||||
// 更新内容区域位置
|
// 更新内容区域和用户资料区域位置
|
||||||
const content = document.querySelector('.moments-content')
|
const content = document.querySelector('.moments-content')
|
||||||
|
const userProfile = document.querySelector('.user-profile')
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
content.style.transform = `translateY(${this.refreshHeight}px)`
|
content.style.transform = `translateY(${this.refreshHeight}px)`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (userProfile) {
|
||||||
|
userProfile.style.transform = `translateY(${this.refreshHeight}px)`
|
||||||
|
}
|
||||||
|
|
||||||
// 标记当前已触发刷新,防止重复触发
|
// 标记当前已触发刷新,防止重复触发
|
||||||
this.isRefreshing = true
|
this.isRefreshing = true
|
||||||
|
|
||||||
@ -494,10 +500,17 @@ export default {
|
|||||||
|
|
||||||
// 更新界面显示
|
// 更新界面显示
|
||||||
const content = document.querySelector('.moments-content')
|
const content = document.querySelector('.moments-content')
|
||||||
|
const userProfile = document.querySelector('.user-profile')
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
content.style.transform = `translateY(${this.refreshHeight}px)`
|
content.style.transform = `translateY(${this.refreshHeight}px)`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同时移动用户头像和用户名
|
||||||
|
if (userProfile) {
|
||||||
|
userProfile.style.transform = `translateY(${this.refreshHeight}px)`
|
||||||
|
}
|
||||||
|
|
||||||
// 根据拉动距离决定刷新状态
|
// 根据拉动距离决定刷新状态
|
||||||
if (this.refreshHeight >= threshold) {
|
if (this.refreshHeight >= threshold) {
|
||||||
this.refreshState = 'ready'
|
this.refreshState = 'ready'
|
||||||
@ -516,6 +529,8 @@ export default {
|
|||||||
|
|
||||||
// 强制刷新DOM
|
// 强制刷新DOM
|
||||||
const content = document.querySelector('.moments-content')
|
const content = document.querySelector('.moments-content')
|
||||||
|
const userProfile = document.querySelector('.user-profile')
|
||||||
|
|
||||||
if (content) {
|
if (content) {
|
||||||
// 确保内容区域回到原位
|
// 确保内容区域回到原位
|
||||||
content.style.transform = 'translateY(0)'
|
content.style.transform = 'translateY(0)'
|
||||||
@ -524,6 +539,11 @@ export default {
|
|||||||
content.offsetHeight
|
content.offsetHeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 同时重置用户头像和用户名位置
|
||||||
|
if (userProfile) {
|
||||||
|
userProfile.style.transform = 'translateY(0)'
|
||||||
|
}
|
||||||
|
|
||||||
// 确保指示器被完全移除
|
// 确保指示器被完全移除
|
||||||
// Vue的v-if会处理DOM的移除,所以这里不需要额外的DOM操作
|
// Vue的v-if会处理DOM的移除,所以这里不需要额外的DOM操作
|
||||||
},
|
},
|
||||||
@ -533,6 +553,12 @@ export default {
|
|||||||
this.refreshState = 'loading'
|
this.refreshState = 'loading'
|
||||||
this.isRefreshing = true // 确保刷新标记被设置
|
this.isRefreshing = true // 确保刷新标记被设置
|
||||||
|
|
||||||
|
// 确保在刷新状态下用户头像和用户名保持在正确位置
|
||||||
|
const userProfile = document.querySelector('.user-profile')
|
||||||
|
if (userProfile && this.refreshHeight > 0) {
|
||||||
|
userProfile.style.transform = `translateY(${this.refreshHeight}px)`
|
||||||
|
}
|
||||||
|
|
||||||
// 模拟数据库查询延迟
|
// 模拟数据库查询延迟
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
try {
|
try {
|
||||||
@ -675,12 +701,13 @@ export default {
|
|||||||
.user-profile {
|
.user-profile {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 5%;
|
right: 5%;
|
||||||
bottom: 200px;
|
bottom: 290px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
gap: 20px;
|
gap: 20px;
|
||||||
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-name {
|
.user-name {
|
||||||
@ -697,28 +724,47 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.moments-content {
|
.moments-content {
|
||||||
padding: 30px 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-top: -300px;
|
margin-top: -350px;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
background-color: transparent;
|
background-color: #fff;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
|
border-top-left-radius: 20px;
|
||||||
|
border-top-right-radius: 20px;
|
||||||
|
box-shadow: 0 -5px 20px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.moments-content::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 10%;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 15px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.moment-item:first-child {
|
||||||
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.moment-item {
|
.moment-item {
|
||||||
background-color: #fff;
|
background-color: transparent;
|
||||||
padding: 25px 15% 25px 15%;
|
padding: 25px 15% 25px 15%;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: none;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post-user-info {
|
.post-user-info {
|
||||||
@ -794,7 +840,7 @@ export default {
|
|||||||
color: #999;
|
color: #999;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
border-top: 1px solid #f0f0f0;
|
border-top: 1px solid rgba(240, 240, 240, 0.6);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -879,7 +925,7 @@ export default {
|
|||||||
|
|
||||||
.interaction-area {
|
.interaction-area {
|
||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
background-color: #f7f7f7;
|
background-color: rgba(247, 247, 247, 0.7);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@ -978,8 +1024,13 @@ export default {
|
|||||||
|
|
||||||
@media screen and (max-width: 768px) {
|
@media screen and (max-width: 768px) {
|
||||||
.moments-content {
|
.moments-content {
|
||||||
padding: 20px 0;
|
padding: 0;
|
||||||
margin-top: -150px;
|
margin-top: -260px;
|
||||||
|
border-top-left-radius: 15px;
|
||||||
|
border-top-right-radius: 15px;
|
||||||
|
}
|
||||||
|
.moment-item:first-child {
|
||||||
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
.moment-item {
|
.moment-item {
|
||||||
padding: 15px 5%;
|
padding: 15px 5%;
|
||||||
@ -989,7 +1040,7 @@ export default {
|
|||||||
}
|
}
|
||||||
.user-profile {
|
.user-profile {
|
||||||
right: 3%;
|
right: 3%;
|
||||||
bottom: 150px;
|
bottom: 220px;
|
||||||
}
|
}
|
||||||
.single-image {
|
.single-image {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -2,29 +2,33 @@
|
|||||||
<el-container class="customer-dashboard">
|
<el-container class="customer-dashboard">
|
||||||
<el-header>
|
<el-header>
|
||||||
<h1>中医药与心理健康</h1>
|
<h1>中医药与心理健康</h1>
|
||||||
<el-menu>
|
<div class="menu-wrapper">
|
||||||
<el-menu-item index="1" @click="$router.push('/customer/home')">首页</el-menu-item>
|
<el-menu :default-active="activeIndex" mode="horizontal" background-color="#4CAF50" text-color="#fff" active-text-color="#ffd04b">
|
||||||
<el-dropdown placement="bottom-start">
|
<el-menu-item index="/customer/home" @click="$router.push('/customer/home')">首页</el-menu-item>
|
||||||
<el-menu-item index="2"> 教育与预防 </el-menu-item>
|
<el-sub-menu index="/customer/education">
|
||||||
<template #dropdown>
|
<template #title>教育与预防</template>
|
||||||
<el-dropdown-menu>
|
<el-menu-item index="/customer/knowledge-base" @click="$router.push('/customer/knowledge-base')">知识库</el-menu-item>
|
||||||
<el-dropdown-item @click="$router.push('/customer/knowledge-base')">知识库</el-dropdown-item>
|
<el-menu-item index="/customer/wellness-guide" @click="$router.push('/customer/wellness-guide')">养生指南</el-menu-item>
|
||||||
<el-dropdown-item @click="$router.push('/customer/wellness-guide')">养生指南</el-dropdown-item>
|
</el-sub-menu>
|
||||||
</el-dropdown-menu>
|
<el-sub-menu index="/customer/assessment">
|
||||||
</template>
|
<template #title>心理健康评估</template>
|
||||||
</el-dropdown>
|
<el-menu-item index="/customer/psychological-test" @click="$router.push('/customer/psychological-test')">心理测试</el-menu-item>
|
||||||
<el-dropdown placement="bottom-start">
|
<el-menu-item index="/customer/questionnaire" @click="$router.push('/customer/questionnaire')">问卷调查</el-menu-item>
|
||||||
<el-menu-item index="3"> 心理健康评估 </el-menu-item>
|
</el-sub-menu>
|
||||||
<template #dropdown>
|
<el-menu-item index="/customer/social-circle" @click="$router.push('/customer/social-circle')">匿名分享圈</el-menu-item>
|
||||||
<el-dropdown-menu>
|
|
||||||
<el-dropdown-item @click="$router.push('/customer/psychological-test')">心理测试</el-dropdown-item>
|
|
||||||
<el-dropdown-item @click="$router.push('/customer/questionnaire')">问卷调查</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</template>
|
|
||||||
</el-dropdown>
|
|
||||||
<el-menu-item index="4" @click="$router.push('/customer/social-circle')">匿名分享圈</el-menu-item>
|
|
||||||
</el-menu>
|
</el-menu>
|
||||||
<el-button @click="logout" type="danger">退出登录</el-button>
|
</div>
|
||||||
|
<div class="user-avatar-container">
|
||||||
|
<el-dropdown>
|
||||||
|
<el-avatar :size="40" :src="userAvatar" class="user-avatar" @click="$router.push('/customer/profile')"></el-avatar>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item @click="$router.push('/customer/profile')">个人信息</el-dropdown-item>
|
||||||
|
<el-dropdown-item @click="logout" divided>退出登录</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
|
</div>
|
||||||
</el-header>
|
</el-header>
|
||||||
<el-main>
|
<el-main>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
@ -33,15 +37,27 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'CustomerDashboard',
|
name: 'CustomerDashboard',
|
||||||
methods: {
|
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
userAvatar: require('@/assets/user/1.jpg')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
activeIndex () {
|
||||||
|
const path = this.$route.path
|
||||||
|
// 设置主菜单路径映射
|
||||||
|
if (path.includes('/customer/knowledge-base') || path.includes('/customer/wellness-guide')) {
|
||||||
|
return '/customer/education'
|
||||||
|
} else if (path.includes('/customer/psychological-test') || path.includes('/customer/questionnaire')) {
|
||||||
|
return '/customer/assessment'
|
||||||
|
} else {
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
logout () {
|
logout () {
|
||||||
this.$router.push('/login')
|
this.$router.push('/login')
|
||||||
}
|
}
|
||||||
@ -65,19 +81,87 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 80%;
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.el-menu {
|
.el-menu {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 20px;
|
background-color: transparent !important;
|
||||||
background-color: transparent;
|
|
||||||
border: none;
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.el-menu-item {
|
.el-menu-item {
|
||||||
color: greet;
|
font-size: 15px;
|
||||||
}*/
|
height: 56px;
|
||||||
|
line-height: 56px;
|
||||||
|
margin: 0 15px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-sub-menu {
|
||||||
|
margin: 0 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu-item.is-active {
|
||||||
|
color: #ffd04b !important;
|
||||||
|
background-color: rgba(255, 255, 255, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.el-menu-item:hover {
|
.el-menu-item:hover {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
background: rgba(255, 255, 255, 0.2) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-avatar-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 2px solid white;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar:hover {
|
||||||
|
transform: scale(1.05);
|
||||||
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 992px) {
|
||||||
|
.el-header {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu-item, .el-sub-menu {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-avatar-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,19 +1,244 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="user-profile">
|
<div class="user-profile-container">
|
||||||
<h2>个人信息</h2>
|
<el-card class="profile-card">
|
||||||
<p>在这里您可以查看和编辑您的个人信息。</p>
|
<div class="profile-header">
|
||||||
<!-- 这里可以添加个人信息表单或功能 -->
|
<el-avatar :size="100" :src="userInfo.avatar" class="profile-avatar"></el-avatar>
|
||||||
|
<div class="upload-avatar">
|
||||||
|
<el-upload
|
||||||
|
class="avatar-uploader"
|
||||||
|
action="#"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-change="handleAvatarChange"
|
||||||
|
:auto-upload="false"
|
||||||
|
>
|
||||||
|
<el-button type="primary" size="small">更换头像</el-button>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-divider content-position="center">基本信息</el-divider>
|
||||||
|
|
||||||
|
<el-form :model="userInfo" label-width="100px" :rules="rules" ref="userForm">
|
||||||
|
<el-form-item label="用户名" prop="username">
|
||||||
|
<el-input v-model="userInfo.username" placeholder="请输入用户名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="真实姓名" prop="realName">
|
||||||
|
<el-input v-model="userInfo.realName" placeholder="请输入真实姓名"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="性别">
|
||||||
|
<el-radio-group v-model="userInfo.gender">
|
||||||
|
<el-radio label="male">男</el-radio>
|
||||||
|
<el-radio label="female">女</el-radio>
|
||||||
|
<el-radio label="other">其他</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="电子邮箱" prop="email">
|
||||||
|
<el-input v-model="userInfo.email" placeholder="请输入电子邮箱"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="电话号码" prop="phone">
|
||||||
|
<el-input v-model="userInfo.phone" placeholder="请输入电话号码"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="出生日期">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="userInfo.birthday"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择日期"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-divider content-position="center">隐私设置</el-divider>
|
||||||
|
|
||||||
|
<el-form-item label="匿名分享圈">
|
||||||
|
<el-switch
|
||||||
|
v-model="userInfo.anonymousShare"
|
||||||
|
active-text="使用真实姓名"
|
||||||
|
inactive-text="使用匿名"
|
||||||
|
:active-value="false"
|
||||||
|
:inactive-value="true"
|
||||||
|
></el-switch>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="个人资料可见性">
|
||||||
|
<el-select v-model="userInfo.profileVisibility" placeholder="请选择">
|
||||||
|
<el-option label="所有人可见" value="public"></el-option>
|
||||||
|
<el-option label="仅我的关注者可见" value="followers"></el-option>
|
||||||
|
<el-option label="仅自己可见" value="private"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-divider content-position="center">安全设置</el-divider>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="changePassword">修改密码</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="saveProfile">保存资料</el-button>
|
||||||
|
<el-button @click="resetForm">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'UserProfile'
|
name: 'UserProfile',
|
||||||
|
data () {
|
||||||
|
// 电子邮箱验证规则
|
||||||
|
const validateEmail = (rule, value, callback) => {
|
||||||
|
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
||||||
|
if (value && !emailRegex.test(value)) {
|
||||||
|
callback(new Error('请输入有效的电子邮箱'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手机号验证规则
|
||||||
|
const validatePhone = (rule, value, callback) => {
|
||||||
|
const phoneRegex = /^1[3-9]\d{9}$/
|
||||||
|
if (value && !phoneRegex.test(value)) {
|
||||||
|
callback(new Error('请输入有效的手机号码'))
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
userInfo: {
|
||||||
|
avatar: require('@/assets/user/1.jpg'),
|
||||||
|
username: 'Infinity',
|
||||||
|
realName: '张三',
|
||||||
|
gender: 'male',
|
||||||
|
email: 'user@example.com',
|
||||||
|
phone: '13800138000',
|
||||||
|
birthday: '',
|
||||||
|
anonymousShare: true,
|
||||||
|
profileVisibility: 'followers'
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
username: [
|
||||||
|
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
||||||
|
{ min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
email: [
|
||||||
|
{ required: true, message: '请输入电子邮箱', trigger: 'blur' },
|
||||||
|
{ validator: validateEmail, trigger: 'blur' }
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入手机号码', trigger: 'blur' },
|
||||||
|
{ validator: validatePhone, trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleAvatarChange (file) {
|
||||||
|
this.userInfo.avatar = URL.createObjectURL(file.raw)
|
||||||
|
// 这里应该添加上传逻辑
|
||||||
|
this.$message.success('头像更新成功')
|
||||||
|
},
|
||||||
|
saveProfile () {
|
||||||
|
this.$refs.userForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
// 这里应该添加保存到服务器的逻辑
|
||||||
|
this.$message({
|
||||||
|
message: '个人资料保存成功',
|
||||||
|
type: 'success'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error('请正确填写表单')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
resetForm () {
|
||||||
|
this.$refs.userForm.resetFields()
|
||||||
|
},
|
||||||
|
changePassword () {
|
||||||
|
this.$prompt('请输入当前密码', '修改密码', {
|
||||||
|
confirmButtonText: '下一步',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputType: 'password',
|
||||||
|
inputPlaceholder: '当前密码'
|
||||||
|
}).then(({ value }) => {
|
||||||
|
if (value) {
|
||||||
|
this.$prompt('请输入新密码', '修改密码', {
|
||||||
|
confirmButtonText: '下一步',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputType: 'password',
|
||||||
|
inputPlaceholder: '新密码'
|
||||||
|
}).then(({ value: newPassword }) => {
|
||||||
|
if (newPassword) {
|
||||||
|
this.$prompt('请再次输入新密码', '修改密码', {
|
||||||
|
confirmButtonText: '确认修改',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
inputType: 'password',
|
||||||
|
inputPlaceholder: '确认新密码'
|
||||||
|
}).then(({ value: confirmPassword }) => {
|
||||||
|
if (newPassword === confirmPassword) {
|
||||||
|
// 这里应该添加修改密码的逻辑
|
||||||
|
this.$message.success('密码修改成功')
|
||||||
|
} else {
|
||||||
|
this.$message.error('两次输入的密码不一致')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.user-profile {
|
.user-profile-container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.profile-card {
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.profile-avatar {
|
||||||
|
border: 4px solid #f0f0f0;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-avatar {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-divider {
|
||||||
|
margin: 25px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.user-profile-container {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
753
src/views/customer/knowledgeBase.vue
Normal file
753
src/views/customer/knowledgeBase.vue
Normal file
@ -0,0 +1,753 @@
|
|||||||
|
<template>
|
||||||
|
<div class="knowledge-container">
|
||||||
|
<!-- 顶部背景图区域 -->
|
||||||
|
<div class="knowledge-cover">
|
||||||
|
<img :src="coverImage" alt="封面图" class="cover-image">
|
||||||
|
<div class="title-area">
|
||||||
|
<h1 class="page-title">知识库</h1>
|
||||||
|
<p class="page-subtitle">探索您感兴趣的领域,获取专业知识</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 搜索框 -->
|
||||||
|
<div class="search-box">
|
||||||
|
<el-input
|
||||||
|
v-model="searchQuery"
|
||||||
|
placeholder="搜索知识库内容..."
|
||||||
|
prefix-icon="el-icon-search"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="searchContent"
|
||||||
|
></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 知识库内容区域 -->
|
||||||
|
<div class="knowledge-content">
|
||||||
|
<!-- 分类标签 -->
|
||||||
|
<div class="category-tabs">
|
||||||
|
<el-tabs v-model="activeCategory" @tab-click="handleCategoryChange">
|
||||||
|
<el-tab-pane v-for="category in categories" :key="category.id" :label="category.name" :name="category.id"></el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 知识条目列表 -->
|
||||||
|
<div class="knowledge-list">
|
||||||
|
<div v-for="item in filteredKnowledgeItems" :key="item.id" class="knowledge-item">
|
||||||
|
<!-- 知识条目头部 -->
|
||||||
|
<div class="item-header">
|
||||||
|
<div class="category-tag" :style="{backgroundColor: getCategoryColor(item.categoryId)}">
|
||||||
|
{{ getCategoryName(item.categoryId) }}
|
||||||
|
</div>
|
||||||
|
<span class="item-date">{{ item.date }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 知识条目标题 -->
|
||||||
|
<h2 class="item-title">{{ item.title }}</h2>
|
||||||
|
|
||||||
|
<!-- 知识条目内容 -->
|
||||||
|
<div class="item-content" v-html="item.content"></div>
|
||||||
|
|
||||||
|
<!-- 知识条目附件 -->
|
||||||
|
<div class="item-attachments" v-if="item.attachments && item.attachments.length > 0">
|
||||||
|
<div class="attachment-title">
|
||||||
|
<i class="el-icon-paperclip"></i>
|
||||||
|
<span>附件</span>
|
||||||
|
</div>
|
||||||
|
<div class="attachment-list">
|
||||||
|
<div v-for="(attachment, index) in item.attachments" :key="index" class="attachment-item">
|
||||||
|
<i :class="getAttachmentIcon(attachment.type)"></i>
|
||||||
|
<span class="attachment-name">{{ attachment.name }}</span>
|
||||||
|
<el-button type="text" size="mini" @click="downloadAttachment(attachment)">
|
||||||
|
<i class="el-icon-download"></i>
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 知识条目图片 -->
|
||||||
|
<div class="item-images" v-if="item.images && item.images.length > 0">
|
||||||
|
<template v-if="item.images.length === 1">
|
||||||
|
<el-image
|
||||||
|
:src="item.images[0]"
|
||||||
|
:preview-src-list="item.images"
|
||||||
|
fit="cover"
|
||||||
|
class="single-image"
|
||||||
|
></el-image>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-image
|
||||||
|
v-for="(img, index) in item.images"
|
||||||
|
:key="index"
|
||||||
|
:src="img"
|
||||||
|
:preview-src-list="item.images"
|
||||||
|
fit="cover"
|
||||||
|
class="grid-image"
|
||||||
|
></el-image>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部操作区 -->
|
||||||
|
<div class="item-footer">
|
||||||
|
<div class="action-btn" @click="handleFavorite(item)">
|
||||||
|
<i :class="['el-icon-star-off', { 'favorited': item.isFavorited }]"></i>
|
||||||
|
<span>{{ item.isFavorited ? '取消收藏' : '收藏' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="action-btn" @click="handleShare(item)">
|
||||||
|
<i class="el-icon-share"></i>
|
||||||
|
<span>分享</span>
|
||||||
|
</div>
|
||||||
|
<div class="more-actions" @click="showActionsMenu(item, $event)">
|
||||||
|
<i class="el-icon-more"></i>
|
||||||
|
</div>
|
||||||
|
<div class="actions-menu" v-if="item.showActions">
|
||||||
|
<div class="menu-item" @click="handlePrint(item)">
|
||||||
|
<i class="el-icon-printer"></i>
|
||||||
|
<span>打印</span>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item" @click="handleReport(item)">
|
||||||
|
<i class="el-icon-warning-outline"></i>
|
||||||
|
<span>报告问题</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 无内容提示 -->
|
||||||
|
<div class="no-content" v-if="filteredKnowledgeItems.length === 0">
|
||||||
|
<i class="el-icon-info-circle"></i>
|
||||||
|
<p>没有找到相关内容</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 回到顶部 -->
|
||||||
|
<el-backtop></el-backtop>
|
||||||
|
|
||||||
|
<!-- 分享对话框 -->
|
||||||
|
<el-dialog
|
||||||
|
title="分享知识"
|
||||||
|
v-model="shareDialogVisible"
|
||||||
|
width="90%"
|
||||||
|
custom-class="share-dialog"
|
||||||
|
>
|
||||||
|
<div class="share-options">
|
||||||
|
<div class="share-option" v-for="option in shareOptions" :key="option.id" @click="handleShareOption(option)">
|
||||||
|
<i :class="option.icon"></i>
|
||||||
|
<span>{{ option.name }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
coverImage: require('@/assets/user/1.jpg'),
|
||||||
|
searchQuery: '',
|
||||||
|
activeCategory: 'all',
|
||||||
|
shareDialogVisible: false,
|
||||||
|
selectedItem: null,
|
||||||
|
categories: [
|
||||||
|
{ id: 'all', name: '全部', color: '#409EFF' },
|
||||||
|
{ id: 'tech', name: '技术', color: '#67C23A' },
|
||||||
|
{ id: 'business', name: '商业', color: '#E6A23C' },
|
||||||
|
{ id: 'design', name: '设计', color: '#F56C6C' },
|
||||||
|
{ id: 'health', name: '健康', color: '#909399' }
|
||||||
|
],
|
||||||
|
knowledgeItems: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
categoryId: 'tech',
|
||||||
|
title: 'Vue.js 3.0 核心特性解析',
|
||||||
|
content: '本文详细介绍了Vue.js 3.0的核心特性,包括Composition API、Teleport、Fragments等新功能,以及性能优化方面的提升。使用Vue 3.0可以让您的应用获得更好的性能和开发体验。',
|
||||||
|
date: '2023-05-15',
|
||||||
|
images: [require('@/assets/user/1.jpg')],
|
||||||
|
attachments: [
|
||||||
|
{ name: 'Vue3教程.pdf', type: 'pdf', url: '#' },
|
||||||
|
{ name: 'Demo代码.zip', type: 'zip', url: '#' }
|
||||||
|
],
|
||||||
|
isFavorited: false,
|
||||||
|
showActions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
categoryId: 'business',
|
||||||
|
title: '企业数字化转型策略',
|
||||||
|
content: '数字化转型已成为企业发展的必经之路。本文分析了数字化转型的关键步骤、常见挑战和成功案例,为企业提供了实用的转型策略指南。',
|
||||||
|
date: '2023-05-10',
|
||||||
|
images: [
|
||||||
|
require('@/assets/user/1.jpg'),
|
||||||
|
require('@/assets/user/1.jpg')
|
||||||
|
],
|
||||||
|
attachments: [
|
||||||
|
{ name: '数字化转型白皮书.docx', type: 'word', url: '#' }
|
||||||
|
],
|
||||||
|
isFavorited: true,
|
||||||
|
showActions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
categoryId: 'design',
|
||||||
|
title: 'UI/UX设计趋势2023',
|
||||||
|
content: '2023年的UI/UX设计趋势呈现多样化发展。本文探讨了包括微互动、3D元素、黑暗模式优化、声音UI等在内的主要设计趋势,以及它们如何影响用户体验。',
|
||||||
|
date: '2023-04-28',
|
||||||
|
images: [
|
||||||
|
require('@/assets/user/1.jpg'),
|
||||||
|
require('@/assets/user/1.jpg'),
|
||||||
|
require('@/assets/user/1.jpg')
|
||||||
|
],
|
||||||
|
attachments: [],
|
||||||
|
isFavorited: false,
|
||||||
|
showActions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
categoryId: 'health',
|
||||||
|
title: '远程工作与心理健康',
|
||||||
|
content: '长期远程工作可能对心理健康产生影响。本文提供了一系列保持心理健康的实用建议,包括建立工作常规、设置专用工作空间、定期休息等策略。',
|
||||||
|
date: '2023-04-15',
|
||||||
|
images: [],
|
||||||
|
attachments: [
|
||||||
|
{ name: '远程工作健康指南.pdf', type: 'pdf', url: '#' }
|
||||||
|
],
|
||||||
|
isFavorited: false,
|
||||||
|
showActions: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
categoryId: 'tech',
|
||||||
|
title: '区块链技术在供应链中的应用',
|
||||||
|
content: '区块链技术为供应链管理带来了革命性变化。本文探讨了区块链如何提升供应链的透明度、可追溯性和效率,并分析了实际应用案例。',
|
||||||
|
date: '2023-03-22',
|
||||||
|
images: [require('@/assets/user/1.jpg')],
|
||||||
|
attachments: [],
|
||||||
|
isFavorited: true,
|
||||||
|
showActions: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
shareOptions: [
|
||||||
|
{ id: 'wechat', name: '微信', icon: 'el-icon-chat-dot-round' },
|
||||||
|
{ id: 'weibo', name: '微博', icon: 'el-icon-chat-line-round' },
|
||||||
|
{ id: 'link', name: '复制链接', icon: 'el-icon-link' },
|
||||||
|
{ id: 'qrcode', name: '二维码', icon: 'el-icon-picture-outline-round' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredKnowledgeItems () {
|
||||||
|
// 先根据分类筛选
|
||||||
|
let result = this.knowledgeItems
|
||||||
|
if (this.activeCategory !== 'all') {
|
||||||
|
result = result.filter(item => item.categoryId === this.activeCategory)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 再根据搜索关键词筛选
|
||||||
|
if (this.searchQuery) {
|
||||||
|
const query = this.searchQuery.toLowerCase()
|
||||||
|
result = result.filter(item =>
|
||||||
|
item.title.toLowerCase().includes(query) ||
|
||||||
|
item.content.toLowerCase().includes(query)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCategoryName (categoryId) {
|
||||||
|
const category = this.categories.find(c => c.id === categoryId)
|
||||||
|
return category ? category.name : '未分类'
|
||||||
|
},
|
||||||
|
getCategoryColor (categoryId) {
|
||||||
|
const category = this.categories.find(c => c.id === categoryId)
|
||||||
|
return category ? category.color : '#909399'
|
||||||
|
},
|
||||||
|
getAttachmentIcon (type) {
|
||||||
|
const icons = {
|
||||||
|
pdf: 'el-icon-document',
|
||||||
|
word: 'el-icon-document-checked',
|
||||||
|
excel: 'el-icon-document',
|
||||||
|
zip: 'el-icon-folder',
|
||||||
|
image: 'el-icon-picture',
|
||||||
|
video: 'el-icon-video-camera',
|
||||||
|
audio: 'el-icon-headset'
|
||||||
|
}
|
||||||
|
return icons[type] || 'el-icon-document'
|
||||||
|
},
|
||||||
|
handleCategoryChange () {
|
||||||
|
// 切换分类时滚动到顶部
|
||||||
|
window.scrollTo(0, 0)
|
||||||
|
},
|
||||||
|
searchContent () {
|
||||||
|
// 搜索内容
|
||||||
|
console.log('搜索关键词:', this.searchQuery)
|
||||||
|
},
|
||||||
|
handleFavorite (item) {
|
||||||
|
item.isFavorited = !item.isFavorited
|
||||||
|
this.$message({
|
||||||
|
message: item.isFavorited ? '已添加到收藏' : '已取消收藏',
|
||||||
|
type: 'success',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleShare (item) {
|
||||||
|
this.selectedItem = item
|
||||||
|
this.shareDialogVisible = true
|
||||||
|
},
|
||||||
|
handleShareOption (option) {
|
||||||
|
this.$message({
|
||||||
|
message: `通过${option.name}分享成功`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
this.shareDialogVisible = false
|
||||||
|
},
|
||||||
|
showActionsMenu (item, event) {
|
||||||
|
// 阻止事件传播到document,避免立即触发关闭
|
||||||
|
event.stopPropagation()
|
||||||
|
|
||||||
|
// 关闭其他所有条目的操作菜单
|
||||||
|
this.knowledgeItems.forEach(i => {
|
||||||
|
if (i.id !== item.id) {
|
||||||
|
i.showActions = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 切换当前条目的操作菜单显示状态
|
||||||
|
item.showActions = !item.showActions
|
||||||
|
},
|
||||||
|
closeAllActionMenus () {
|
||||||
|
this.knowledgeItems.forEach(item => {
|
||||||
|
item.showActions = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handlePrint (item) {
|
||||||
|
console.log('打印:', item.title)
|
||||||
|
item.showActions = false
|
||||||
|
this.$message({
|
||||||
|
message: '准备打印...',
|
||||||
|
type: 'info',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleReport (item) {
|
||||||
|
console.log('报告问题:', item.title)
|
||||||
|
item.showActions = false
|
||||||
|
this.$message({
|
||||||
|
message: '已提交问题报告,感谢您的反馈',
|
||||||
|
type: 'success',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downloadAttachment (attachment) {
|
||||||
|
console.log('下载附件:', attachment.name)
|
||||||
|
this.$message({
|
||||||
|
message: `开始下载: ${attachment.name}`,
|
||||||
|
type: 'success',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
// 添加document点击事件监听器,用于点击页面其他区域时关闭操作菜单
|
||||||
|
document.addEventListener('click', this.closeAllActionMenus)
|
||||||
|
},
|
||||||
|
beforeUnmount () {
|
||||||
|
// 移除事件监听器
|
||||||
|
document.removeEventListener('click', this.closeAllActionMenus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.knowledge-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knowledge-cover {
|
||||||
|
position: relative;
|
||||||
|
height: 40vh;
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #000;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-area {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 30%;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 36px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0;
|
||||||
|
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-top: 10px;
|
||||||
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||||
|
max-width: 80%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 50px;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 80%;
|
||||||
|
max-width: 600px;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box .el-input {
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box .el-input >>> .el-input__inner {
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
font-size: 16px;
|
||||||
|
padding-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knowledge-content {
|
||||||
|
padding: 50px 0 30px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 960px;
|
||||||
|
margin: 0 auto;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tabs {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tabs >>> .el-tabs__nav-wrap::after {
|
||||||
|
height: 1px;
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tabs >>> .el-tabs__active-bar {
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 1.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tabs >>> .el-tabs__item {
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knowledge-list {
|
||||||
|
margin-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knowledge-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 25px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 12px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 3px 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-date {
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-title {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-content {
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-attachments {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #666;
|
||||||
|
font-size: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-title i {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-item i {
|
||||||
|
margin-right: 10px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.attachment-name {
|
||||||
|
flex: 1;
|
||||||
|
color: #333;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-images {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.single-image {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
padding-bottom: 100%;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-image img {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 15px;
|
||||||
|
border-top: 1px solid #f0f0f0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 15px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn .favorited {
|
||||||
|
color: #FF9900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-actions {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #666;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
z-index: 21;
|
||||||
|
}
|
||||||
|
|
||||||
|
.more-actions i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actions-menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 36px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
background-color: #555;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 22;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
min-width: 100px;
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item:hover {
|
||||||
|
background-color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item i {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-content {
|
||||||
|
text-align: center;
|
||||||
|
padding: 50px 0;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-content i {
|
||||||
|
font-size: 48px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-content p {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-options {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 15px;
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-option {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-option:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-option i {
|
||||||
|
font-size: 24px;
|
||||||
|
color: #409EFF;
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.share-option span {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 768px) {
|
||||||
|
.knowledge-content {
|
||||||
|
padding: 50px 15px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.knowledge-item {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-images {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-subtitle {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-footer {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue
Block a user