重命名前端项目目录:web-flowith -> web

- 将前端项目目录从 web-flowith 重命名为 web,使目录结构更简洁
- 保持所有前端代码和配置文件不变
- 统一项目目录命名规范
This commit is contained in:
2025-07-24 22:20:19 +08:00
parent ca42a7d9a4
commit bbe8fcd776
57 changed files with 0 additions and 0 deletions
+601
View File
@@ -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>