diff --git a/src/app.config.ts b/src/app.config.ts index be35419..b58ead8 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -1,5 +1,6 @@ export default defineAppConfig({ pages: [ + 'pages/login/index/index', 'pages/login/verification/index', 'pages/login/terms/index', @@ -11,8 +12,11 @@ export default defineAppConfig({ 'pages/detail/index', 'pages/message/index', 'pages/orderCheck/index', + 'pages/userInfo/myself/index', // 个人中心 - + 'pages/userInfo/edit/index', // 个人中心 + 'pages/userInfo/favorites/index', // 个人中心 + 'pages/userInfo/orders/index', // 个人中心 // 'pages/mapDisplay/index', ], diff --git a/src/app.ts b/src/app.ts index cf34ab9..03ca3a2 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,11 +1,12 @@ import { Component, ReactNode } from 'react' -import Taro from '@tarojs/taro'; import './nutui-theme.scss' import './app.scss' import { useDictionaryStore } from './store/dictionaryStore' import { useGlobalStore } from './store/global' import { check_login_status } from './services/loginService'; +// import { getNavbarHeight } from "@/utils/getNavbarHeight"; + interface AppProps { children: ReactNode } @@ -15,13 +16,6 @@ class App extends Component { onLaunch() { console.log('小程序启动,初始化逻辑写这里') - // 已经登录过就跳转到 列表页 - let is_login = check_login_status() - if (is_login) { - Taro.redirectTo({ - url: '/pages/list/index' - }) - } } componentDidMount() { diff --git a/src/components/Auth/index.tsx b/src/components/Auth/index.tsx new file mode 100644 index 0000000..137e358 --- /dev/null +++ b/src/components/Auth/index.tsx @@ -0,0 +1,51 @@ +import React, { useEffect, useState } from 'react' +import Taro from '@tarojs/taro' +import { View } from '@tarojs/components' +import { check_login_status } from '@/services/loginService' + + + +export function getCurrentFullPath(): string { + const pages = Taro.getCurrentPages() + const currentPage = pages.at(-1) + + if (currentPage) { + console.log(currentPage, 'currentPage get') + const route = currentPage.route + const options = currentPage.options || {} + + const query = Object.keys(options) + .map(key => `${key}=${options[key]}`) + .join('&') + + return query ? `/${route}?${query}` : `/${route}` + } + return '' +} + +export default function withAuth

(WrappedComponent: React.ComponentType

) { + const ComponentWithAuth: React.FC

= (props: P) => { + const [authed, setAuthed] = useState(false) + useEffect(() => { + const is_login = check_login_status() + setAuthed(is_login) + + if (!is_login) { + const currentPage = getCurrentFullPath() + Taro.redirectTo({ + url: `/pages/login/index/index${ + currentPage ? `?redirect=${encodeURIComponent(currentPage)}` : '' + }`, + }) + } + }, []) + + if (!authed) { + return // 空壳,避免 children 渲染出错 + } + + return + } + + return ComponentWithAuth +} \ No newline at end of file diff --git a/src/components/EditModal/EditModal.scss b/src/components/EditModal/EditModal.scss new file mode 100644 index 0000000..aae757b --- /dev/null +++ b/src/components/EditModal/EditModal.scss @@ -0,0 +1,178 @@ +// 编辑弹窗组件样式 +.edit_modal_overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + z-index: 1000; + display: flex; + align-items: flex-end; + justify-content: center; +} + +.edit_modal_container { + width: 100%; + background: #FAFAFA; + border-radius: 20px 20px 0px 0px; + animation: slideUp 0.3s ease-out; +} + +@keyframes slideUp { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } +} + +// 标题栏 +.modal_header { + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px; + border-bottom: 1px solid rgba(0, 0, 0, 0.06); + + .modal_title { + font-family: 'PingFang SC'; + font-weight: 600; + font-size: 22px; + line-height: 1.27em; + color: #000000; + flex: 1; + text-align: center; + } + + .close_button { + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; + background: #FFFFFF; + border: 1px solid rgba(0, 0, 0, 0.06); + border-radius: 50%; + cursor: pointer; + box-shadow: 0px 4px 36px 0px rgba(0, 0, 0, 0.06); + + .close_icon { + position: relative; + width: 24px; + height: 24px; + + .close_line { + position: absolute; + top: 50%; + left: 50%; + width: 10px; + height: 2px; + background: #000000; + transform: translate(-50%, -50%) rotate(45deg); + + &:nth-child(2) { + transform: translate(-50%, -50%) rotate(-45deg); + } + } + } + } +} + +// 内容区域 +.modal_content { + padding: 0px 16px 20px; + display: flex; + flex-direction: column; + gap: 20px; + + .input_container { + display: flex; + flex-direction: column; + gap: 8px; + background: #FFFFFF; + border: 1px solid rgba(0, 0, 0, 0.06); + border-radius: 12px; + padding: 10px 16px; + box-shadow: 0px 4px 36px 0px rgba(0, 0, 0, 0.06); + min-height: 120px; + + .text_input { + flex: 1; + font-family: 'PingFang SC'; + font-weight: 400; + font-size: 14px; + line-height: 1.71em; + color: #000000; + border: none; + background: transparent; + outline: none; + resize: none; + min-height: 80px; + + &::placeholder { + color: rgba(60, 60, 67, 0.3); + } + } + + .char_count { + display: flex; + justify-content: flex-end; + align-items: center; + + .count_text { + font-family: 'PingFang SC'; + font-weight: 400; + font-size: 14px; + line-height: 1.71em; + color: rgba(60, 60, 67, 0.3); + } + } + } + + .validation_message { + padding: 0px 8px; + + .validation_text { + font-family: 'PingFang SC'; + font-weight: 400; + font-size: 12px; + line-height: 1.5em; + color: rgba(60, 60, 67, 0.6); + } + } +} + +// 底部按钮 +.modal_footer { + padding: 8px 10px; + display: flex; + gap: 8px; + + .save_button { + flex: 1; + height: 52px; + background: #000000; + border: 1px solid rgba(0, 0, 0, 0.06); + border-radius: 16px; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + box-shadow: 0px 8px 64px 0px rgba(0, 0, 0, 0.1); + backdrop-filter: blur(32px); + + .save_text { + font-family: 'PingFang SC'; + font-weight: 600; + font-size: 16px; + line-height: 1.4em; + color: rgba(255, 255, 255, 0.3); + } + + &:active { + transform: scale(0.98); + } + } +} \ No newline at end of file diff --git a/src/components/EditModal/index.tsx b/src/components/EditModal/index.tsx new file mode 100644 index 0000000..0f97ce9 --- /dev/null +++ b/src/components/EditModal/index.tsx @@ -0,0 +1,119 @@ +import React, { useState, useEffect } from 'react'; +import { View, Text, Textarea, Button } from '@tarojs/components'; +import Taro from '@tarojs/taro'; +import './EditModal.scss'; + +interface EditModalProps { + visible: boolean; + title: string; + placeholder: string; + initialValue: string; + maxLength: number; + onSave: (value: string) => void; + onCancel: () => void; + validationMessage?: string; +} + +const EditModal: React.FC = ({ + visible, + title, + placeholder, + initialValue, + maxLength, + onSave, + onCancel, + validationMessage +}) => { + const [value, setValue] = useState(initialValue); + const [isValid, setIsValid] = useState(true); + + useEffect(() => { + if (visible) { + setValue(initialValue); + } + }, [visible, initialValue]); + + const handle_input_change = (e: any) => { + const new_value = e.detail.value; + setValue(new_value); + + // 验证输入 + const valid = new_value.length >= 2 && new_value.length <= maxLength; + setIsValid(valid); + }; + + const handle_save = () => { + if (!isValid) { + Taro.showToast({ + title: validationMessage || `请填写 2-${maxLength} 个字符`, + icon: 'none', + duration: 2000 + }); + return; + } + + onSave(value); + }; + + const handle_cancel = () => { + setValue(initialValue); + onCancel(); + }; + + if (!visible) { + return null; + } + + return ( + + + {/* 标题栏 */} + + {title} + + + + + + + + + {/* 内容区域 */} + + {/* 文本输入区域 */} + +