From dfa1cbdd2ffbdcdd30aecb27c6a2df124d7fa7d0 Mon Sep 17 00:00:00 2001
From: ayou <550244300@qq.com>
Date: Thu, 25 Sep 2025 21:51:45 +0800
Subject: [PATCH] =?UTF-8?q?feat(=E5=89=8D=E7=AB=AF):=20=E4=BC=98=E5=8C=96?=
=?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=B8=83=E5=B1=80=E5=92=8C=E6=9F=A5=E8=AF=A2?=
=?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=A0=B7=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 在FlowList和FlowRunLogs页面添加PageHeader组件
- 统一ScheduleJobs页面的查询表单样式为内联布局
- 为表格分页添加showSizeChanger选项
- 新增Rust代码规范文档
---
.trae/rules/code_rules.md | 60 ++++++++++++++++++
frontend/src/pages/FlowList.tsx | 4 +-
frontend/src/pages/FlowRunLogs.tsx | 4 +-
frontend/src/pages/ScheduleJobs.tsx | 95 ++++++++++++++---------------
4 files changed, 111 insertions(+), 52 deletions(-)
create mode 100644 .trae/rules/code_rules.md
diff --git a/.trae/rules/code_rules.md b/.trae/rules/code_rules.md
new file mode 100644
index 0000000..9565e3d
--- /dev/null
+++ b/.trae/rules/code_rules.md
@@ -0,0 +1,60 @@
+# Rust 复杂文件代码规范顺序(紧凑版)
+
+1. **文件说明**
+ - 使用 `//!` 模块文档注释,描述文件或模块作用。
+ - 必须位于文件最顶部。
+
+2. **版权声明(可选)**
+ - 如果项目需要版权信息,放在文档注释之后。
+
+3. **外部依赖和模块引入(use)**
+ - 所有 `use` 必须放在文件顶部,不能出现在中间或底部。
+ - 引入顺序:标准库 -> 当前 crate 模块 -> 父模块 -> 第三方库
+ - 每一类之间空 1 行,同一类内部按字母序排列
+ - 所有 `use` **不允许**添加注释说明分组
+ - 紧凑要求:单行导入尽量合并,不要强行拆成多行
+
+4. **子模块声明(mod)**
+ - 写在所有 `use` 之后
+ - `pub mod`、`mod` 都在这里集中声明
+
+5. **常量定义(const / static)**
+ - 必须在类型定义之前
+ - 命名使用 `SCREAMING_SNAKE_CASE`
+ - 紧凑要求:值较短时保持单行,不要拆行
+
+6. **类型别名(type)**
+ - 放在常量之后、结构体之前
+
+7. **结构体定义(struct)**
+ - 放在文件的类型区域开头
+ - 所有 `struct` 必须集中写在这里,不允许与 `impl` 穿插
+ - 紧凑要求:字段数量不多时保持单行;字段多时每行一个
+
+8. **枚举定义(enum)**
+ - 紧随结构体之后,集中定义所有枚举类型
+ - 紧凑要求:简单枚举保持单行,复杂枚举多行
+
+9. **联合体定义(union)**
+ - 如果需要,放在枚举之后
+
+10. **Trait 定义**
+ - 紧跟在所有数据类型(struct/enum/union)之后
+
+11. **实现块(impl Struct)**
+ - 必须放在类型定义和 Trait 定义之后
+ - 内部方法顺序:构造函数 -> 公共方法 -> 私有方法
+ - 紧凑要求:函数体内调用链、元组、match 分支若能在一行内写清楚,则保持单行
+
+12. **Trait 实现(impl Trait for Struct)**
+ - 紧跟对应的 `impl Struct` 之后
+ - 不要与其他类型的实现混在一起
+
+13. **自由函数(fn,不属于任何 impl)**
+ - 文件中独立函数放在最后
+ - 按功能分组,可以用注释分隔
+ - 紧凑要求:参数少的函数调用保持单行
+
+14. **测试模块(#[cfg(test)] mod tests)**
+ - 永远放在文件最末尾
+ - 仅用于单元测试代码
\ No newline at end of file
diff --git a/frontend/src/pages/FlowList.tsx b/frontend/src/pages/FlowList.tsx
index cc2d6bd..a24f8b6 100644
--- a/frontend/src/pages/FlowList.tsx
+++ b/frontend/src/pages/FlowList.tsx
@@ -4,6 +4,7 @@ import { PlusOutlined, ReloadOutlined, DeleteOutlined, EditOutlined, EyeOutlined
import { useNavigate } from 'react-router-dom'
import api, { type ApiResp } from '../utils/axios'
import dayjs from 'dayjs'
+import PageHeader from '../components/PageHeader'
interface FlowSummary { id: string; name: string; code?: string; remark?: string; created_at: string; updated_at: string; last_modified_by?: string }
// 新增:扩展 Doc 以便复用
@@ -206,7 +207,7 @@ export default function FlowList() {
width: 720,
content: (
-{data.data?.yaml}
+ {data.data?.yaml}
)
})
@@ -219,6 +220,7 @@ export default function FlowList() {
return (
+
@@ -141,7 +141,7 @@ export default function FlowRunLogs() {
dataSource={data}
columns={columns}
scroll={{ x: 1600 }}
- pagination={{ current: page, pageSize, total, onChange: (p, ps) => fetchData(p, ps) }}
+ pagination={{ current: page, pageSize, total, showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100], onChange: (p, ps) => fetchData(p, ps) }}
/>
diff --git a/frontend/src/pages/ScheduleJobs.tsx b/frontend/src/pages/ScheduleJobs.tsx
index 952be59..cd711fa 100644
--- a/frontend/src/pages/ScheduleJobs.tsx
+++ b/frontend/src/pages/ScheduleJobs.tsx
@@ -27,19 +27,22 @@ export default function ScheduleJobs() {
const [total, setTotal] = useState(0)
const [page, setPage] = useState(1)
const [pageSize, setPageSize] = useState(10)
- const [keyword, setKeyword] = useState('')
- const [enabledFilter, setEnabledFilter] = useState<'all' | 'true' | 'false'>('all')
+ // 使用与系统日志一致的查询表单样式:内联 Form + 查询/重置
+ const [searchForm] = Form.useForm()
const [modalOpen, setModalOpen] = useState(false)
const [editing, setEditing] = useState(null)
const [form] = Form.useForm()
const [flowOptions, setFlowOptions] = useState([])
- const fetchJobs = async (p: number = page, ps: number = pageSize, kw: string = keyword, ef: 'all' | 'true' | 'false' = enabledFilter) => {
+ const fetchJobs = async (p: number = page, ps: number = pageSize) => {
+ const v = searchForm.getFieldsValue()
setLoading(true)
try {
- const params: any = { page: p, page_size: ps, keyword: kw }
- if (ef !== 'all') params.enabled = ef === 'true'
+ const params: any = { page: p, page_size: ps }
+ if (v.keyword) params.keyword = String(v.keyword).trim()
+ // 按系统日志风格:下拉框 allowClear,不选择即为“全部”;选择 true/false 才加入过滤
+ if (typeof v.enabled === 'boolean') params.enabled = v.enabled
const { data } = await api.get('/schedule_jobs', { params })
if (data?.code === 0) {
const resp = data.data as PageResp
@@ -67,7 +70,7 @@ export default function ScheduleJobs() {
}
}
- useEffect(() => { fetchJobs(1, pageSize, keyword, enabledFilter) }, [])
+ useEffect(() => { fetchJobs(1, pageSize) }, [])
const columns: ColumnsType = useMemo(() => [
{ title: '名称', dataIndex: 'name', key: 'name' },
@@ -144,7 +147,7 @@ export default function ScheduleJobs() {
if (data?.code === 0) {
message.success('创建成功')
setModalOpen(false)
- fetchJobs(1, pageSize, keyword, enabledFilter)
+ fetchJobs(1, pageSize)
} else {
throw new Error(data?.message || '创建失败')
}
@@ -161,7 +164,7 @@ export default function ScheduleJobs() {
if (data?.code === 0) {
message.success('删除成功')
const nextPage = data?.data?.deleted ? (data?.data?.remaining === 0 && page > 1 ? page - 1 : page) : page
- fetchJobs(nextPage, pageSize, keyword, enabledFilter)
+ fetchJobs(nextPage, pageSize)
} else {
throw new Error(data?.message || '删除失败')
}
@@ -201,52 +204,46 @@ export default function ScheduleJobs() {
}
}
- const handleSearch = () => {
- fetchJobs(1, pageSize, keyword, enabledFilter)
- }
-
return (
-
-
-
- setKeyword(e.target.value)} onSearch={handleSearch} style={{ width: 280 }} />
-