@yorha2b-lab/autodev 7.5.6 → 7.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ bunker init
|
|
|
56
56
|
> **💡 零配置演示模式 (Demo Mode)**
|
|
57
57
|
> 项目默认开启 Demo 模式:
|
|
58
58
|
> 1. 无需配置 API_KEY,直接运行 `bunker boot`。
|
|
59
|
-
> 2. 向 `./bunker/
|
|
59
|
+
> 2. 向 `./bunker/mission` 目录丢入任意图片(系统自动空投标准 `example.json` 构筑包)。
|
|
60
60
|
> 3. 若想识别真实代码/截图,请在 `bunker/config.js` 中将 `useDemo` 设为 `false` 并配置 `.env`。
|
|
61
61
|
|
|
62
62
|
创建 `.env` 文件并配置以下环境变量:
|
package/README_EN.md
CHANGED
|
@@ -56,7 +56,7 @@ bunker init
|
|
|
56
56
|
> **💡 Zero-Config Demo Mode**
|
|
57
57
|
> Demo mode is enabled by default:
|
|
58
58
|
> 1. No `API_KEY` required, run `bunker boot` directly.
|
|
59
|
-
> 2. Drop any image into `./bunker/
|
|
59
|
+
> 2. Drop any image into `./bunker/mission` (system ignores image content and drops standard `example.json` construction package).
|
|
60
60
|
> 3. To recognize real screenshots, set `useDemo: false` in `bunker/config.js` and configure `.env`.
|
|
61
61
|
|
|
62
62
|
Create a `.env` file and configure environment variables:
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import dayjs from 'dayjs'
|
|
2
2
|
import { MyBaseForm } from './MyBaseForm'
|
|
3
|
-
import { useState, useEffect } from 'react'
|
|
3
|
+
import { useMemo, useState, useEffect } from 'react'
|
|
4
4
|
import { Row, Col, Form, Button, Space } from 'antd'
|
|
5
|
+
import { SearchOutlined, RedoOutlined } from '@ant-design/icons'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @component MySearchForm
|
|
@@ -17,9 +18,9 @@ import { Row, Col, Form, Button, Space } from 'antd'
|
|
|
17
18
|
* @param {number} [props.defaultPageSize=10] - 默认吞吐量:重置时的初始每页条数
|
|
18
19
|
* @param {Function} [props.onValuesChange] - 联动传感:当表单值变动时的即时反馈
|
|
19
20
|
* @param {Object} props.initialValues - 初始信号:从 URL 或缓存中解析出的初始参数
|
|
21
|
+
* @param {React.ReactNode} [props.extra] - 额外挂件:在按钮区域注入自定义战术单元
|
|
20
22
|
* @param {Function} props.setSearch - 状态分发器:用于更新全局搜索参数并触发重新构筑
|
|
21
23
|
* @param {Object} props.search - 当前的全局搜索状态(包含 pageNo, pageSize 及各过滤项)
|
|
22
|
-
* @param {React.ReactNode} [props.extraOperate] - 额外挂件:在按钮区域注入自定义战术单元
|
|
23
24
|
* @param {boolean} props.loading - 战场负载状态:请求中时锁定按钮,防止由于重复指令导致的逻辑冲突
|
|
24
25
|
* @param {boolean} [props.syncUrlParams=true] - 物理同步开关:是否将搜索状态实时镜像至 URL 链接中
|
|
25
26
|
*
|
|
@@ -31,10 +32,12 @@ import { Row, Col, Form, Button, Space } from 'antd'
|
|
|
31
32
|
* formItems={[{ label: '状态', name: 'status', type: 'select', options: [...] }]}
|
|
32
33
|
* />
|
|
33
34
|
*/
|
|
34
|
-
export const MySearchForm = ({ form, search, loading, labelCol, setSearch, formItems, showLimit = 7, initialValues, initialParams, customReset,
|
|
35
|
+
export const MySearchForm = ({ form, search, options, loading, labelCol, setSearch, formItems, showLimit = 7, initialValues, initialParams, customReset, extra, customFinish, onValuesChange, syncUrlParams = true, defaultPageSize = 10 }) => {
|
|
35
36
|
|
|
36
37
|
const [limit, setLimit] = useState(showLimit)
|
|
37
38
|
|
|
39
|
+
const searchItems = useMemo(() => formItems.map(item => ({ ...item, ...(['select'].includes(item.type) ? { options: item.options ?? options?.[item.name] ?? [] } : {}) })), [formItems, options])
|
|
40
|
+
|
|
38
41
|
/**
|
|
39
42
|
* @function handleReset
|
|
40
43
|
* @description 执行“归零协议”:清除当前所有搜索信号,并可选择性擦除 URL 中的物理记录。
|
|
@@ -115,15 +118,19 @@ export const MySearchForm = ({ form, search, loading, labelCol, setSearch, formI
|
|
|
115
118
|
newValues[item.name] = [dayjs(Number(initialValues[startKey])), dayjs(Number(initialValues[endKey]))]
|
|
116
119
|
}
|
|
117
120
|
}
|
|
121
|
+
// 处理多选框回显
|
|
122
|
+
if (item.hasOwnProperty('mode') && !!initialValues[item.name]) {
|
|
123
|
+
newValues[item.name] = initialValues[item.name]?.split(',')
|
|
124
|
+
}
|
|
118
125
|
})
|
|
119
126
|
form.setFieldsValue(newValues)
|
|
120
127
|
}
|
|
121
|
-
}, [
|
|
128
|
+
}, [form, formItems, initialValues])
|
|
122
129
|
|
|
123
130
|
return (
|
|
124
|
-
<Form form={form} onFinish={handleFinish} labelCol={labelCol} onValuesChange={onValuesChange}>
|
|
131
|
+
<Form form={form} onFinish={handleFinish} labelCol={labelCol} onValuesChange={onValuesChange} className='searchForm'>
|
|
125
132
|
<Row gutter={24}>
|
|
126
|
-
{
|
|
133
|
+
{searchItems.slice(0, limit)?.map((item, ind) => (
|
|
127
134
|
<Col key={ind} span={item.span ?? 6}>
|
|
128
135
|
{/* 物理装配:利用底层 MyBaseForm 单元进行渲染 */}
|
|
129
136
|
<MyBaseForm item={item} form={form} />
|
|
@@ -137,9 +144,9 @@ export const MySearchForm = ({ form, search, loading, labelCol, setSearch, formI
|
|
|
137
144
|
<Col flex='auto' style={{ textAlign: 'right' }}>
|
|
138
145
|
<Form.Item>
|
|
139
146
|
<Space>
|
|
140
|
-
<Button type='primary' loading={loading} htmlType='submit'>查询</Button>
|
|
141
|
-
<Button onClick={handleReset} loading={loading} htmlType='reset'>重置</Button>
|
|
142
|
-
{
|
|
147
|
+
<Button type='primary' icon={<SearchOutlined />} loading={loading} htmlType='submit'>查询</Button>
|
|
148
|
+
<Button icon={<RedoOutlined />} onClick={handleReset} loading={loading} htmlType='reset'>重置</Button>
|
|
149
|
+
{extra}
|
|
143
150
|
{/* 动态伸缩协议:根据当前零部件数量决定是否显示展开/收起按钮 */}
|
|
144
151
|
{formItems.length > showLimit && (<a onClick={() => setLimit(formItems.length > limit ? formItems.length : showLimit)}>{formItems.length > limit ? '展开' : '收起'}</a>)}
|
|
145
152
|
</Space>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Table } from 'antd'
|
|
1
|
+
import { Space, Table } from 'antd'
|
|
2
2
|
import { EditableRow, EditableCell } from './EditableCell'
|
|
3
3
|
import { useRef, useMemo, useEffect, useCallback } from 'react'
|
|
4
4
|
|
|
@@ -54,7 +54,7 @@ import { useRef, useMemo, useEffect, useCallback } from 'react'
|
|
|
54
54
|
* }}
|
|
55
55
|
* />
|
|
56
56
|
*/
|
|
57
|
-
export const MyTable = ({ size, query, total, search, autoScroll, onChange, pagination, renderAction, rowClassName, customSave, setDataSource, lineFormChange, columns = [], rowSelection, rowKey = 'id', loading = false, dataSource = [], scroll = { x: 'max-content' }, isLocalPaging = false, ...restProps }) => {
|
|
57
|
+
export const MyTable = ({ size, query, total, search, autoScroll, onChange, setSearch, pagination, renderAction, rowClassName, customSave, setDataSource, lineFormChange, columns = [], rowSelection, rowKey = 'id', loading = false, dataSource = [], scroll = { x: 'max-content' }, isLocalPaging = false, ...restProps }) => {
|
|
58
58
|
|
|
59
59
|
const tableRef = useRef(null)
|
|
60
60
|
const hasScrolledRef = useRef(false)
|
|
@@ -101,10 +101,37 @@ export const MyTable = ({ size, query, total, search, autoScroll, onChange, pagi
|
|
|
101
101
|
const mergedColumns = useMemo(() => {
|
|
102
102
|
return columns.map(col => {
|
|
103
103
|
if (!col.editType) {
|
|
104
|
+
let currentCol = { ...col }
|
|
104
105
|
if (col.renderAction && renderAction?.[col.dataIndex]) {
|
|
105
|
-
|
|
106
|
+
currentCol.render = renderAction[col.dataIndex]
|
|
106
107
|
}
|
|
107
|
-
|
|
108
|
+
if (col.search) {
|
|
109
|
+
currentCol = {
|
|
110
|
+
...currentCol,
|
|
111
|
+
filterSearch: true,
|
|
112
|
+
onFilter: (value, record) => col.remote ? undefined : col.customFilter({ value, record, dataIndex: col.dataIndex }),
|
|
113
|
+
filterDropdown: ({ close, confirm, selectedKeys, clearFilters, setSelectedKeys }) => (
|
|
114
|
+
<Space direction='vertical' style={{ padding: 12 }}>
|
|
115
|
+
{col.customFilterDropdown({ dataIndex: col.dataIndex, selectedKeys, setSelectedKeys })}
|
|
116
|
+
<div style={{ display: 'flex' }}>
|
|
117
|
+
<a style={{ marginLeft: 'auto', marginRight: 8 }} onClick={() => {
|
|
118
|
+
if (col.remote) {
|
|
119
|
+
setSearch(prev => ({ ...prev, pageNo: 1, [col.dataIndex]: col.formatFilter?.(selectedKeys) ?? selectedKeys?.toString() }))
|
|
120
|
+
}
|
|
121
|
+
confirm()
|
|
122
|
+
}}>确定</a>
|
|
123
|
+
<a onClick={() => {
|
|
124
|
+
if (col.remote) {
|
|
125
|
+
setSearch(prev => ({ ...prev, pageNo: 1, [col.dataIndex]: undefined }))
|
|
126
|
+
}
|
|
127
|
+
clearFilters()
|
|
128
|
+
}}>重置</a>
|
|
129
|
+
</div>
|
|
130
|
+
</Space>
|
|
131
|
+
),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return currentCol
|
|
108
135
|
}
|
|
109
136
|
return {
|
|
110
137
|
...col,
|
|
@@ -113,6 +140,7 @@ export const MyTable = ({ size, query, total, search, autoScroll, onChange, pagi
|
|
|
113
140
|
handleSave,
|
|
114
141
|
title: col.title,
|
|
115
142
|
rules: col.rules,
|
|
143
|
+
extra: col.extra,
|
|
116
144
|
options: col.options,
|
|
117
145
|
editType: col.editType,
|
|
118
146
|
dataIndex: col.dataIndex,
|
|
@@ -145,7 +173,7 @@ export const MyTable = ({ size, query, total, search, autoScroll, onChange, pagi
|
|
|
145
173
|
}),
|
|
146
174
|
...(typeof pagination === 'object' ? pagination : {})
|
|
147
175
|
}
|
|
148
|
-
}, [total, search, pagination
|
|
176
|
+
}, [total, search, pagination])
|
|
149
177
|
|
|
150
178
|
/**
|
|
151
179
|
* @description [视觉追踪协议] 当检测到 query.rowIndex 信号时,执行“物理重定向”。
|