Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
12 commits
Select commit Hold shift + click to select a range
fb77e82
更新 package.json 和 pnpm-lock.yaml,添加测试相关依赖(vitest、@testing-library/rea…
felixzhu97 May 10, 2025
8ce2da2
docs: 删除多个低代码平台相关文档,包括产品说明、技术实现方案、用户手册等,以精简文档结构并聚焦核心内容。
felixzhu97 May 10, 2025
8b42787
ci: Add GitHub Actions workflow directory
felixzhu97 May 10, 2025
5a395fe
ci: 在 GitHub Actions 工作流中添加 pnpm 安装步骤,以确保依赖项的正确管理和构建环境的准备。
felixzhu97 May 10, 2025
df4c567
ci: 更新 GitHub Actions 工作流,调整 Node.js 版本为 18.x,并使用 pnpm/action-setup 安…
felixzhu97 May 10, 2025
2e8431a
ci: 更新 GitHub Actions 工作流,移除对拉取请求的触发配置,以简化工作流设置。
felixzhu97 May 10, 2025
d04905b
Revert "ci: 更新 GitHub Actions 工作流,调整 Node.js 版本为 18.x,并使用 pnpm/action…
felixzhu97 May 10, 2025
7ed78d2
更新 README.md,添加项目官网和特点介绍;修改代码导出组件,优化代码格式和逻辑;删除不再需要的文档文件,包括主要组件 Schema…
felixzhu97 May 10, 2025
43af66c
更新配置文件以支持更多图片格式和优化 CSS;在页面组件中实现懒加载以提升性能,并添加首次访问欢迎对话框和教程功能;在画布组件中增加键盘快…
felixzhu97 May 10, 2025
7d835c0
删除多个架构相关的 PlantUML 文件,包括后端组件、前端组件、容器、上下文和部署图,以精简项目结构并聚焦核心内容。
felixzhu97 May 10, 2025
dfa978e
删除多个组件和样式文件,以精简项目结构并聚焦核心功能;更新组件导入路径,确保与新结构一致。
felixzhu97 May 10, 2025
406deae
在 README.md 中添加了“低代码核心原理”链接,以丰富文档内容并提供更多相关信息。
felixzhu97 May 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Unit Tests

on:
push:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"

- name: Install pnpm
run: corepack enable && corepack prepare pnpm@latest --activate

- name: Install dependencies
run: pnpm install

- name: Run unit tests
run: pnpm test
7 changes: 6 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ next-env.d.ts
# IDE
.idea

docs/qa
docs/qa

*/.DS_Store

# coverage
coverage/
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# 低代码平台
# 低代码平台 [![CI Status](https://github.com/your-org/low-code-platform/actions/workflows/unit-tests.yml/badge.svg)](https://github.com/your-org/low-code-platform/actions)

## 项目简介

本项目是一个基于 Next.js 和 React 的低代码平台,支持可视化页面搭建、组件拖拽、属性配置、主题编辑、模板库、表单生成、动画编辑、多人协作等功能,适用于快速构建 Web 应用。

- **官网**: [https://lowcode.example.com](https://lowcode.example.com)
- **特点**:
- 可视化低代码搭建平台,拖拽即可生成页面
- 丰富的组件库,覆盖常见业务场景
- 支持自定义组件开发与扩展
- 实时预览与代码导出功能
- 多主题支持与样式定制
- 协作编辑与版本管理

## 主要功能

- 可视化页面搭建与实时预览
Expand Down Expand Up @@ -78,8 +87,10 @@ pnpm dev
如需二次开发或部署,请参考下方产品与技术文档:

- [用户手册](docs/用户手册.md)
- [产品说明](docs/project/product-description.md)
- [技术文档](docs/project/technical-description.md)
- [产品说明](docs/产品说明.md)
- [技术文档](docs/技术文档.md)
- [术语表](docs/术语表.md)
- [低代码核心原理](docs/低代码核心原理.md)
- [C4 架构模型文档](docs/architecture/)

## 贡献指南
Expand Down
14 changes: 7 additions & 7 deletions components/animation-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import {
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import { Slider } from "@/components/ui/slider"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
} from "@/src/shared/ui/dialog"
import { Button } from "@/src/shared/ui/button"
import { Label } from "@/src/shared/ui/label"
import { Slider } from "@/src/shared/ui/slider"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/src/shared/ui/select"
import { Play, Sparkles } from "lucide-react"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/src/shared/ui/card"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/src/shared/ui/tabs"

interface AnimationEditorProps {
componentId: string | null
Expand Down
142 changes: 115 additions & 27 deletions components/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,26 @@ import type React from "react"

import { useState, useEffect, useRef, useCallback } from "react"
import { useDrop } from "react-dnd"
import { ScrollArea } from "@/components/ui/scroll-area"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/components/ui/card"
import { Separator } from "@/components/ui/separator"
import { Trash2, Smartphone, Tablet, BarChart, LineChart, PieChart, ArrowUpDown, Filter } from "lucide-react"
import type { Component, ThemeConfig, DataSource, TableColumn } from "@/lib/types"
import { cn } from "@/lib/utils"
import { Switch } from "@/components/ui/switch"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { Checkbox } from "@/components/ui/checkbox"
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Badge } from "@/components/ui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { ScrollArea } from "@/src/shared/ui/scroll-area"
import { Button } from "@/src/shared/ui/button"
import { Input } from "@/src/shared/ui/input"
import { Card, CardContent, CardHeader, CardTitle, CardDescription, CardFooter } from "@/src/shared/ui/card"
import { Separator } from "@/src/shared/ui/separator"
import { Trash2, Smartphone, Tablet, BarChart, LineChart, PieChart, ArrowUpDown, Filter, HelpCircle, Keyboard } from "lucide-react"
import type { Component, ThemeConfig, DataSource, TableColumn } from "@/src/shared/utils/types"
import { cn } from "@/src/shared/utils/utils"
import { Switch } from "@/src/shared/ui/switch"
import { Label } from "@/src/shared/ui/label"
import { Textarea } from "@/src/shared/ui/textarea"
import { Checkbox } from "@/src/shared/ui/checkbox"
import { RadioGroup, RadioGroupItem } from "@/src/shared/ui/radio-group"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/src/shared/ui/select"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/src/shared/ui/tabs"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/src/shared/ui/table"
import { Badge } from "@/src/shared/ui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/src/shared/ui/avatar"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/src/shared/ui/tooltip"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from "@/src/shared/ui/dialog"

type CanvasProps = {
onSelectComponent: (component: Component | null) => void
Expand All @@ -48,6 +50,8 @@ export function Canvas({
const [snapToGrid, setSnapToGrid] = useState(false)
const [selectedId, setSelectedId] = useState<string | null>(null)
const [dropTargetId, setDropTargetId] = useState<string | null>(null)
const [showKeyboardShortcuts, setShowKeyboardShortcuts] = useState(false)
const [showTooltips, setShowTooltips] = useState(true)

// 添加拖拽状态
const [isDragging, setIsDragging] = useState(false)
Expand Down Expand Up @@ -1745,25 +1749,90 @@ export function Canvas({
[drop],
)

// 显示键盘快捷键对话框
const toggleKeyboardShortcuts = () => {
setShowKeyboardShortcuts(!showKeyboardShortcuts)
}

// 显示/隐藏工具提示
const toggleTooltips = () => {
setShowTooltips(!showTooltips)
}

// 键盘快捷键列表
const keyboardShortcuts = [
{ key: "Delete / Backspace", description: "删除所选组件" },
{ key: "↑ / ↓ / ← / →", description: "微调所选组件位置" },
{ key: "Shift + 拖动", description: "保持组件比例" },
{ key: "Ctrl + Z", description: "撤销上一步操作" },
{ key: "Ctrl + Y", description: "重做操作" },
{ key: "Ctrl + D", description: "复制所选组件" },
{ key: "Esc", description: "取消选择" },
]

return (
<div className="flex-1 bg-gray-50">
{!isPreviewMode && (
<div className="flex h-12 items-center justify-between border-b bg-background px-4">
<span className="font-medium">画布</span>
<div className="flex items-center gap-4">
<div className="flex items-center gap-2">
<Label htmlFor="show-grid" className="text-xs">
显示网格
</Label>
<Switch id="show-grid" checked={showGrid} onCheckedChange={setShowGrid} size="sm" />
<Label htmlFor="show-grid" className="text-xs text-muted-foreground">网格</Label>
<Switch id="show-grid" checked={showGrid} onCheckedChange={setShowGrid} />
</div>
<div className="flex items-center gap-2">
<Label htmlFor="snap-grid" className="text-xs">
对齐网格
</Label>
<Switch id="snap-grid" checked={snapToGrid} onCheckedChange={setSnapToGrid} size="sm" />
<Label htmlFor="snap-grid" className="text-xs text-muted-foreground">对齐</Label>
<Switch id="snap-grid" checked={snapToGrid} onCheckedChange={setSnapToGrid} />
</div>
<Button variant="outline" size="icon" onClick={handleClear} disabled={components.length === 0}>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="flex items-center gap-2">
<Label htmlFor="show-tooltips" className="text-xs text-muted-foreground">提示</Label>
<Switch id="show-tooltips" checked={showTooltips} onCheckedChange={toggleTooltips} />
</div>
</TooltipTrigger>
<TooltipContent side="bottom">
<p>显示/隐藏操作提示</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>

<Dialog open={showKeyboardShortcuts} onOpenChange={setShowKeyboardShortcuts}>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" onClick={toggleKeyboardShortcuts}>
<Keyboard className="h-4 w-4" />
</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>键盘快捷键</DialogTitle>
<DialogDescription>
使用这些快捷键可以更高效地操作画布
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<Table>
<TableHeader>
<TableRow>
<TableHead>快捷键</TableHead>
<TableHead>功能</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{keyboardShortcuts.map((shortcut, index) => (
<TableRow key={index}>
<TableCell className="font-mono">{shortcut.key}</TableCell>
<TableCell>{shortcut.description}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
</DialogContent>
</Dialog>

<Button variant="ghost" size="icon" onClick={handleClear} disabled={components.length === 0}>
<Trash2 className="h-4 w-4" />
</Button>
</div>
Expand Down Expand Up @@ -1820,6 +1889,25 @@ export function Canvas({
) : (
rootComponents.map((component) => renderComponent(component))
)}

{/* 新手引导提示 - 只在画布空且不是预览模式时显示 */}
{components.length === 0 && !isPreviewMode && (
<div className="absolute inset-0 flex flex-col items-center justify-center text-center p-4 pointer-events-none">
<div className="max-w-md space-y-4 bg-background/90 backdrop-blur-sm p-6 rounded-lg shadow-lg border">
<HelpCircle className="h-12 w-12 mx-auto text-muted-foreground/50" />
<h3 className="text-xl font-medium">开始创建您的低代码应用</h3>
<p className="text-muted-foreground">
从左侧面板拖拽组件到此画布,构建您的应用界面。使用右侧属性面板自定义组件。
</p>
<div className="flex justify-center gap-2 pointer-events-auto">
<Button size="sm" variant="outline" onClick={toggleKeyboardShortcuts}>
<Keyboard className="mr-2 h-4 w-4" />
快捷键
</Button>
</div>
</div>
</div>
)}
</div>
</ScrollArea>
</div>
Expand Down
Loading