diff --git a/nkebao/src/pages/mobile/mine/main/index.tsx b/nkebao/src/pages/mobile/mine/main/index.tsx index 605dc1ec..4f98d71e 100644 --- a/nkebao/src/pages/mobile/mine/main/index.tsx +++ b/nkebao/src/pages/mobile/mine/main/index.tsx @@ -1,13 +1,11 @@ import React, { useState, useEffect } from "react"; import { useNavigate } from "react-router-dom"; -import { Card, NavBar, List, Button, Dialog, Toast } from "antd-mobile"; +import { Card, NavBar, List, Button, Toast } from "antd-mobile"; import { - LogoutOutlined, PhoneOutlined, MessageOutlined, DatabaseOutlined, FolderOpenOutlined, - BellOutlined, SettingOutlined, } from "@ant-design/icons"; import MeauMobile from "@/components/MeauMobile/MeauMoible"; @@ -15,6 +13,7 @@ import Layout from "@/components/Layout/Layout"; import style from "./index.module.scss"; import { useUserStore } from "@/store/module/user"; import { getDashboard } from "./api"; + const Mine: React.FC = () => { const navigate = useNavigate(); const { user } = useUserStore(); @@ -25,7 +24,6 @@ const Mine: React.FC = () => { content: 156, balance: 0, }); - const [showLogoutDialog, setShowLogoutDialog] = useState(false); // 用户信息 const currentUserInfo = { @@ -102,19 +100,6 @@ const Mine: React.FC = () => { loadStats(); }, []); - const handleLogout = () => { - // 清除本地存储的用户信息 - localStorage.removeItem("token"); - localStorage.removeItem("token_expired"); - localStorage.removeItem("userInfo"); - setShowLogoutDialog(false); - navigate("/login"); - Toast.show({ - content: "退出成功", - position: "top", - }); - }; - const handleFunctionClick = (path: string) => { navigate(path); }; @@ -227,42 +212,7 @@ const Mine: React.FC = () => { ))} - - {/* 退出登录按钮 */} - - - {/* 退出登录确认对话框 */} - setShowLogoutDialog(false)} - /> ); }; diff --git a/nkebao/src/pages/mobile/mine/setting/SecuritySetting.tsx b/nkebao/src/pages/mobile/mine/setting/SecuritySetting.tsx index bdd371b9..9ae89537 100644 --- a/nkebao/src/pages/mobile/mine/setting/SecuritySetting.tsx +++ b/nkebao/src/pages/mobile/mine/setting/SecuritySetting.tsx @@ -1,6 +1,6 @@ import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; -import { NavBar, List, Button, Dialog, Toast, Card, Input } from "antd-mobile"; +import { NavBar, List, Dialog, Toast, Card, Input } from "antd-mobile"; import { LockOutlined, MobileOutlined, @@ -10,7 +10,7 @@ import { import Layout from "@/components/Layout/Layout"; import { useUserStore } from "@/store/module/user"; import style from "./index.module.scss"; - +import NavCommon from "@/components/NavCommon"; const SecuritySetting: React.FC = () => { const navigate = useNavigate(); const { user } = useUserStore(); @@ -92,15 +92,7 @@ const SecuritySetting: React.FC = () => { ]; return ( - navigate(-1)} style={{ background: "#fff" }}> - - 安全设置 - - - } - > + }>
{/* 安全提示卡片 */} @@ -125,9 +117,7 @@ const SecuritySetting: React.FC = () => { prefix={item.icon} title={item.title} description={item.description} - extra={} onClick={item.onClick} - arrow /> ))} @@ -163,30 +153,36 @@ const SecuritySetting: React.FC = () => { title="修改密码" content={
- - setPasswordForm(prev => ({ ...prev, oldPassword: value })) - } - /> - - setPasswordForm(prev => ({ ...prev, newPassword: value })) - } - /> - - setPasswordForm(prev => ({ ...prev, confirmPassword: value })) - } - /> +
+ + setPasswordForm(prev => ({ ...prev, oldPassword: value })) + } + /> +
+
+ + setPasswordForm(prev => ({ ...prev, newPassword: value })) + } + /> +
+
+ + setPasswordForm(prev => ({ ...prev, confirmPassword: value })) + } + /> +
} closeOnAction diff --git a/nkebao/src/pages/mobile/mine/setting/index.module.scss b/nkebao/src/pages/mobile/mine/setting/index.module.scss index d3cc2ff5..ef57738d 100644 --- a/nkebao/src/pages/mobile/mine/setting/index.module.scss +++ b/nkebao/src/pages/mobile/mine/setting/index.module.scss @@ -1,30 +1,39 @@ .save-buttons { padding: 12px; - background: #fff; } .setting-page { padding: 12px; .user-card { - margin-bottom: 12px; - border-radius: 12px; + margin-bottom: 16px; + border-radius: 16px; overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1); + background: linear-gradient( + 135deg, + var(--primary-color) 0%, + var(--primary-color-dark) 100% + ); + position: relative; .user-info { display: flex; align-items: center; - padding: 16px; + padding: 20px; gap: 16px; + position: relative; + z-index: 1; .avatar { - width: 60px; - height: 60px; - border-radius: 30px; + width: 70px; + height: 70px; + border-radius: 35px; overflow: hidden; flex-shrink: 0; - background: #f0f0f0; - border: 2px solid #e0e0e0; + background: rgba(255, 255, 255, 0.2); + border: 3px solid rgba(255, 255, 255, 0.3); + position: relative; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); img { width: 100%; @@ -35,13 +44,18 @@ .avatar-placeholder { width: 100%; height: 100%; - background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + background: linear-gradient( + 135deg, + var(--primary-color) 0%, + var(--primary-color-dark) 100% + ); display: flex; align-items: center; justify-content: center; color: white; - font-size: 24px; + font-size: 28px; font-weight: bold; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } } @@ -50,19 +64,20 @@ min-width: 0; .username { - font-size: 18px; - font-weight: 600; - color: #333; - margin-bottom: 4px; + font-size: 20px; + font-weight: 700; + color: white; + margin-bottom: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .account { font-size: 14px; - color: #666; - margin-bottom: 4px; + color: rgba(255, 255, 255, 0.8); + margin-bottom: 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -70,99 +85,205 @@ .role { font-size: 12px; - color: #999; - background: #f0f0f0; - padding: 2px 8px; - border-radius: 10px; + color: rgba(255, 255, 255, 0.9); + background: rgba(255, 255, 255, 0.2); + padding: 4px 12px; + border-radius: 12px; display: inline-block; + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.3); } } + + .user-actions { + flex-shrink: 0; + } } } .setting-group { - margin-bottom: 12px; - border-radius: 12px; + margin-bottom: 16px; + border-radius: 16px; overflow: hidden; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + background: white; + border: 1px solid rgba(0, 0, 0, 0.05); .group-title { - padding: 12px 16px 8px; - font-size: 14px; - font-weight: 600; - color: #666; - background: #fafafa; + padding: 16px 20px 12px; + font-size: 15px; + font-weight: 700; + color: #333; + background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%); border-bottom: 1px solid #f0f0f0; + display: flex; + align-items: center; + gap: 8px; + + .group-icon { + font-size: 16px; + } } - :global(.adm-list) { - --border-inner: solid 1px #f0f0f0; - --border-top: none; - --border-bottom: none; - --adm-font-size-main: 16px; - --adm-color-text: #333; - --adm-color-text-secondary: #666; + .setting-list { + :global(.adm-list) { + --border-inner: solid 1px #f0f0f0; + --border-top: none; + --border-bottom: none; + --adm-font-size-main: 16px; + --adm-color-text: #333; + --adm-color-text-secondary: #666; - .adm-list-item { - padding: 16px; - min-height: 56px; + .adm-list-item { + padding: 16px 20px; + min-height: 64px; + transition: all 0.2s ease; + position: relative; - .adm-list-item-content { - padding: 0; - } - - .adm-list-item-content-prefix { - margin-right: 12px; - font-size: 20px; - color: var(--primary-color); - } - - .adm-list-item-content-main { - flex: 1; - min-width: 0; - - .adm-list-item-content-main-title { - font-size: 16px; - font-weight: 500; - color: #333; - margin-bottom: 4px; + &:hover { + background: #f8f9fa; + transform: translateX(4px); } - .adm-list-item-content-main-description { - font-size: 14px; - color: #666; - line-height: 1.4; + &:active { + background: #e9ecef; + transform: scale(0.98); } - } - .adm-list-item-content-extra { - margin-left: 8px; - } + .adm-list-item-content { + padding: 0; + } - &:last-child { - border-bottom: none; - } + .adm-list-item-content-prefix { + margin-right: 16px; + } - &:active { - background-color: #f5f5f5; + .adm-list-item-content-main { + flex: 1; + min-width: 0; + + .adm-list-item-content-main-title { + font-size: 16px; + font-weight: 600; + color: #333; + margin-bottom: 4px; + } + + .adm-list-item-content-main-description { + font-size: 14px; + color: #666; + line-height: 1.4; + } + } + + .adm-list-item-content-extra { + margin-left: 8px; + } + + &:last-child { + border-bottom: none; + } } } } } + .setting-icon { + width: 40px; + height: 40px; + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-size: 18px; + background: rgba(24, 144, 255, 0.1); + color: var(--primary-color); + transition: all 0.2s ease; + + &:hover { + transform: scale(1.1); + background: rgba(24, 144, 255, 0.2); + } + } + + .setting-title { + display: flex; + align-items: center; + gap: 8px; + } + + .setting-badge { + background: #ff4d4f; + color: white; + font-size: 10px; + padding: 2px 6px; + border-radius: 8px; + font-weight: 500; + } + + .setting-item { + transition: all 0.2s ease; + } + .version-info { - text-align: center; - padding: 24px 16px; - color: #999; - font-size: 12px; - line-height: 1.6; + .version-card { + background: white; + border-radius: 16px; + padding: 24px; + margin-bottom: 16px; + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08); + display: flex; + align-items: center; + gap: 16px; - span { - display: block; - margin-bottom: 4px; + .app-logo { + flex-shrink: 0; + width: 60px; + height: 60px; + img { + width: 100%; + height: 100%; + object-fit: cover; + } + } - &:last-child { - margin-bottom: 0; + .version-details { + flex: 1; + text-align: left; + + .app-name { + font-size: 18px; + font-weight: 700; + color: #333; + margin-bottom: 4px; + } + + .version-text { + font-size: 14px; + color: #666; + margin-bottom: 2px; + } + + .build-info { + font-size: 12px; + color: #999; + } + } + } + + .copyright { + color: #999; + font-size: 12px; + line-height: 1.6; + text-align: center; + span { + display: block; + margin-bottom: 4px; + + &:last-child { + margin-bottom: 0; + color: #ccc; + } } } } @@ -252,7 +373,9 @@ flex-direction: column; gap: 12px; padding: 16px 0; - + .line { + margin-bottom: 12px; + } :global(.adm-input) { border: 1px solid #d9d9d9; border-radius: 8px; diff --git a/nkebao/src/pages/mobile/mine/setting/index.tsx b/nkebao/src/pages/mobile/mine/setting/index.tsx index 3f728d75..8090bdc2 100644 --- a/nkebao/src/pages/mobile/mine/setting/index.tsx +++ b/nkebao/src/pages/mobile/mine/setting/index.tsx @@ -7,12 +7,15 @@ import { InfoCircleOutlined, LogoutOutlined, SettingOutlined, + LockOutlined, + HeartOutlined, + StarOutlined, } from "@ant-design/icons"; import Layout from "@/components/Layout/Layout"; import { useUserStore } from "@/store/module/user"; import { useSettingsStore } from "@/store/module/settings"; import style from "./index.module.scss"; - +import NavCommon from "@/components/NavCommon"; interface SettingItem { id: string; title: string; @@ -22,6 +25,8 @@ interface SettingItem { value?: boolean; path?: string; onClick?: () => void; + badge?: string; + color?: string; } const Setting: React.FC = () => { @@ -29,15 +34,11 @@ const Setting: React.FC = () => { const { user, logout } = useUserStore(); const { settings, updateSetting } = useSettingsStore(); const [showLogoutDialog, setShowLogoutDialog] = useState(false); + const [avatarError, setAvatarError] = useState(false); - // 处理开关变化 - const handleSwitchChange = (key: keyof typeof settings, value: boolean) => { - updateSetting(key, value); - - Toast.show({ - content: `设置已${value ? "开启" : "关闭"}`, - position: "top", - }); + // 处理头像加载错误 + const handleAvatarError = () => { + setAvatarError(true); }; // 退出登录 @@ -78,6 +79,7 @@ const Setting: React.FC = () => { icon: , type: "navigate", path: "/userSet", + color: "var(--primary-color)", }, { id: "security", @@ -86,12 +88,22 @@ const Setting: React.FC = () => { icon: , type: "navigate", path: "/security", + color: "var(--primary-color)", }, ], }, { - title: "其他", + title: "应用设置", items: [ + { + id: "privacy", + title: "隐私保护", + description: "数据隐私、权限管理", + icon: , + type: "navigate", + path: "/privacy", + color: "var(--primary-color)", + }, { id: "clearCache", title: "清除缓存", @@ -99,15 +111,14 @@ const Setting: React.FC = () => { icon: , type: "button", onClick: handleClearCache, + color: "var(--primary-color)", + badge: "2.3MB", }, - { - id: "privacy", - title: "用户隐私协议", - description: "查看用户隐私协议和数据处理说明", - icon: , - type: "navigate", - path: "/privacy", - }, + ], + }, + { + title: "其他", + items: [ { id: "about", title: "关于我们", @@ -115,6 +126,7 @@ const Setting: React.FC = () => { icon: , type: "navigate", path: "/about", + color: "var(--primary-color)", }, { id: "logout", @@ -123,6 +135,7 @@ const Setting: React.FC = () => { icon: , type: "button", onClick: () => setShowLogoutDialog(true), + color: "#ff4d4f", }, ], }, @@ -143,37 +156,55 @@ const Setting: React.FC = () => { return ( + {item.icon} +
+ } + title={ +
+ {item.title} + {item.badge && ( + {item.badge} + )} +
+ } description={item.description} extra={ item.type === "switch" ? ( - item.onClick?.()} /> + item.onClick?.()} + style={ + { + "--checked-color": item.color || "var(--primary-color)", + } as React.CSSProperties + } + /> ) : null } onClick={handleClick} arrow={item.type === "navigate"} + className={style["setting-item"]} /> ); }; return ( - navigate(-1)} style={{ background: "#fff" }}> - - 设置 - - - } - > + }>
{/* 用户信息卡片 */}
- {user?.avatar ? ( - 头像 + {user?.avatar && !avatarError ? ( + 头像 ) : (
{user?.username?.charAt(0) || "用"} @@ -191,21 +222,54 @@ const Setting: React.FC = () => { {user?.isAdmin === 1 ? "管理员" : "普通用户"}
+
+ +
{/* 设置列表 */} {settingGroups.map((group, groupIndex) => ( -
{group.title}
- {group.items.map(renderSettingItem)} +
+ ⚙️ + {group.title} +
+ + {group.items.map(renderSettingItem)} +
))} {/* 版本信息 */}
- 版本 1.0.0 - © 2024 存客宝管理系统 +
+
+ +
+
+
存客宝
+
版本 3.0.0
+
Build 2025-7-30
+
+
+
+ © 2024 存客宝管理系统 + 让客户管理更简单 +