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

feat: 添加项目指南文档,包含项目结构、构建和开发命令、编码风格及提交规范

上级 d686697f
# Repository Guidelines
## Project Structure & Module Organization
This is a React 18 administration application built with Vite. Application code lives in `src/`: route-level features are grouped in `src/pages/`, reusable UI in `src/components/` and `src/common/`, API clients in `src/api/`, and shared hooks and helpers in `src/hooks/` and `src/utils/`. Routing, layout, and state are maintained in `src/routes/`, `src/layout/`, and `src/store/`. Styles are primarily colocated Less files. Static assets belong in `src/assets/`; files that must be served unchanged belong in `public/`. The formula editor source and its built output are under `public/formula-editor/`.
## Build, Test, and Development Commands
- `npm ci` installs the exact dependency versions from `package-lock.json`.
- `npm run dev` starts Vite with HTTPS and the API proxy configured in `vite.config.js`.
- `npm run build` creates a production bundle in `dist/`.
- `npm run build:dev` builds with Vite's development mode settings.
- `npm run preview` serves the production bundle for a local smoke test.
- `npm run lint` runs ESLint on `src/` and automatically fixes supported issues. Review the resulting diff.
## Coding Style & Naming Conventions
Follow the existing JavaScript/JSX style: two-space indentation, single quotes, no semicolons, and functional React components. Use `PascalCase` for component names, `camelCase` for functions and variables, and `useXxx` for hooks. Existing feature folders generally use lowercase or kebab-case names and expose entry points as `index.jsx`. Prefer the `@/` alias for imports rooted at `src/`. ESLint extends the recommended React and React Hooks rules; keep hook dependency arrays accurate.
## Testing Guidelines
No automated test framework or coverage threshold is currently configured. For every change, run `npm run lint` and `npm run build`, then smoke-test affected routes with `npm run dev`. Verify editor changes with realistic content, uploads, and API failure states. If adding tests, colocate them as `*.test.jsx` or `*.test.js` and add the associated runner command to `package.json`.
## Commit & Pull Request Guidelines
Recent history follows Conventional Commit-style prefixes such as `feat:`, `fix:`, `refactor:`, and `chore:`. Keep the subject concise, imperative, and focused on one change. Pull requests should explain the user-facing impact, list validation performed, link the relevant issue, and include screenshots or recordings for UI changes. Call out API, proxy, dependency, or configuration changes explicitly; never commit credentials or environment-specific secrets.
...@@ -18,11 +18,10 @@ ...@@ -18,11 +18,10 @@
"@reduxjs/toolkit": "^1.9.7", "@reduxjs/toolkit": "^1.9.7",
"@wangeditor/editor": "^5.1.23", "@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-react": "^1.0.6", "@wangeditor/editor-for-react": "^1.0.6",
"@wangeditor/plugin-link-card": "^1.0.0",
"ahooks": "^3.8.0", "ahooks": "^3.8.0",
"ali-oss": "^6.20.0", "ali-oss": "^6.20.0",
"antd": "^5.21.6", "antd": "^5.21.6",
"axios": "^1.6.2", "axios": "^1.18.1",
"dayjs": "^1.11.11", "dayjs": "^1.11.11",
"easy-formula-editor": "^0.0.2-alpha.1", "easy-formula-editor": "^0.0.2-alpha.1",
"echarts": "^5.4.3", "echarts": "^5.4.3",
...@@ -38,7 +37,6 @@ ...@@ -38,7 +37,6 @@
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"nanoid": "^3.3.8", "nanoid": "^3.3.8",
"qs": "^6.11.2", "qs": "^6.11.2",
"rc-slider-captcha": "^1.3.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-error-boundary": "^4.0.13", "react-error-boundary": "^4.0.13",
...@@ -46,9 +44,7 @@ ...@@ -46,9 +44,7 @@
"react-router-dom": "^6.23.1", "react-router-dom": "^6.23.1",
"react-use": "^17.6.0", "react-use": "^17.6.0",
"redux-persist": "^6.0.0", "redux-persist": "^6.0.0",
"sm4js": "^0.0.6",
"snabbdom": "^3.6.2", "snabbdom": "^3.6.2",
"xml-formatter": "^3.6.2",
"zustand": "^4.5.5" "zustand": "^4.5.5"
}, },
"devDependencies": { "devDependencies": {
......
{ {
"version": 1, "version": 1,
"skills": { "skills": {
"improve": {
"source": "shadcn/improve",
"sourceType": "github",
"skillPath": "skills/improve/SKILL.md",
"computedHash": "39a9358732dcff385e9e4d3e60b4547856f834e54a58b35e455aa9bd49928c13"
},
"vercel-react-best-practices": { "vercel-react-best-practices": {
"source": "vercel-labs/agent-skills", "source": "vercel-labs/agent-skills",
"sourceType": "github", "sourceType": "github",
......
import { useState, useEffect, useCallback } from 'react' import { useState, useEffect, useCallback } from 'react'
import { Modal, Tree, App, Button, Flex } from 'antd' import { Modal, Tree, App, Button, Flex, Empty } from 'antd'
import { getTagList, bindTag } from '../api' import { getTagList, bindTag } from '../api'
function getIds(nodes) { function getIds(nodes) {
let ids = [] let ids = []
nodes.forEach(node => { nodes.forEach((node) => {
ids.push(node.id) ids.push(node.id)
if (node.children && node.children.length > 0) { if (node.children && node.children.length > 0) {
ids = ids.concat(getIds(node.children)) ids = ids.concat(getIds(node.children))
...@@ -21,7 +21,7 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => { ...@@ -21,7 +21,7 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => {
const [expandedKeys, setExpandedKeys] = useState([]) const [expandedKeys, setExpandedKeys] = useState([])
const fetchList = useCallback(() => { const fetchList = useCallback(() => {
getTagList({ type: 2, parent_id: chapter.book_id, chapter_id: chapter.id }).then(res => { getTagList({ type: 2, parent_id: chapter.book_id, chapter_id: chapter.id }).then((res) => {
setTreeData(res.data) setTreeData(res.data)
setExpandedKeys(getIds(res.data)) setExpandedKeys(getIds(res.data))
}) })
...@@ -31,18 +31,18 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => { ...@@ -31,18 +31,18 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => {
fetchList() fetchList()
}, [fetchList]) }, [fetchList])
const toggleBind = async node => { const toggleBind = async (node) => {
await bindTag({ await bindTag({
tag_id: node.id, tag_id: node.id,
book_id: chapter.book_id, book_id: chapter.book_id,
chapter_id: chapter.id, chapter_id: chapter.id,
option_type: node.is_checked ? 'delete' : 'add' option_type: node.is_checked ? 'delete' : 'add',
}) })
message.success('操作成功') message.success('操作成功')
fetchList() fetchList()
} }
const titleRender = node => { const titleRender = (node) => {
return ( return (
<Flex justify="space-between"> <Flex justify="space-between">
<span>{node.name}</span> <span>{node.name}</span>
...@@ -54,6 +54,7 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => { ...@@ -54,6 +54,7 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => {
} }
return ( return (
<Modal title="关联知识图谱" centered {...props} footer={null}> <Modal title="关联知识图谱" centered {...props} footer={null}>
{treeData.length > 0 ? (
<Tree <Tree
blockNode blockNode
selectable={false} selectable={false}
...@@ -63,15 +64,9 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => { ...@@ -63,15 +64,9 @@ const BindKnowledgeGraph = ({ chapter = {}, ...props }) => {
titleRender={titleRender} titleRender={titleRender}
onExpand={setExpandedKeys} onExpand={setExpandedKeys}
/> />
{/* <TreeSelect ) : (
multiple <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无知识图谱" />
showSearch )}
treeDefaultExpandAll
value={value}
treeData={treeData}
fieldNames={{ label: 'name', value: 'id' }}
onChange={setValue}
style={{ width: '100%' }}></TreeSelect> */}
</Modal> </Modal>
) )
} }
......
Markdown 格式
0% 或
您添加了 0 人 到此讨论。请谨慎行事。
请先完成此评论的编辑!
请 注册 或者 后发表评论