Skip to content

开发指南

text
相关代码: src/, server/

本地开发流程

Vite 提供热更新,修改前端代码后自动刷新。

修改 server/ 代码需要重启 Node 服务(npm run server)。

添加新功能

场景 1:新增页面

  1. 创建页面组件
tsx
// src/pages/NewPage.tsx
export default function NewPage() {
  return <div>New Page</div>
}
  1. 添加路由
tsx
// src/App.tsx
import NewPage from '@/pages/NewPage'

<Route path="new-page" element={<NewPage />} />
  1. 添加菜单项
tsx
// src/layouts/AdminLayout.tsx
const menuItems = [
  // ...existing items
  { key: 'new-page', icon: <SomeIcon />, label: '新功能' }
]

场景 2:新增用户代理接口

当需要访问新的用户私有数据时:

typescript
// server/proxyRoutes.ts
router.get('/users/:userId/new-resource', getUserToken, async (req, res) => {
  await proxyRequest(
    req,
    res,
    '/apis/leopard.io/v1alpha1/new-resource',
    (req as any).userToken,
    apiBaseUrl
  )
})

关键点:

  • 使用 getUserToken 中间件自动获取用户 Token
  • proxyRequest 处理请求转发

场景 3:新增产品类型

  1. 添加产品配置
typescript
// src/config/productConfig.ts
'new-product': {
  label: '新产品',
  addRoute: '/sku/add/new-product',
  editRoute: '/sku/edit/new-product',
  columns: newProductColumns,
}
  1. 创建列配置
tsx
// src/components/sku/columns/newProductColumns.tsx
export const newProductColumns: ColumnType<SKU>[] = [
  // ...column definitions
]
  1. 创建 SKU 表单页面(如需自定义)
tsx
// src/pages/sku/AddNewProductSKUPage.tsx

API 调用模式

管理员 API(公共数据)

typescript
// src/services/api.ts
const response = await api.get('/products/skus')
// 请求会自动添加管理员 Token

用户代理 API(私有数据)

typescript
// 直接调用 proxy 路由
const response = await axios.get(`/proxy/users/${userId}/orders`)
// Node 层会自动注入用户 Token

数据转换

EAV → 扁平结构

typescript
const mapLeopardSkuToFrontend = (item: any): SKU => {
  const fields = item.specFields || []
  const fieldMap = new Map(fields.map((f: any) => [f.key, f.value]))

  return {
    gpuModel: fieldMap.get('gpu-model') || '',
    // ...
  }
}

单位转换

typescript
// 价格:元 → 微元
const priceInMicroYuan = Math.round(priceInYuan * 1_000_000)

// 内存:GB → MB
const memoryInMB = Math.round(memoryInGB * 1024)

调试技巧

查看 Node 代理日志

终端会显示所有代理请求:

[Admin Proxy] GET /api/leopard/products/skus -> https://api.example.com/...
[Proxy] Forwarding to: https://api.example.com/apis/leopard.io/v1alpha1/orders
[TokenManager] Using cached token for user user123

查看 Token 缓存

bash
cat data/tokens.json

网络请求调试

浏览器开发者工具 → Network,筛选 /api//proxy/

生产构建

bash
npm run build

产物:

  • dist/ - 静态资源
  • dist/server/ - Node 服务

Docker 部署

bash
# 本地测试
docker build -t drun-pitstop:local .
docker run -p 3001:3001 \
  -e VITE_API_BASE_URL=... \
  -e VITE_API_TOKEN=... \
  drun-pitstop:local

# 多架构生产镜像
docker buildx build --platform linux/amd64,linux/arm64 \
  -t release.daocloud.io/ndx-product/drun-pitstop:v1.0.0 \
  --push .

代码风格

  • TypeScript 严格模式
  • ESLint 配置在 eslint.config.js
  • 运行 npm run lint 检查

下一步