feat: 忘记密码/修改密码 + 设置页结构重组 + barrel cleanup + LoginPage 版本统一
新增: - ForgotPasswordModal — 手机号+短信验证码重置密码 (AuthAPI.resetPassword) - ChangePasswordModal — 当前密码验证后修改密码 (AuthAPI.changePassword) - useSmsCooldown Hook — 通用短信发送冷却逻辑,供注册/忘记密码复用 - PasswordSetting — 设置页账号安全区块,双选项:修改密码 / 短信验证码重置 修改: - LoginForm \"忘记密码?\" 链接接入 ForgotPasswordModal(替换 TODO) - LoginPage 移除 edition 业务版本 UI 区分,登录/注册 Tab 全局统一 - 设置页 Section 组件移入 blocks/ 子目录(git mv 保留历史) - auth.ts sendSms URL 修正: /sms/send → /send-sms 清理: - settings/index.ts 移除 4 个未使用 re-export,精简为仅 SettingsPage - navbar/index.ts 移除未使用 re-export,精简为仅 NavBar 文档: - WORKLOG.md 新增 2026-06-08 工作日志 - ARCHITECTURE.md / PROJECT.md 更新设置页目录结构与新组件 - TODO.md 忘记密码流程标记已完成 + 短信人机验证列入后期优化
This commit is contained in:
@@ -12,8 +12,8 @@
|
|||||||
// - 用户可读错误信息(errorMessage)
|
// - 用户可读错误信息(errorMessage)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
import { useMemo } from 'react';
|
import {useMemo} from 'react';
|
||||||
import { useAppContext } from '@/contexts/app-context';
|
import {useAppContext} from '@/contexts/app-context';
|
||||||
import {
|
import {
|
||||||
TaskAPI,
|
TaskAPI,
|
||||||
ModelAPI,
|
ModelAPI,
|
||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
type Banner,
|
type Banner,
|
||||||
type ModelCategory,
|
type ModelCategory,
|
||||||
} from '@/services/modules';
|
} from '@/services/modules';
|
||||||
import { useAsyncData, useAsyncMutation } from './use-async';
|
import {useAsyncData, useAsyncMutation} from './use-async';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// Banner
|
// Banner
|
||||||
@@ -34,12 +34,12 @@ import { useAsyncData, useAsyncMutation } from './use-async';
|
|||||||
|
|
||||||
/** 首页轮播图数据 Hook */
|
/** 首页轮播图数据 Hook */
|
||||||
export function useBannerList() {
|
export function useBannerList() {
|
||||||
const { isLoggedIn } = useAppContext();
|
const {isLoggedIn} = useAppContext();
|
||||||
|
|
||||||
return useAsyncData<Banner[]>(
|
return useAsyncData<Banner[]>(
|
||||||
fetchBanners,
|
fetchBanners,
|
||||||
[],
|
[],
|
||||||
{ enabled: isLoggedIn, label: 'banner-list' },
|
{enabled: isLoggedIn, label: 'banner-list'},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,12 +49,12 @@ export function useBannerList() {
|
|||||||
|
|
||||||
/** 模型列表数据 Hook(按类别分别请求后合并) */
|
/** 模型列表数据 Hook(按类别分别请求后合并) */
|
||||||
export function useModelList() {
|
export function useModelList() {
|
||||||
const { isLoggedIn } = useAppContext();
|
const {isLoggedIn} = useAppContext();
|
||||||
|
|
||||||
// 使用单个 fetcher 返回合并后的结果
|
// 使用单个 fetcher 返回合并后的结果
|
||||||
const result = useAsyncData<ModelsListResponseBody[]>(
|
const result = useAsyncData<ModelsListResponseBody[]>(
|
||||||
async () => {
|
async () => {
|
||||||
const categories: ModelCategory[] = ['txt2img', 'img2img', 'img2video', 'txt2audio'];
|
const categories: ModelCategory[] = ["image_to_image", "text_to_image", "image_to_video", "text_to_audio"];
|
||||||
const results = await Promise.allSettled(
|
const results = await Promise.allSettled(
|
||||||
categories.map((category) =>
|
categories.map((category) =>
|
||||||
ModelAPI.fetchModels({
|
ModelAPI.fetchModels({
|
||||||
@@ -77,7 +77,7 @@ export function useModelList() {
|
|||||||
return allModels;
|
return allModels;
|
||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
{ enabled: isLoggedIn, label: 'model-list' },
|
{enabled: isLoggedIn, label: 'model-list'},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 按类别分组
|
// 按类别分组
|
||||||
@@ -116,13 +116,13 @@ export interface UseTaskListParams {
|
|||||||
* 本 Hook 仅负责数据获取、竞态控制、错误日志。
|
* 本 Hook 仅负责数据获取、竞态控制、错误日志。
|
||||||
*/
|
*/
|
||||||
export function useTaskList(params: UseTaskListParams) {
|
export function useTaskList(params: UseTaskListParams) {
|
||||||
const { isLoggedIn } = useAppContext();
|
const {isLoggedIn} = useAppContext();
|
||||||
const { requestParams, refreshSignal = 0 } = params;
|
const {requestParams, refreshSignal = 0} = params;
|
||||||
|
|
||||||
return useAsyncData(
|
return useAsyncData(
|
||||||
() => TaskAPI.getTaskList(requestParams),
|
() => TaskAPI.getTaskList(requestParams),
|
||||||
[requestParams, refreshSignal],
|
[requestParams, refreshSignal],
|
||||||
{ enabled: isLoggedIn, label: 'task-list' },
|
{enabled: isLoggedIn, label: 'task-list'},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,12 +132,12 @@ export function useTaskList(params: UseTaskListParams) {
|
|||||||
|
|
||||||
/** 任务详情 Hook(taskId 为 null 时不请求) */
|
/** 任务详情 Hook(taskId 为 null 时不请求) */
|
||||||
export function useTaskDetail(taskId: string | null | undefined) {
|
export function useTaskDetail(taskId: string | null | undefined) {
|
||||||
const { isLoggedIn } = useAppContext();
|
const {isLoggedIn} = useAppContext();
|
||||||
|
|
||||||
return useAsyncData<TaskInfoItemResponseBody>(
|
return useAsyncData<TaskInfoItemResponseBody>(
|
||||||
() => TaskAPI.getTaskInfo(taskId!),
|
() => TaskAPI.getTaskInfo(taskId!),
|
||||||
[taskId],
|
[taskId],
|
||||||
{ enabled: isLoggedIn && !!taskId, label: 'task-detail' },
|
{enabled: isLoggedIn && !!taskId, label: 'task-detail'},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,5 +162,5 @@ export function useSubmitTask(options?: {
|
|||||||
|
|
||||||
// ---------- 重新导出类型和工具 ----------
|
// ---------- 重新导出类型和工具 ----------
|
||||||
|
|
||||||
export { MODEL_CATEGORY_LABELS };
|
export {MODEL_CATEGORY_LABELS};
|
||||||
export type { ModelCategory, ModelsListResponseBody, TaskInfoItemResponseBody, Banner };
|
export type {ModelCategory, ModelsListResponseBody, TaskInfoItemResponseBody, Banner};
|
||||||
|
|||||||
Reference in New Issue
Block a user