feat: 新增招生在线、老师详情、留言功能及登录页面,更新首页样式和图标

This commit is contained in:
yangzhe 2025-07-04 13:35:43 +08:00
parent 6acb8fe916
commit 5427c79fe7
26 changed files with 1417 additions and 102 deletions

View File

@ -0,0 +1,91 @@
<template>
<!-- 咨询电话 -->
<u-popup
v-model="showPopup"
mode="center"
border-radius="16"
closeable
close-icon-color="#999999"
close-icon-pos="top-right"
>
<view class="phone-popup">
<view class="phone-title">招生电话</view>
<view class="phone-content">0790-6764666/6765666</view>
<view class="phone-button">
<u-button class="cancel-button" type="default" @click="closePopup"
>取消</u-button
>
</view>
</view>
</u-popup>
</template>
<script>
export default {
name: "AdvicePhone",
props: {
show: {
type: Boolean,
default: false,
},
},
data() {
return {
showPopup: false,
};
},
watch: {
show: {
handler(newVal) {
this.showPopup = newVal;
},
immediate: true,
},
showPopup(val) {
if (val !== this.show) {
this.$emit("update:show", val);
}
},
},
methods: {
closePopup() {
this.showPopup = false;
this.$emit("update:show", false);
},
},
};
</script>
<style lang="scss" scoped>
.phone-popup {
width: 600rpx;
padding: 60rpx 0;
background: #ffffff;
border-radius: 16rpx;
.phone-title {
text-align: center;
font-family: DouyinSans;
font-weight: bold;
font-size: 40rpx;
color: #477bfb;
margin-bottom: 40rpx;
}
.phone-content {
margin-bottom: 120rpx;
text-align: center;
font-family: PingFang SC;
font-size: 32rpx;
color: #333333;
}
.phone-button {
padding: 0 40rpx;
.cancel-button {
border-radius: 16rpx;
}
}
}
</style>

184
components/LeaveMessage.vue Normal file
View File

@ -0,0 +1,184 @@
<template>
<!-- 留言 -->
<u-popup
v-model="showPopup"
mode="bottom"
@close="closePopup"
close-icon-color="#333"
close-icon-pos="top-right"
borderRadius="16"
closeable
>
<view class="leave-message-container">
<view class="leave-message-title">留言</view>
<view class="leave-message-content">
<textarea
class="message-input"
v-model="messageContent"
placeholder="请输入留言100字以内"
maxlength="100"
placeholder-style="color: #999999;"
:disabled="loading"
></textarea>
</view>
<view class="message-buttons">
<u-button
class="submit-btn"
type="primary"
@click="handleSubmit"
:disabled="loading"
>
{{ loading ? "提交中..." : "提交" }}
</u-button>
<u-button
class="cancel-btn"
type="default"
@click="closePopup"
:disabled="loading"
>
取消
</u-button>
</view>
</view>
</u-popup>
</template>
<script>
export default {
name: "LeaveMessage",
props: {
show: {
type: Boolean,
default: false,
},
teacher: {
type: Object,
default: () => null,
},
},
data() {
return {
showPopup: false,
messageContent: "",
loading: false,
};
},
watch: {
show: {
handler(newVal) {
this.showPopup = newVal;
},
immediate: true,
},
showPopup(val) {
if (val !== this.show) {
this.$emit("update:show", val);
}
},
},
methods: {
closePopup() {
if (this.loading) return; //
this.messageContent = "";
this.showPopup = false;
this.$emit("update:show", false);
},
handleSubmit() {
if (this.loading) return; //
if (!this.messageContent.trim()) {
uni.showToast({
title: "请输入留言内容",
icon: "none",
});
return;
}
//
this.loading = true;
uni.showLoading({
title: "提交中...",
});
//
setTimeout(() => {
//
uni.hideLoading();
this.loading = false;
//
this.$emit("submit", {
content: this.messageContent,
teacher: this.teacher,
success: true,
});
//
uni.showToast({
title: "留言成功",
icon: "success",
});
//
this.messageContent = "";
//
this.showPopup = false;
this.$emit("update:show", false);
}, 1500); // 1.5
},
},
};
</script>
<style lang="scss" scoped>
.leave-message-container {
padding: 40rpx 0 0;
background-color: #ffffff;
border-radius: 16rpx;
overflow: hidden;
.leave-message-title {
font-size: 32rpx;
color: #333333;
text-align: left;
padding-left: 30rpx;
margin-bottom: 30rpx;
font-weight: 400;
}
.leave-message-content {
padding: 0 30rpx;
.message-input {
width: 100%;
height: 280rpx;
background-color: #f5f5f5;
border-radius: 16rpx;
padding: 24rpx;
font-size: 28rpx;
box-sizing: border-box;
color: #333333;
}
}
.message-buttons {
padding: 30rpx 0;
display: flex;
justify-content: center;
align-items: center;
gap: 50rpx;
.cancel-btn,
.submit-btn {
width: 156rpx;
height: 70rpx;
margin: 0;
border-radius: 16rpx;
}
.submit-btn {
background-color: #477bfb;
}
}
}
</style>

View File

@ -20,6 +20,30 @@
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}, },
{
"path": "pages/home/admissions/index",
"style": {
"navigationBarTitleText": "招办在线",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/home/teacherInfo/index",
"style": {
"navigationBarTitleText": "老师详情",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/login/login/index",
"style": {
"navigationBarTitleText": "登录",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{ {
"path": "pages/login/login/login", "path": "pages/login/login/login",
"style": { "style": {

View File

@ -0,0 +1,249 @@
<template>
<view class="admissions-container">
<view class="header">
<div class="header-left">
<u-icon
class="header-left-icon"
name="arrow-left"
@click="handleLeftClick"
></u-icon>
</div>
<text class="header-title">招办在线</text>
<div></div>
</view>
<view class="admissions-content">
<view class="teacher-list">
<!-- 教师列表 -->
<view
class="teacher-item"
v-for="(teacher, index) in teacherList"
:key="index"
>
<image class="teacher-avatar" :src="teacher.avatar"></image>
<view class="teacher-info">
<view class="teacher-detail">
<view class="teacher-name">
<text>{{ teacher.name }}</text>
<view v-if="teacher.online" class="online-status">
<view class="online-dot"></view>
<text>在线</text>
</view>
</view>
<view class="teacher-department">{{ teacher.department }}</view>
</view>
<view class="ask-button" @click="handleAskQuestion(teacher)">{{
teacher.online ? "立即提问" : "留言"
}}</view>
</view>
</view>
</view>
</view>
<!-- 留言弹出层 -->
<leave-message
:show.sync="showLeaveMessage"
:teacher="currentTeacher"
@submit="handleMessageSubmit"
/>
</view>
</template>
<script>
import LeaveMessage from "@/components/LeaveMessage.vue";
export default {
components: {
LeaveMessage,
},
data() {
return {
showLeaveMessage: false,
teacherList: [
{
id: 1,
name: "孙老师",
department: "招就处",
avatar: "/static/common/images/avatar.png",
online: true,
},
{
id: 2,
name: "杨老师",
department: "电子信息学院",
avatar: "/static/common/images/student.png",
online: false,
},
{
id: 3,
name: "招办赵老师",
department: "财政学院/会计专业",
avatar: "/static/common/images/student.png",
online: true,
},
{
id: 4,
name: "招办王老师",
department: "电子信息学院",
avatar: "/static/common/images/student.png",
online: false,
},
],
currentTeacher: null,
};
},
methods: {
handleLeftClick() {
uni.navigateBack();
},
handleAskQuestion(teacher) {
if (!teacher.online) {
//
this.currentTeacher = teacher;
this.showLeaveMessage = true;
} else {
//
uni.navigateTo({
url: `/pages/home/teacherInfo/index?teacherId=${teacher.id}`,
});
}
},
handleMessageSubmit(data) {
console.log("提交留言:", data.content, "教师:", data.teacher?.name);
//
// uni.showToast({
// title: "",
// icon: "success",
// });
//
if (data.success) {
console.log("留言提交成功,可以进行后续操作");
//
}
},
},
};
</script>
<style lang="scss" scoped>
.admissions-container {
min-height: 100vh;
padding-bottom: calc(112rpx + env(safe-area-inset-bottom));
padding-top: 88rpx;
background-color: #ffffff;
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #ffffff;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
z-index: 99;
.header-left {
font-size: 36rpx;
}
.header-title {
font-size: 36rpx;
font-weight: 500;
color: #333333;
}
}
.admissions-content {
.teacher-list {
.teacher-item {
display: flex;
justify-content: flex-start;
align-items: center;
background-color: #ffffff;
padding: 0 30rpx;
// margin-bottom: 30rpx;
border-radius: 16rpx;
.teacher-avatar {
width: 96rpx;
height: 96rpx;
border-radius: 50%;
margin-right: 24rpx;
object-fit: cover;
}
.teacher-info {
padding: 30rpx 0;
flex: 1;
flex-shrink: 0;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #f2f2f2;
.teacher-detail {
.teacher-name {
display: flex;
align-items: center;
font-size: 28rpx;
font-weight: 600;
color: #333333;
margin-bottom: 12rpx;
.online-status {
display: flex;
align-items: center;
margin-left: 16rpx;
.online-dot {
width: 14rpx;
height: 14rpx;
border-radius: 50%;
background-color: #4cd964;
margin-right: 8rpx;
}
text {
font-size: 24rpx;
color: #4cd964;
font-weight: normal;
}
}
}
.teacher-department {
font-size: 24rpx;
color: #999999;
}
}
.ask-button {
color: #ffffff;
background-color: #4f6aff;
font-size: 24rpx;
width: 152rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border-radius: 50rpx;
}
}
}
}
}
}
/* 响应式布局 - PC端样式 */
@media screen and (min-width: 768px) {
.admissions-container {
.content {
max-width: 1200rpx;
margin: 0 auto;
}
}
}
</style>

View File

@ -15,14 +15,17 @@
<!-- 首页 --> <!-- 首页 -->
<view class="content" v-if="!isChat"> <view class="content" v-if="!isChat">
<view class="welcome-message"> <view class="welcome-message">
<image class="avatar" src="/static/common/icon/ai-avatar.png"></image> <image
class="avatar"
src="/static/common/images/images_logo.png"
></image>
<text class="message-text" <text class="message-text"
>Hi~我是小小新您的AI聊天伙伴未来高效认知助手我们可尽量互相解惑</text >Hi~我是小小新您的AI聊天伙伴未来高效认知助手我们可尽量互相解惑</text
> >
</view> </view>
<view class="qa-section"> <!-- <view class="qa-section">
<view class="qa-header"> <view class="qa-header">
<text class="qa-title">大家都在问</text> <text class="qa-title">大家都在问</text>
<view class="more-link"> <view class="more-link">
@ -43,7 +46,17 @@
<button class="chat-button" @click="isChat = true"> <button class="chat-button" @click="isChat = true">
<image <image
class="chat-icon" class="chat-icon"
src="/static/common/icon/chat-icon.png" src="/static/common/images/icon_chat.png"
></image>
<text class="chat-text">开启对话</text>
</button>
</view> -->
<view class="start-chat">
<button class="chat-button" @click="isChat = true">
<image
class="chat-icon"
src="/static/common/images/icon_chat.png"
></image> ></image>
<text class="chat-text">开启对话</text> <text class="chat-text">开启对话</text>
</button> </button>
@ -54,6 +67,7 @@
class="feature-item" class="feature-item"
v-for="(item, index) in features" v-for="(item, index) in features"
:key="index" :key="index"
@click="handleFeatureClick(item)"
> >
<image :src="item.icon" class="feature-icon"></image> <image :src="item.icon" class="feature-icon"></image>
<text class="feature-text">{{ item.title }}</text> <text class="feature-text">{{ item.title }}</text>
@ -74,7 +88,8 @@
@scroll="onScroll" @scroll="onScroll"
> >
<!-- 头部卡片 --> <!-- 头部卡片 -->
<view class="chat-card"> <!-- 后端让先注释 -->
<!-- <view class="chat-card">
<view class="chat-card-title">源小新AI校园小助手</view> <view class="chat-card-title">源小新AI校园小助手</view>
<view class="chat-card-desc" <view class="chat-card-desc"
>我是你们的AI校园助手我可以为您答疑解惑</view >我是你们的AI校园助手我可以为您答疑解惑</view
@ -88,7 +103,7 @@
> >
<view class="question-item">我什么时候能够知道自己是否被录取?</view> <view class="question-item">我什么时候能够知道自己是否被录取?</view>
</view> </view>
</view> </view> -->
<!-- 对话内容区域 --> <!-- 对话内容区域 -->
<view class="chat-content"> <view class="chat-content">
@ -114,12 +129,20 @@
<view class="message-content"> <view class="message-content">
<text>{{ message.content }}</text> <text>{{ message.content }}</text>
</view> </view>
<view class="user-avatar"></view> <image
class="user-avatar"
src="/static/common/images/avatar.png"
mode="scaleToFill"
/>
</view> </view>
<!-- AI消息 --> <!-- AI消息 -->
<view class="message-left" v-else :id="'msg-' + message.id"> <view class="message-left" v-else :id="'msg-' + message.id">
<view class="ai-avatar"></view> <image
class="ai-avatar"
src="/static/common/images/avatar_ai.png"
mode="scaleToFill"
/>
<view class="message-content"> <view class="message-content">
<text space="nbsp" decode>{{ message.content }}</text> <text space="nbsp" decode>{{ message.content }}</text>
</view> </view>
@ -134,15 +157,28 @@
<!-- 悬浮工具栏 --> <!-- 悬浮工具栏 -->
<view class="floating-tabs"> <view class="floating-tabs">
<view class="tab-item"> <view class="tab-item">
<view class="tab-icon icon-people"></view> <image
class="tab-icon"
src="/static/common/images/icon_admissions2.png"
mode="scaleToFill"
/>
<text>招生在线</text> <text>招生在线</text>
</view> </view>
<view class="tab-item"> <view class="tab-item">
<view class="tab-icon icon-board"></view> <image
class="tab-icon"
src="/static/common/images/icon_messageBoard2.png"
mode="scaleToFill"
/>
<text>留言板</text> <text>留言板</text>
</view> </view>
<view class="tab-item"> <view class="tab-item">
<view class="tab-icon icon-phone"></view> <image
class="tab-icon"
src="/static/common/images/icon_phone2.png"
mode="scaleToFill"
/>
<text>电话咨询</text> <text>电话咨询</text>
</view> </view>
</view> </view>
@ -156,7 +192,11 @@
placeholder-style="color: #adadad;" placeholder-style="color: #adadad;"
/> />
<view class="send-btn"> <view class="send-btn">
<view class="send-icon"></view> <image
class="send-icon"
src="/static/common/images/icon_send.png"
mode="scaleToFill"
/>
</view> </view>
</view> </view>
</view> </view>
@ -214,19 +254,25 @@
</view> </view>
</view> </view>
</u-popup> </u-popup>
<!-- 咨询电话弹出层 -->
<advice-phone :show.sync="advicePhoneShow"></advice-phone>
</view> </view>
</template> </template>
<script> <script>
import CustomTabBar from "@/components/custom-tab-bar/custom-tab-bar.vue"; import CustomTabBar from "@/components/custom-tab-bar/custom-tab-bar.vue";
import AdvicePhone from "@/components/AdvicePhone.vue";
export default { export default {
components: { components: {
CustomTabBar, CustomTabBar,
AdvicePhone,
}, },
data() { data() {
return { return {
isChat: false, isChat: false,
advicePhoneShow: false,
questionList: [ questionList: [
"学习哪些专业比较好?", "学习哪些专业比较好?",
@ -238,15 +284,15 @@ export default {
features: [ features: [
{ {
title: "招办在线", title: "招办在线",
icon: "/static/common/feature/zhaobao.png", icon: "/static/common/images/icon_admissions.png",
}, },
{ {
title: "留言板", title: "留言板",
icon: "/static/common/feature/zhiyin.png", icon: "/static/common/images/icon_messageBoard.png",
}, },
{ {
title: "电话咨询", title: "电话咨询",
icon: "/static/common/feature/phone.png", icon: "/static/common/images/icon_phone.png",
}, },
], ],
popupShow: false, popupShow: false,
@ -373,19 +419,36 @@ export default {
.exec(); .exec();
}); });
}, },
handleFeatureClick(item) {
if (item.title === "电话咨询") {
this.advicePhoneShow = true;
} else if (item.title === "招办在线") {
uni.navigateTo({
url: "/pages/home/admissions/index",
});
} else if (item.title === "留言板") {
// this.leaveMessageShow = true;
}
},
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.home-container { .home-container {
min-height: 100vh; height: 100vh;
background-color: #f5f7fc; // background-color: #f5f7fc;
padding-bottom: calc( padding-bottom: calc(
112rpx + env(safe-area-inset-bottom) 112rpx + env(safe-area-inset-bottom)
); /* 为自定义tabBar预留空间 */ ); /* 为自定义tabBar预留空间 */
padding-top: 88rpx; padding-top: 88rpx;
background-image: url("/static/common/images/images_bg.png");
width: 100%;
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 0 88rpx;
.header { .header {
position: fixed; position: fixed;
top: 0; top: 0;
@ -412,6 +475,7 @@ export default {
.content { .content {
padding: 30rpx; padding: 30rpx;
padding-top: 100rpx;
.welcome-message { .welcome-message {
// display: inline-block; // display: inline-block;
@ -419,14 +483,14 @@ export default {
background-color: rgba(255, 255, 255, 0.8); background-color: rgba(255, 255, 255, 0.8);
border-radius: 16rpx; border-radius: 16rpx;
padding: 24rpx; padding: 24rpx;
margin-bottom: 30rpx; margin-bottom: 32rpx;
// margin-bottom: 100rpx;
.avatar { .avatar {
display: inline-block; display: inline-block;
width: 42rpx; width: 42rpx;
height: 34rpx; height: 34rpx;
margin-right: 12rpx; margin-right: 12rpx;
background-color: #4377fe;
} }
.message-text { .message-text {
@ -441,7 +505,7 @@ export default {
background-color: #ffffff; background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
padding: 30rpx; padding: 30rpx;
margin-bottom: 30rpx; margin-bottom: 32rpx;
.qa-header { .qa-header {
display: flex; display: flex;
@ -487,14 +551,39 @@ export default {
border: none; border: none;
.chat-icon { .chat-icon {
width: 40rpx; width: 38rpx;
height: 40rpx; height: 32rpx;
margin-right: 12rpx; margin-right: 12rpx;
} }
.chat-text { .chat-text {
color: #ffffff; color: #ffffff;
font-size: 30rpx; font-size: 32rpx;
}
}
}
.start-chat {
.chat-button {
display: flex;
align-items: center;
justify-content: center;
background-color: #4377fe;
border-radius: 16rpx;
height: 88rpx;
width: 100%;
margin-top: 30rpx;
border: none;
.chat-icon {
width: 38rpx;
height: 32rpx;
margin-right: 12rpx;
}
.chat-text {
color: #ffffff;
font-size: 32rpx;
} }
} }
} }
@ -505,14 +594,13 @@ export default {
padding: 30rpx; padding: 30rpx;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin-top: 40rpx; margin-top: 32rpx;
gap: 30rpx; gap: 30rpx;
.feature-item { .feature-item {
height: 210rpx; height: 210rpx;
border-radius: 16rpx; border-radius: 16rpx;
background-color: #fafafc; background-color: #fafafc;
// background-color: #4377fe;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
@ -523,9 +611,7 @@ export default {
.feature-icon { .feature-icon {
width: 80rpx; width: 80rpx;
height: 80rpx; height: 80rpx;
margin-bottom: 16rpx; margin-bottom: 12rpx;
background-color: #e1e5f2;
border-radius: 50%;
} }
.feature-text { .feature-text {
@ -646,10 +732,7 @@ export default {
.chat-container { .chat-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: calc(100vh - 300rpx);
background-color: #f5f8ff;
padding: 30rpx; padding: 30rpx;
// padding-bottom: 200rpx; /* */
box-sizing: border-box; box-sizing: border-box;
.chat-scroll { .chat-scroll {
@ -715,7 +798,6 @@ export default {
height: 64rpx; height: 64rpx;
border-radius: 50%; border-radius: 50%;
margin-right: 16rpx; margin-right: 16rpx;
background-color: #4370fe;
flex-shrink: 0; flex-shrink: 0;
} }
@ -778,74 +860,9 @@ export default {
margin-right: 12rpx; margin-right: 12rpx;
.tab-icon { .tab-icon {
width: 32rpx; width: 28rpx;
height: 32rpx; height: 28rpx;
border-radius: 50%;
margin-right: 10rpx; margin-right: 10rpx;
position: relative;
&.icon-people {
background-color: #4370fe;
&:before {
content: "";
position: absolute;
width: 15rpx;
height: 15rpx;
border-radius: 50%;
background-color: white;
top: 8rpx;
left: 12rpx;
}
&:after {
content: "";
position: absolute;
width: 24rpx;
height: 12rpx;
border: 2rpx solid white;
border-radius: 12rpx 12rpx 0 0;
border-bottom: none;
background-color: transparent;
bottom: 6rpx;
left: 7rpx;
}
}
&.icon-board {
background-color: #d0d0d0;
&:before {
content: "";
position: absolute;
width: 22rpx;
height: 15rpx;
background-color: white;
top: 12rpx;
left: 9rpx;
}
&:after {
content: "";
position: absolute;
width: 10rpx;
height: 5rpx;
border-radius: 0 0 10rpx 10rpx;
background-color: white;
top: 7rpx;
left: 15rpx;
}
}
&.icon-phone {
background-color: #d0d0d0;
&:before {
content: "";
position: absolute;
width: 20rpx;
height: 20rpx;
border: 2rpx solid white;
border-radius: 50%;
top: 8rpx;
left: 8rpx;
}
}
} }
text { text {
@ -884,10 +901,8 @@ export default {
justify-content: center; justify-content: center;
.send-icon { .send-icon {
width: 30rpx; width: 40rpx;
height: 30rpx; height: 46rpx;
background-color: #4370fe;
clip-path: polygon(0% 0%, 0% 100%, 100% 50%);
} }
} }
} }

View File

@ -0,0 +1,456 @@
<template>
<view class="teacherInfo-container">
<view class="header">
<div class="header-left">
<u-icon
class="header-left-icon"
name="arrow-left"
@click="handleLeftClick"
></u-icon>
</div>
<text class="header-title">老师详情</text>
<div></div>
</view>
<div class="teacher-info-card">
<div class="card-content">
<image class="teacher-avatar" :src="teacherInfo.avatar"></image>
<div class="teacher-info">
<div class="teacher-name">{{ teacherInfo.name }}</div>
<div class="teacher-school">
<image
class="school-icon"
src="/static/common/images/icon_college.png"
></image>
<text class="school-text">{{ teacherInfo.school }}</text>
</div>
<div class="teacher-college">
<image
class="college-icon"
src="/static/common/images/icon_major.png"
></image>
<text class="college-text">{{ teacherInfo.college }}</text>
</div>
</div>
</div>
<div class="action-buttons">
<button class="action-btn consult-btn" @click="handleConsult">
<image
class="btn-icon"
src="/static/common/images/icon_consult.png"
></image>
<text class="btn-text">在线咨询</text>
</button>
<button class="action-btn message-btn" @click="handleMessage">
<image
class="btn-icon"
src="/static/common/images/icon_edit.png"
></image>
<text class="btn-text">留言提问</text>
</button>
</div>
</div>
<!-- 老师回答 -->
<view class="teacher-answers">
<view class="answer-title">老师回答</view>
<view
class="answer-item"
v-for="(item, index) in answerList"
:key="item.id"
>
<view class="student-info">
<image class="student-avatar" :src="item.studentAvatar"></image>
<text class="student-name">{{ item.studentName }}</text>
<text class="answer-time">{{ item.time }}</text>
</view>
<view class="question">
<view class="question-tag"></view>
<view class="question-content">{{ item.question }}</view>
</view>
<view class="answer">
<view class="answer-tag"></view>
<view class="answer-content">
<view class="answer-text">{{ item.fullAnswer }}</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
components: {},
data() {
return {
teacherId: "",
teacherInfo: {
id: 1,
name: "孙老师",
school: "江西新能源科技职业学院",
college: "生命科学与工程学院·生物工程专业",
avatar: "/static/common/images/avatar2.png",
online: true,
},
answerList: [
{
id: 1,
studentName: "浙江考生13024",
studentAvatar: "/static/common/images/avatar.png",
time: "2025/6/26 15:45:12",
question: "学校在录取时有没有一些专业会有特殊要求?",
fullAnswer:
"考生身体健康状况必须符合教育部、原卫生部中国残疾人联合的《普通高等学校招生体检工作指导意见》和人力资源社会保障部",
},
{
id: 2,
studentName: "浙江考生13024",
studentAvatar: "/static/common/images/avatar.png",
time: "2025/6/26 15:45:12",
question: "学校在录取时有没有一些专业会有特殊要求?",
fullAnswer:
"考生身体健康状况必须符合教育部、原卫生部中国残疾人联合的《普通高等学校招生体检工作指导意见》。",
},
{
id: 3,
studentName: "浙江考生13024",
studentAvatar: "/static/common/images/avatar.png",
time: "2025/6/26 15:45:12",
question: "学校在录取时有没有一些专业会有特殊要求?",
fullAnswer:
"考生身体健康状况必须符合教育部、原卫生部中国残疾人联合的《普通高等学校招生体检工作指导意见》和人力资源社会保障部、教育部、原卫生部、见》和人力资源社会保障部、教育部、原卫生部中共发布的相关规定。部分专业确有特殊要求,如航空服务类专业对身高、视力等有特殊要求,艺术类专业要求有艺术基础等。建议考生在填报志愿前,详细了解意向专业的招生要求。",
},
],
};
},
mounted() {},
onLoad(options) {
if (options.teacherId) {
this.teacherId = options.teacherId;
this.getTeacherInfo();
}
//
this.$nextTick(() => {
this.checkTextOverflow();
});
},
methods: {
handleLeftClick() {
uni.navigateBack();
},
getTeacherInfo() {
//
console.log("获取教师ID为", this.teacherId, "的信息");
//
},
handleConsult() {
console.log("在线咨询");
//
},
handleMessage() {
console.log("留言提问");
//
},
},
};
</script>
<style lang="scss" scoped>
.teacherInfo-container {
min-height: 100vh;
padding-bottom: calc(112rpx + env(safe-area-inset-bottom));
padding: 32rpx;
padding-top: calc(88rpx + 40rpx);
background-image: url(/static//common/images/images_bg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
.header {
position: fixed;
top: 0;
left: 0;
right: 0;
background-color: #ffffff;
height: 88rpx;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 30rpx;
z-index: 99;
.header-left {
font-size: 36rpx;
}
.header-title {
font-size: 36rpx;
font-weight: 500;
color: #333333;
}
}
.teacher-info-card {
// margin: 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
padding: 26rpx 32rpx 32rpx 32rpx;
.card-content {
display: flex;
align-items: center;
margin-bottom: 36rpx;
.teacher-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 10rpx;
margin-right: 30rpx;
object-fit: cover;
}
.teacher-info {
display: flex;
flex-direction: column;
justify-content: space-between;
gap: 8rpx;
flex: 1;
.teacher-name {
font-family: PingFang SC;
font-weight: bold;
font-size: 32rpx;
color: #333333;
}
.teacher-school,
.teacher-college {
display: flex;
align-items: center;
.school-icon,
.college-icon {
margin-right: 16rpx;
width: 24rpx;
height: 24rpx;
display: inline-block;
text-align: center;
}
.school-text,
.college-text {
font-size: 24rpx;
color: #666666;
}
}
}
}
.action-buttons {
display: flex;
justify-content: space-between;
.action-btn {
display: flex;
align-items: center;
justify-content: center;
width: 46%;
height: 60rpx;
border-radius: 16rpx;
font-size: 32rpx;
border: none;
.btn-icon {
margin-right: 16rpx;
width: 24rpx;
height: 24rpx;
}
.btn-text {
font-size: 24rpx;
font-weight: 500;
}
}
.consult-btn {
background-color: #4f6aff;
color: #ffffff;
}
.message-btn {
background-color: #ffffff;
color: #4f6aff;
border: 1px solid #4f6aff;
}
}
}
}
/* 老师回答区域样式 */
.teacher-answers {
margin-top: 50rpx;
.answer-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 28rpx;
}
.answer-item {
background-color: #ffffff;
border-radius: 16rpx;
padding: 32rpx;
margin-bottom: 32rpx;
border: 1px solid #ccc;
.student-info {
display: flex;
align-items: center;
margin-bottom: 32rpx;
.student-avatar {
width: 40rpx;
height: 40rpx;
border-radius: 20rpx;
margin-right: 16rpx;
}
.student-name {
flex: 1;
font-size: 26rpx;
color: #666666;
font-weight: 500;
}
.answer-time {
font-size: 24rpx;
color: #666666;
}
}
.question {
display: flex;
margin-bottom: 24rpx;
.question-tag {
width: 40rpx;
height: 40rpx;
background-color: #4e7eff;
color: #ffffff;
font-size: 24rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8rpx;
margin-right: 32rpx;
flex-shrink: 0;
font-weight: 500;
}
.question-content {
font-size: 32rpx;
color: #333333;
flex: 1;
}
}
.answer {
display: flex;
align-items: flex-start;
.answer-tag {
width: 40rpx;
height: 40rpx;
background-color: #ffbd41;
color: #ffffff;
font-size: 24rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 8rpx;
margin-right: 32rpx;
flex-shrink: 0;
font-weight: 500;
}
.answer-content {
font-size: 28rpx;
color: #666666;
flex: 1;
position: relative;
.answer-text {
word-break: break-word;
transition: all 0.3s;
}
&:not(.content-expanded) .answer-text {
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
}
&.content-expanded {
.expand-btn-container {
margin-top: 16rpx;
text-align: right;
}
}
.expand-btn-container {
display: block;
}
&:not(.content-expanded) .expand-btn-container {
position: absolute;
right: 0;
bottom: 0;
z-index: 2;
background-color: #ffffff;
padding-left: 10rpx;
padding-right: 0;
}
.expand-btn {
color: #4e7eff;
display: inline-block;
font-size: 26rpx;
cursor: pointer;
white-space: nowrap;
padding: 0 4rpx;
.expand-icon {
font-size: 20rpx;
display: inline-block;
vertical-align: middle;
margin-left: 4rpx;
}
}
}
}
}
}
/* 响应式布局 - PC端样式 */
@media screen and (min-width: 768px) {
.teacherInfo-container {
.content {
max-width: 1200rpx;
margin: 0 auto;
}
}
}
</style>

296
pages/login/login/index.vue Normal file
View File

@ -0,0 +1,296 @@
<template>
<view class="login-container">
<view class="login-header">
<view class="logo-container">
<image
class="logo-icon"
src="/static/common/images/images_logo.png"
></image>
<text class="logo-text"
>我是 <text class="logo-name">源小新</text></text
>
</view>
<view class="welcome-text">
欢迎使用源小新校园AI助手快让我来帮助你吧
</view>
</view>
<view
class="login-form"
:style="{ 'padding-top': isTeacher ? '40rpx' : '80rpx' }"
>
<view class="login-type" v-if="isTeacher">
<view
class="type-item"
:class="{ active: loginType === 'psd' }"
@click="switchLoginType('psd')"
>密码登录</view
>
<view class="divider">|</view>
<view
class="type-item"
:class="{ active: loginType === 'code' }"
@click="switchLoginType('code')"
>验证码登录</view
>
</view>
<view class="form-content">
<view class="form-item">
<text class="form-label">手机号</text>
<view class="input-wrapper">
<input
type="text"
class="form-input"
placeholder="请输入手机号"
v-model="phone"
/>
</view>
</view>
<view class="form-item" v-if="isTeacher && loginType === 'psd'">
<text class="form-label">密码</text>
<view class="input-wrapper">
<input
type="text"
class="form-input"
placeholder="请输入密码"
v-model="password"
/>
</view>
</view>
<view class="form-item" v-if="loginType === 'code'">
<text class="form-label">验证码</text>
<view class="input-wrapper">
<input
type="text"
class="form-input"
placeholder="请输入验证码"
v-model="code"
/>
<text class="get-code-btn" @click="getCode">获取验证码</text>
</view>
</view>
</view>
<view class="button-container">
<button class="login-button" @click="login">登录</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isTeacher: true, //
phone: "",
password: "",
code: "",
loginType: "code", //
};
},
methods: {
switchLoginType(type) {
this.loginType = type;
},
getCode() {
//
},
login() {
//
},
},
};
</script>
<style lang="scss" scoped>
.login-container {
// min-height: 100vh;
height: 100vh;
width: 100%;
padding: 0 30rpx;
display: flex;
flex-direction: column;
box-sizing: border-box;
background-image: url(/static//common/images/images_bg.png);
background-repeat: no-repeat;
background-size: 100% 100%;
background-position: 50%;
.login-header {
margin-top: 120rpx;
display: flex;
flex-direction: column;
align-items: center;
.logo-container {
display: flex;
align-items: center;
margin-bottom: 20rpx;
.logo-icon {
width: 48rpx;
height: 38rpx;
margin-right: 16rpx;
}
.logo-text {
font-size: 32rpx;
color: #333;
.logo-name {
font-family: DouyinSans;
font-weight: bold;
font-size: 48rpx;
color: #3e6aff;
line-height: 24rpx;
margin-left: 16rpx;
}
}
}
.welcome-text {
font-family: DouyinSans;
font-weight: bold;
font-size: 27rpx;
color: #5a5f76;
margin-bottom: 60rpx;
}
}
.login-form {
background: linear-gradient(0deg, #f6f6f6 0%, #ffffff 100%);
flex: 1;
border-radius: 40rpx 40rpx 0 0;
padding: 80rpx 40rpx;
display: flex;
flex-direction: column;
.login-type {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 60rpx;
font-size: 28rpx;
color: #999999;
.type-item {
padding: 0 20rpx;
position: relative;
font-family: PingFang SC;
&.active {
font-size: 32rpx;
font-weight: bold;
color: #4f6aff;
&::after {
content: "";
position: absolute;
bottom: 4px;
left: 50%;
-webkit-transform: translateX(-50%);
transform: translateX(-50%);
width: 76%;
height: 0px;
border-radius: 3px;
box-shadow: 0px 0px 4px 2px rgba(79, 106, 255, 1);
}
}
}
.divider {
color: #5a5f76;
margin: 0 30rpx;
font-weight: 300;
}
}
.form-content {
.form-item {
margin-bottom: 32rpx;
.form-label {
display: block;
position: relative;
padding-left: 30rpx;
font-family: PingFang SC;
font-size: 28rpx;
color: #333333;
margin-bottom: 16rpx;
&::before {
content: "";
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 20rpx;
height: 20rpx;
border: 2rpx solid #4370fe;
border-radius: 4rpx;
}
}
&:nth-child(2) {
.form-label::before {
border-radius: 50%;
}
}
.input-wrapper {
position: relative;
.form-input {
width: 100%;
height: 90rpx;
background-color: #f2f2f2;
border-radius: 20rpx;
font-size: 28rpx;
padding: 0 32rpx;
box-sizing: border-box;
.uni-input-placeholder {
color: #cccccc;
}
}
.get-code-btn {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
height: 60rpx;
line-height: 60rpx;
padding: 0 30rpx;
color: #4370fe;
font-size: 28rpx;
border-left: 1px solid #557bf9;
}
}
}
}
.button-container {
margin-top: 60rpx;
.login-button {
width: 100%;
height: 90rpx;
background-color: #4f6aff;
color: #ffffff;
font-size: 32rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
border: none;
}
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

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: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB