重命名前端项目目录:web-flowith -> web
- 将前端项目目录从 web-flowith 重命名为 web,使目录结构更简洁 - 保持所有前端代码和配置文件不变 - 统一项目目录命名规范
This commit is contained in:
@@ -0,0 +1,601 @@
|
||||
<template>
|
||||
<div class="settings-page">
|
||||
<!-- 头部 -->
|
||||
<header class="page-header">
|
||||
<div class="header-content">
|
||||
<div class="header-left">
|
||||
<a-button type="text" @click="$router.back()" class="back-btn">
|
||||
<ArrowLeftOutlined />
|
||||
</a-button>
|
||||
<h1 class="page-title">用户设置</h1>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<main class="page-main">
|
||||
<div class="container">
|
||||
<div class="settings-content">
|
||||
<!-- 用户信息区域 -->
|
||||
<a-card class="user-info-card">
|
||||
<div class="user-profile">
|
||||
<a-avatar :size="80" :src="userAvatar" class="user-avatar">
|
||||
<UserOutlined />
|
||||
</a-avatar>
|
||||
<div class="user-details">
|
||||
<h2 class="user-name">{{ userStore.user?.nickname || '未登录用户' }}</h2>
|
||||
<p class="user-email">{{ userStore.user?.email || '未绑定邮箱' }}</p>
|
||||
<a-button type="primary" size="small" @click="showLoginModal = true">
|
||||
{{ userStore.isLoggedIn ? '切换账号' : '登录/注册' }}
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<!-- 设置选项 -->
|
||||
<div class="settings-sections">
|
||||
<!-- 账户设置 -->
|
||||
<a-card title="账户设置" class="settings-card">
|
||||
<div class="settings-list">
|
||||
<div class="setting-item" @click="showProfileModal = true">
|
||||
<div class="setting-info">
|
||||
<UserOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">个人资料</div>
|
||||
<div class="setting-desc">管理您的个人信息</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item" @click="showSecurityModal = true">
|
||||
<div class="setting-info">
|
||||
<SafetyOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">账户安全</div>
|
||||
<div class="setting-desc">密码、手机号等安全设置</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<!-- 应用设置 -->
|
||||
<a-card title="应用设置" class="settings-card">
|
||||
<div class="settings-list">
|
||||
<div class="setting-item">
|
||||
<div class="setting-info">
|
||||
<BellOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">消息通知</div>
|
||||
<div class="setting-desc">管理推送通知设置</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-switch v-model:checked="notificationEnabled" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="setting-info">
|
||||
<EyeOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">隐私模式</div>
|
||||
<div class="setting-desc">保护您的隐私数据</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-switch v-model:checked="privacyMode" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item">
|
||||
<div class="setting-info">
|
||||
<BgColorsOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">主题设置</div>
|
||||
<div class="setting-desc">选择您喜欢的主题色彩</div>
|
||||
</div>
|
||||
</div>
|
||||
<a-select
|
||||
v-model:value="selectedTheme"
|
||||
style="width: 120px"
|
||||
@change="changeTheme"
|
||||
>
|
||||
<a-select-option value="default">默认蓝</a-select-option>
|
||||
<a-select-option value="orange">温暖橙</a-select-option>
|
||||
<a-select-option value="green">自然绿</a-select-option>
|
||||
<a-select-option value="purple">优雅紫</a-select-option>
|
||||
</a-select>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<!-- 数据管理 -->
|
||||
<a-card title="数据管理" class="settings-card">
|
||||
<div class="settings-list">
|
||||
<div class="setting-item" @click="exportData">
|
||||
<div class="setting-info">
|
||||
<DownloadOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">导出数据</div>
|
||||
<div class="setting-desc">导出您的聊天记录和日记</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item" @click="clearCache">
|
||||
<div class="setting-info">
|
||||
<ClearOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">清除缓存</div>
|
||||
<div class="setting-desc">清理应用缓存数据</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<!-- 关于应用 -->
|
||||
<a-card title="关于应用" class="settings-card">
|
||||
<div class="settings-list">
|
||||
<div class="setting-item" @click="showAboutModal = true">
|
||||
<div class="setting-info">
|
||||
<InfoCircleOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">关于开心APP</div>
|
||||
<div class="setting-desc">版本信息和开发团队</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item" @click="showPrivacyModal = true">
|
||||
<div class="setting-info">
|
||||
<FileProtectOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">隐私政策</div>
|
||||
<div class="setting-desc">了解我们如何保护您的隐私</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
|
||||
<div class="setting-item" @click="showTermsModal = true">
|
||||
<div class="setting-info">
|
||||
<FileTextOutlined class="setting-icon" />
|
||||
<div class="setting-text">
|
||||
<div class="setting-title">服务条款</div>
|
||||
<div class="setting-desc">使用条款和服务协议</div>
|
||||
</div>
|
||||
</div>
|
||||
<RightOutlined class="setting-arrow" />
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
|
||||
<!-- 退出登录 -->
|
||||
<div class="logout-section" v-if="userStore.isLoggedIn">
|
||||
<a-button type="primary" danger block size="large" @click="logout">
|
||||
<LogoutOutlined />
|
||||
退出登录
|
||||
</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 登录模态框 -->
|
||||
<a-modal
|
||||
v-model:open="showLoginModal"
|
||||
title="登录/注册"
|
||||
:footer="null"
|
||||
width="400px"
|
||||
>
|
||||
<a-tabs v-model:activeKey="loginTab" centered>
|
||||
<a-tab-pane key="login" tab="登录">
|
||||
<a-form :model="loginForm" layout="vertical" @finish="handleLogin">
|
||||
<a-form-item label="用户名" name="username" :rules="[{ required: true, message: '请输入用户名' }]">
|
||||
<a-input v-model:value="loginForm.username" placeholder="请输入用户名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="密码" name="password" :rules="[{ required: true, message: '请输入密码' }]">
|
||||
<a-input-password v-model:value="loginForm.password" placeholder="请输入密码" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" block :loading="loginLoading">
|
||||
登录
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
|
||||
<a-tab-pane key="register" tab="注册">
|
||||
<a-form :model="registerForm" layout="vertical" @finish="handleRegister">
|
||||
<a-form-item label="用户名" name="username" :rules="[{ required: true, message: '请输入用户名' }]">
|
||||
<a-input v-model:value="registerForm.username" placeholder="请输入用户名" />
|
||||
</a-form-item>
|
||||
<a-form-item label="邮箱" name="email" :rules="[{ required: true, type: 'email', message: '请输入有效邮箱' }]">
|
||||
<a-input v-model:value="registerForm.email" placeholder="请输入邮箱" />
|
||||
</a-form-item>
|
||||
<a-form-item label="密码" name="password" :rules="[{ required: true, min: 6, message: '密码至少6位' }]">
|
||||
<a-input-password v-model:value="registerForm.password" placeholder="请输入密码" />
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit" block :loading="registerLoading">
|
||||
注册
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-modal>
|
||||
|
||||
<!-- 其他模态框 -->
|
||||
<a-modal v-model:open="showProfileModal" title="个人资料" @ok="saveProfile">
|
||||
<a-form :model="profileForm" layout="vertical">
|
||||
<a-form-item label="昵称">
|
||||
<a-input v-model:value="profileForm.nickname" placeholder="请输入昵称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="邮箱">
|
||||
<a-input v-model:value="profileForm.email" placeholder="请输入邮箱" />
|
||||
</a-form-item>
|
||||
<a-form-item label="手机号">
|
||||
<a-input v-model:value="profileForm.phone" placeholder="请输入手机号" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
|
||||
<a-modal v-model:open="showAboutModal" title="关于开心APP" :footer="null">
|
||||
<div class="about-content">
|
||||
<div class="app-info">
|
||||
<img src="https://r2.flowith.net/files/o/1752574406770-thoughtful_kaikai_character_generation_index_1@1024x1024.png" alt="开心APP" class="app-logo" />
|
||||
<h3>开心APP</h3>
|
||||
<p>版本 1.0.0</p>
|
||||
<p>你的情绪陪伴使者</p>
|
||||
</div>
|
||||
<div class="app-description">
|
||||
<p>开心APP致力于为用户提供温暖的情绪陪伴服务,通过AI助手"开开"与用户进行智能对话,帮助用户记录情绪、管理生活,共同成长。</p>
|
||||
</div>
|
||||
</div>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue'
|
||||
import {
|
||||
ArrowLeftOutlined,
|
||||
UserOutlined,
|
||||
SafetyOutlined,
|
||||
BellOutlined,
|
||||
EyeOutlined,
|
||||
BgColorsOutlined,
|
||||
DownloadOutlined,
|
||||
ClearOutlined,
|
||||
InfoCircleOutlined,
|
||||
FileProtectOutlined,
|
||||
FileTextOutlined,
|
||||
LogoutOutlined,
|
||||
RightOutlined,
|
||||
} from '@ant-design/icons-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { useUserStore, useAppStore } from '@/stores'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const appStore = useAppStore()
|
||||
|
||||
// 响应式数据
|
||||
const showLoginModal = ref(false)
|
||||
const showProfileModal = ref(false)
|
||||
const showSecurityModal = ref(false)
|
||||
const showAboutModal = ref(false)
|
||||
const showPrivacyModal = ref(false)
|
||||
const showTermsModal = ref(false)
|
||||
const loginTab = ref('login')
|
||||
const loginLoading = ref(false)
|
||||
const registerLoading = ref(false)
|
||||
const notificationEnabled = ref(true)
|
||||
const privacyMode = ref(false)
|
||||
const selectedTheme = ref('default')
|
||||
const userAvatar = ref('https://r2.flowith.net/files/o/1752574406770-thoughtful_kaikai_character_generation_index_1@1024x1024.png')
|
||||
|
||||
// 表单数据
|
||||
const loginForm = reactive({
|
||||
username: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
const registerForm = reactive({
|
||||
username: '',
|
||||
email: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
const profileForm = reactive({
|
||||
nickname: '',
|
||||
email: '',
|
||||
phone: ''
|
||||
})
|
||||
|
||||
// 方法
|
||||
const handleLogin = async () => {
|
||||
loginLoading.value = true
|
||||
try {
|
||||
const success = await userStore.login(loginForm)
|
||||
if (success) {
|
||||
message.success('登录成功')
|
||||
showLoginModal.value = false
|
||||
resetLoginForm()
|
||||
} else {
|
||||
message.error('登录失败,请检查用户名和密码')
|
||||
}
|
||||
} catch (error) {
|
||||
message.error('登录失败,请重试')
|
||||
} finally {
|
||||
loginLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleRegister = async () => {
|
||||
registerLoading.value = true
|
||||
try {
|
||||
// TODO: 实现注册逻辑
|
||||
message.success('注册成功')
|
||||
showLoginModal.value = false
|
||||
resetRegisterForm()
|
||||
} catch (error) {
|
||||
message.error('注册失败,请重试')
|
||||
} finally {
|
||||
registerLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const resetLoginForm = () => {
|
||||
loginForm.username = ''
|
||||
loginForm.password = ''
|
||||
}
|
||||
|
||||
const resetRegisterForm = () => {
|
||||
registerForm.username = ''
|
||||
registerForm.email = ''
|
||||
registerForm.password = ''
|
||||
}
|
||||
|
||||
const saveProfile = () => {
|
||||
userStore.updateProfile(profileForm)
|
||||
showProfileModal.value = false
|
||||
message.success('个人资料保存成功')
|
||||
}
|
||||
|
||||
const changeTheme = (theme: string) => {
|
||||
const themeColors = {
|
||||
default: '#4A90E2',
|
||||
orange: '#F5A623',
|
||||
green: '#52c41a',
|
||||
purple: '#722ed1'
|
||||
}
|
||||
|
||||
appStore.setTheme({
|
||||
primaryColor: themeColors[theme as keyof typeof themeColors]
|
||||
})
|
||||
message.success('主题切换成功')
|
||||
}
|
||||
|
||||
const exportData = () => {
|
||||
message.info('数据导出功能开发中...')
|
||||
}
|
||||
|
||||
const clearCache = () => {
|
||||
localStorage.clear()
|
||||
message.success('缓存清理成功')
|
||||
}
|
||||
|
||||
const logout = () => {
|
||||
userStore.logout()
|
||||
message.success('已退出登录')
|
||||
}
|
||||
|
||||
// 组件挂载
|
||||
onMounted(() => {
|
||||
if (userStore.user) {
|
||||
profileForm.nickname = userStore.user.nickname || ''
|
||||
profileForm.email = userStore.user.email || ''
|
||||
profileForm.phone = userStore.user.phone || ''
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.settings-page {
|
||||
min-height: 100vh;
|
||||
background: $light-gray;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
background: white;
|
||||
box-shadow: $shadow-sm;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.header-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $spacing-md $spacing-lg;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.header-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-md;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
color: $text-medium;
|
||||
|
||||
&:hover {
|
||||
color: $tech-blue;
|
||||
}
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: $font-size-lg;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page-main {
|
||||
padding: $spacing-lg;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.settings-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $spacing-lg;
|
||||
}
|
||||
|
||||
// 用户信息卡片
|
||||
.user-info-card {
|
||||
.user-profile {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-lg;
|
||||
}
|
||||
|
||||
.user-avatar {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.user-details {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: $font-size-xl;
|
||||
font-weight: $font-weight-semibold;
|
||||
color: $text-dark;
|
||||
margin: 0 0 $spacing-xs 0;
|
||||
}
|
||||
|
||||
.user-email {
|
||||
color: $text-medium;
|
||||
margin: 0 0 $spacing-md 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置卡片
|
||||
.settings-card {
|
||||
.settings-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $spacing-md 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
cursor: pointer;
|
||||
transition: background-color $transition-normal;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(74, 144, 226, 0.05);
|
||||
margin: 0 (-$spacing-lg);
|
||||
padding-left: $spacing-lg;
|
||||
padding-right: $spacing-lg;
|
||||
border-radius: $border-radius-md;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: $spacing-md;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.setting-icon {
|
||||
font-size: $font-size-lg;
|
||||
color: $tech-blue;
|
||||
}
|
||||
|
||||
.setting-text {
|
||||
.setting-title {
|
||||
font-weight: $font-weight-medium;
|
||||
color: $text-dark;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.setting-desc {
|
||||
font-size: $font-size-sm;
|
||||
color: $text-medium;
|
||||
}
|
||||
}
|
||||
|
||||
.setting-arrow {
|
||||
color: $text-medium;
|
||||
font-size: $font-size-sm;
|
||||
}
|
||||
}
|
||||
|
||||
// 退出登录区域
|
||||
.logout-section {
|
||||
margin-top: $spacing-lg;
|
||||
}
|
||||
|
||||
// 关于应用模态框
|
||||
.about-content {
|
||||
text-align: center;
|
||||
|
||||
.app-info {
|
||||
margin-bottom: $spacing-lg;
|
||||
|
||||
.app-logo {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: $border-radius-lg;
|
||||
margin-bottom: $spacing-md;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: $font-size-xl;
|
||||
font-weight: $font-weight-bold;
|
||||
color: $text-dark;
|
||||
margin-bottom: $spacing-xs;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $text-medium;
|
||||
margin-bottom: $spacing-xs;
|
||||
}
|
||||
}
|
||||
|
||||
.app-description {
|
||||
text-align: left;
|
||||
padding: $spacing-md;
|
||||
background: $light-gray;
|
||||
border-radius: $border-radius-md;
|
||||
|
||||
p {
|
||||
line-height: 1.6;
|
||||
color: $text-dark;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user