refactor: 消除占位页面 + 删除 barrel 导出 — 页面集中注册 + 直接导入
- 删除 8 个占位页面文件(Account/Vip/Recharge/Billing/Orders/Projects/Quota/ComplianceAssets) - PageDispatcher: PAGE_MAP 支持无组件页面自动渲染 PlaceholderPage - 新增页面只需在 PAGE_MAP 加一行配置,无需创建独立文件 - 删除 services/modules/index.ts barrel,13 个文件改为直接导入 - IDE 跳转到定义一步到位,import 自文档化 - TypeScript 编译零错误 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -12,11 +12,10 @@ import type { Platform, Edition } from '@shared/types';
|
|||||||
|
|
||||||
import { getPlatform, isDev } from '@/utils/platform';
|
import { getPlatform, isDev } from '@/utils/platform';
|
||||||
import { safeIpcOn, safeIpcOff } from '@/utils/ipc';
|
import { safeIpcOn, safeIpcOff } from '@/utils/ipc';
|
||||||
import type { LoginResponseBody } from '@/services/modules';
|
import { AuthAPI, type LoginResponseBody } from '@/services/modules/auth';
|
||||||
import { setToken, clearToken, initTokenStore } from '@/services/request';
|
import { setToken, clearToken, initTokenStore } from '@/services/request';
|
||||||
import { emit, EVENTS } from '@/utils/event-bus';
|
import { emit, EVENTS } from '@/utils/event-bus';
|
||||||
import { logger } from '@/utils/logger';
|
import { logger } from '@/utils/logger';
|
||||||
import { AuthAPI } from '@/services/modules';
|
|
||||||
import { getAutoLoginFlag, clearAutoLoginFlag } from '@/services/auth-persistence';
|
import { getAutoLoginFlag, clearAutoLoginFlag } from '@/services/auth-persistence';
|
||||||
import {
|
import {
|
||||||
initAuthRefresh,
|
initAuthRefresh,
|
||||||
|
|||||||
@@ -7,21 +7,18 @@
|
|||||||
// - floating → FloatingPanel(非模态浮动面板,可拖拽,不阻断交互)
|
// - floating → FloatingPanel(非模态浮动面板,可拖拽,不阻断交互)
|
||||||
//
|
//
|
||||||
// 支持多面板共存(floating 类型可同时打开多个)
|
// 支持多面板共存(floating 类型可同时打开多个)
|
||||||
|
//
|
||||||
|
// PAGE_MAP 集中注册所有可调度页面:
|
||||||
|
// 有真实组件 → { component: XxxPage }
|
||||||
|
// 占位页面 → 只写 label,自动渲染 PlaceholderPage
|
||||||
|
// 新增页面只需在这里加一行,无需创建独立文件
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
import {useState, useEffect, useCallback, useRef, type ComponentType} from 'react';
|
import { useState, useEffect, useCallback, useRef, type ComponentType } from 'react';
|
||||||
import {Modal, Drawer} from 'antd';
|
import { Modal, Drawer } from 'antd';
|
||||||
import {on, off, EVENTS} from '@/utils/event-bus';
|
import { on, off, EVENTS } from '@/utils/event-bus';
|
||||||
import {FloatingPanel} from '@/components/ui/FloatingPanel';
|
import { FloatingPanel } from '@/components/ui/FloatingPanel';
|
||||||
import {ComplianceAssetsPage} from '@/pages/compliance-assets/ComplianceAssetsPage';
|
import { WechatWorkPage } from '@/pages/wechat-work/WechatWorkPage';
|
||||||
import {AccountPage} from '@/pages/account/AccountPage';
|
|
||||||
import {VipPage} from '@/pages/vip/VipPage';
|
|
||||||
import {RechargePage} from '@/pages/recharge/RechargePage';
|
|
||||||
import {BillingPage} from '@/pages/billing/BillingPage';
|
|
||||||
import {OrdersPage} from '@/pages/orders/OrdersPage';
|
|
||||||
import {ProjectsPage} from '@/pages/projects/ProjectsPage';
|
|
||||||
import {QuotaPage} from '@/pages/quota/QuotaPage';
|
|
||||||
import {WechatWorkPage} from '@/pages/wechat-work/WechatWorkPage';
|
|
||||||
|
|
||||||
// ---------- 类型 ----------
|
// ---------- 类型 ----------
|
||||||
|
|
||||||
@@ -39,20 +36,54 @@ interface ActivePanel {
|
|||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- target → 页面组件映射 ----------
|
interface PageConfig {
|
||||||
|
/** 页面组件(未提供则使用占位组件) */
|
||||||
|
component?: ComponentType;
|
||||||
|
/** 页面标签(显示在容器标题栏) */
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
const PAGE_MAP: Record<string, ComponentType> = {
|
// ---------- 占位组件 ----------
|
||||||
'/compliance-assets': ComplianceAssetsPage,
|
|
||||||
'/account': AccountPage,
|
function PlaceholderPage({ label }: { label: string }) {
|
||||||
'/vip': VipPage,
|
return (
|
||||||
'/recharge': RechargePage,
|
<div style={{ padding: 8 }}>
|
||||||
'/billing': BillingPage,
|
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>{label} — 页面开发中</p>
|
||||||
'/orders': OrdersPage,
|
</div>
|
||||||
'/projects': ProjectsPage,
|
);
|
||||||
'/quota': QuotaPage,
|
}
|
||||||
'/wechat-work': WechatWorkPage,
|
|
||||||
|
/** 创建一个包装了 label 的稳定占位组件(模块级,避免渲染时重建) */
|
||||||
|
function makePlaceholder(label: string): ComponentType {
|
||||||
|
const Placeholder = () => <PlaceholderPage label={label} />;
|
||||||
|
return Placeholder;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------- target → 页面组件映射 ----------
|
||||||
|
//
|
||||||
|
// 新增页面只需在此加一行 ——
|
||||||
|
// 有自定义组件:{ component: XxxPage, label: '页面标题' }
|
||||||
|
// 占位页面: { label: '页面标题' } ← 自动渲染 "页面标题 — 页面开发中"
|
||||||
|
|
||||||
|
const PAGE_MAP: Record<string, PageConfig> = {
|
||||||
|
'/wechat-work': { component: WechatWorkPage, label: '企业微信' },
|
||||||
|
'/compliance-assets': { label: '合规素材库' },
|
||||||
|
'/account': { label: '查帐户' },
|
||||||
|
'/vip': { label: '开会员/激活' },
|
||||||
|
'/recharge': { label: '充值积分' },
|
||||||
|
'/billing': { label: '消费记录' },
|
||||||
|
'/orders': { label: '订单明细' },
|
||||||
|
'/projects': { label: '项目管理' },
|
||||||
|
'/quota': { label: '查配额' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 解析页面组件:有自定义组件用自定义,否则用占位 */
|
||||||
|
function resolvePage(target: string): ComponentType | null {
|
||||||
|
const config = PAGE_MAP[target];
|
||||||
|
if (!config) return null;
|
||||||
|
return config.component || makePlaceholder(config.label);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------- 组件 ----------
|
// ---------- 组件 ----------
|
||||||
|
|
||||||
export function PageDispatcher() {
|
export function PageDispatcher() {
|
||||||
@@ -66,7 +97,7 @@ export function PageDispatcher() {
|
|||||||
// 监听 OPEN_PAGE 事件
|
// 监听 OPEN_PAGE 事件
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handler = (payload: unknown) => {
|
const handler = (payload: unknown) => {
|
||||||
const {target, modalType, label} = payload as PageEventPayload;
|
const { target, modalType, label } = payload as PageEventPayload;
|
||||||
|
|
||||||
if (!target || !PAGE_MAP[target]) {
|
if (!target || !PAGE_MAP[target]) {
|
||||||
console.warn(`[PageDispatcher] 未找到页面组件: ${target}`);
|
console.warn(`[PageDispatcher] 未找到页面组件: ${target}`);
|
||||||
@@ -76,10 +107,10 @@ export function PageDispatcher() {
|
|||||||
if (modalType === 'floating') {
|
if (modalType === 'floating') {
|
||||||
// 浮动面板:追加到列表
|
// 浮动面板:追加到列表
|
||||||
const id = `fp-${nextIdRef.current++}`;
|
const id = `fp-${nextIdRef.current++}`;
|
||||||
setFloatingPanels((prev) => [...prev, {id, target, label}]);
|
setFloatingPanels((prev) => [...prev, { id, target, label }]);
|
||||||
} else {
|
} else {
|
||||||
// modal / drawer:单实例,覆盖之前的
|
// modal / drawer:单实例,覆盖之前的
|
||||||
setSingleton({target, modalType, label});
|
setSingleton({ target, modalType, label });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,7 +129,7 @@ export function PageDispatcher() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// 单实例对应的页面组件
|
// 单实例对应的页面组件
|
||||||
const SingletonPage = singleton ? PAGE_MAP[singleton.target] : null;
|
const SingletonPage = singleton ? resolvePage(singleton.target) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -111,9 +142,7 @@ export function PageDispatcher() {
|
|||||||
onCancel={closeSingleton}
|
onCancel={closeSingleton}
|
||||||
footer={null}
|
footer={null}
|
||||||
destroyOnHidden={true}
|
destroyOnHidden={true}
|
||||||
mask={{
|
mask={{ closable: true }}
|
||||||
closable: true,
|
|
||||||
}}
|
|
||||||
width={640}
|
width={640}
|
||||||
>
|
>
|
||||||
<SingletonPage />
|
<SingletonPage />
|
||||||
@@ -135,7 +164,7 @@ export function PageDispatcher() {
|
|||||||
|
|
||||||
{/* ======== Floating Panels ======== */}
|
{/* ======== Floating Panels ======== */}
|
||||||
{floatingPanels.map((panel) => {
|
{floatingPanels.map((panel) => {
|
||||||
const PageContent = PAGE_MAP[panel.target];
|
const PageContent = resolvePage(panel.target);
|
||||||
if (!PageContent) return null;
|
if (!PageContent) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {useEffect, useState, useCallback} from 'react';
|
|||||||
import {Drawer, Card, Typography, Empty, Tag, Spin, Modal, Tooltip} from 'antd';
|
import {Drawer, Card, Typography, Empty, Tag, Spin, Modal, Tooltip} from 'antd';
|
||||||
import {NotificationOutlined} from '@ant-design/icons';
|
import {NotificationOutlined} from '@ant-design/icons';
|
||||||
|
|
||||||
import {fetchAnnouncements, type Announcement, AnnouncementListResponse} from '@/services/modules';
|
import { fetchAnnouncements, type Announcement, type AnnouncementListResponse } from '@/services/modules/announcement';
|
||||||
|
|
||||||
const {Text, Paragraph} = Typography;
|
const {Text, Paragraph} = Typography;
|
||||||
|
|
||||||
|
|||||||
@@ -14,18 +14,9 @@
|
|||||||
|
|
||||||
import {useMemo} from 'react';
|
import {useMemo} from 'react';
|
||||||
import {useAppContext} from '@/components/AppProvider';
|
import {useAppContext} from '@/components/AppProvider';
|
||||||
import {
|
import { TaskAPI, type TaskListRequestParams, type TaskInfoItemResponseBody, type CreatTaskRequestBody } from '@/services/modules/task';
|
||||||
TaskAPI,
|
import { ModelAPI, MODEL_CATEGORY_LABELS, type ModelsListResponseBody, type ModelCategoryStringEnum } from '@/services/modules/models';
|
||||||
ModelAPI,
|
import { fetchBanners, type Banner } from '@/services/modules/banner';
|
||||||
fetchBanners,
|
|
||||||
MODEL_CATEGORY_LABELS,
|
|
||||||
type TaskListRequestParams,
|
|
||||||
type TaskInfoItemResponseBody,
|
|
||||||
type CreatTaskRequestBody,
|
|
||||||
type ModelsListResponseBody,
|
|
||||||
type Banner,
|
|
||||||
type ModelCategoryStringEnum,
|
|
||||||
} from '@/services/modules';
|
|
||||||
import {useAsyncData, UseAsyncDataReturn, useAsyncMutation} from './use-async';
|
import {useAsyncData, UseAsyncDataReturn, useAsyncMutation} from './use-async';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// AccountPage — 查帐户(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function AccountPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>查帐户 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// BillingPage — 消费记录(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function BillingPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>消费记录 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// ComplianceAssetsPage — 合规素材库(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function ComplianceAssetsPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>合规素材库 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,8 @@ import { createContext, useContext, useState, useCallback, useRef, useEffect, us
|
|||||||
import { theme as antTheme, Empty } from 'antd';
|
import { theme as antTheme, Empty } from 'antd';
|
||||||
|
|
||||||
import { useAppContext } from '@/components/AppProvider';
|
import { useAppContext } from '@/components/AppProvider';
|
||||||
import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules';
|
import type { ModelsListResponseBody } from '@/services/modules/models';
|
||||||
|
import type { TaskInfoItemResponseBody } from '@/services/modules/task';
|
||||||
import { LeftPanel } from './components/LeftPanel';
|
import { LeftPanel } from './components/LeftPanel';
|
||||||
import { CenterPanel } from './components/CenterPanel';
|
import { CenterPanel } from './components/CenterPanel';
|
||||||
import { RightPanel } from './components/RightPanel';
|
import { RightPanel } from './components/RightPanel';
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { CloseOutlined } from '@ant-design/icons';
|
|||||||
import type { CarouselRef } from 'antd/es/carousel';
|
import type { CarouselRef } from 'antd/es/carousel';
|
||||||
|
|
||||||
import { useBannerList } from '@/hooks/use-api';
|
import { useBannerList } from '@/hooks/use-api';
|
||||||
import type { Banner } from '@/services/modules';
|
import type { Banner } from '@/services/modules/banner';
|
||||||
|
|
||||||
// ---------- 组件 Props ----------
|
// ---------- 组件 Props ----------
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,8 @@ import { useHomeContext } from '@/pages/home/HomeContent';
|
|||||||
import { useAppContext } from '@/components/AppProvider';
|
import { useAppContext } from '@/components/AppProvider';
|
||||||
import { useSubmitTask } from '@/hooks/use-api';
|
import { useSubmitTask } from '@/hooks/use-api';
|
||||||
import { emit, EVENTS } from '@/utils/event-bus';
|
import { emit, EVENTS } from '@/utils/event-bus';
|
||||||
import type { ModelsListResponseBody, TaskInfoItemResponseBody } from '@/services/modules';
|
import type { ModelsListResponseBody } from '@/services/modules/models';
|
||||||
|
import type { TaskInfoItemResponseBody } from '@/services/modules/task';
|
||||||
|
|
||||||
const { Text, Title } = Typography;
|
const { Text, Title } = Typography;
|
||||||
const { TextArea } = Input;
|
const { TextArea } = Input;
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ import { AppstoreOutlined } from '@ant-design/icons';
|
|||||||
|
|
||||||
import { useModelList } from '@/hooks/use-api';
|
import { useModelList } from '@/hooks/use-api';
|
||||||
import { useHomeContext } from '@/pages/home/HomeContent';
|
import { useHomeContext } from '@/pages/home/HomeContent';
|
||||||
import { resolveCategoryLabel, MODEL_CATEGORIES } from '@/services/modules';
|
import { resolveCategoryLabel, MODEL_CATEGORIES, type ModelsListResponseBody, type ModelCategoryStringEnum } from '@/services/modules/models';
|
||||||
import type { ModelsListResponseBody, ModelCategoryStringEnum } from '@/services/modules';
|
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
|
|
||||||
import { useHomeContext } from '@/pages/home/HomeContent';
|
import { useHomeContext } from '@/pages/home/HomeContent';
|
||||||
import { useTaskDetail } from '@/hooks/use-api';
|
import { useTaskDetail } from '@/hooks/use-api';
|
||||||
import type { TaskStatusString } from '@/services/modules';
|
import type { TaskStatusString } from '@/services/modules/task';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ import type {
|
|||||||
TaskInfoItemResponseBody,
|
TaskInfoItemResponseBody,
|
||||||
TaskListRequestParams,
|
TaskListRequestParams,
|
||||||
TaskStatusString,
|
TaskStatusString,
|
||||||
} from '@/services/modules';
|
} from '@/services/modules/task';
|
||||||
import { TaskStatusMap, OutputTypeMap } from '@/services/modules';
|
import { TaskStatusMap, OutputTypeMap } from '@/services/modules/task';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { Modal, Input, Button, Typography, App } from 'antd';
|
|||||||
import { LockOutlined, KeyOutlined, SafetyOutlined } from '@ant-design/icons';
|
import { LockOutlined, KeyOutlined, SafetyOutlined } from '@ant-design/icons';
|
||||||
|
|
||||||
import { useTheme } from '@/components/ThemeProvider';
|
import { useTheme } from '@/components/ThemeProvider';
|
||||||
import { AuthAPI } from '@/services/modules';
|
import { AuthAPI } from '@/services/modules/auth';
|
||||||
import { validatePassword, validateConfirmPassword } from '../config/validators';
|
import { validatePassword, validateConfirmPassword } from '../config/validators';
|
||||||
|
|
||||||
const { Text, Title } = Typography;
|
const { Text, Title } = Typography;
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
|
|
||||||
import { useTheme } from '@/components/ThemeProvider';
|
import { useTheme } from '@/components/ThemeProvider';
|
||||||
import { AuthAPI } from '@/services/modules';
|
import { AuthAPI } from '@/services/modules/auth';
|
||||||
import {
|
import {
|
||||||
validatePhone,
|
validatePhone,
|
||||||
validateSmsCode,
|
validateSmsCode,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { LoginForm } from './components/LoginForm';
|
|||||||
import { RegisterForm } from './components/RegisterForm';
|
import { RegisterForm } from './components/RegisterForm';
|
||||||
import { ForgotPasswordModal } from './components/ForgotPasswordModal';
|
import { ForgotPasswordModal } from './components/ForgotPasswordModal';
|
||||||
import { useAuthState } from './hooks/use-auth-state';
|
import { useAuthState } from './hooks/use-auth-state';
|
||||||
import { AuthAPI, LoginResponseBody } from '@/services/modules';
|
import { AuthAPI, type LoginResponseBody } from '@/services/modules/auth';
|
||||||
import { getDeviceId } from '@/utils/device';
|
import { getDeviceId } from '@/utils/device';
|
||||||
import type { LoginFormValues, RegisterFormValues } from './types';
|
import type { LoginFormValues, RegisterFormValues } from './types';
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// OrdersPage — 订单明细(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function OrdersPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>订单明细 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// ProjectsPage — 项目管理(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function ProjectsPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>项目管理 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// QuotaPage — 查配额(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function QuotaPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>查配额 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// RechargePage — 充值积分(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function RechargePage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>充值积分 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// VipPage — 开会员/激活(占位组件,后续实现具体功能)
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export function VipPage() {
|
|
||||||
return (
|
|
||||||
<div style={{ padding: 8 }}>
|
|
||||||
<p style={{ color: 'inherit', opacity: 0.6, margin: 0 }}>开会员/激活 — 页面开发中</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
import { useEffect, useState, useCallback } from 'react';
|
import { useEffect, useState, useCallback } from 'react';
|
||||||
import { Spin, Empty } from 'antd';
|
import { Spin, Empty } from 'antd';
|
||||||
import { WechatOutlined } from '@ant-design/icons';
|
import { WechatOutlined } from '@ant-design/icons';
|
||||||
import { fetchBanners, type Banner } from '@/services/modules';
|
import { fetchBanners, type Banner } from '@/services/modules/banner';
|
||||||
|
|
||||||
export function WechatWorkPage() {
|
export function WechatWorkPage() {
|
||||||
const [banner, setBanner] = useState<Banner | null>(null);
|
const [banner, setBanner] = useState<Banner | null>(null);
|
||||||
|
|||||||
@@ -12,8 +12,7 @@
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
||||||
import { setToken, setTokenRefreshHandler } from './request';
|
import { setToken, setTokenRefreshHandler } from './request';
|
||||||
import { AuthAPI } from './modules';
|
import { AuthAPI, type RefreshTokenResponseBody } from './modules/auth';
|
||||||
import type { RefreshTokenResponseBody } from './modules';
|
|
||||||
import {
|
import {
|
||||||
getSafeStore,
|
getSafeStore,
|
||||||
setSafeStore,
|
setSafeStore,
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
// ============================================================
|
|
||||||
// API 模块统一导出
|
|
||||||
// ============================================================
|
|
||||||
|
|
||||||
export {
|
|
||||||
fetchAnnouncements,
|
|
||||||
type Announcement,
|
|
||||||
type AnnouncementType,
|
|
||||||
type AnnouncementListResponse,
|
|
||||||
} from './announcement';
|
|
||||||
|
|
||||||
export {
|
|
||||||
AuthAPI,
|
|
||||||
type SendSMSRequestBody,
|
|
||||||
type RegisterRequestBody,
|
|
||||||
type RegisterResponseBody,
|
|
||||||
type LoginRequestBody,
|
|
||||||
type LoginResponseBody,
|
|
||||||
type RefreshTokenRequestBody,
|
|
||||||
type RefreshTokenResponseBody,
|
|
||||||
type UserInfoBody,
|
|
||||||
type ChangePasswordRequestBody,
|
|
||||||
type UsePhoneResetPasswordRequestBody,
|
|
||||||
} from './auth';
|
|
||||||
|
|
||||||
export {
|
|
||||||
fetchBanners,
|
|
||||||
type Banner,
|
|
||||||
type BannerListResponse,
|
|
||||||
} from './banner';
|
|
||||||
|
|
||||||
export {
|
|
||||||
ModelAPI,
|
|
||||||
MODEL_CATEGORIES,
|
|
||||||
MODEL_CATEGORY_LABELS,
|
|
||||||
CATEGORY_SLUG_MAP,
|
|
||||||
resolveCategoryLabel,
|
|
||||||
toCategorySlug,
|
|
||||||
type ModelsListReqeustParams,
|
|
||||||
type ModelsListResponseBody,
|
|
||||||
type ModelInfoRequestParams,
|
|
||||||
type ModelInfoResponseBody,
|
|
||||||
type ModelCategoryStringEnum,
|
|
||||||
type ParamSchemaItem,
|
|
||||||
} from './models';
|
|
||||||
|
|
||||||
export {
|
|
||||||
TaskAPI,
|
|
||||||
OutputTypeMap,
|
|
||||||
TaskStatusMap,
|
|
||||||
type OutputTypeString,
|
|
||||||
type TaskStatusString,
|
|
||||||
type TaskListRequestParams,
|
|
||||||
type CreatTaskRequestBody,
|
|
||||||
type ExportTaskCSVParams,
|
|
||||||
type ContentItem,
|
|
||||||
type ImageUiParams,
|
|
||||||
type VideoUiParams,
|
|
||||||
type AudioUiParams,
|
|
||||||
type TaskInfoItemResponseBody,
|
|
||||||
type TaskInfoDataResponseBody,
|
|
||||||
type TaskStatusResponseBody,
|
|
||||||
} from './task';
|
|
||||||
Reference in New Issue
Block a user