100 lines
6.2 KiB
Markdown
100 lines
6.2 KiB
Markdown
|
|
# AGENTS.md - `views/setting`
|
||
|
|
|
||
|
|
## Scope
|
||
|
|
|
||
|
|
This file applies to `src/views/setting/**`.
|
||
|
|
|
||
|
|
This directory implements the account settings page at route `/settings`. The route is cached in `src/router/index.ts` with `meta: { cache: true }`, so stateful changes should handle re-entry and refresh deliberately.
|
||
|
|
|
||
|
|
## Project Rules
|
||
|
|
|
||
|
|
- Do not start local services by default. Assume the project service is already running unless the user explicitly asks you to start one, or you first ask for permission because runtime verification requires it.
|
||
|
|
- Keep the current Vue 3 style: Composition API, `<script setup lang="ts">`, typed props/emits, and scoped Less in SFCs.
|
||
|
|
- Prefer `rg` for code search.
|
||
|
|
- Keep edits focused on this feature. Do not refactor unrelated settings, router, API, or language files unless the setting page change requires it.
|
||
|
|
|
||
|
|
## Page Architecture
|
||
|
|
|
||
|
|
- `index.vue` is the route-level composition surface. Keep it thin: page shell, banner, section composition, and lifecycle wiring only.
|
||
|
|
- `useSettingsForm.ts` owns settings state, API calls, save/discard behavior, email verification state, validation, and language synchronization.
|
||
|
|
- `types.ts` owns setting-page domain types and option constants.
|
||
|
|
- `components/SettingsSection.vue` provides the two-column section layout.
|
||
|
|
- `components/ProfileSection.vue` renders profile fields, role selection, and avatar upload.
|
||
|
|
- `components/SecuritySection.vue` renders email/password editing controls and emits security actions upward.
|
||
|
|
- `components/RegionSection.vue` renders language and region selectors.
|
||
|
|
- `components/SettingsActions.vue` renders edit/save/verify/discard actions.
|
||
|
|
- `components/EmailVerificationDialog.vue` owns the verification-code modal UI, countdown, local code input, and submit/resend events.
|
||
|
|
- `components/Radio.vue` is a local button-based single/multiple select control. For role selection, it is used with `multiple` and `max="2"`.
|
||
|
|
|
||
|
|
## Data Flow
|
||
|
|
|
||
|
|
- Preserve the `sourceData` / `draftData` split in `useSettingsForm.ts`.
|
||
|
|
- `sourceData` is the last loaded/saved server state.
|
||
|
|
- `draftData` is the editable copy used while `isEditing` is true.
|
||
|
|
- `displayData` switches between them based on `isEditing`.
|
||
|
|
- Child components should receive data through props or `v-model:*` bindings and report changes with typed emits.
|
||
|
|
- Do not let child components mutate parent objects directly.
|
||
|
|
- Keep security-only draft fields in `securityDraft` (`newEmail`, `newPassword`, `currentPassword`) rather than mixing them into `draftData`.
|
||
|
|
- `handleDiscard()` must reset profile draft, security draft, verification state, and section editing flags.
|
||
|
|
|
||
|
|
## API Contracts
|
||
|
|
|
||
|
|
The setting page currently depends on `src/api/user.ts`:
|
||
|
|
|
||
|
|
- `fetchUserProfile()` -> `/buyer/profile/getProfile`
|
||
|
|
- `updateUserProfile(data)` -> `/buyer/profile/setProfile`
|
||
|
|
- `updateUserAvatar({ avatarUrl })` -> `/buyer/profile/setAvatar`
|
||
|
|
- `uploadFile(file)` -> `/buyer/profile/upload`
|
||
|
|
- `fetchVerifyCode()` -> `/buyer/profile/sendEmailChangeCode`
|
||
|
|
- `verifyEmailCode(verifyCode)` -> `/buyer/profile/verifyEmailChangeCode`
|
||
|
|
|
||
|
|
When saving settings:
|
||
|
|
|
||
|
|
- Trim text fields before building the payload.
|
||
|
|
- Send `roles` as `string[]`.
|
||
|
|
- Send `verifyCode` only when email or password is being changed.
|
||
|
|
- Hash `oldPassword` and `newPassword` with `md5` only when changing password.
|
||
|
|
- Keep email/password verification behavior centralized in `useSettingsForm.ts`; child components should only emit intent.
|
||
|
|
|
||
|
|
## Language And Region
|
||
|
|
|
||
|
|
- Frontend setting values are `english` and `chinese`.
|
||
|
|
- i18n locale values are `ENGLISH` and `CHINESE_SIMPLIFIED`.
|
||
|
|
- Backend language values are `en` and `zh-CN`.
|
||
|
|
- Keep all language mapping in `useSettingsForm.ts` unless it becomes shared with another feature.
|
||
|
|
- After saving a changed language, update `locale.value` and `localStorage.language`.
|
||
|
|
- Regions come from `src/utils/area.ts`; display labels are translated through `area.<key>` in `src/lang/en.ts` and `src/lang/zh-cn.ts`.
|
||
|
|
- When adding a language, role, message, or region label, update both language files.
|
||
|
|
|
||
|
|
## Validation And UX
|
||
|
|
|
||
|
|
- Email changes require a valid email format and a successful verification before save.
|
||
|
|
- Password changes use `validateLength`, `validateSpecial`, and `validateCase` from `src/views/login/tools`.
|
||
|
|
- New password must not equal the current password.
|
||
|
|
- Password changes also require verification using the current account email.
|
||
|
|
- `SettingsActions.vue` intentionally shows the Verify Email action before Save when `needsEmailVerification` is true.
|
||
|
|
- `EmailVerificationDialog.vue` owns its 60-second resend countdown and clears timers on close/unmount.
|
||
|
|
- Avoid adding visible instructional copy unless the product requirement asks for it; most labels and tips already come from i18n.
|
||
|
|
|
||
|
|
## Styling
|
||
|
|
|
||
|
|
- Existing layout uses fixed `rem` sizing, Kaisei font classes, white/gray/black styling, and Element Plus controls restyled with `:deep`.
|
||
|
|
- Keep SFC styles scoped.
|
||
|
|
- Reuse local Less mixins such as `.field-text()`, `.field-frame()`, and `.control-wrapper()` within components when extending matching controls.
|
||
|
|
- Preserve the two-column settings layout: left label/description and right content area.
|
||
|
|
- Be careful with responsive changes: this page currently has large fixed widths and desktop-oriented spacing.
|
||
|
|
|
||
|
|
## Known Maintenance Notes
|
||
|
|
|
||
|
|
- `RegionSection.vue` imports `RegionValue` from `../types`, but `types.ts` currently does not export `RegionValue`. If touching region typing, define/export a proper region type instead of using `any`.
|
||
|
|
- `ProfileSection.vue` currently includes `console.log(file)` and `debugger` in avatar upload. Remove these when working on avatar upload.
|
||
|
|
- `ProfileSection.vue` reads `avatarUrl` through `(displayData as any)` even though `SettingsData` does not include it. If avatar display is changed, type the field explicitly.
|
||
|
|
- Some verification button markup in `SecuritySection.vue` is commented out. Prefer either restoring it intentionally or deleting stale comments when working in that area.
|
||
|
|
|
||
|
|
## Verification
|
||
|
|
|
||
|
|
- For type-only or state-flow changes, run `npm run type-check` when feasible.
|
||
|
|
- For production-impacting changes, run `npm run build-typeCheck` when feasible.
|
||
|
|
- Do not start `npm run dev` unless the user explicitly asks or has approved runtime verification.
|
||
|
|
- If you cannot run checks, explain why in the final response.
|