提交 926d0553 authored 作者: 王鹏飞's avatar 王鹏飞

refactor(admin): remove inactive legacy entry files

上级 0df18cab
# Admin Legacy Cleanup Audit
## Scope and method
This audit traced static imports, re-exports, literal dynamic imports, CSS imports, and `@/` aliases from the Vite entry. It also checked source references with `rg`, the route-boundary tests, and a production build after the minimal deletion.
The active route chain is:
```text
apps/admin/index.html
-> src/main.jsx
-> src/App.tsx
-> src/app/routes.tsx
-> src/modules/*/routes.tsx
```
`src/app/route-manifest.ts` remains the canonical public-URL inventory used by tests. The static active graph contained 406 local files, including 37 files under `src/pages`.
## Deleted in this cleanup
These files had no inbound edge from the active entry/module graph and were removed as explicitly authorized:
```text
apps/admin/src/routes/index.jsx
apps/admin/src/routes/routes.jsx
apps/admin/src/routes/lazyLoadAndDelay.jsx
apps/admin/src/components/list/index.jsx
apps/admin/src/common/TableCom/index.jsx
```
Evidence for the legacy route deletion:
- `index.html` loads only `/src/main.jsx`.
- `main.jsx` renders `App.tsx`; `App.tsx` imports `@/app/routes`, not `@/routes`.
- The only importer of `src/routes/routes.jsx` was `src/routes/index.jsx`; nothing imported `src/routes/index.jsx`.
- `lazyLoadAndDelay.jsx` was imported only by the deleted legacy route table.
- The route-boundary tests still pass after deletion and confirm that root routing delegates to domain modules.
- The production build succeeds after deletion.
Evidence for the old list-component deletion:
- No active `main/App/app/modules/layout/utils` file imports `@/components/list` or `@/common/TableCom`.
- The current list implementation is `src/shared/components/AppList`.
- `common/TableCom` and `components/list` were absent from the active static graph; tests and production build pass after removal.
## Runtime files that must remain
### Route/menu metadata
```text
main.jsx -> App.tsx -> app/routes.tsx -> layout/index.jsx
-> utils/breadCrumb.js -> config/component.js
```
`apps/admin/src/config/component.js` is therefore runtime code, not an unused route table. `generateToAntdMenus` reads its names, component metadata, `isChild`, and `childThirdRoutes`. Do not delete it until the layout/menu metadata path is replaced.
### Legacy pagination
```text
app/routes.tsx -> modules/members/routes.tsx
-> modules/members/list/routes.tsx
-> modules/members/list/components/MemberDetailView.tsx
-> common/Pagination/index.jsx
```
`apps/admin/src/common/Pagination/` remains active and cannot be removed.
### Legacy pages and requests still in the active graph
These exact files remain reachable and must not be deleted:
```text
pages/advertisement/adsense/request.js
pages/advertisement/index.jsx
pages/books/audit/index.less
pages/books/audit/preview.jsx
pages/books/classify/request.js
pages/books/index.jsx
pages/books/management/addedit/index.jsx
pages/books/management/api.js
pages/books/question-bank/questionEditr/index.jsx
pages/books/question-bank/request.js
pages/books/sale/discussDetail/index.jsx
pages/books/sale/edit.jsx
pages/books/sale/request.js
pages/books/section/api.js
pages/books/section/components/BindKnowledgeGraph.jsx
pages/books/section/components/EditChapterEditors.jsx
pages/books/section/components/form-chapter-title.jsx
pages/books/section/index.jsx
pages/books/section/index.less
pages/books/section/request.js
pages/jurisdiction/index.jsx
pages/jurisdiction/role/request.js
pages/member/index.jsx
pages/setting/help/addedit/requet.js
pages/setting/index.jsx
pages/student/book/index.jsx
pages/student/book/index.less
pages/student/book/request.js
pages/teacher/index.jsx
pages/user-module/index.jsx
pages/user-module/index.less
pages/user-module/login/index.jsx
pages/user-module/login/request/api.js
pages/user-module/login/request/index.js
pages/user-module/request/api.js
pages/user-module/request/request.jsx
pages/user-module/userInfo/index.jsx
```
Important representative chains:
- `modules/books/management/routes.tsx` reaches the legacy add/edit screen and the full `pages/books/section` editor subtree.
- `modules/books/sale/routes.tsx` reaches the legacy sale editor and discussion-detail screen, which still depend on legacy sale/classify requests.
- `modules/books/audit` reaches the legacy preview and audit stylesheet; preview also depends on the section request.
- `modules/advertisements/advert` still deliberately uses the legacy adsense request and help-center OSS token request.
- Auth, account, student-book, and the top-level domain layouts remain compatibility wrappers over legacy pages.
## Inactive pages retained for a later domain cleanup
The audit also found legacy page files outside the active graph. They were not removed in this minimal cleanup because they must be handled by domain and some still contain textual imports of the deleted legacy list helpers.
In particular:
- Fourteen inactive legacy pages still contain `@/common/TableCom` imports.
- `pages/setting/coupon/index.jsx` still contains an `@/components/list` import.
- `config/component.js` still contains legacy component-path strings for menu metadata; these are not dynamic imports, but should be updated only when that metadata layer is redesigned.
Recommended next step: delete inactive pages in domain-sized commits, remove their now-stale helper imports at the same time, and rerun the active-graph audit after each domain. Do not delete the 37 reachable files listed above.
## Post-cleanup verification
- Active-entry/module `rg` check for the deleted route and list helpers: no references.
- Full-page-tree `rg`: only the inactive legacy-page imports documented above remain.
- `pnpm test`: passed, 11 tests.
- `pnpm build`: passed; only the existing formula-editor and large-chunk warnings were emitted.
## Concerns
- The retained inactive pages are not independently buildable until their stale `TableCom`/`components/list` imports are removed or replaced. They are outside the current Vite runtime graph, which is why the admin build remains valid.
- `config/component.js` couples backend menu data to legacy component-path metadata even though current routing is module-owned; it needs a separate migration before removal.
import { useState, useEffect } from "react";
import { Table } from "antd";
const TableCom = (props) => {
const [obj, setObj] = useState({});
const { columns = [], data = [], loading = false } = props;
useEffect(() => {
let height = document.querySelector(".ant-table-tbody")?.clientHeight || 0;
let x = true;
if (height > 600) {
setObj({ x, y: 600 });
} else {
setObj({ x });
}
}, [data.length]);
return (
<Table
// scroll={obj}
columns={columns}
rowKey={(record) => record.id}
dataSource={data}
loading={loading}
pagination={false}
></Table>
);
};
export default TableCom;
import { useState, useEffect, forwardRef, useImperativeHandle } from "react";
import { Table, Row, Col, Form, Button, Space } from "antd";
import IconReset from "@/assets/images/icon/reset.png";
import IconReload from "@/assets/images/icon/reload.png";
import IconFilter from "@/assets/images/icon/filter.png";
const AppList = (props, ref) => {
const { remote = {}, filters = [], filterAside, ...rest } = props;
const [data, setData] = useState({ total: 0, list: [] });
const [page, setPage] = useState({ current: 1, pageSize: 10 });
const [form] = Form.useForm();
const [loading, setLoading] = useState(false);
// 分页配置
const pagination = {
showSizeChanger: true,
showQuickJumper: true,
pageSizeOptions: ["10", "20", "30", "40"],
showTotal: (total) => `共${total}条数据`,
onChange: handlePageChange,
};
// 获取列表数据
async function fetchData() {
let { request, beforeRequest, afterRequest } = remote;
if (!request) return;
setLoading(true);
let params = { page: page.current, page_size: page.pageSize, ...form.getFieldsValue() };
if (beforeRequest) {
params = await beforeRequest(params);
}
const res = await request(params);
const { list = [], total = 0 } = afterRequest
? await afterRequest(res.data, params)
: res.data || {};
setData({ list, total });
setLoading(false);
}
useEffect(() => {
fetchData();
}, [page]);
// 筛选
async function handleSearch() {
setPage({ ...page, current: 1 });
}
// 重置
async function handleReset() {
// 清空筛选条件
form.resetFields();
setPage({ ...page, current: 1 });
}
// 刷新
async function handleReload(isForce = false) {
isForce ? await handleSearch() : await fetchData();
}
// 分页改变
async function handlePageChange(current, pageSize) {
setPage({ current, pageSize });
}
const onValuesChange = (changedValues) => {
const [value] = Object.values(changedValues);
!value && handleReload();
};
useImperativeHandle(ref, () => {
return { handleSearch, handleReset, handleReload };
});
const filterElement = (
<div className="app-list-filter" style={{ marginBottom: 20 }}>
<div className="app-list-filter" style={{ marginBottom: 20 }}>
<Row justify="space-between">
<Col>
<Form layout="inline" autoComplete="off" form={form} onValuesChange={onValuesChange}>
{filters.map((item) => (
<Form.Item label={item.label} name={item.name} key={item.label}>
{item.element}
</Form.Item>
))}
<Space>
<Button
type="primary"
htmlType="button"
ghost
icon={<Icon src={IconFilter} />}
onClick={handleSearch}
>
筛选
</Button>
<Button
type="primary"
htmlType="button"
ghost
icon={<Icon src={IconReset} />}
onClick={handleReset}
>
重置
</Button>
<Button
type="primary"
htmlType="button"
ghost
icon={<Icon src={IconReload} />}
onClick={handleReload}
>
刷新
</Button>
</Space>
</Form>
</Col>
<Col>{filterAside}</Col>
</Row>
</div>
</div>
);
return (
<div className="app-list">
{filters.length > 0 && filterElement}
<div className="app-list-table">
<Table
rowKey="id"
dataSource={data.list}
loading={loading}
pagination={pagination}
{...rest}
></Table>
</div>
</div>
);
};
const Icon = ({ src }) => {
const IconStyle = { height: "12px", objectFit: "contain" };
return <img src={src} style={IconStyle} />;
};
export default forwardRef(AppList);
import { useRoutes } from "react-router";
import routes from "./routes";
const GetRoutesDynamic = () => {
const element = useRoutes(routes);
return <>{element}</>;
};
export { GetRoutesDynamic };
import { lazy, Suspense } from "react";
import { Navigate } from "react-router";
import { Spin } from "antd";
/*** 实现路由懒加载* @param Comp 懒加载组件* @returns */
const lazyLoad = (Comp) => {
return (
<Suspense fallback={<Spin />}>
<Comp />
</Suspense>
);
};
const Modules = import.meta.glob("../pages/**/*.jsx"); // 在vite中必须这样动态引入所有组件地址
const lazyLoadModule = (moduleName) => {
const Module = lazy(Modules[`../pages/${moduleName}.jsx`]);
return (
<Suspense fallback={<Spin>Loading...</Spin>}>
<Module></Module>
</Suspense>
);
};
const filterAsyncRouter = (menuData) => {
let temp = [];
menuData.forEach((item) => {
const route = {
name: item.name,
path: item.path,
element: "",
};
route.element = lazyLoadModule(item.component); // 懒加载路由
if (item.children) {
route.children = filterAsyncRouter(item.children); // 如有有嵌套路由则递归加载
}
temp.push(route);
});
return temp;
};
const authComponent = (Com) => {
const token = localStorage.getItem("kiwi.token") || true;
return token ? lazyLoad(Com) : <Navigate to="/login" />;
};
export { lazyLoad, lazyLoadModule, authComponent, filterAsyncRouter };
import { lazy } from "react";
import { Navigate } from "react-router";
import { authComponent } from "./lazyLoadAndDelay"; // 添加一个固定的延迟时间,以便你可以看到加载状态
import Layout from "@/layout/index";
const baseRouter = [
{
path: "/",
element: authComponent(Layout),
children: [
{
index: true,
element: <Navigate to="/books/management" />,
},
// 书籍管理
{
path: "books",
title: "书籍管理",
Component: lazy(() => import("@/pages/books/index")),
children: [
{
index: true,
element: <Navigate to="management" />,
},
{
path: "management",
title: "写书管理",
Component: lazy(() => import("@/pages/books/management/index")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/books/management/list/index")),
},
{
path: "list",
Component: lazy(() => import("@/pages/books/management/list/index")),
},
{
path: "add-edit",
Component: lazy(() => import("@/pages/books/management/addedit/index")),
},
{
path: "chapter",
Component: lazy(() => import("@/pages/books/section/index")),
},
],
},
{
path: "audit",
title: "书籍审核",
Component: lazy(() => import("@/pages/books/audit/index")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/books/audit/table")),
},
{
path: "/books/audit/dataset",
Component: lazy(() => import("@/pages/books/audit/table")),
},
{
path: "/books/audit/detail",
Component: lazy(() => import("@/pages/books/audit/detail")),
},
],
},
{
path: "/books/classify",
title: "书籍分类",
Component: lazy(() => import("@/pages/books/classify/index")),
},
{
path: "/books/label",
title: "书籍标签",
Component: lazy(() => import("@/pages/books/label/index")),
},
{
path: "/books/sale",
title: "在售书籍",
Component: lazy(() => import("@/pages/books/sale/index")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/books/sale/table")),
},
{
path: "/books/sale/dataset",
Component: lazy(() => import("@/pages/books/sale/table")),
},
{
path: "/books/sale/detail",
Component: lazy(() => import("@/pages/books/sale/edit")),
},
{
path: "/books/sale/discussP",
Component: lazy(() => import("@/pages/books/sale/discussList/index")),
},
{
path: "/books/sale/discuss-detail",
Component: lazy(() => import("@/pages/books/sale/discussDetail/index")),
},
],
},
{
path: "/books/question-bank",
title: "题库管理",
Component: lazy(() => import("@/pages/books/question-bank/index")),
},
{
path: "/books/discussion",
title: "讨论互动",
Component: lazy(() => import("@/pages/books/discussion/index")),
},
{
path: "/books/order-management",
title: "订单管理",
Component: lazy(() => import("@/pages/books/order-management/index")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/books/order-management/tab/table")),
},
{
path: "/books/order-management/dataset",
Component: lazy(() => import("@/pages/books/order-management/tab/table")),
},
{
path: "/books/order-management/sale-statistics",
Component: lazy(() => import("@/pages/books/order-management/tab/salesStatistics")),
},
],
},
{
path: "/books/design",
title: "在线设计",
Component: lazy(() => import("@/pages/books/design/index")),
},
],
},
// 用户管理
{
path: "member",
title: "用户管理",
Component: lazy(() => import("@/pages/member/index")),
children: [
{
index: true,
element: <Navigate to="/member/list" />,
},
{
path: "/member/list",
title: "用户管理",
Component: lazy(() => import("@/pages/member/list/index")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/member/list/list")),
},
{
path: "/member/list/query",
Component: lazy(() => import("@/pages/member/list/list")),
},
{
path: "/member/list/detail",
Component: lazy(() => import("@/pages/member/detail/index")),
},
],
},
{
path: "/member/userlevel",
title: "用户等级",
Component: lazy(() => import("@/pages/member/userlevel/index")),
},
],
},
// 广告管理
{
path: "advertisement",
title: "广告管理",
Component: lazy(() => import("@/pages/advertisement/index")),
children: [
{
index: true,
element: <Navigate to="/advertisement/advert" />,
},
{
path: "/advertisement/advert",
title: "广告管理",
Component: lazy(() => import("@/pages/advertisement/advert/index")),
},
{
path: "/advertisement/adsense",
title: "广告位管理",
Component: lazy(() => import("@/pages/advertisement/adsense/index")),
},
],
},
// 系统设置
{
path: "setting",
title: "系统设置",
Component: lazy(() => import("@/pages/setting/index")),
children: [
{
index: true,
element: <Navigate to="/setting/applied" />,
},
{
path: "/setting/help",
title: "帮助中心",
Component: lazy(() => import("@/pages/setting/help/index")),
children: [
{
index: true,
element: <Navigate to="/setting/help/list" />,
},
{
path: "/setting/help/list",
Component: lazy(() => import("@/pages/setting/help/table")),
},
{
path: "/setting/help/addedit",
Component: lazy(() => import("@/pages/setting/help/addedit/index")),
},
],
},
{
path: "/setting/applied",
title: "应用管理",
Component: lazy(() => import("@/pages/setting/applied/index")),
},
{
path: "/setting/personalized-setting",
title: "个性化设置",
Component: lazy(() => import("@/pages/setting/personalized-setting/index")),
},
{
path: "/setting/point-management",
title: "积分管理",
Component: lazy(() => import("@/pages/setting/point-management/index")),
},
{
path: "/setting/app-version",
title: "APP版本管理",
Component: lazy(() => import("@/pages/setting/app-version/index")),
},
{
path: "/setting/coupon",
title: "优惠卷管理",
Component: lazy(() => import("@/pages/setting/coupon/index")),
},
{
path: "/setting/sensitive",
title: "敏感词搜索",
Component: lazy(() => import("@/pages/setting/sensitive/index")),
},
{
path: "/setting/feedback",
title: "意见反馈",
Component: lazy(() => import("@/pages/setting/feedback/index")),
},
],
},
// 权限管理
{
path: "jurisdiction",
title: "权限管理",
Component: lazy(() => import("@/pages/jurisdiction/index")),
children: [
{
index: true,
element: <Navigate to="/jurisdiction/role" />,
},
{
path: "/jurisdiction/admin",
title: "管理员管理",
Component: lazy(() => import("@/pages/jurisdiction/admin/index")),
},
{
path: "/jurisdiction/role",
title: "角色管理",
Component: lazy(() => import("@/pages/jurisdiction/role/index")),
},
],
},
// 老师管理
{
path: "teacher",
title: "老师管理",
Component: lazy(() => import("@/pages/teacher/index")),
children: [
{
index: true,
element: <Navigate to="/teacher/list" />,
},
{
path: "/teacher/list",
title: "老师管理",
Component: lazy(() => import("@/pages/teacher/query/index")),
},
],
},
{
path: "userinfo",
Component: lazy(() => import("@/pages/user-module/userInfo")),
},
{
path: "editor",
Component: lazy(() => import("@/pages/editor/index")),
},
],
},
{
path: "login",
Component: lazy(() => import("@/pages/user-module")),
children: [
{
index: true,
Component: lazy(() => import("@/pages/user-module/login")),
},
],
},
{
path: "student/book",
Component: lazy(() => import("@/pages/student/book/index")),
},
{ path: "*", element: <Navigate to="/" /> },
];
export default baseRouter;
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论