diff --git a/.env.local b/.env.local
index a361a78c..93b036e1 100644
--- a/.env.local
+++ b/.env.local
@@ -2,4 +2,6 @@ SQL_HOST=localhost
SQL_PORT=3306
SQL_USER=root
SQL_PASSWORD=admin
-SQL_DATABASE=tiny_engine
\ No newline at end of file
+SQL_DATABASE=tiny_engine
+
+backend_url=http://localhost:9090/material-center/api/component/bundle/create
\ No newline at end of file
diff --git a/docs/api/backend-api/material-center.md b/docs/api/backend-api/material-center.md
index 52c0049a..222bd09b 100644
--- a/docs/api/backend-api/material-center.md
+++ b/docs/api/backend-api/material-center.md
@@ -327,3 +327,54 @@ tenant 通过前端配置统一 x-lowcode-org 请求头传递,接口中不用
+## 物料同步接口
+
+
+
+### 基本信息
+
+**Path:** /material-center/api/component/bundle/create
+
+**Method:** POST
+
+**接口描述:**
+
+
处理物料同步上传bundle.json文件创建或更新组件
+
+
+### 请求参数
+
+**Headers**
+
+| 参数名称 | 参数值 | 是否必须 | 示例 | 备注 |
+| ------------ | ---------------- | -------- | ---- | ---- |
+| Content-Type | multipart/form-data | 是 | | |
+
+**路径参数**
+
+| 参数名称 | 示例 | 备注 |
+| -------- | ---- | ------ |
+| file | bundle.json | bundle.json文件 |
+
+**Body**
+
+
+
+
+ | 名称 | 类型 | 是否必须 | 默认值 | 备注 | 其他信息 |
+
+
+
+
+
+
+### 返回数据
+
+
+
+
+ | 名称 | 类型 | 是否必须 | 默认值 | 备注 | 其他信息 |
+
+ | data | object | 非必须 | | | |
| ├─ insertNum | number | 非必须 | | 新增组件数 | |
| ├─ updateNum | number | 非必须 | | 更新组件数 | |
+
+
\ No newline at end of file
diff --git a/docs/solutions/imgs/bundle_upload.png b/docs/solutions/imgs/bundle_upload.png
new file mode 100644
index 00000000..886b3472
Binary files /dev/null and b/docs/solutions/imgs/bundle_upload.png differ
diff --git a/docs/solutions/imgs/component_create_code.png b/docs/solutions/imgs/component_create_code.png
new file mode 100644
index 00000000..d7866518
Binary files /dev/null and b/docs/solutions/imgs/component_create_code.png differ
diff --git a/docs/solutions/material-sync-solution.md b/docs/solutions/material-sync-solution.md
index 3a7cda1c..2e1343eb 100644
--- a/docs/solutions/material-sync-solution.md
+++ b/docs/solutions/material-sync-solution.md
@@ -1,10 +1,24 @@
## 物料同步方案
+### 方案一 (推荐使用)
+通过前端脚本上传编辑好的bundle.json文件。
+```shell
+pnpm uploadMaterials
+```
+
+#### 注意事项
+1. bundle.json文件内组件版本version字段为必须字段,缺少的需要补充不然上传接口报错
+2. bundle.json文件内组件版本version与数据库t_component内version不一致时为新增,一致为更新,也可根据自身需求更改相关代码逻辑
+3. .env.local中配置访问后端接口的路径,默认java后端路径
+
+
+
+### 方案二
由于当前情况下物料无法通过页面交互维护,提供一个临时方案,由前端托管物料。
在本地运行时提供nodejs脚本维护物料,执行脚本保证mockServer工程和前端工程物料的同步。如果启动了后端服务,还可以连接数据库,保证本地json文件和数据库的一致性。

-### 拆分脚本
+#### 拆分脚本
```shell
pnpm splitMaterials
@@ -13,7 +27,7 @@ pnpm splitMaterials
之前对物料的修改要先从大文件bundle.json中找到对应组件,然后进行修改调试,很容易出现找错组件或难以对比历史的情况。
执行该脚本可以将物料资产包拆分为单个组件或区块,再结合构建的脚本,可以将修改限制在相对较小的文件中,便于维护物料和对比变更。
-### 构建脚本
+#### 构建脚本
```shell
pnpm buildMaterials
@@ -26,14 +40,15 @@ pnpm buildMaterials
- 连接数据库,初始化组件表,将组件数据写入数据库
- 监听组件文件变化,重新构建物料资产包和应用 mock 数据,新增或更新数据库中组件数据
-### 注意事项
+#### 注意事项
1. 本地还没有执行过拆分脚本的,先执行一次,后续可以不用再执行,只需要对单个组件进行维护
2. 单个组件文件需要遵循物料协议,更新文件后保存即可触发重新构建物料资产包,刷新页面后生效
3. 连接数据库失败,不影响构建本地物料资产包即bundle.json
4. 连接数据库需要的配置项在`.env.local`中
+5. 数据关联关系可能没有入库,如果查询不到新添加的组件,需要手动在数据库表r_material_component、r_material_history_component添加关联关系数据
-### 部署建议
+#### 部署建议
需要将设计器进行部署时,关于物料的部署方案,以下供参考:
diff --git a/package.json b/package.json
index 49b9ce1e..5e101abe 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,8 @@
"setup": "node ./scripts/setup.js",
"splitMaterials": "node ./scripts/splitMaterials.mjs",
"buildMaterials": "node ./scripts/buildMaterials.mjs",
- "updateTemplate": "node ./scripts/updateTemplate.mjs"
+ "updateTemplate": "node ./scripts/updateTemplate.mjs",
+ "uploadMaterials": "node scripts/uploadMaterials.mjs"
},
"devDependencies": {
"@eslint/js": "^8.57.1",
diff --git a/scripts/uploadMaterials.mjs b/scripts/uploadMaterials.mjs
new file mode 100644
index 00000000..9435f87e
--- /dev/null
+++ b/scripts/uploadMaterials.mjs
@@ -0,0 +1,40 @@
+import { Buffer } from 'buffer'
+import dotenv from 'dotenv'
+import fs from 'fs-extra'
+import path from 'node:path'
+import Logger from './logger.mjs'
+
+const logger = new Logger('uploadMaterials')
+
+// 先构造出.env*文件的绝对路径
+const appDirectory = fs.realpathSync(process.cwd())
+const resolveApp = (relativePath) => path.resolve(appDirectory, relativePath)
+const pathsDotenv = resolveApp('.env')
+dotenv.config({ path: `${pathsDotenv}.local` })
+const { backend_url } = process.env
+
+const bundlePath = path.join(process.cwd(), '/designer-demo/public/mock/bundle.json')
+const bundle = fs.readJSONSync(bundlePath)
+const jsonBuffer = Buffer.from(JSON.stringify(bundle))
+const boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'
+const formHeaders = {
+ 'Content-Type': `multipart/form-data; boundary=${boundary}`,
+}
+
+let body = `--${boundary}\r\n`
+body += 'Content-Disposition: form-data; name="file"; filename="bundle.json"\r\n'
+body += 'Content-Type: application/json\r\n\r\n'
+body += jsonBuffer.toString() + `\r\n--${boundary}--`
+
+fetch(backend_url, {
+ method: 'POST',
+ headers: formHeaders,
+ body: body,
+})
+ .then(response => response.json())
+ .then(data => {
+ logger.success('File uploaded successfully:', data)
+ })
+ .catch(error => {
+ logger.error('Error uploading file:', error)
+ })