文件上传
可以使用 fs.* 处理器, 制作文件上传接口。在管理界面中, 使用 Upload 组件实现文件、图片或视频上传功能。
约定
- 示例中约定应用根目录为
/data/app
, 实际编写时需替换为应用根目录。 - 示例中约定服务器地址为
http://127.0.0.1:5099
, 实际编写时需自行替换。 - 使用
<>
标识自行替换的内容。 例如:icon-<图标名称>
, 实际编写时应替换为:icon-foo
,icon-bar
...
文件上传
给 product
Model 添加一个 images
JSON 字段用来保存产品图片文件地址。
json
{
"name": "产品",
"table": { "name": "product", "comment": "产品表" },
"columns": [
{ "label": "ID", "name": "id", "type": "ID", "comment": "ID" },
{ "label": "日期", "name": "day", "type": "datetime", "index": true },
{
"label": "名称",
"name": "name",
"type": "string",
"length": 128,
"index": true
},
{
"label": "图集",
"name": "images",
"type": "json",
"nullable": true
},
{
"label": "上架状态",
"name": "online",
"type": "boolean",
"default": false,
"comment": "上架状态 true 上架 false 下架",
"index": true
},
{
"label": "状态",
"name": "status",
"type": "enum",
"default": "enabled",
"option": ["enabled", "disabled"],
"comment": "状态:enabled打开,disabled关闭",
"index": true
},
{ "label": "用户ID", "name": "user_id", "type": "integer", "index": true },
{ "label": "总金额", "name": "amount", "type": "decimal", "index": true },
{ "label": "备注", "name": "remark", "type": "text", "nullable": true }
],
"values": [],
"relations": {
"users": {
"type": "hasOne",
"model": "xiang.user",
"key": "id",
"foreign": "user_id",
"query": {}
}
},
"option": { "timestamps": true, "soft_deletes": true }
}
更新数据表结构
bash
yao migrate -n product
Upload & Image 组件
给 product
Table 添加图集字段, 实现图片上传管理。
使用 Cloud Props
生成一个文件上传接口。
jsonc
{
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Downalod" }, // 使用 Image 组件显示已上传图片
"edit": {
"type": "Upload",
"compute": "Upload",
"props": {
"filetype": "image", // 上传文件类型设定为 image
"$api": {
"process": "fs.system.Upload" // 声明一个API接口, 并绑定 fs.system.Upload 处理器
}
}
}
}
}
使用 Downalod
和 Upload
Compute 处理器转换图片预览 URL
Compute | 原始值 | 转换后 |
---|---|---|
Downalod | ["/path/img.png"] | ["/api/__yao/table/<Widget ID>/download/<field>?name=/path/img.png"] |
Upload | ["/api/__yao/table/<Widget ID>/download/<field>?name=/path/img.png"] | ["/path/img.png"] |
组件 Props 以 $ 开头的 KEY, 引擎将其解析为一个 API 接口。并把接口路由和查询参数, 作为参数替换原值。
json
{
"name": "产品",
"action": { "bind": { "model": "product" } },
"layout": {
"header": { "preset": {} },
"filter": {
"columns": [{ "name": "名称", "width": 4 }],
"actions": [
{
"title": "添加产品",
"icon": "icon-plus",
"width": 3,
"action": {
"Common.openModal": {
"Form": { "type": "edit", "model": "product" }
}
}
}
]
},
"table": {
"columns": [
{ "name": "图集", "width": 300 },
{ "name": "联动", "width": 200 },
{ "name": "名称", "width": 200 },
{ "name": "备注", "width": 200 },
{ "name": "上架状态", "width": 200 }
],
"operation": {
"fold": false,
"width": 255,
"actions": [
{
"title": "查看",
"icon": "icon-eye",
"action": {
"Common.openModal": {
"Form": { "type": "view", "model": "product" }
}
}
},
{
"title": "编辑",
"icon": "icon-edit-2",
"action": {
"Common.openModal": {
"Form": { "type": "edit", "model": "product" }
}
}
}
]
}
}
},
"fields": {
"table": {
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Download" },
"edit": {
"type": "Upload",
"compute": "Upload",
"props": {
"filetype": "image",
"$api": { "process": "fs.system.Upload" }
}
}
},
"联动": {
"bind": "online",
"view": {
"bind": "new_field",
"type": "Text",
"compute": {
"process": "Concat",
"args": ["$C(row.name)", "(", "$C(row.remark)", ")"]
}
},
"edit": {
"type": "Select",
"props": {
"options": [
{ "label": "已上架", "value": true },
{ "label": "已下架", "value": false }
]
}
}
}
}
}
}
自定义上传接口
使用 API Widget 创建一个文件上传接口, 将处理器指定为 fs.system.Upload。
/data/app/apis/upload.http.json
jsonc
{
"name": "文件上传",
"version": "1.0.0",
"description": "文件上传",
"guard": "bearer-jwt",
"paths": [
{
"path": "/file",
"method": "POST",
"guard": "-",
"process": "fs.system.Upload",
"in": ["$file.file"],
"out": { "status": 200, "type": "application/json" }
}
]
}
运行调试
添加一个测试文件用于上传
bash
mkdir -p /data/app/data/ # 如 data 目录不存在, 创建一个 data 目录
echo "Upload Test" > /data/app/data/upload-test.txt
bash
curl http://127.0.0.1:5099/api/upload/file \
-F file=@data/upload-test.txt
自定义上传逻辑
逻辑编排
使用 Flow
新建一个 Flow DSL 文件编排上传逻辑
jsonc
{
"label": "文件上传",
"version": "1.0.0",
"description": "文件上传",
"nodes": [
{
"name": "文件",
"process": "fs.system.ReadFile",
"args": ["{{$in[0].tempFile}}"]
},
{
"name": "当前时刻",
"process": "utils.now.Timestampms",
"args": []
},
{
"name": "名称",
"process": "utils.str.Concat",
"args": ["{{$res.当前时刻}}", ".txt"]
},
{
"name": "文件名",
"process": "utils.str.JoinPath",
"args": ["/", "texts", "{{$res.名称}}"]
},
{
"name": "保存文件",
"process": "fs.system.WriteFile",
"args": ["{{$res.文件名}}", "{{$res.文件}}", "0644"]
}
],
"output": "{{$res.文件名}}"
}
运行调试
创建个临时文件用于上传
bash
tempfile=$(mktemp)
echo "Upload Test" > $tempfile
echo $tempfile
bash
yao run flows.upload.file '::{"tempFile":"<tempfile>"}'
使用 Script
新建一个 Script 脚本编排上传逻辑
javascript
/**
* 上传文件
* @param {*} temp
* @returns
*/
function File(temp) {
temp = temp || {};
if (!temp.tempFile) {
throw new Exception('参数错误', 400);
}
var fs = new FS('system');
let tempFile = temp.tempFile || null;
var data = fs.ReadFile(tempFile);
let now = new Date().getTime();
let file = `/texts/${now}.txt`;
fs.WriteFile(file, data, 0644);
return file;
}
运行调试
创建个临时文件用于上传
bash
tempfile=$(mktemp)
echo "Upload Test" > $tempfile
echo $tempfile
bash
yao run scripts.upload.File '::{"tempFile":"<tempfile>"}'
在接口中使用
/data/app/apis/upload.http.json
jsonc
{
"name": "文件上传",
"version": "1.0.0",
"description": "文件上传",
"guard": "bearer-jwt",
"group": "upload",
"paths": [
{
"path": "/file",
"method": "POST",
"guard": "-",
"process": "fs.system.Upload",
"in": ["$file.file"],
"out": { "status": 200, "type": "application/json" }
},
{
"path": "/flow",
"method": "POST",
"guard": "-",
"process": "flows.upload.file",
"in": ["$file.file"],
"out": { "status": 200, "type": "application/json" }
},
{
"path": "/script",
"method": "POST",
"guard": "-",
"process": "scripts.upload.File",
"in": ["$file.file"],
"out": { "status": 200, "type": "application/json" }
}
]
}
运行调试
添加一个测试文件用于上传
bash
mkdir -p /data/app/data/ # 如 data 目录不存在, 创建一个 data 目录
echo "Upload Test" > /data/app/data/upload-test.txt
bash
curl http://127.0.0.1:5099/api/upload/file \
-F file=@data/upload-test.txt
bash
curl http://127.0.0.1:5099/api/upload/flow \
-F file=@data/upload-test.txt
bash
curl http://127.0.0.1:5099/api/upload/script \
-F file=@data/upload-test.txt
在 Upload 组件中使用
使用 Cloud Props
jsonc
{
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Download" },
"edit": {
"type": "Upload",
"compute": "Upload",
"props": {
"filetype": "image",
"$api": {
"process": "flows.upload.file" // 绑定 flows.upload.file 处理器
}
}
}
}
}
jsonc
{
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Download" },
"edit": {
"type": "Upload",
"compute": "Upload",
"props": {
"filetype": "image",
"$api": {
"process": "scripts.upload.File" // 绑定 scripts.upload.File 处理器
}
}
}
}
}
使用 props.api
jsonc
{
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Download" },
"edit": {
"type": "Upload",
"compute": "Upload",
"props": { "filetype": "image", "api": "/apis/upload/flow" }
}
}
}
jsonc
{
"图集": {
"bind": "images",
"view": { "type": "Image", "compute": "Download" },
"edit": {
"type": "Upload",
"compute": "Download",
"props": { "filetype": "image", "api": "/apis/upload/script" }
}
}
}