个人空间页面代码

方丽彤 1 year ago
commit e18773897b

@ -0,0 +1,4 @@
> 1%
last 2 versions
not dead
not ie 11

@ -0,0 +1,17 @@
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended'
],
parserOptions: {
parser: '@babel/eslint-parser'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}

23
.gitignore vendored

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

@ -0,0 +1,24 @@
# demo
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

13677
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,30 @@
{
"name": "demo",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^1.7.7",
"core-js": "^3.8.3",
"element-plus": "^2.8.6",
"vite": "^5.4.10",
"vue": "^3.2.13",
"vue-router": "^4.4.5",
"vue-virtual-scroller": "^1.1.2"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"unplugin-auto-import": "^0.18.3",
"unplugin-vue-components": "^0.27.4"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

@ -0,0 +1,20 @@
<template>
<router-view/>
</template>
<script setup></script>
<style>
/* 让页面铺满整个屏幕,不出现滚动条 */
html,
body,
#app {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: auto;
}
</style>

@ -0,0 +1,27 @@
/* 给圆形定义关键帧 */
@keyframes switch {
0% {
left: calc(4px * 0.2);
}
60% {
left:calc(4px * 0.2);
width: calc(112px * 0.2);
}
100%{
left: calc(104px * 0.2);
}
}
@keyframes reverse_switch {
0% {
left: calc(104px * 0.2);
}
60%{
left: calc(74px * 0.2);
width: calc(112px * 0.2);
}
100%{
left: calc(4px * 0.2);
}
}

@ -0,0 +1,80 @@
.communitybase
{
height: 100vh;
background-image: url("../../pictures/communityback.png");
background-size: 90%;
background-attachment: fixed; /* 背景固定 */
background-position: -600px; /* 向左移动背景图像 50px */
background-position: center; /* 可以选择让背景居中 */
z-index: -1;
}
.touxiang
{
position: absolute;
top:50%;
left:5%;
border-radius: 10px;
width: 50px;
height:50px;
transform: translateY(-50%)
}
.leftinfo
{
background-color: rgba(255,255,255,0.8);
width: 15%;
position: fixed;
left:0%;
border: 3px solid orchid;
height:100%;
}
.rightheat
{
background-color: rgba(255,255,255,0.8);
position: fixed;
right:0%;
width: 15%;
border: 3px solid orchid;
height:100%;
}
.familytitle
{
position: absolute;
top:8%;
left:35%;
font-size: 14px;
font-weight: bold;
}
.familycontent
{
position: absolute;
bottom:12%;
left:35%;
font-size: 13px;
}
.Hotsearchnum{
border-radius: 50%;
width: 25px;
height: 25px;
display: flex;
justify-content: center;
align-items: center;
}
.middle
{
position: absolute;
left:50%;
transform: translateX(-50%);
width: 65%;
border: 3px solid orchid;
height:100%;
z-index:1;
}
.post-list {
}

@ -0,0 +1,147 @@
.base{
height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background-image: url("@/assets/pictures/background.png");
background-size: 100%;
}
.loginAndRegist{
position: absolute;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
right:6%;
top:35%;
}
.loginArea{
background-color: rgba(255,255,255,0.8);
opacity: 0.8;
border-top-left-radius: 15px;
border-bottom-left-radius: 15px;
height: 400px;
width: 400px;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
overflow: hidden;
}
.registArea{
opacity: 0.8;
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
height: 400px;
width: 400px;
background-color: rgba(255,255,255,0.8);
z-index: 1;
display: flex;
flex-direction: column;
justify-content:center ;
align-items: center;
}
.showInfo{
border-top-right-radius: 15px;
border-bottom-right-radius: 15px;
position: absolute;
height: 400px;
width: 400px;
z-index:2;
top: 0;
right: 0;
background-image: url("@/assets/pictures/welcome.png");
background-size: 90%;
}
.showInfo:hover{
background-size: 100%;
background-position: -50px -50px;
}
.title{
width: 80%;
flex:1;
border-bottom: 1px solid #E44B9D;
display: flex;
align-items: center;
color: #E44B9D;
font-weight: bold;
font-size: 24px;
display: flex;
justify-content: center;
}
#aaa{
transition: 0.3s linear;
}
.pwdArea{
width: 100%;
flex:2;
display: flex;
flex-direction: column;
color: #E44B9D;
font-size: 20px;
font-weight: bold;
}
.pwdArea input{
height: 30px;
border-radius:15px ;
padding-left: 10px;
font-size: 13px;
}
/* 移除输入框边框 */
.el-input__inner {
border: none !important;
outline: none !important;
}
.pwdArea input:focus{
border: 2px solid #E44B9D;
}
.btnArea{
flex:1;
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
}
.rigestTitle{
width: 70%;
flex: 1;
color: #E44B9D;
font-weight: bold;
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #E44B9D;
}
.registForm{
flex: 2;
display: flex;
flex-direction: column;
color: #E44B9D;
font-size: 20px;
font-weight: bold;
}
.registForm input{
outline: none;
height: 30px;
border-radius:13px ;
padding-left: 10px;
font-size: 12px;
border: 1px solid gray;
}
.registForm input:focus{
border: 2px solid #E44B9D;
}
#elselect:focus{
border: 2px solid #E44B9D;
}
.registBtn{
flex: 1;
display: flex;
justify-content: center;
align-items: center;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 354 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 243 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 829 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 761 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

@ -0,0 +1,57 @@
<template>
<div class="comment-input">
<textarea v-model="commentText" placeholder="输入评论..." rows="3"></textarea>
<button @click="submitComment"></button>
</div>
</template>
<script>
export default {
data() {
return {
commentText: '', //
};
},
methods: {
submitComment() {
if (this.commentText.trim()) {
this.$emit('submitComment', this.commentText); //
this.commentText = ''; //
this.$emit('updateLikeCount', this.likeCount + 1);
} else {
alert("评论不能为空!");
}
}
}
};
</script>
<style scoped>
.comment-input {
display: flex;
flex-direction: column;
}
textarea {
margin-bottom: 10px;
padding: 10px;
font-size: 14px;
border-radius: 5px;
border: 1px solid #ddd;
}
button {
align-self: flex-end;
padding: 8px 15px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
</style>

@ -0,0 +1,173 @@
<template>
<div class="post-card">
<div class="post-header">
<img :src="avatarUrl" alt="avatar" class="avatar" />
<div class="user-info">
<strong>{{ username }}</strong>
<span>{{ timestamp }}</span>
</div>
</div>
<div class="post-content">
<p>{{ content }}</p>
<div style="display: flex;justify-content: center;">
<img v-if="imageUrl" :src="imageUrl" alt="post image" />
</div>
</div>
<div class="post-footer">
<button @click="increaseLikeCount" :class="{'liked': isLiked}">
<span v-if="isLiked"></span>
<span v-else>🤍</span>
{{ likeCount }}
</button>
<button @click="toggleCommentsVisibility">
{{ isCommentsVisible ? '隐藏评论' : '查看评论' }}
💬
{{ commentCount }}
</button>
</div>
<!-- 评论区的过渡动画 -->
<transition name="fade" @before-enter="beforeEnter" @enter="enter" @leave="leave">
<div v-if="isCommentsVisible" class="comments-section">
<div v-for="(comment, index) in comments" :key="index" class="comment">
<p><strong>{{ comment.username }}:</strong> {{ comment.text }}</p>
</div>
<!-- 发布评论 -->
<CommentInput @submitComment="addComment" />
</div>
</transition>
</div>
</template>
<script>
import CommentInput from './CommentInput.vue';
export default {
components: { CommentInput },
props: {
avatarUrl: String,
username: String,
timestamp: String,
content: String,
imageUrl: String,
likeCount: Number,
commentCount: Number,
isCommentsVisible: Boolean,
comments: Array, //
},
methods: {
increaseLikeCount() {
this.$emit('updateLikeCount', this.likeCount + 1);
this.isLiked = !this.isLiked;
},
increaseCommentCount() {
this.$emit('updateCommentCount', this.commentCount + 1);
},
toggleCommentsVisibility() {
this.$emit('toggleCommentsVisibility');
},
addComment(commentText) {
this.$emit('addComment', commentText); //
},
beforeEnter(el) {
el.style.maxHeight = '0';
},
enter(el, done) {
el.offsetHeight; //
el.style.transition = 'max-height 0.3s ease-in-out';
el.style.maxHeight = `${el.scrollHeight}px`;
done();
},
leave(el, done) {
el.style.transition = 'max-height 0.3s ease-in-out';
el.style.maxHeight = '0';
done();
}
}
};
</script>
<style scoped>
button {
background: none;
border: none;
font-size: 1rem;
cursor: pointer;
outline: none;
padding: 0;
}
/* 点赞后的红色样式 */
@keyframes scaleAnimation {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
/* .liked 类,应用动画 */
.liked {
color: red;
animation: scaleAnimation 0.5s ease-in-out;
}
.post-card {
opacity: 0.95;
margin: 20px;
border: 1px solid #ddd;
padding: 15px;
border-radius: 8px;
background-color: #fff;
}
.post-header {
display: flex;
align-items: center;
}
.avatar {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 10px;
}
.user-info {
font-size: 14px;
}
.post-footer {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.comments-section {
margin-top: 15px;
padding: 10px;
background-color: #f9f9f9;
border-radius: 8px;
overflow: hidden; /* 确保在 max-height 动画过程中隐藏溢出的内容 */
}
.comment {
margin-bottom: 10px;
}
/* 过渡效果 */
.fade-enter-active, .fade-leave-active {
transition: max-height 0.3s ease-in-out;
}
.fade-enter, .fade-leave-to {
max-height: 0;
}
</style>

@ -0,0 +1,35 @@
<template>
<div class="main-content">
</div>
</template>
<<<<<<< HEAD
<style scoped>
=======
<style>
>>>>>>> a6b76ef7f39f0d43fb6b42d4a7d62d28e3f1da78
.main-content {
/* 设置背景为渐变色 */
background:
url('@/assests/pictures/backtree.png') no-repeat center center,linear-gradient(to bottom, rgba(252, 220, 215, 1) 0%, rgba(252, 220, 215, 1) 5%, rgba(255, 249, 161, 1) 25%, rgba(255, 249, 161, 1) 100%);
box-sizing: border-box; /* 使内边距计算在总高度内 */
background-size:auto 90% 60%;
background-position: center; /* 使背景图居中 */
height: 100vh; /* 使主界面高度占满整个视口 */
padding: 20px; /* 添加一些内边距 */
box-sizing: border-box; /* 使内边距计算在总高度内 */
}
</style>
<script>
export default
{
name: 'BackGround', //
//
}
</script>

@ -0,0 +1,88 @@
<template>
<el-menu
:default-active="activeIndex"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#ffffff"
text-color="#000000"
active-text-color="#FEB2D7"
>
<div class="logo">
<img src="../assets/pictures/Logo.png" alt="Logo" />
</div>
<el-menu-item index="1">智能推荐</el-menu-item>
<el-sub-menu index="2">
<template #title>{{communityName}}</template>
<el-menu-item index="2-1">私信聊天</el-menu-item>
<el-menu-item index="2-2">社区动态</el-menu-item>
</el-sub-menu>
<el-menu-item index="3" disabled>情感助手</el-menu-item>
<el-menu-item index="4">个人空间</el-menu-item>
<div class="tu">
<img src="@/assets/pictures/tu.png" alt="tu" />
</div>
</el-menu>
<div class="h-6" />
</template>
<script setup>
import { useRouter } from 'vue-router'
import { ref,onMounted } from 'vue'
const router = useRouter()
const activeIndex = ref('1') // '1'
const communityName = ref('社区互动')
const handleSelect = (indexPath) => {
if (indexPath === '1') {
router.push('/main/recommend') //
}
else if(indexPath === '2-1') {
router.push('/main/chat')
communityName.value = '私信聊天'
}
else if(indexPath === '2-2') {
router.push('/main/community')
communityName.value = '社区动态'
}
else if(indexPath === '4') {
router.push('/main/spacePage')
}
}
onMounted(() => {
if (window.location.pathname === '/') {
router.push('/main/recommend')
}
})
</script>
<script>
export default {
name: 'HeaderComponent',
}
</script>
<style>
.el-menu-demo {
justify-content: space-between; /* 平铺菜单项 */
font-weight: bold; /* 加粗字体 */
}
/* 取消悬停和选中时的背景色 */
.el-menu--horizontal > .el-menu-item:not(.is-disabled):focus,
.el-menu--horizontal > .el-menu-item:not(.is-disabled):hover,
.el-menu--horizontal > .el-menu-item.is-active {
background-color: transparent !important;
}
.logo img,
.tu img {
height: 50px; /* 根据需要调整高度 */
width: auto; /* 自适应宽度 */
margin-right: 10px; /* 与菜单项的间距 */
}
.el-menu-item {
line-height: 70px; /* 设置菜单项的行高,和菜单高度一致 */
font-weight: bold; /* 加粗字体 */
}
</style>

@ -0,0 +1,16 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
const app = createApp(App)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.use(ElementPlus)
app.use(router)
app.mount('#app')

@ -0,0 +1,64 @@
import login from '@/views/login/login.vue'
import main from '../views/Main.vue'
import recommend from '@/views/recommend/index.vue'
import community from '@/views/community/trends.vue'
import chat from '@/views/chat/chat.vue'
import informationPage from '@/views/space/informationPage.vue'
import spacePage from '@/views/space/spacePage.vue'
import familyTree from '@/views/space/familyTree.vue'
import spaceTest from '@/views/space/spaceTest.vue'
import {createRouter ,createWebHashHistory} from 'vue-router'
const routes = [
{
path : '/',
redirect:'/main/recommend',
component : spaceTest,
},
{
path:'/main',
component : main,
children:[
{
path:'recommend',
component: recommend
},
{
path:'community',
component: community
},
{
path:'chat',
component: chat
},
{
path:'login',
component:login
},
{
path:'informationPage',
component:informationPage
},
{
path:'spacePage',
component:spacePage
},
{
path:'familyTree',
component:familyTree
}
]
},
]
const router = createRouter({
routes,
history:createWebHashHistory()
})
export default router

@ -0,0 +1,18 @@
// 存储、获取、删除token的文件
// 定义 setToken 函数,用于将 token 存储到 localStorage
export function setToken(token) {
localStorage.setItem('authToken', token);
}
// 定义 getToken 函数,用于从 localStorage 获取 token
export function getToken() {
return localStorage.getItem('authToken');
}
// 定义 removeToken 函数,用于从 localStorage 删除 token
export function removeToken() {
localStorage.removeItem('authToken');
}

@ -0,0 +1,64 @@
// axiosConfig.js
import axios from 'axios';
import {getToken} from '@/token/auth' // 注意这里使用了解构赋值来导入getToken函数
// 创建axios实例
const service = axios.create({
baseURL: 'http://47.122.59.26:8080/api', // 配置基础URL
timeout: 5000, // 请求超时时间
});
// 请求拦截器
service.interceptors.request.use(
config => {
// 在发送请求之前做些什么
const token = getToken(); // 获取token的方式取决于你的应用
// console.log('请求拦截器的token是' +token)
console.log('Request Config:', config);
if (token) {
config.headers['Authorization'] = `Bearer ${token}`; // 设置token
// axios.defaults.headers.common['Authorization'] = 'Bearer ' + token;
}
config.headers['Accept'] = 'application/json';
return config;
},
error => {
// 对请求错误做些什么
console.error('Request Error:', error);
return Promise.reject(error);
}
);
// 响应拦截器
service.interceptors.response.use(
response => {
// 对响应数据做点什么
// 注意这里返回已经包含data
const res = response.data;
// 你可以根据实际情况在这里添加一些通用的响应处理逻辑
// 例如,根据返回的状态码判断请求是否成功
// if (res.code !== 200) {
// 业务错误处理,比如弹窗提示等
// return Promise.reject(new Error(res.message || 'Error'));
// } else {
return res;
// }
},
error => {
// 对响应错误做点什么
// if (error.response) {
// 请求已发出但服务器响应的状态码不在2xx的范围
// console.error('Error status:', error.response.status);
// console.error('Error data:', error.response.data);
// } else if (error.request) {
// 请求已发出,但没有收到响应
// console.error('Error request:', error.request);
// } else {
// 在设置请求时触发错误
console.error('响应拦截器errorMessage:', error.message);
// }
return Promise.reject(error);
}
);
export default service;

@ -0,0 +1,21 @@
<template>
<heade/>
<div></div>
<router-view/>
</template>
<script setup>
import heade from '../components/header.vue'
// import background from '../components/background.vue'
</script>
<script>
export default {
name: 'MainView', //
//
}
</script>

@ -0,0 +1,77 @@
<template>
<div v-if="name == yours" class="card-layout-1">
<img id="card-icon-1" :src="your_icon" alt="" style="width: 50px;height:50px">
<div class="card-color-size-1">{{ content }} {{ console.log(content) }}</div>
</div>
<div v-else class="card-layout-2">
<div class="card-color-size-2">{{ content }} {{ console.log(content) }}</div>
<img id="card-icon-2" :src="my_icon" alt="" style="width: 50px;height:50px">
</div>
</template>
<script>
export default{
data(){
return{
msg: ''
}
},
props:{
yours: String,
content: String,
name: String,
your_icon: String,
my_icon: String,
},
computed:{
}
}
</script>
<style scoped>
.card-layout-1{
display: flex;
margin: 10px;
margin-left: 30px;
margin-top: 30px;
/* max-width: 70%; */
}
.card-layout-2{
display: flex;
justify-content: flex-end;
margin: 10px;
margin-right: 30px;
margin-top: 30px;
/* max-width: 70%; */
}
.card-color-size-1{
white-space: pre-line;
background-color: rgb(248, 248, 248);
margin-left: 10px;
border-radius: 10px;
border-bottom-left-radius: 0px;
padding: 10px;
}
#card-icon-1{
align-self: flex-end;
border: 2px solid #ff68b8;
border-radius: 100%;
}
#card-icon-2{
align-self: flex-end;
border: 2px solid #ff68b8;
border-radius: 100%;
}
.card-color-size-2{
white-space: pre-line;
background-color: #fcb7dc;
margin-right: 10px;
border-radius: 10px;
border-bottom-right-radius: 0px;
padding: 10px;
}
</style>

@ -0,0 +1,71 @@
<template>
<div class="container" :style="{height: containerHeight}" @scroll="scroll_event">
<div class="list" :style="{top: listTop}">
<slot :show_list="getShowList" :show_height="one_height"></slot>
<div :style="{height: barHeight}"></div>
</div>
</div>
</template>
<script>
export default{
data(){
return{
start : 0,
end : this.shownum,
}
},
props:{
shownum: Number,
items: Array,
one_height: Number,
},
computed:{
containerHeight(){
return this.shownum*this.one_height + 'px'
},
getShowList(){
console.log(this.items.slice(this.start,this.end))
return this.items.slice(this.start,this.end)
},
barHeight(){
return this.one_height * (this.items.length-this.start-this.shownum+1) + 'px'
},
listTop(){
console.log(this.items,this.shownum,this.one_height)
return this.one_height * this.start + 'px'
}
},
methods:{
scroll_event(e){
const top = e.target.scrollTop
this.start = Math.floor(top / this.one_height)
this.end = this.start + this.shownum
}
}
}
</script>
<style scoped>
.container{
overflow-y: scroll;
align-items: center;
background-color: transparent;
width: 100%;
height: 100%;
scrollbar-color:#F3ABB6 #FFFF;
/* text-align: center; */
/* height: 100px; */
}
.list{
position: relative;
top: 0;
width: 100%;
}
</style>

@ -0,0 +1,117 @@
<template>
<!-- <h4>我是动效滚动</h4> -->
<div>
<input type="checkbox" class="honneyBtn" v-model="status" :id="cnt">
<label for="honneyBtn" class="test">{{ status }}</label>
</div>
</template>
<script>
export default{
data(){
return{
status: false,
}
},
mounted(){
//
this.status = this.Status
},
props:{
Status:Boolean,
cnt:String,
ReviseStatus2Father: Function
// Status2:String
},
watch:{
status(newvalue){
this.status = newvalue
this.ReviseStatus2Father(this.status)
console.log(this.newvalue)
},
Status(){
this.status = this.Status
}
}
}
</script>
<style scoped>
:root{
--honey-width:200px;
--honey-height:100px;
}
input{
/* display: none; */
opacity: 0;
width: calc(200px * 0.2);
height: calc(100px * 0.2);
}
label{
/* 圆角矩形组件 */
display: block;
position: relative;
background-color:#979797;
width: calc(200px * 0.2);
height: calc(100px * 0.2);
border-radius: 200px;
padding: 0px;
margin: 0px;
transition: all 0.37s ease-in;
position: inherit;
top: -50%;
z-index: -1;
}
label::before{
/* 圆角矩形里面的按钮 */
content: '';
position: absolute;
width: calc(82px * 0.2);
height: calc(82px * 0.2);
border-radius: 50%;
border: calc(2px * 0.2) solid #b0b0b0;
background-color: white;
top: calc(7px * 0.2);
left: calc(5px * 0.2);
transition: all 1s ease-in;
animation: reverse_switch 0.35s forwards;
}
.honneyBtn:checked + label{
background-color: #FE4E96;
}
.honneyBtn:checked + label::before{
border:calc(2px * 0.2) solid #fc5ea0;
animation: switch 0.35s forwards;
}
/* 给圆形定义关键帧 */
@keyframes switch {
0% {
left: calc(4px * 0.2);
}
60% {
left:calc(4px * 0.2);
width: calc(112px * 0.2);
}
100%{
left: calc(104px * 0.2);
}
}
@keyframes reverse_switch {
0% {
left: calc(104px * 0.2);
}
60%{
left: calc(74px * 0.2);
width: calc(112px * 0.2);
}
100%{
left: calc(4px * 0.2);
}
}
</style>

@ -0,0 +1,495 @@
<template>
<div class="chat-totallayout">
<div class="chat-leftlayout">
<div class="chat-leftline1">
<p>信息</p>
<p>{{ new_msg_nums }}条新信息</p>
</div>
<div class="chat-leftline2">
<img id="chatSearchImg" src="@/assets/pictures/chat/search.png">
<input id="chatSearchInput" type="search" v-model="searchName">
</div>
<div class="chat-leftline3">
<ChatList :shownum="Number(7)" :items="showSearchList" :one_height="Number(58)" v-slot="a">
<div class="chat-friends" v-for="(item,index) of a.show_list" :key="index" @click="clickFriendList(item)">
<img id="chatIconImg" :src="item.icon" />
<div class="chat-friend-text">
<p id="chatFriendName">{{ item.name }}</p>
<p id="chatFriendMsg">{{ getLatestNew(item) }}</p>
</div>
<p id="chatTime">{{ item.chatHistory[item.chatHistory.length - 1].time.split(' ')[1] }}</p>
</div>
</ChatList>
</div>
</div>
<div class="chat-middlelayout">
<ChatList v-if="chatWith == '' ? false : true" :shownum="Number(5)" :items="getFriendObject.chatHistory" :one_height="Number(100)" v-slot="a">
<div v-for="(item,index) of a.show_list" :key="index">
<ChatCard :your_icon="getFriendObject.icon" :my_icon="userInfo.icon" :name="item.name" :yours="chatWith" :content="historyContentHandle(item.content)"></ChatCard>
</div>
</ChatList>
<div class="send-msg">
<img :src="userInfo.icon" alt="" style="width: 40px;height: 40px; border-radius: 50%;">
<input id="send-msg-input" type="search" v-model="sendingMsg">
<button class="search-btn" @click="sendMsg"></button>
</div>
</div>
<div class="chat-rightlayout" v-if="chatWith != ''">
<img :src="getFriendObject.icon" alt="" style="width: 90px;height: 90px; border-radius: 50%;border: 1px solid #f85096;">
<p style="font-weight: 600; font-size: large;">{{ getFriendObject.name }}</p>
<div class="friend-information">
<img src="../../assets/pictures/chat/Location.png" alt="" style="height: 20px;">
<p>{{ getFriendObject.position }}</p>
<img src="../../assets/pictures/chat/Calendar.png" alt="" style="height: 20px;">
<p>{{ getFriendObject.birth }}</p>
</div>
<div class="chat-special-btn" style="position: relative;top: -3%;">
<div class="chat-home-tree-btn">
<button class="chat-home-page-btn" style=""></button>
<p style="color: #f85096;">他的主页</p>
</div>
<div class="chat-home-tree-btn">
<button class="chat-tree-btn"></button>
<p style="color: #a75efb;">族谱树</p>
</div>
</div>
<div style="position: relative;top: -3%; width: 60%; height: 2px; background: linear-gradient(to right, transparent, gray, transparent);opacity: 0.7;">
</div>
<div style="position: relative;top: -1%;font-size: small;">你和他已经聊了{{ getFriendObject.beeing_friends_time }}</div>
<div class="chat-connection" style="position: relative;top: 1%;">
<img src="../../assets/pictures/chat/GuanZhu.png" style="height: 23px;">
<p style="position: relative;top: -27%;">关注他{{ getFriendObject.concern_status }}</p>
<HonneyBtn style="position: relative;top: 6%;" cnt="1" :Status="getFriendObject.concern_status " :ReviseStatus2Father="concernStatusRevise"></HonneyBtn>
</div>
<div class="chat-connection" style="position: relative;top: -2%;">
<img src="../../assets/pictures/chat/HeiMinDan.png" style="height: 25px;">
<p style="position: relative;top: -25%;">拉黑他{{ getFriendObject.black_status }}</p>
<HonneyBtn style="position: relative;top: 10%;" cnt="2" :Status="getFriendObject.black_status" :ReviseStatus2Father="blackStatusRevise"></HonneyBtn>
</div>
<div style="position:relative;top: -4%;width: 60%; height: 2px; background: linear-gradient(to right, transparent, gray, transparent);opacity: 0.7;"></div>
<p style="position: relative;top: -5%;">可能感兴趣的人</p>
<div class="chat-recomend" style="position: relative;top: -5%;">
<div v-for="(item,index) of recomendList" :key="index" style="display: flex;flex-direction: column;align-items: center;">
<img :src="item.icon" alt="" style="width: 50px;height: 50px;border: 2px solid #f85096;border-radius: 50%;">
<p>{{ item.name }}</p>
</div>
</div>
</div>
</div>
</template>
<script>
// import RecycleScroller from 'vue-virtual-scroller';
import HonneyBtn from './HonneyBtn.vue';
import ChatCard from './ChatCard.vue';
import ChatList from './ChatList.vue';
export default {
name: 'chatIndex', //
data(){
return{
searchName: '',
new_msg_nums: 1,
chatWith:'',
userInfo:{
name:'我',
icon:'/icon/abc.jpg'
},
sendingMsg: '',
//
// 使assetspublic
// iconpublic
// public
friendsInfoList: [
{name:'潇潇',icon:'/icon/icon.png',position:'london',birth:'2004-1-1',concern_status:false,black_status:true,beeing_friends_time: 302,
chatHistory:[
{name:'我',content:'早重中之重做做做做做做做做做做做做做做做做做做做战争之子战争之子做做做做',time:'2024-11-24 1:24'},
{name:'潇潇',content:'中',time:'2024-11-24 2:11'},
{name:'我',content:'晚',time:'2024-11-24 3:24'},
]},
{name:'小刚','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 2,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'小刚',content:'hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh',time:'2024-11-25 22:11'},
]},
{name:'吴伟',icon:'/icon/icon.png',position:'endland',birth:'2004-5-2',concern_status:false,black_status:false,beeing_friends_time: 32,
chatHistory:[
{name:'我',content:'早上好',time:'2024-11-24 22:25'},
{name:'吴伟',content:'iii',time:'2024-11-24 23:11'},
]},
{name:'小闽','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'小闽',content:'h',time:'2024-11-25 22:11'},
]},
{name:'小','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'小',content:'h',time:'2024-11-25 22:11'},
]},
{name:'闽','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'闽',content:'h',time:'2024-11-25 22:11'},
]},
{name:'哈哈','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'哈哈',content:'h',time:'2024-11-25 22:11'},
]},
{name:'kk','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'kk',content:'h',time:'2024-11-25 22:11'},
]},
{name:'44','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'44',content:'h',time:'2024-11-25 22:11'},
]},
{name:'77','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'77',content:'h',time:'2024-11-25 22:11'},
]},
{name:'88','icon':'/icon/UserIcon.png',position:'china',birth:'2003-3-4',concern_status:false,black_status:false,beeing_friends_time: 1,
chatHistory:[
{name:'我',content:'you are',time:'2024-11-24 22:24'},
{name:'88',content:'h',time:'2024-11-25 22:11'},
]},
],
showSearchList: [],
recomendList: [
{name:'Amon',icon:'/icon/bird.jpg'},
{name:'果果',icon:'/icon/icon.png'},
{name:'xixi',icon:'/icon/UserIcon.png'},
]
}
},
mounted(){
if(this.searchName == '')
this.showSearchList = this.friendsInfoList
},
components:{
HonneyBtn,
// RecycleScroller,
ChatCard,
ChatList
},
methods:{
clickFriendList(item){
let who = item.name
if(this.chatWith != who){
this.sendingMsg = ''
}
this.chatWith = item.name
console.log(this.chatWith)
},
sendMsg(){
const dayjs = require('dayjs')
const formattedTime = dayjs().format('YYYY-MM-DD HH:mm');
console.log(formattedTime)
for(let i=0;i<this.friendsInfoList.length;i++){
if(this.friendsInfoList[i].name == this.chatWith && this.sendingMsg != ''){
this.friendsInfoList[i].chatHistory.push({name:this.userInfo.name,content:this.sendingMsg,time:formattedTime})
// console.log(this.friendsInfoList[i].chatHistory)
break
}
}
this.sendingMsg = ''
},
concernStatusRevise(data){
this.getFriendObject.concern_status = data
},
blackStatusRevise(data){
this.getFriendObject.black_status = data
},
historyContentHandle(content){
let char_sizeof = 0
let new_content = content
for(let i = 0;i<content.length;i++){
let charCode = new_content.charCodeAt(i)
if(charCode <= 128 && charCode >= 0 && content[i] != '\n'){
char_sizeof += 1
}else{
char_sizeof += 2
}
if (char_sizeof % 40 == 0){
new_content = new_content.slice(0,i) + '\n' + new_content.slice(i)
}
}
return new_content
},
getLatestNew(object){
let latest_new = object.chatHistory[object.chatHistory.length - 1].content
if(latest_new.length > 14){
latest_new= latest_new.slice(0,13) + '...'
}
return latest_new
},
},
watch:{
searchName(newvalue){
this.showSearchList = []
if(newvalue == ''){
this.showSearchList = this.friendsInfoList
}
else{
this.friendsInfoList.map((x) =>{
if(x.name.includes(newvalue)){
this.showSearchList.push(x)
}
})
}
}
},
computed:{
getFriendObject(){
let FriendObject = {}
if(this.chatWith != ''){
this.friendsInfoList.map((x) =>{
if(x.name == this.chatWith){
FriendObject = x
}
})
}
console.log(FriendObject)
return FriendObject
},
}
}
</script>
<style scoped>
.chat-totallayout{
display: flex;
flex-direction: row;
height: 85%;
width: 100%;
/* flex-grow: 0;
flex-shrink: 0; */
/* background-color: aqua; */
}
.chat-leftlayout{
/* background-color: azure; */
width: 25%;
height: 100%;
display: flex;
flex-direction: column;
}
.chat-middlelayout{
background: linear-gradient(to top, #fff9a1 65%, #fcdcd7);
width: 55%;
height: 100%;
display: flex;
flex-direction: column;
position: relative;
}
.chat-rightlayout{
/* background-color: red; */
position: relative;
width: 20%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
margin-top: 3%;
}
/**************整体布局***************/
/*************左边************** *****/
/* 第一行 */
.chat-leftline1{
display: flex;
/* background-color: antiquewhite; */
align-items: center;
margin-left: 30px;
}
.chat-leftlayout :nth-child(1){
flex-shrink: 0;
font-size: 30px;
font-weight: 600;
}
.chat-leftline1 :nth-child(2){
flex-shrink: 0;
font-size: 20px;
font-weight: 600;
color: rgb(61, 243, 243);
margin-left: 15px;
position: relative;
top: 2px;
}
/* 第二行 */
.chat-leftline2{
display: flex;
align-items: center;
}
#chatSearchImg{
height: 16px;
position: relative;
left: 23px;
top: -18px;
z-index: 1;
}
#chatSearchInput{
outline: none;
height: 30px;
width: 300px;
border: 2px solid #E44B9D;
border-radius: 8px;
padding-left: 30px;
position: relative;
top: -18px;
transition: all 0.5s;
}
#chatSearchInput:focus{
border-color: #fdadd8;
}
/* 第三行 */
.chat-leftline3{
display: flex;
flex-direction: column;
/* align-items: center; */
}
.chat-friends{
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid rgb(222, 222, 222);
/* background-color: #E44B9D; */
height: 70px;
width: 90%;
margin: 0 auto;
/* transition: all 0.2ss; */
}
.chat-friends:hover{
background-color: #fff2f9;
}
.chat-friends:active{
background-color: #fcb8dd;
}
.chat-friend-text{
position: relative;
width: 60%;
/* background-color: #E44B9D; */
flex-shrink: 0;
}
#chatIconImg{
height: 50px;
width: 50px;
}
/* .chat-friend-text{
background-color: aliceblue;
} */
#chatFriendName{
font-size: medium;
color: black;
line-height: 10px;
}
#chatFriendMsg{
font-size: small;
font-weight: 300;
color: gray;
/* line-height: 0px; */
}
#chatTime{
font-size: small;
font-weight: 300;
color: gray;
/* background-color: #fdadd8; */
}
/*****************中间****************** */
.send-msg{
align-self: center;
justify-self: flex-end;
display: flex;
position: absolute;
bottom: 5%;
width: 80%;
}
#send-msg-input{
outline: none;
border: 1px solid #E44B9D;
border-radius: 10px;
width: 90%;
margin: 5px;
}
.search-btn{
background-image: url("@/assets/pictures/chat/SendBtn.png");
background-size: 100% 100%;
width: 40px;
height: 40px;
border: none;
overflow: hidden;
border-radius: 10px;
}
.search-btn:active{
background-image: url("@/assets/pictures/chat/SendBtn.png");
background-size: 100% 100%;
width: 40px;
height: 40px;
border: none;
overflow: hidden;
border-radius: 10px;
background-color: #a75efb;
}
/*****************右边***************************/
.friend-information{
width: 75%;
display: flex;
justify-content: space-around;
color: gray;
position: relative;
top: 0%;
}
.friend-information p{
position: relative;
top: -31%;
}
.chat-special-btn{
display: flex;
justify-content: space-around;
width: 85%;
height: 20%;
}
.chat-home-tree-btn{
display: flex;
flex-direction: column;
justify-content: flex-end;
align-items: center;
}
.chat-home-page-btn{
background-color: #f85096;
background-image: url('../../assets/pictures/chat/portrait.png');
background-size: 60% 60%;
background-position: center center;
background-repeat: no-repeat;
height: 60px;width: 60px; border: none; border-radius: 50%;
}
.chat-tree-btn{
background-color: #a75efb;
background-image: url('../../assets/pictures/chat/tree.png');
background-size: 60% 60%;
background-position: center center;
background-repeat: no-repeat;
height: 60px;width: 60px; border: none; border-radius: 50%;
}
.chat-connection{
display: flex;
width: 62%;
justify-content: space-around;
}
.chat-recomend{
display: flex;
flex-direction: row;
justify-content: space-around;
width: 90%;
}
</style>

@ -0,0 +1,165 @@
<template>
<div class=communitybase>
<div class=leftinfo>
<div class=focus style="position: absolute; font-weight: bold; font-size: 18px; left:8%;top:1%">
你的关注
</div>
<div class=num style="position:absolute; font-size: 14px; right:20%; top:1.5%; color: #45D4CF;">
{{myfollows.weidu}}条新动态
</div>
<div class=followslist style="position:absolute;display: flex;flex-direction: column;top:7%;width:100%;gap:7%">
<div>
<div class= "alldongtai" style="display: flex; flex-direction: row;justify-content:center; position: relative; align-items: center;">
<el-icon color="#45D4CF" size="30px"> <Grid /></el-icon>
<div style="margin-left: 40px; font-weight: bold; font-size: 16px;">全部动态</div>
</div>
<hr style="width: 100%; height: 0.001px; background-color: #D8D8D8;margin-top: 3%;">
</div>
<div v-for="(follow, index) in myfollows.list" :key="index" style="margin-top: 8%;">
<div class="follows" style="display: flex; flex-direction: row; justify-content: center; align-items: center; position: relative;width: 100%;">
<img class="touxiang" src="../../assets/pictures/touxiang.png" style="width: 18%; height: auto;" />
<div style="margin-left: 40px; font-weight: bold; font-size: 16px;">{{ follow.name }}</div>
</div>
<hr style="width: 100%; height: 0.001px; background-color: #D8D8D8; margin-top: 5%;">
</div>
</div>
</div>
<div class=middle>
<div class="post-list">
<div
v-for="(post, index) in posts"
:key="index"
class="post-card"
>
<PostCard
:avatarUrl="post.avatarUrl"
:username="post.username"
:timestamp="post.timestamp"
:content="post.content"
:imageUrl="post.imageUrl"
:likeCount="post.likeCount"
:commentCount="post.commentCount"
:isCommentsVisible="post.isCommentsVisible"
:comments="post.comments"
@updateLikeCount="updateLikeCount(index, $event)"
@updateCommentCount="updateCommentCount(index, $event)"
@toggleCommentsVisibility="toggleCommentsVisibility(index)"
@addComment="addComment(index, $event)"
/>
</div>
</div>
</div>
<div class=rightheat style="display: flex;flex-direction:column;">
<div style="position:relative; top:1%; display: flex;flex-direction:row;justify-content:center;gap:15px">
<el-icon color="red" size="30px"><Odometer /></el-icon>
<div style="font-weight:550; font-size: 18px;">热门动态</div>
</div>
<div class= heatlist style="margin-top:20px;display: flex;flex-direction:row;">
<div style="position:relative; display: flex;flex-direction:column; color: white; font-weight: bold;margin-left: 20px ;gap:11px">
<div class=Hotsearchnum style="background-color:red;">1</div>
<div class=Hotsearchnum style="background-color:#FF7E38;">2</div>
<div class=Hotsearchnum style="background-color:#FFC74F;">3</div>
<div class=Hotsearchnum style="background-color:gray;">4</div>
<div class=Hotsearchnum style="background-color:gray;">5</div>
<div class=Hotsearchnum style="background-color:gray;">6</div>
<div class=Hotsearchnum style="background-color:gray;">7</div>
</div>
<div style=" font-size: 14px;font-weight:500;margin-left: 30px;display: flex;flex-direction:column;gap:17px">
<li style="list-style-type: none;" v-for="(item, index) in HotsearchList" :key="index">{{ item }}</li>
</div>
</div>
<div style="width: 100%; height: 1px; background: linear-gradient(to right, transparent, gray, transparent);margin-top: 20px"></div>
<div style="position:relative; top:1%; display: flex;flex-direction:row;justify-content:center;gap:15px">
<el-icon color="#FEB7D9" size="25px"><Notebook /></el-icon>
<div style="font-weight:550; font-size: 18px;">热门家族故事</div>
</div>
<div class="familystorelist" style="margin-top: 20px; display: flex; justify-content: center; flex-direction: column; gap: 10px;">
<div v-for="(story, index) in familystories" :key="index" class="familystore" style="width: 95%; height: 70px; background-color: rgba(255, 225, 240, 0.7); border-radius: 10%; position: relative;">
<img class="touxiang" src="../../assets/pictures/touxiang.png" />
<div class="familytitle">{{ story.title }}</div>
<div class="familycontent">{{ story.content }}</div>
</div>
</div>
</div>
</div>
</template>
<script>
import PostCard from '../../components/PostCard.vue';
export default {
name: 'CommunityIndex', //
components: { PostCard },
//
data() {
return {
isLiked: false,
HotsearchList: ["麦琳爱吃烧鸡","马思唯收官战","国足绝杀","再见爱人","杨子黄圣依","黄磊的豆角","邪恶栀子花计划"],
familystories: [
{ title: '我是怎么起家的', content: '我的父母来自于印度,后面通过自己的打拼...' },
{ title: '我的祖父', content: '我的祖父曾经参加过二战,有一次在诺曼底...' },
{ title: '我竟然是皇室成员!', content: '在我的18岁生日上妈妈告诉我祖母其实是...' },
],
myfollows:{weidu:7,list:[{name:'乔一鱼'},{name:'邓紫棋'},{name:'马思唯'},{name:'陶喆'}]},
posts: [
{
avatarUrl: 'https://via.placeholder.com/40',
username: '小明',
timestamp: '1小时前',
content: '今天的天气真好,适合出去玩!',
imageUrl: 'https://via.placeholder.com/400x200',
likeCount: 24,
commentCount: 6,
isCommentsVisible: false,
comments: [] //
},
{
avatarUrl: 'https://via.placeholder.com/40',
username: '小红',
timestamp: '2小时前',
content: '刚看完一场电影,真是太感人了!',
imageUrl: '',
likeCount: 36,
commentCount: 12,
isCommentsVisible: false,
comments: [] //
},
]
};
},
methods: {
updateLikeCount(index, newLikeCount) {
this.posts[index].likeCount = newLikeCount;
},
updateCommentCount(index, newCommentCount) {
this.posts[index].commentCount = newCommentCount;
},
toggleCommentsVisibility(index) {
this.posts[index].isCommentsVisible = !this.posts[index].isCommentsVisible;
},
addComment(index, commentText) {
this.posts[index].comments.push({
username: '匿名用户',
text: commentText
});
this.posts[index].commentCount += 1;
}
}
}
</script>
<style scoped>
@import url('../../assets/css/community/community.css');
</style>

@ -0,0 +1,286 @@
<template>
<div class="base">
<!-- 注册登录界面 -->
<div class="loginAndRegist">
<!--登录表单-->
<div class="loginArea">
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 标语 -->
<div v-show="isShow" class="title">
登录
</div>
</transition>
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 密码框和用户名框 -->
<div v-show="isShow" class="pwdArea">
<div style="flex: 1;justify-content: center;display: flex;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;
<el-input class="username" v-model="loginUser.name" style="width: 185px;" placeholder="请输入用户名"></el-input>
</div>
<div style="flex: 1;justify-content: center;display: flex;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;
<el-input placeholder="请输入密码" v-model="loginUser.password" style="width: 185px" show-password></el-input>
</div>
<div style="flex: 1;justify-content: center;display: flex;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;
<el-input placeholder="请输入验证码" v-model="loginUser.code" style="width: 125px" ></el-input>
<img src="../../assets/pictures/yanzheng.png" style="width: 60px" alt="假验证码" />
</div>
</div>
</transition>
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 登录注册按钮 -->
<div v-show="isShow" class="btnArea">
<el-button
type="success"
round
style="background-color: #E44B9D; letter-spacing: 5px; height: 40px; width: 100px; font-size: 14px;"
@click="UserLogin">
登录
</el-button>
</div>
</transition>
</div>
<!-- 注册表单 -->
<div class="registArea">
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 注册表头-->
<div v-show="!isShow" class="rigestTitle">
注册
</div>
</transition>
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 注册表单-->
<div v-show="!isShow" class="registForm">
<div style="flex: 1;display: flex;justify-content: center;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:
<el-input
placeholder="请输入用户名"
v-model="regUser.regUsername"
style="width: 165px;margin-left: 10px"
clearable
>
</el-input>
</div>
<div style="flex: 1;display: flex;justify-content: center;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:
<el-input placeholder="请输入密码" style="width: 165px;margin-left: 10px" v-model="regUser.regPwd" show-password></el-input>
</div>
<div style="flex: 1;display: flex;justify-content: center;align-items: center;">
&nbsp;&nbsp;&nbsp;:
<el-input placeholder="请再次输入密码" style="width: 165px;margin-left: 10px" v-model="regUser.regRePwd" show-password></el-input>
</div>
<div style="flex: 1;display: flex;align-items: center">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:
<el-input placeholder="请输入验证码" v-model="regUser.code" style="width: 105px;margin-left: 10px"></el-input>
<img src="../../assets/pictures/yanzheng.png" style="width: 60px;" alt="假验证码" />
</div>
</div>
</transition>
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 注册按钮-->
<div v-show="!isShow" class="registBtn">
<el-button type="success" round style="background-color: #E44B9D;letter-spacing: 5px ;height: 40px; width: 100px; font-size: 14px" @click="userRegister"></el-button>
</div>
</transition>
</div>
<!-- 信息展示界面 -->
<div id="aaa" class="showInfo"
:style="{
borderTopRightRadius:styleObj.bordertoprightradius,
borderBottomRightRadius:styleObj.borderbottomrightradius,
borderTopLeftRadius:styleObj.bordertopleftradius,
borderBottomLeftRadius:styleObj.borderbottomleftradius,
right:styleObj.rightDis
}"
ref="showInfoView">
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 没有用户输入用户名或者找不到用户名的时候 -->
<div v-show="isShow" style="display: flex;flex-direction: column;align-items: center;justify-content: center;width: 100%;height: 100%">
<!-- 欢迎语 -->
<div style="flex: 2;display: flex;align-items: center;font-size: 22px;color: #E44B9D;font-weight: bold">
欢迎你加入恋爱森林
</div>
<!-- 欢迎图片 -->
<div style="flex: 2">
<el-button type="success" style="background-color:#E44B9D;border: 1px solid #ffffff; height: 40px; width: 180px; font-size: 14px" round @click="changeToRegiest"></el-button>
</div>
</div>
</transition>
<!-- 用户输入用户名时展示头像以及姓名 -->
<!-- <div>-->
<!-- </div>-->
<transition
name="animate__animated animate__bounce"
enter-active-class="animate__fadeInUp"
leave-active-class="animate__zoomOut"
appear
>
<!-- 用户注册的时候展示信息 -->
<div v-show="!isShow" style="display: flex;flex-direction: column;align-items: center;justify-content: center;width: 100%;height: 100%">
<!-- 欢迎语 -->
<div style="flex: 2;display: flex;align-items: center;font-size: 22px;color: #E44B9D;font-weight: bold">
欢迎注册
</div>
<!-- 欢迎图片 -->
<div style="flex: 2">
<el-button type="success" style="background-color:#E44B9D;border: 1px solid #ffffff;height: 40px; width: 180px; font-size: 14px" round @click="changeToLogin"></el-button>
</div>
</div>
</transition>
</div>
</div>
</div>
</template>
<script>
// import 'animate.css';
// eslint-disable-next-line no-unused-vars
import {Axios as request} from "axios";
import axios from '@/utils/axiosConfig';
import {setToken} from '@/token/auth'
export default {
name:'loginIndex',
data(){
return{
//
loginUser:{
name:"",
password:"",
code:'',
},
admins:{},
////
regUser:{
regUsername:'',
regRePwd:'',
regPwd:'',
code:'',
},
styleObj:{
bordertoprightradius:'15px',
borderbottomrightradius: '15px',
bordertopleftradius:'0px',
borderbottomleftradius:'0px',
rightDis:'0px'
},
isShow:true
}
},
methods:{
changeToRegiest(){
this.styleObj.bordertoprightradius= '0px'
this.styleObj.borderbottomrightradius='0px'
this.styleObj.bordertopleftradius='15px'
this.styleObj.borderbottomleftradius='15px'
this.styleObj.rightDis='50%'
this.isShow = !this.isShow
},
changeToLogin(){
this.styleObj.bordertoprightradius= '15px'
this.styleObj.borderbottomrightradius='15px'
this.styleObj.bordertopleftradius='0px'
this.styleObj.borderbottomleftradius='0px'
this.styleObj.rightDis='0px'
this.isShow = !this.isShow
},
async UserLogin() {
this.$router.push('/main');
if(this.loginUser.code === 'Yj98') {
try {
const response = await axios.post('', null, {
params: {
username: this.loginUser.name,
password: this.loginUser.password
}
});
console.log('登录成功', response)
// tokendata
// !!!
const token = response.token;
// token
setToken(token);
// console.log( 'token' + getToken() )
//
this.$router.push('/main');
} catch (error) {
//
console.error('登录错误:', error);
}
}else{
alert("验证码错误")
}
},
async userRegister() {
if (this.regUser.regPwd !== this.regUser.regRePwd) {
alert('两次输入的密码不一致');
return;
}
if (this.regUser.code !== 'Yj98') {
alert('验证码错误')
}
try {
//
const response = await axios.post('', null, {
params:{
username: this.regUser.regUsername,
password: this.regUser.regPwd,
}
});
//
alert('注册成功');
console.log('注册成功', response);
} catch (error) {
//
console.error('注册失败', error);
}
}
},
}
</script>
<style scoped>
@import url('../../assets/css/login/login.css');
</style>

@ -0,0 +1,9 @@
<template>
智能推荐
</template>
<script>
export default {
name: 'RecommendIndex', //
//
}
</script>

Binary file not shown.

@ -0,0 +1,150 @@
<template>
<div class="background">
<div class="tree">
<TreeChart :json="treeData">
<template v-slot:node="{ node }">
<div class="node-info">
<img :src="node.image_url" alt="image" class="node-image" />
<div class="info">
<div class="name">{{ node.name }}</div>
<button @click="toggleNode(node)">
{{ node.expanded ? '隐藏下一代' : '显示下一代' }}
</button>
</div>
</div>
<div v-if="node.expanded" class="children">
<!-- 子节点展示 -->
<TreeChart :json="node.children" v-if="node.children && node.children.length"/>
</div>
</template>
</TreeChart>
</div>
</div>
</template>
<script>
import TreeChart from "vue-tree-chart-3";
export default {
components: {
TreeChart
},
data() {
return {
treeData: {
name: '爸爸',
image_url: require('@/assets/pictures/Inbase.png'),
expanded: true, //
children: [
{
name: 'children1',
image_url: "https://static.refined-x.com/avat1.jpg",
expanded: true,
},
{
name: 'children2',
image_url: "https://static.refined-x.com/avat2.jpg",
expanded: true,
mate: [{
name: 'mate',
image_url: "https://static.refined-x.com/avat3.jpg"
}],
children: [
{
name: 'grandchild',
image_url: "https://static.refined-x.com/avat.jpg"
},
{
name: 'grandchild2',
image_url: "https://static.refined-x.com/avat1.jpg",
expanded: true,
children:[
{
name:'dd',
image_url: "https://static.refined-x.com/avat1.jpg",
}
]
},
{
name: 'grandchild3',
image_url: "https://static.refined-x.com/avat2.jpg"
},
{
name:'hh',
image_url: "https://static.refined-x.com/avat2.jpg"
}
]
},
{
name: 'children3',
image_url: "https://static.refined-x.com/avat.jpg"
}
]
}
};
},
methods: {
toggleNode(node) {
node.expanded = !node.expanded; // /
}
}
};
</script>
<style scoped>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.background {
display: flex;
align-content: center;
justify-content: center;
background-image: url("../../assets/pictures/Inbase3.png");
background-size: cover;
background-position: center top;
background-repeat: no-repeat;
height: 100vh;
width: 100%;
}
.tree {
display: flex;
position: absolute;
background: rgba(255, 255, 255, 0.8);
width: 1100px;
height: 700px;
border-radius: 30px;
margin-top: 30px;
margin-left: 240px;
padding-top: 100px;
justify-content: center;
align-items: center;
flex-shrink: 0;
}
.node-info {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.node-image {
width: 40px;
height: 40px;
border-radius: 50%;
margin-bottom: 10px;
}
.info {
font-size: 14px;
}
.children {
margin-top: 20px;
padding-left: 20px;
display: flex;
flex-direction: column;
}
</style>

@ -0,0 +1,216 @@
<template>
<div>
<!-- 个人资料 -->
<div class="base">
<div class="profile">
<h2>编辑简介</h2>
<div class="profile-content">
<!-- 头像 -->
<div class="avatar-container">
<img :src="user.avatar || defaultAvatar" alt="Avatar" class="avatar">
<!-- 编辑头像 -->
<label for="avatar-upload" class="edit-icon">
<input type="file" id="avatar-upload" @change="uploadImage" hidden>
</label>
</div>
<!-- 个人信息 -->
<div class="info">
<div class="column">
<label>账号</label>
<input type="text" v-model="user.account">
<label>邮箱</label>
<input type="email" v-model="user.email">
<label>生日</label>
<input type="date" v-model="user.birthday">
<label>职业</label>
<input type="text" v-model="user.job">
</div>
<div class="column">
<label>姓名</label>
<input type="text" v-model="user.name">
<label>密码</label>
<input type="password" v-model="user.password">
<label>居住地</label>
<input type="text" v-model="user.location">
<label>个人签名</label>
<input type="text" v-model="user.signature">
<!-- 保存按钮 -->
<button @click="saveProfile"></button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
user: {
avatar: '',
account: 'Charlene Reed',
email: 'charlenereed@gmail.com',
birthday: '1990-01-25',
job: 'San Jose, California, USA',
name: 'Charlene Reed',
password: '',
location: 'San Jose, California, USA',
signature: 'gali建帅 马思唯最好',
},
defaultAvatar: 'https://via.placeholder.com/150', //
};
},
methods: {
//
uploadImage(event) {
const file = event.target.files[0];
if (file) {
this.user.avatar = URL.createObjectURL(file);
}
},
//
async saveProfile() {
try {
//
const response = await axios.post('',null, {
params:{
avatar: this.user.avatar,
account: this.user.account,
email: this.user.email,
birthday: this.user.birthday,
job: this.user.job,
name: this.user.name,
password: this.user.password,
location: this.user.location,
signature: this.user.signature,
}
});
if (response.data.success) {
alert('个人信息已保存!');
} else {
alert('保存失败,请重试!');
}
} catch (error) {
console.error('保存时出错:', error);
alert('保存失败,请检查网络或稍后重试!');
}
},
},
};
</script>
<style scoped>
/* 个人资料 */
.base{
display: flex;
background-image: url("../../assets/pictures/Inbase.png");
background-size: 100%;
justify-content: center;
align-content: center;
height: 100vh;
padding:12px 200px;
}
.profile {
display: flex;
flex-direction: column;
background-color:rgba(255,255,255,0.8);
height: 600px;
width:930px;
border-radius: 50px;
margin: 20px;
}
.profile h2 {
position: relative;
display: inline-block;
margin-left: 48px;
margin-top: 32px;
font-size: 24px;
color: #FE4E96;
padding-bottom: 12px;
border-bottom:#F4F5F7 2px solid;
}
.profile h2::before{
content: '';
position: absolute;
bottom: 0;
left: -12px;
width: 124px;
border-bottom: #FEB2D7 4px solid;
}
.profile-content {
display: flex;
gap: 20px;
}
.avatar-container {
position: relative;
display: inline-block;
width: 140px;
height: 140px;
}
.avatar {
width: 100%;
height: 100%;
border-radius: 50%;
margin-left: 20px;
object-fit: cover;
background-color: #d3d3d3;
border: 2px solid #ccc;
}
.avatar-container input[type="file"]{
display: none;
}
.edit-icon {
position: absolute;
bottom: 0;
right: 0;
background-color: pink;
border-radius: 50%;
padding: 5px;
cursor: pointer;
}
.info {
display: flex;
margin-left: 70px;
gap: 20px;
}
.column {
display: flex;
flex-direction: column;
width: 256px;
gap: 20px;
padding-right: 80px;
}
.column input{
width: 116%;
height: 28px;
padding: 8px;
border-radius: 50px;
border: 1px solid #DFEAF2;
}
.column label {
display: block; /* 使标签独占一行 */
margin-bottom: -4px; /* 增加标签和输入框之间的间距 */
font-size: 14px; /* 可以调整字体大小 */
}
button {
display: flex;
flex-direction: row;
justify-content: center;
height: 40px;
width: 150px;
padding-top: 12px;
margin-left: 150px;
margin-top: 16px;
background-color:#F177A8;
color: #fff;
border: none;
border-radius: 50px;
cursor: pointer;
}
</style>

@ -0,0 +1,9 @@
<template>
个人空间
</template>
<script>
export default {
name: 'spaceIndex', //
//
}
</script>

@ -0,0 +1,637 @@
<template>
<div class="container">
<div class="content">
<div class="profile-card">
<!-- 头像 -->
<div class="avatar-section">
<div class="avatar-container">
<img :src="user.avatar || defaultAvatar" alt="Avatar" class="avatar">
<!-- 更多信息按钮 -->
<button @click="showMoreInfo" class="showMoreInfo-btn">
<img src="../../assets/pictures/more.png" alt="">
</button>
<!-- 族谱树按钮 -->
<button @click="showFamilyTree" class="showFamilytree-btn">
<img src="../../assets/pictures/tree.png" alt="">
</button>
</div>
</div>
<!-- 基本信息 -->
<div class="user-info">
<h2>{{ userInfo.name || "加载中..." }}</h2>
<div class="info-container">
<p>
<img src="../../assets/pictures/map.png" style="width: 19px;">
{{ userInfo.location || "加载中..." }}
</p>
<p>
<img src="../../assets/pictures/calendar.png" style="width: 17px;">
{{ userInfo.joinedDate || "加载中..." }}
</p>
</div>
</div>
<!-- 兴趣爱好 / 择偶期望 / 职业 -->
<div class="interests">
<p>
<img src="../../assets/pictures/interest.png" alt="">
<span class="in-text">
<span class="title">兴趣爱好:</span>
<span class="text-content" id="interest">{{ userInfo.interests || "加载中..." }}</span>
</span>
</p>
<p>
<img src="../../assets/pictures/double.png" alt="">
<span class="in-text">
<span class="title">择偶期望:</span>
<span class="text-content" id="expectation">{{ userInfo.expectation || "加载中..." }}</span>
</span>
</p>
<p>
<img src="../../assets/pictures/career.png" alt="">
<span class="in-text">
<span class="title">职业:</span>
<span class="text-content" id="career">{{ userInfo.career || "加载中..." }}</span>
</span>
</p>
</div>
<!-- 操作按钮 -->
<div class="actions">
<button @click="editProfile"></button>
<button @click="privateChat"></button>
</div>
</div>
<div class="post-container">
<div class="heade">
<div class="left-header">
<span :class="{ 'active': selectedTab === 'all' }" @click="selectedTab = 'all'">全部</span>
<hr v-if="selectedTab === 'all'" />
</div>
<div class="right-header">家族故事</div>
</div>
<div class="post">
<div class="post-header">
<img src="../../assets/pictures/post1.png" alt="" />
<div class="post-info">
<h3>Devon Lane @johndue · 23s</h3>
<p>Tom is in a big hurry.</p>
</div>
</div>
<div class="post-img">
<img src="../../assets/pictures/post2.png" alt="" />
</div>
<div class="post-footer">
<div class="reactions">
<!-- 爱心图标用于点赞 -->
<div class="Like">
<span @click="increaseCount('like')" :class="{'liked': isLiked}">
<span v-if="isLiked"></span>
<span v-else>🤍</span>
</span>
{{ likeCount }}
</div>
<!-- 评论图标 -->
<div class="comment">
<span @click="increaseCount('comment')">
💬
</span>
{{ commentCount }}
</div>
</div>
<div class="comment-section">
<img src="../../assets/pictures/post1.png" alt="">
<input type="text" placeholder="Tweet your answer" />
<button class="answer-btn">Answer</button>
</div>
<div class="comments">
<div class="comment-item">
<img src="../../assets/pictures/post1.png" alt="Angela Arden's Profile Picture" />
<div class="comment-content">
<h4>Angela Arden @angela_arden</h4>
<p>Concordo...</p>
<div class="comment-actions">
<span class="comment">
<img src="../../assets/pictures/Vector.png" style="width: 16px;">
<span class="comment-count">2</span>
</span>
<span class="clockwise">
<img src="../../assets/pictures/ArrowsClockwise.png" style="width: 16px;">
<span class="clockwise-count">1</span>
</span>
<span class="like">
<img src="../../assets/pictures/Heart.png" style="width: 16px;">
<span class="like-count">3</span>
</span>
</div>
</div>
</div>
<div class="comment-item">
<img src="../../assets/pictures/post1.png" alt="Julia Stone's Profile Picture" />
<div class="comment-content">
<h4>Julia Stone @julia</h4>
<p>Olha, faz sentido!</p>
<div class="comment-actions">
<span class="comment">
<img src="../../assets/pictures/Vector.png" style="width: 16px;">
<span class="comment-count">2</span>
</span>
<span class="clockwise">
<img src="../../assets/pictures/ArrowsClockwise.png" style="width: 16px;">
<span class="clockwise-count">1</span>
</span>
<span class="like">
<img src="../../assets/pictures/Heart.png" style="width: 16px;">
<span class="like-count">3</span>
</span>
</div>
</div>
</div>
<div class="comment-item">
<img src="../../assets/pictures/post1.png" alt="Joey Tribiani's Profile Picture" />
<div class="comment-content">
<h4>Joey Tribiani @joey</h4>
<p>Parabéns pelo progresso!</p>
<div class="comment-actions">
<span class="comment">
<img src="../../assets/pictures/Vector.png" style="width: 16px;">
<span class="comment-count">2</span>
</span>
<span class="clockwise">
<img src="../../assets/pictures/ArrowsClockwise.png" style="width: 16px;">
<span class="clockwise-count">1</span>
</span>
<span class="like">
<img src="../../assets/pictures/Heart.png" style="width: 16px;">
<span class="like-count">3</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
likeCount: 0,
isLiked:false,
commentCount:0,
user: {
avatar: "", // URL
},
userInfo: {
name: "", //
location: "", //
joinedDate: "", //
interests: "", //
expectation: "", //
career: "", //
},
defaultAvatar: "https://via.placeholder.com/150", //
};
},
methods: {
increaseCount(type){
if(type === 'like'){
if(this.isLiked){
this.likeCount--;
}else{
this.likeCount++;
}
this.isLiked=!this.isLiked;
}else if(type === 'comment'){
this.commentCount++;
}
},
async fetchUserInfo() {
try {
//
const response = await axios.get("/api/getUserInfo", {
params: {
userId: "12345", // ID
},
});
//
// {
// avatar: "https://example.com/avatar.jpg",
// name: "John Doe",
// location: "San Jose, California",
// joinedDate: "2021-01-01",
// interests: ", , ",
// expectation: "",
// career: ""
// }
//
this.user.avatar = response.data.avatar;
this.userInfo.name = response.data.name;
this.userInfo.location = response.data.location;
this.userInfo.joinedDate = response.data.joinedDate;
this.userInfo.interests = response.data.interests;
this.userInfo.expectation = response.data.expectation;
this.userInfo.career = response.data.career;
} catch (error) {
console.error("获取用户信息失败:", error);
alert("无法加载用户信息,请稍后重试!");
}
},
selectTab(tab) {
this.selectedTab = tab;
},
showMoreInfo() {
},
showFamilyTree() {
this.$router.push('/main/familyTree');
},
editProfile() {
this.$router.push('/main/informationPage'); // 使
},
privateChat() {
// Navigate to private chat page
}
},
mounted() {
//
this.fetchUserInfo();
},
};
</script>
<style scoped>
.content {
display: flex;
justify-content: space-between;
background-image: url("../../assets/pictures/Inbase2.png");
background-size: 100%;
height: 100vh;
padding: 20px;
}
.profile-card {
background-color: #FFFFFF;
padding: 20px;
border-radius: 30px;
margin-top: 70px;
margin-left: 40px;
width: 410px;
height: 540px;
border-top: 10px solid #9EAFFD;
position: relative; /* 为伪元素定位 */
}
.profile-card::before {
content: '';
position: absolute;
top: -10px; /* 使蓝色区域位于框外 */
left: 0;
right: 0;
height: 20px; /* 蓝色区域的高度 */
border-top-left-radius: 30px; /* 圆角与卡片的左上角对齐 */
border-top-right-radius: 30px; /* 圆角与卡片的右上角对齐 */
overflow: hidden;
}
.avatar-section {
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.avatar-container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.avatar {
margin-bottom: 20px;
width: 138px;
height: 138px;
border-radius: 50%;
}
.showMoreInfo-btn,
.showFamilytree-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 80px;
height: 80px;
border-radius: 50%; /* 圆形按钮 */
border: none;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); /* 添加阴影效果 */
}
.showMoreInfo-btn {
left: -130px; /* 在头像左侧 */
top: 110px;
}
.showFamilytree-btn {
right: -130px; /* 在头像右侧 */
top: 110px;
}
.user-info {
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
}
.user-info h2{
font-size: 21px;
margin-top: 8px;
font-weight: normal;
font-style: Italic;
white-space: nowrap; /* 防止文本换行 */
}
.info-container {
display: flex;
justify-content: center;
margin-top: -55px;
gap: 5px;
}
.user-info p{
margin-top: 40px;
display: flex;
flex-direction: row;
justify-content: center;
font-size: 14px;
white-space: nowrap;
}
.interests p{
display: flex;
flex-direction: row;
align-content: center;
margin-top: 4px;
}
.interests p img{
width: 44px;
height: 44px;
margin-top: 6px;
margin-left: 8px;
}
.interests p .in-text{
display: flex;
flex-direction: column;
gap: 10px;
}
.interests p .title{
margin-left: 12px;
margin-top: 10px;
font-size: 18px;
font-weight: bold;
white-space: nowrap;
}
.interests p .text-content{
font-size: 14px;
margin-left: 10px;
}
.actions button {
color:white;
font-size: 18px;
background-color: #f077a8;
padding: 10px 20px;
margin-left: 55px;
margin-right: 40px;
margin-top: 30px;
border: none;
border-radius: 30px;
width: 100px;
cursor: pointer;
}
.post-container {
font-family: Arial, sans-serif;
display: flex;
/* align-items: center; */
background: rgba(255, 255, 255, 0.8);
height: 620px;
margin: 30px auto;
border-radius: 30px;
width: 750px;
padding: 20px;
}
.heade{
display: flex;
justify-content: space-between;
align-content: center;
padding-left: 180px;
white-space: nowrap;
}
.left-header span {
cursor: pointer;
}
.left-header .active {
color: #1DA1F2;
}
.left-header hr {
border-color:#1DA1F2;
width: 100px;
margin-left: -32px;
margin-top: 5px;
}
.right-header {
padding-left: 280px;
}
.post {
margin-left: -600px;
margin-top: 200px;
border-radius: 10px;
margin-bottom: 20px;
}
.post-header {
display: flex;
margin-top:-160px;
margin-left: 30px;
padding: 10px;
position: relative;
}
.post-header img {
width: 56px;
height: 56px;
border-radius: 50%;
}
.post-info h3 {
margin-top:6px;
padding-left: 20px;
font-size: 14px;
font-weight: normal;
font-family: Italic;
font-style: ABeeZee;
white-space: nowrap;
}
.post-info p {
margin: 0;
font-size: 18px;
white-space: nowrap;
margin-left: 80px;
}
.post-img {
display: flex;
left: 220px;
width: 329px;
height: 163px;
position: relative;
}
.post-footer {
padding: 10px;
}
/* 图标的样式 */
.reactions span {
font-size: 24px;
cursor: pointer;
margin: 0 2px;
display: inline-block;
transition: transform 0.3s;
}
/* 点赞图标选中时的样式 */
.liked {
color: red; /* 红色表示已点赞 */
transform: scale(1.2); /* 点击时稍微放大 */
}
/* 图标悬停时的效果 */
.reactions span:hover {
transform: scale(1.1); /* 悬停时稍微放大 */
}
/* 增加点赞和评论数值的可读性 */
.reactions {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 20px;
padding: 0 10px;
}
.comment{
display: flex;
align-items: center;
margin-right: 70px;
}
.Like{
margin-left: 170px;
}
/* .reactions span img {
padding-left: 230px;
padding-top: 10px;
} */
.reactions .count {
font-size: 21px;
color: #666;
padding-left: 8px;
}
.comment-section {
display: flex;
align-items: center;
margin-bottom: 10px;
padding-left: 120px;
/* border-bottom: 1px solid #ccc; */
}
.comment-section img {
width: 46px;
padding-bottom: 10px;
padding-top: 10px;
}
.comment-section input {
flex: 1;
height: 40px;
width: 380px;
border-radius: 5px;
border: none;
font-size: 16px;
padding-left: 14px;
}
.answer-btn {
background-color: #f077a8;
color: white;
border: none;
border-radius: 50px;
padding: 5px 10px;
margin-right: -80px;
font-size: 15px;
cursor: pointer;
}
.comments {
padding-left: 120px;
max-height: 220px;
width: 550px;
overflow: auto;
}
.comment-item {
display: flex;
align-items: center;
border-top: 1px solid #ccc;
}
.comment-item img {
width: 46px;
border-radius: 50%;
margin-right: 10px;
padding-bottom: 10px;
}
.comment-content h4 {
margin: 0;
padding-top: 10px;
padding-bottom: 6px;
font-size: 12px;
}
.comment-content p {
margin: 0;
font-size: 12px;
color: #666;
}
.comment-actions {
display: flex;
justify-content: space-between;
align-content: center;
font-size: 12px;
color: #666;
}
.comment-actions span {
display: flex;
align-content: center;
padding-top: 10px;
padding-left: 5px;
}
.comment-actions span span{
padding-top: 2px;
}
</style>

@ -0,0 +1,22 @@
<template>
<div>
<!-- 使用组件 -->
<Header></Header>
</div>
</template>
<script>
//
import Header from '@/components/header.vue';
export default {
components: {
//
Header
}
};
</script>
<style scoped>
</style>

@ -0,0 +1,4 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true
})
Loading…
Cancel
Save