Merge branch 'main' of http://sl.vrgon.com:3000/JiXinHui/YingXingAI
|
@ -0,0 +1,94 @@
|
||||||
|
<template>
|
||||||
|
<div class="page-header">
|
||||||
|
<u-navbar
|
||||||
|
:title="title"
|
||||||
|
:is-back="isBack"
|
||||||
|
:back-text="backText"
|
||||||
|
:border-bottom="borderBottom"
|
||||||
|
:background="background"
|
||||||
|
:title-color="titleColor"
|
||||||
|
:title-size="titleSize"
|
||||||
|
:title-bold="titleBold"
|
||||||
|
:z-index="zIndex"
|
||||||
|
@leftClick="onBackClick"
|
||||||
|
>
|
||||||
|
<template v-slot:right>
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</template>
|
||||||
|
<slot></slot>
|
||||||
|
</u-navbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'PageHeader',
|
||||||
|
props: {
|
||||||
|
// 页面标题
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示返回按钮
|
||||||
|
isBack: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 返回按钮文字
|
||||||
|
backText: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 是否显示底部边框
|
||||||
|
borderBottom: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// 导航栏背景
|
||||||
|
background: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
background: '#ffffff'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 标题颜色
|
||||||
|
titleColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#191919'
|
||||||
|
},
|
||||||
|
// 标题字体大小
|
||||||
|
titleSize: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 34
|
||||||
|
},
|
||||||
|
// 标题是否加粗
|
||||||
|
titleBold: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
// z-index 层级
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 980
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 处理返回按钮点击
|
||||||
|
onBackClick() {
|
||||||
|
this.$emit('back');
|
||||||
|
},
|
||||||
|
// 处理选项卡切换
|
||||||
|
switchTab(tabValue) {
|
||||||
|
this.$emit('tab-change', tabValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.page-header {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,110 @@
|
||||||
|
<template>
|
||||||
|
<u-tabbar
|
||||||
|
:value="currentIndex"
|
||||||
|
:show="true"
|
||||||
|
:bg-color="'#fff'"
|
||||||
|
:border-top="false"
|
||||||
|
:fixed="true"
|
||||||
|
:height="148"
|
||||||
|
:list="formattedTabList"
|
||||||
|
@change="switchTab"
|
||||||
|
>
|
||||||
|
</u-tabbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "TabBar",
|
||||||
|
props: {
|
||||||
|
currentPath: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentIndex: 0,
|
||||||
|
tabList: [
|
||||||
|
{
|
||||||
|
text: "会话列表",
|
||||||
|
iconText: "📋",
|
||||||
|
useImg: true,
|
||||||
|
icon: "/static/tabbar/tabbar-icon1.png",
|
||||||
|
activeIcon: "/static/tabbar/tabbar-icon1.png",
|
||||||
|
pagePath: "/pages/home/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "留言板",
|
||||||
|
iconText: "📊",
|
||||||
|
useImg: true,
|
||||||
|
icon: "/static/tabbar/tabbar-icon2.png",
|
||||||
|
activeIcon: "/static/tabbar/tabbar-icon2.png",
|
||||||
|
pagePath: "/pages/notes/index",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: "我的",
|
||||||
|
iconText: "👤",
|
||||||
|
useImg: true,
|
||||||
|
icon: "/static/tabbar/tabbar-icon3.png",
|
||||||
|
activeIcon: "/static/tabbar/tabbar-icon3.png",
|
||||||
|
pagePath: "/pages/my/index",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 格式化tabList为uview的u-tabbar所需格式
|
||||||
|
formattedTabList() {
|
||||||
|
return this.tabList.map((item) => {
|
||||||
|
return {
|
||||||
|
text: item.text,
|
||||||
|
iconPath: item.icon,
|
||||||
|
selectedIconPath: item.activeIcon,
|
||||||
|
pagePath: item.pagePath,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 根据当前路径设置激活的tab
|
||||||
|
this.setActiveTab();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setActiveTab() {
|
||||||
|
const currentPath = this.currentPath || this.getCurrentPath();
|
||||||
|
this.tabList.forEach((item, index) => {
|
||||||
|
if (currentPath.includes(item.pagePath)) {
|
||||||
|
this.currentIndex = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getCurrentPath() {
|
||||||
|
// 获取当前页面路径
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
if (pages.length > 0) {
|
||||||
|
const currentPage = pages[pages.length - 1];
|
||||||
|
return "/" + currentPage.route;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
},
|
||||||
|
switchTab(index) {
|
||||||
|
if (this.currentIndex === index) return;
|
||||||
|
|
||||||
|
this.currentIndex = index;
|
||||||
|
this.$emit("change", this.tabList[index].pagePath, index);
|
||||||
|
|
||||||
|
// 跳转到对应页面
|
||||||
|
uni.switchTab({
|
||||||
|
url: this.tabList[index].pagePath,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* /deep/.u-icon__img {
|
||||||
|
width: 54rpx !important;
|
||||||
|
height: 54rpx !important;
|
||||||
|
} */
|
||||||
|
</style>
|
51
pages.json
|
@ -13,10 +13,23 @@
|
||||||
},
|
},
|
||||||
"pages": [
|
"pages": [
|
||||||
{
|
{
|
||||||
"path": "pages/home/index/index",
|
"path": "pages/home/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "首页",
|
"navigationBarTitleText": "会话列表",
|
||||||
"enablePullDownRefresh": false,
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/notes/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "留言板",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/my/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -176,8 +189,34 @@
|
||||||
"subPackages": [],
|
"subPackages": [],
|
||||||
"globalStyle": {
|
"globalStyle": {
|
||||||
"navigationBarTextStyle": "black",
|
"navigationBarTextStyle": "black",
|
||||||
"navigationBarTitleText": "应行AI",
|
"navigationBarTitleText": "英星AI",
|
||||||
"navigationBarBackgroundColor": "#FFFFFF",
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
"backgroundColor": "#FFFFFF"
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#999999",
|
||||||
|
"selectedColor": "#4a6cf7",
|
||||||
|
"borderStyle": "black",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/home/index",
|
||||||
|
"iconPath": "static/tabbar/icon_home.png",
|
||||||
|
"selectedIconPath": "static/tabbar/icon_home_active.png",
|
||||||
|
"text": "会话列表"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/notes/index",
|
||||||
|
"iconPath": "static/tabbar/icon_message.png",
|
||||||
|
"selectedIconPath": "static/tabbar/icon_message_active.png",
|
||||||
|
"text": "留言板"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/my/index",
|
||||||
|
"iconPath": "static/tabbar/icon_my.png",
|
||||||
|
"selectedIconPath": "static/tabbar/icon_my_active.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<template>
|
||||||
|
<div class="home-page">
|
||||||
|
<!-- 使用PageHeader组件 -->
|
||||||
|
<PageHeader
|
||||||
|
title="会话列表"
|
||||||
|
:is-back="false"
|
||||||
|
:border-bottom="true"
|
||||||
|
:background="headerBackground"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<!-- 这里是会话列表内容 -->
|
||||||
|
<div class="placeholder">会话列表内容区域</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 使用TabBar组件 -->
|
||||||
|
<TabBar :currentPath="'/pages/home/index'" @change="handleTabChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TabBar from '@/components/TabBar.vue';
|
||||||
|
import PageHeader from '@/components/PageHeader.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'HomePage',
|
||||||
|
components: {
|
||||||
|
TabBar,
|
||||||
|
PageHeader
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
headerBackground: {
|
||||||
|
background: 'linear-gradient(to right, #e0eafc, #cfdef3)'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleTabChange(path, index) {
|
||||||
|
console.log('切换到标签页:', path, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.home-page {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f6fa;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 15px;
|
||||||
|
padding-bottom: 60px; /* 为底部导航栏预留空间 */
|
||||||
|
overflow: hidden; /* 防止滚动条出现 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,249 @@
|
||||||
|
<template>
|
||||||
|
<div class="my-page">
|
||||||
|
<PageHeader
|
||||||
|
title="我的"
|
||||||
|
:is-back="false"
|
||||||
|
:border-bottom="false"
|
||||||
|
:background="headerBackground"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<div class="user-info">
|
||||||
|
<div class="avatar">
|
||||||
|
<!-- <img src="" alt="用户头像" /> -->
|
||||||
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<div class="name">孙老师</div>
|
||||||
|
<div class="tag">
|
||||||
|
<image
|
||||||
|
class="tag-icon"
|
||||||
|
src="@/static/notes/collage-icon.png"
|
||||||
|
></image>
|
||||||
|
江西师范学科技职业学院
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
<image class="tag-icon" src="@/static/notes/major-icon.png"></image>
|
||||||
|
生命科学与工程学院 工业工程专业
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="statistics">
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-num">36</div>
|
||||||
|
<div class="stat-label">总答题</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-num">10</div>
|
||||||
|
<div class="stat-label">已完成</div>
|
||||||
|
</div>
|
||||||
|
<div class="stat-item">
|
||||||
|
<div class="stat-num">26</div>
|
||||||
|
<div class="stat-label">未回复</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="banner">
|
||||||
|
<img src="@/static/notes/banner.png" alt="banner" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="menu-list">
|
||||||
|
<div class="menu-item" @click="navigateTo('personal-info')">
|
||||||
|
<div class="menu-icon">
|
||||||
|
<image src="@/static/notes/menu1.png" class="menu-icon-img"></image>
|
||||||
|
</div>
|
||||||
|
<div class="menu-text">个人信息</div>
|
||||||
|
<view class="arrow-icon">
|
||||||
|
<u-icon name="arrow-right" color="#999" size="24"></u-icon>
|
||||||
|
</view>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item" @click="navigateTo('change-password')">
|
||||||
|
<div class="menu-icon">
|
||||||
|
<image src="@/static/notes/menu2.png" class="menu-icon-img"></image>
|
||||||
|
</div>
|
||||||
|
<div class="menu-text">修改密码</div>
|
||||||
|
<view class="arrow-icon">
|
||||||
|
<u-icon name="arrow-right" color="#999" size="24"></u-icon>
|
||||||
|
</view>
|
||||||
|
</div>
|
||||||
|
<div class="menu-item" @click="navigateTo('logout-records')">
|
||||||
|
<div class="menu-icon">
|
||||||
|
<image src="@/static/notes/menu3.png" class="menu-icon-img"></image>
|
||||||
|
</div>
|
||||||
|
<div class="menu-text">退出登录</div>
|
||||||
|
<view class="arrow-icon">
|
||||||
|
<u-icon name="arrow-right" color="#999" size="24"></u-icon>
|
||||||
|
</view>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<TabBar :currentPath="'/pages/my/index'" @change="handleTabChange" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TabBar from "@/components/TabBar.vue";
|
||||||
|
import PageHeader from "@/components/PageHeader.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MyPage",
|
||||||
|
components: {
|
||||||
|
TabBar,
|
||||||
|
PageHeader,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
headerBackground: {
|
||||||
|
background: "transparent",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
navigateTo(route) {
|
||||||
|
// 导航到指定路由
|
||||||
|
console.log("导航到:", route);
|
||||||
|
},
|
||||||
|
handleTabChange(path, index) {
|
||||||
|
console.log("切换到标签页:", path, index);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.my-page {
|
||||||
|
height: 100vh;
|
||||||
|
/* background-color: #f5f6fa; */
|
||||||
|
background-image: url("@/static/notes/bg.png");
|
||||||
|
background-position: center top;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 100% auto; /* 以宽度为基准等比例缩放 */
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 60px; /* 为底部导航栏预留空间 */
|
||||||
|
overflow: hidden; /* 防止滚动条出现 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 148rpx;
|
||||||
|
height: 148rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info .name {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-icon {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
font-size: 10px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 26rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistics {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
/* margin-top: 5px;
|
||||||
|
padding: 15px 0; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0 26rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-num {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 40rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner {
|
||||||
|
padding: 0 26rpx 0 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner img {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 8px;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 54rpx 30rpx 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow-icon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon-img {
|
||||||
|
width: 28rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,449 @@
|
||||||
|
<template>
|
||||||
|
<div class="notes-page">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">留言板</div>
|
||||||
|
<!-- 顶部切换标签 -->
|
||||||
|
<div class="tab-header">
|
||||||
|
<div
|
||||||
|
class="tab-item"
|
||||||
|
:class="{ active: activeTab === 'unread' }"
|
||||||
|
@click="switchTab('unread')"
|
||||||
|
>
|
||||||
|
未回复
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="tab-item"
|
||||||
|
:class="{ active: activeTab === 'replied' }"
|
||||||
|
@click="switchTab('replied')"
|
||||||
|
>
|
||||||
|
已回复
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 内容区域包装器 -->
|
||||||
|
<div class="content-wrapper">
|
||||||
|
<!-- 留言列表 -->
|
||||||
|
<scroll-view class="message-list" scroll-y>
|
||||||
|
<view v-for="(item, index) in currentMessages" :key="index">
|
||||||
|
<u-swipe-action
|
||||||
|
:options="swipeOptions"
|
||||||
|
:show="item.show"
|
||||||
|
:index="index"
|
||||||
|
@click="handleSwipeClick"
|
||||||
|
@open="e => handleSwipeOpen(e, index)"
|
||||||
|
@close="e => handleSwipeClose(e, index)"
|
||||||
|
@content-click="() => closeOther(index)"
|
||||||
|
:btn-width="80"
|
||||||
|
:disabled="false"
|
||||||
|
>
|
||||||
|
<view class="message-item">
|
||||||
|
<view class="message-header">
|
||||||
|
<view class="user-info">
|
||||||
|
<image class="avatar" :src="item.avatar || defaultAvatar"></image>
|
||||||
|
<text class="username">{{item.username}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="message-time">{{item.time}}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="message-content">
|
||||||
|
<view class="question">
|
||||||
|
<view class="question-icon">问</view>
|
||||||
|
<view class="question-text">{{item.question}}</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="reply-button" @click.stop="handleReply(item)" v-if="!item.reply">
|
||||||
|
<u-icon name="chat" color="#4a6cf7" size="16"></u-icon>
|
||||||
|
<text>回复</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="reply-content" v-if="item.reply">
|
||||||
|
<view class="reply-header">
|
||||||
|
<view class="reply-icon">答</view>
|
||||||
|
<view class="reply-info">
|
||||||
|
<text>{{item.replyUser}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="reply-text" :class="{'expanded': item.expanded}">{{item.reply}}</view>
|
||||||
|
<view class="expand-button" v-if="item.reply.length > 100" @click.stop="toggleExpand(item)">
|
||||||
|
{{ item.expanded ? '收起' : '展开' }} <u-icon :name="item.expanded ? 'arrow-up' : 'arrow-down'" size="12"></u-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="reply-button" @click.stop="handleReply(item)" v-if="item.reply">
|
||||||
|
<u-icon name="chat" color="#4a6cf7" size="16"></u-icon>
|
||||||
|
<text>回复</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</u-swipe-action>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 无数据提示 -->
|
||||||
|
<view class="empty-tip" v-if="currentMessages.length === 0">
|
||||||
|
暂无留言数据
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 使用TabBar组件 -->
|
||||||
|
<TabBar :currentPath="'/pages/notes/index'" @change="handleTabChange" />
|
||||||
|
|
||||||
|
<!-- 开发中提示弹窗 -->
|
||||||
|
<u-modal
|
||||||
|
v-model="showDevModal"
|
||||||
|
:show-cancel-button="false"
|
||||||
|
title="提示"
|
||||||
|
content="该功能正在开发中,敬请期待!"
|
||||||
|
@confirm="showDevModal = false"
|
||||||
|
></u-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import TabBar from '@/components/TabBar.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'NotesPage',
|
||||||
|
components: {
|
||||||
|
TabBar
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeTab: 'unread',
|
||||||
|
showDevModal: false,
|
||||||
|
defaultAvatar: '/static/avatar/default-avatar.png',
|
||||||
|
unreadMessages: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
avatar: '',
|
||||||
|
username: '浙江理工生13024',
|
||||||
|
time: '2023/6/26 15:45:12',
|
||||||
|
question: '学校在录取时有没有一些专业会有特殊要求?',
|
||||||
|
reply: '',
|
||||||
|
expanded: false,
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
avatar: '',
|
||||||
|
username: '理工13024',
|
||||||
|
time: '2023/6/26 15:45:12',
|
||||||
|
question: '在录取时有没有一些专业会有特殊要求?',
|
||||||
|
reply: '',
|
||||||
|
expanded: false,
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
repliedMessages: [
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
avatar: '',
|
||||||
|
username: '浙江理工生13024',
|
||||||
|
time: '2023/6/26 15:45:12',
|
||||||
|
question: '学校在录取时有没有一些专业会有特殊要求?',
|
||||||
|
reply: '学生与体健康状况必须符合教育部、卫生部、中国残疾人联合会印发的《普通高等学校招生体检工作指导意见》和人力资源社会保障部、原卫生部、原教育部、原公安部、原国家人口计划生育委员会制定的有关规定。原卫生部、原教育部、原公安部、原国家人口计划生育委员会制定的有关规定。',
|
||||||
|
replyUser: '系统回复',
|
||||||
|
expanded: false,
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
swipeOptions: [
|
||||||
|
{
|
||||||
|
text: '删除',
|
||||||
|
style: {
|
||||||
|
backgroundColor: '#fa3534',
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: '15px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentMessages() {
|
||||||
|
return this.activeTab === 'unread' ? this.unreadMessages : this.repliedMessages;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
switchTab(tab) {
|
||||||
|
this.activeTab = tab;
|
||||||
|
// 切换选项卡时关闭所有打开的滑动按钮
|
||||||
|
this.closeAllSwipe();
|
||||||
|
},
|
||||||
|
handleTabChange(path, index) {
|
||||||
|
console.log('切换到标签页:', path, index);
|
||||||
|
},
|
||||||
|
handleReply(item) {
|
||||||
|
this.showDevModal = true;
|
||||||
|
},
|
||||||
|
toggleExpand(item) {
|
||||||
|
item.expanded = !item.expanded;
|
||||||
|
},
|
||||||
|
handleSwipeClick(e) {
|
||||||
|
const {index} = e; // 当前点击的滑动单元格索引
|
||||||
|
const btnIndex = e.index; // 点击的按钮索引
|
||||||
|
|
||||||
|
if (btnIndex === 0) { // 删除按钮
|
||||||
|
// 删除当前消息
|
||||||
|
if (this.activeTab === 'unread') {
|
||||||
|
this.unreadMessages.splice(index, 1);
|
||||||
|
} else {
|
||||||
|
this.repliedMessages.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleSwipeOpen(e, index) {
|
||||||
|
// 打开滑动按钮时,关闭其他打开的滑动按钮
|
||||||
|
this.closeOther(index);
|
||||||
|
},
|
||||||
|
handleSwipeClose(e, index) {
|
||||||
|
// 处理滑动关闭事件
|
||||||
|
if (this.activeTab === 'unread') {
|
||||||
|
this.unreadMessages[index].show = false;
|
||||||
|
} else {
|
||||||
|
this.repliedMessages[index].show = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeOther(index) {
|
||||||
|
// 关闭除当前外的所有滑动按钮
|
||||||
|
if (this.activeTab === 'unread') {
|
||||||
|
this.unreadMessages.forEach((item, idx) => {
|
||||||
|
if (idx !== index) {
|
||||||
|
item.show = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.repliedMessages.forEach((item, idx) => {
|
||||||
|
if (idx !== index) {
|
||||||
|
item.show = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closeAllSwipe() {
|
||||||
|
// 关闭所有滑动按钮
|
||||||
|
this.unreadMessages.forEach(item => {
|
||||||
|
item.show = false;
|
||||||
|
});
|
||||||
|
this.repliedMessages.forEach(item => {
|
||||||
|
item.show = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.notes-page {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f6fa;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
background-color: #fff;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部切换标签样式 */
|
||||||
|
.tab-header {
|
||||||
|
display: flex;
|
||||||
|
height: 40px;
|
||||||
|
border-bottom: 1px solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #4A6CF7;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 2px;
|
||||||
|
background-color: #4A6CF7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-wrapper {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding-bottom: 60px; /* 为底部导航栏预留空间 */
|
||||||
|
overflow-y: auto; /* 允许内容滚动 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 留言列表样式 */
|
||||||
|
.message-list {
|
||||||
|
flex: 1;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 8px;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #4a6cf7;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.question-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-button {
|
||||||
|
height: 32px;
|
||||||
|
background-color: #f0f2fd;
|
||||||
|
color: #4a6cf7;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-top: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-button text {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-content {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-icon {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #ff9500;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-info {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.5;
|
||||||
|
color: #333;
|
||||||
|
margin-left: 28px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 3;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-text.expanded {
|
||||||
|
-webkit-line-clamp: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.expand-button {
|
||||||
|
text-align: right;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #4a6cf7;
|
||||||
|
margin-top: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-tip {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
color: #999;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1 @@
|
||||||
|
<!-- 图标文件内容,这是二进制文件,实际使用时需要上传真实图片 -->
|
After Width: | Height: | Size: 446 KiB |
After Width: | Height: | Size: 109 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 749 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 2.2 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.6 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 743 B |
After Width: | Height: | Size: 786 B |