添加 Magic-API 接口快速开发框架的脚本编写助手
This commit is contained in:
parent
b2d286035b
commit
8c6bec031b
18
magic-script-skill/.gitignore
vendored
Normal file
18
magic-script-skill/.gitignore
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Build and Release Folders
|
||||
bin-debug/
|
||||
bin-release/
|
||||
[Oo]bj/
|
||||
[Bb]in/
|
||||
|
||||
# Other files and folders
|
||||
.settings/
|
||||
|
||||
# Executables
|
||||
*.swf
|
||||
*.air
|
||||
*.ipa
|
||||
*.apk
|
||||
|
||||
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
|
||||
# should NOT be excluded as they contain compiler settings and other important
|
||||
# information for Eclipse / Flash Builder.
|
||||
21
magic-script-skill/LICENSE
Normal file
21
magic-script-skill/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Assassin-Q
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
154
magic-script-skill/SKILL.md
Normal file
154
magic-script-skill/SKILL.md
Normal file
@ -0,0 +1,154 @@
|
||||
---
|
||||
name: magic-script
|
||||
description: magic-api 框架接口开发助手,提供 magic-script 脚本编写指导、DB/HTTP 模块使用及语法纠错;当用户需要在 magic-api 中编写接口脚本、调试脚本或排查脚本错误时使用
|
||||
---
|
||||
|
||||
# Magic-Script 脚本开发助手
|
||||
|
||||
Magic-API 是一个基于 Java 的接口快速开发框架,支持通过 magic-script 脚本语言编写接口。magic-script 是一种基于 Mozilla Rhino 的脚本语言,语法类似 JavaScript,专为接口开发优化。
|
||||
|
||||
> **说明**:本 Skill 同时兼容以下称呼方式:
|
||||
> - magic-api / magicapi(框架名称)
|
||||
> - magic-script / MagicScript / magicscript(脚本语言名称)
|
||||
> 无论用户使用哪种称呼,都指代同一套技术栈。
|
||||
|
||||
## 任务目标
|
||||
- 本 Skill 用于:为 magic-api/magicapi 框架提供 magic-script/MagicScript 脚本编写的完整指导
|
||||
- 能力包含:magic-script 语法参考、内置模块(db、http 等)使用方法、接口开发示例和脚本故障排查
|
||||
- 触发条件:用户需要在 magic-api/magicapi 中编写接口脚本、调试 magic-script/MagicScript 代码或解决脚本执行错误时使用
|
||||
|
||||
## 操作步骤
|
||||
- 标准流程:确认场景 → 阅读 SKILL.md → 查阅 references/ 文档 → 编写脚本
|
||||
- 可选分支:遇到脚本错误 → 查阅 faq 相关文档
|
||||
|
||||
## 使用示例
|
||||
|
||||
**示例1:快速查询接口**
|
||||
```javascript
|
||||
// GET /api/user/list 分页查询
|
||||
return db.table('sys_user')
|
||||
.column('id', 'userId')
|
||||
.column('name', 'userName')
|
||||
.where()
|
||||
.eq('status', 1)
|
||||
.page(page, size);
|
||||
```
|
||||
|
||||
**示例2:带参数的增删改查**
|
||||
```javascript
|
||||
// POST /api/user/save 新增用户
|
||||
assert not_blank(body.name) : 400, '用户名不能为空';
|
||||
var userId = db.table('sys_user')
|
||||
.column('name', body.name)
|
||||
.column('create_time', now())
|
||||
.insert();
|
||||
return {code: 200, data: {id: userId}};
|
||||
```
|
||||
|
||||
**示例3:调用外部接口**
|
||||
```javascript
|
||||
import http;
|
||||
var result = http.connect('https://api.example.com/data')
|
||||
.param({key: 'value'})
|
||||
.header('Authorization', 'Bearer xxx')
|
||||
.post()
|
||||
.getBody();
|
||||
return result;
|
||||
```
|
||||
|
||||
## 资源索引
|
||||
|
||||
### 语法类
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/keywords.md` | 关键字、运算符、数据类型 |
|
||||
| `references/script-syntax.md` | 脚本语法详解 |
|
||||
| `references/lambda-async.md` | Lambda表达式与异步调用 |
|
||||
|
||||
### 函数扩展
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/aggregation.md` | 聚合函数(count/sum/max/min/avg/group_concat) |
|
||||
| `references/string-functions.md` | 字符串函数(uuid/is_blank/not_blank) |
|
||||
| `references/date-functions.md` | 日期函数(date_format/now/current_timestamp_millis/current_timestamp) |
|
||||
| `references/number-extensions.md` | Number扩展与数学函数 |
|
||||
| `references/collection-extensions.md` | 列表与Map扩展 |
|
||||
| `references/date-extensions.md` | 日期扩展 |
|
||||
| `references/array-functions.md` | 数组创建函数 |
|
||||
| `references/math-functions.md` | 数学函数(round/floor/ceil/percent) |
|
||||
| `references/other-functions.md` | 其它函数(print/println/ifnull/is_null/not_null) |
|
||||
| `references/object-extensions.md` | Object扩展方法 |
|
||||
| `references/class-extensions.md` | Class扩展方法 |
|
||||
| `references/pattern-extensions.md` | Pattern扩展方法 |
|
||||
|
||||
### 数据库
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/db-query.md` | 数据库查询(select/selectOne/selectInt/selectValue) |
|
||||
| `references/db-update.md` | 数据库增删改(insert/update/batchUpdate/call) |
|
||||
| `references/db-transaction.md` | 事务操作 |
|
||||
| `references/db-cache.md` | 缓存操作(cache/deleteCache) |
|
||||
| `references/single-table.md` | 单表操作(db.table链式API) |
|
||||
| `references/sql-param.md` | SQL参数(#{}、${}、动态SQL、Mybatis语法) |
|
||||
| `references/page.md` | 分页查询 |
|
||||
|
||||
### 模块
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/http-module.md` | HTTP模块调用外部接口 |
|
||||
| `references/request-module.md` | Request模块获取请求信息 |
|
||||
| `references/response-module.md` | Response模块设置响应 |
|
||||
| `references/log-module.md` | 日志模块 |
|
||||
| `references/env-module.md` | 环境配置模块 |
|
||||
| `references/magic-module.md` | Magic模块(调用其他接口) |
|
||||
|
||||
### 集成
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/java-integration.md` | 脚本调用Java |
|
||||
| `references/api-integration.md` | Java调用接口 |
|
||||
|
||||
### 示例
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/quick-start.md` | 快速入门(工程创建、三分钟写接口) |
|
||||
| `references/quick-param.md` | 请求参数获取 |
|
||||
| `references/quick-crud.md` | CRUD操作示例 |
|
||||
| `references/linq.md` | Lambda/LINQ操作示例 |
|
||||
|
||||
### FAQ
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `references/faq.md` | 常见问题 |
|
||||
| `references/validate.md` | 参数校验 |
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **语法限制**:magic-script 不支持 ES6 默认参数语法 `excludeValue = null`,需用 `if (excludeValue === undefined)` 判断;不支持 `new Set()`,需用数组替代
|
||||
|
||||
2. **数组方法**:不支持传统 `for` 循环,需用 `for (value in list)` 或 `for (index, value in list)`;**注意** Collection 扩展提供了 `reduce` 方法用于归约操作
|
||||
|
||||
3. **方法命名**:遍历集合用 `each` 而不是 `forEach`;获取长度用 `size()` 而不是 `length`;判断Map键用 `containsKey()` 而不是 `hasOwnProperty()`
|
||||
|
||||
4. **SQL参数**:`#{}` 防注入占位符用于普通参数,`${}` 字符串拼接用于动态表名/列名/排序字段(存在注入风险)
|
||||
|
||||
5. **类型转换**:`::type` 语法用于类型转换,如 `'123'::int`,转换失败可指定默认值 `'abc'::int(0)`
|
||||
|
||||
6. **获取请求参数**:
|
||||
- URL参数:直接使用变量名 `name`
|
||||
- 表单参数:直接使用变量名 `name`
|
||||
- Header参数:`header.xxx`
|
||||
- Body参数:`body.xxx`
|
||||
- Path参数:`path.xxx` 或直接使用变量名
|
||||
- Cookie参数:`cookie.xxx`
|
||||
- Session参数:`session.xxx`
|
||||
|
||||
7. **循环拼接参数**:`in (#{ids})` 语法会自动对集合参数展开
|
||||
|
||||
8. **多数据源**:使用 `db.slave.select(...)` 格式切换数据源
|
||||
|
||||
9. **SQL缓存**:`db.cache("cacheName", ttl).select(...)` 使用缓存
|
||||
|
||||
10. **事务操作**:
|
||||
- 自动事务:`db.transaction(()=>{...})`
|
||||
- 手动事务:`var tx = db.transaction(); tx.commit(); tx.rollback();`
|
||||
63
magic-script-skill/references/aggregation.md
Normal file
63
magic-script-skill/references/aggregation.md
Normal file
@ -0,0 +1,63 @@
|
||||
# 聚合函数
|
||||
|
||||
## count
|
||||
- 入参:`target`:`Object`
|
||||
- 返回值:`int`
|
||||
- 函数说明:计算集合大小
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return count(list); // 5
|
||||
```
|
||||
|
||||
## sum
|
||||
- 入参:`target`:`Object`
|
||||
- 返回值:`Number`
|
||||
- 函数说明:对集合进行求和
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return sum(list); // 15
|
||||
```
|
||||
|
||||
## max
|
||||
- 入参:`target`:`Object`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:求集合最大值
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return max(list); // 5
|
||||
```
|
||||
|
||||
## min
|
||||
- 入参:`target`:`Object`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:求集合最小值
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return min(list); // 1
|
||||
```
|
||||
|
||||
## avg
|
||||
- 入参:`target`:`Object`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:求集合平均值
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return avg(list); // 3
|
||||
```
|
||||
|
||||
## group_concat
|
||||
- 入参:`target`:`Object`
|
||||
- 入参:`separator`:`String` 分隔符,可省略
|
||||
- 返回值:`Object`
|
||||
- 函数说明:将集合拼接起来
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return group_concat(list); // "1,2,3,4,5"
|
||||
// return group_concat(list,'|'); // "1|2|3|4|5"
|
||||
```
|
||||
128
magic-script-skill/references/api-integration.md
Normal file
128
magic-script-skill/references/api-integration.md
Normal file
@ -0,0 +1,128 @@
|
||||
# Java调用接口
|
||||
|
||||
## 调用接口
|
||||
```java
|
||||
@Autowired
|
||||
MagicAPIService service;
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// 注入变量信息
|
||||
params.put("id", 123);
|
||||
// 内部调用接口不包含code以及message信息,同时也不走拦截器。
|
||||
Object value = service.execute("GET", "/hello", params);
|
||||
// 内部调用接口包含code以及message信息,同时也不走拦截器。
|
||||
// Object value = service.call("GET", "/hello", params);
|
||||
```
|
||||
|
||||
## 调用函数
|
||||
```java
|
||||
@Autowired
|
||||
MagicAPIService service;
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
// 注入变量信息
|
||||
params.put("a", 1);
|
||||
params.put("b", 1);
|
||||
// 调用函数
|
||||
Object value = service.invoke("/test/add", params);
|
||||
```
|
||||
|
||||
## 保存资源
|
||||
```java
|
||||
@Autowired
|
||||
MagicResourceService service;
|
||||
// 保存分组信息
|
||||
service.saveGroup(group);
|
||||
// 保存接口(ApiInfo)、函数(FunctionInfo)、数据源(DataSourceInfo)
|
||||
service.saveFile(apiInfo);
|
||||
```
|
||||
|
||||
## 删除资源
|
||||
```java
|
||||
@Autowired
|
||||
MagicResourceService service;
|
||||
// 删除分组或文件
|
||||
service.delete(id);
|
||||
```
|
||||
|
||||
## 资源列表
|
||||
```java
|
||||
@Autowired
|
||||
MagicResourceService service;
|
||||
// 获取分组下的所有文件
|
||||
service.listFiles(groupId);
|
||||
// 获取接口(api)、函数(function)、数据源(datasource)列表
|
||||
service.files(type);
|
||||
// 获取接口(api)、函数(function)、数据源(datasource)树结构
|
||||
service.tree(type);
|
||||
// 获取全部资源的树结构
|
||||
service.tree();
|
||||
```
|
||||
|
||||
## 其它API
|
||||
|
||||
除了以上列举的`API`以外 `MagicAPIService`还有:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 上传
|
||||
*/
|
||||
boolean upload(InputStream inputStream, String mode) throws IOException;
|
||||
|
||||
/**
|
||||
* 下载
|
||||
*/
|
||||
void download(String groupId, List<SelectedResource> resources, OutputStream os) throws IOException;
|
||||
|
||||
/**
|
||||
* 推送
|
||||
*/
|
||||
JsonBean<?> push(String target, String secretKey, String mode, List<SelectedResource> resources);
|
||||
|
||||
/**
|
||||
* 处理刷新通知
|
||||
*/
|
||||
boolean processNotify(MagicNotify magicNotify);
|
||||
```
|
||||
|
||||
`MagicResourceService` 还有以下方法:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 刷新缓存
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
/**
|
||||
* 移动
|
||||
* @param src 源ID
|
||||
* @param groupId 目标分组
|
||||
*/
|
||||
boolean move(String src, String groupId);
|
||||
|
||||
/**
|
||||
* 复制分组
|
||||
* @param src 源ID
|
||||
* @param target 目标分组
|
||||
*/
|
||||
String copyGroup(String src, String target);
|
||||
|
||||
/**
|
||||
* 获取文件详情
|
||||
*/
|
||||
<T extends MagicEntity> T file(String id);
|
||||
|
||||
/**
|
||||
* 获取分组详情
|
||||
*/
|
||||
Group getGroup(String id);
|
||||
|
||||
/**
|
||||
* 获取完整分组路径
|
||||
*/
|
||||
String getGroupPath(String groupId);
|
||||
|
||||
/**
|
||||
* 获取完整分组名称
|
||||
*/
|
||||
String getGroupName(String groupId);
|
||||
```
|
||||
75
magic-script-skill/references/array-functions.md
Normal file
75
magic-script-skill/references/array-functions.md
Normal file
@ -0,0 +1,75 @@
|
||||
# 数组函数
|
||||
|
||||
## new_int_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`int`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_int_array(1); // [0]
|
||||
```
|
||||
|
||||
## new_long_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`long`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_long_array(1); // [0]
|
||||
```
|
||||
|
||||
## new_double_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`double`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_double_array(1); // [0.0]
|
||||
```
|
||||
|
||||
## new_float_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`float`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_float_array(1); // [0.0]
|
||||
```
|
||||
|
||||
## new_short_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`short`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_short_array(1); // [0]
|
||||
```
|
||||
|
||||
## new_byte_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`byte`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_byte_array(1); // [0]
|
||||
```
|
||||
|
||||
## new_boolean_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`boolean`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_boolean_array(1); // [false]
|
||||
```
|
||||
|
||||
## new_char_array
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`char`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_char_array(1); // ['\0']
|
||||
```
|
||||
|
||||
## new_array
|
||||
- 入参:`Class`:类型
|
||||
- 入参:`size`:`int` 数组长度
|
||||
- 函数说明,创建`Object`类型的数组
|
||||
|
||||
```javascript
|
||||
return new_array(1); // [null] // Object 类型的数组
|
||||
return new_array(String.class, 1); // [null] String类型的数组
|
||||
```
|
||||
25
magic-script-skill/references/class-extensions.md
Normal file
25
magic-script-skill/references/class-extensions.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Class扩展方法
|
||||
|
||||
## newInstance
|
||||
- 入参:`values`:`Object` 可变参数,构造函数的参数
|
||||
- 返回值:`Object`
|
||||
- 函数说明:将`Class`实例化
|
||||
|
||||
```javascript
|
||||
import 'java.text.SimpleDateFormat' as SimpleDateFormat;
|
||||
return SimpleDateFormat.newInstance('yyyy-MM-dd HH:mm:ss');
|
||||
//其实可以简写成 new SimpleDateFormat('yyyy-MM-dd HH:mm:ss'); //这是一个语法糖
|
||||
```
|
||||
|
||||
## 获取类名称
|
||||
支持以下方法
|
||||
- `getName` - 获取完整类名
|
||||
- `getSimpleName` - 获取简单类名
|
||||
- `getCanonicalName` - 获取规范类名
|
||||
|
||||
```javascript
|
||||
import 'java.text.SimpleDateFormat' as SimpleDateFormat;
|
||||
println(SimpleDateFormat.getName()); // java.text.SimpleDateFormat
|
||||
println(SimpleDateFormat.getSimpleName()); // SimpleDateFormat
|
||||
println(SimpleDateFormat.getCanonicalName()); // java.text.SimpleDateFormat
|
||||
```
|
||||
304
magic-script-skill/references/collection-extensions.md
Normal file
304
magic-script-skill/references/collection-extensions.md
Normal file
@ -0,0 +1,304 @@
|
||||
# 数组&集合扩展方法
|
||||
|
||||
为`Collection`,`Iterator`,`Enumeration`,`Object[]` 添加的扩展方法
|
||||
|
||||
## map
|
||||
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||
- 返回值:`Object`
|
||||
- 函数说明:将集合进行循环转换
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5];
|
||||
return list.map(e=>e+1); //返回[2,3,4,5,6]
|
||||
```
|
||||
|
||||
## filter
|
||||
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||
- 返回值:`Object`
|
||||
- 函数说明:将集合进行过滤
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5];
|
||||
return list.filter(e=>e>3); //返回[4,5]
|
||||
return list.filter((item,index)=>index>1); //返回[3,4,5]
|
||||
```
|
||||
|
||||
## each
|
||||
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||
- 返回值:`Object`
|
||||
- 函数说明:循环处理
|
||||
|
||||
```javascript
|
||||
var list = [{name : '小明'},{name : '小花'}];
|
||||
return list.each(item=>item.put('age',18)); //循环添加age属性
|
||||
```
|
||||
|
||||
## sort
|
||||
- 入参:`function`:`Function` 接收一个`Lambda`表达式
|
||||
- 返回值:`Object`
|
||||
- 函数说明:对集合进行排序
|
||||
|
||||
```javascript
|
||||
var list = [1,5,2,3,6];
|
||||
return list.sort((a,b)=>a-b);
|
||||
```
|
||||
|
||||
## first
|
||||
- 返回值:`Object`
|
||||
- 函数说明:返回集合的第一项,集合为空时返回`null`
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return list.first(); // 1
|
||||
```
|
||||
|
||||
## last
|
||||
- 返回值:`Object`
|
||||
- 函数说明:返回集合的最后一项,集合为空时返回`null`
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4,5]
|
||||
return list.last(); // 5
|
||||
```
|
||||
|
||||
## reserve
|
||||
- 返回值:`Object`
|
||||
- 函数说明:对集合进行反转操作
|
||||
|
||||
```javascript
|
||||
var list = [1,5,2,3,6];
|
||||
return list.reserve();
|
||||
```
|
||||
|
||||
## join(拼接)
|
||||
- 入参:`separator` : `String` 分隔符
|
||||
- 返回值:`String`
|
||||
- 函数说明:对集合进行拼接操作
|
||||
|
||||
```javascript
|
||||
var list = [1,5,2,3,6];
|
||||
return list.join('-'); // 1-5-2-3-6
|
||||
```
|
||||
|
||||
## shuffle
|
||||
- 返回值:`Object`
|
||||
- 函数说明:对集合进行打乱处理
|
||||
|
||||
```javascript
|
||||
var list = [1,5,2,3,6];
|
||||
return list.shuffle();
|
||||
```
|
||||
|
||||
## max
|
||||
- 返回值:`Object`
|
||||
- 函数说明:取出集合最大值,如果找不到返回null
|
||||
|
||||
```javascript
|
||||
var list = [1,6,8,9,18,12];
|
||||
return list.max(); // 18
|
||||
```
|
||||
|
||||
## min
|
||||
- 返回值:`Object`
|
||||
- 函数说明:取出集合最小值,如果找不到返回null
|
||||
|
||||
```javascript
|
||||
var list = [6,1,8,9,18,12];
|
||||
return list.min(); // 1
|
||||
```
|
||||
|
||||
## sum
|
||||
- 返回值:`Object`
|
||||
- 函数说明:累加求和,计算不出返回0.0
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4];
|
||||
return list.sum(); // 10
|
||||
```
|
||||
|
||||
## avg
|
||||
- 返回值:`Object`
|
||||
- 函数说明:计算平均值,计算不出返回null
|
||||
|
||||
```javascript
|
||||
var list = [1,2,3,4];
|
||||
return list.avg(); // 2.5
|
||||
```
|
||||
|
||||
## group
|
||||
- 入参:`condition` : `Function` 分组条件
|
||||
- 入参:`mapping` : `Function` 结果映射(省略时不做映射返回List)
|
||||
- 返回值:`Map<Object, List<Object>>`或`Map<Object, Object>`
|
||||
- 函数说明:分组
|
||||
|
||||
```javascript
|
||||
var result = [
|
||||
{ xxx : 1, yyy : 2, value : 11},
|
||||
{ xxx : 1, yyy : 2, value : 22},
|
||||
{ xxx : 2, yyy : 2, value : 33}
|
||||
];
|
||||
|
||||
return result.group(item=>item.xxx + '_' + item.yyy)
|
||||
// 结果:{"1_2": [{...}, {...}], "2_2": [{...}]}
|
||||
```
|
||||
|
||||
## join(关联)
|
||||
- 入参:`target` : `Object` 关联的集合
|
||||
- 入参:`condition` : `Function` 关联条件
|
||||
- 入参:`mapping` : `Function` 结果映射
|
||||
- 返回值:`List<Object>`
|
||||
- 函数说明:将两个集合关联起来
|
||||
|
||||
```javascript
|
||||
var year2019 = [
|
||||
{ "pt":2019, "item_code":"code_1", "sum_price":2234 },
|
||||
{ "pt":2019, "item_code":"code_2", "sum_price":234 }
|
||||
];
|
||||
var year2018 = [
|
||||
{ "pt":2018, "item_code":"code_1", "sum_price":1234.0 }
|
||||
];
|
||||
return year2019.join(year2018, (left, right) => left.item_code == right.item_code, (left, right) => {
|
||||
'年份' : left.pt,
|
||||
'编号' : left.item_code,
|
||||
'今年' : left.sum_price,
|
||||
'去年' : right == null ? 'unknow' : right.sum_price
|
||||
});
|
||||
```
|
||||
|
||||
## asBean(转为Java对象)
|
||||
- 入参:`target` : `Class<?>` 目标类型
|
||||
- 返回值:`List<?>`
|
||||
- 函数说明:将`List<Object>` 转为目标`List`
|
||||
|
||||
```javascript
|
||||
import 'org.ssssssss.script.functions.User' as User;
|
||||
var userList = [{
|
||||
age : 18,
|
||||
weight : 121,
|
||||
money : 123456789L,
|
||||
name : '法外狂徒'
|
||||
}]
|
||||
return userList.asBean(User.class);
|
||||
```
|
||||
|
||||
## every
|
||||
- 入参:`condition` : `Function` 判断条件
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断集合是否都符合条件
|
||||
|
||||
```javascript
|
||||
var vals = [1, 2, 3, 4, 5, 6, 7];
|
||||
return vals.every(e => e > 0); // true
|
||||
```
|
||||
|
||||
## some
|
||||
- 入参:`condition` : `Function` 判断条件
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断集合是否有符合条件的
|
||||
|
||||
```javascript
|
||||
var vals = [1, 2, 3, 4, 5, 6, 7];
|
||||
return vals.some(e => e == 0); // false
|
||||
```
|
||||
|
||||
## reduce
|
||||
- 入参:`function` : `Function` 计算函数
|
||||
- 返回值:`Object`
|
||||
- 函数说明:循环集合通过给定的计算函数返回一个新值
|
||||
|
||||
```javascript
|
||||
var vals = [1, 2, 3];
|
||||
return vals.reduce((sum, val) => sum + val); // 6
|
||||
```
|
||||
|
||||
## find
|
||||
- 入参:`function`:`Function` 查找函数
|
||||
- 返回值:`Object`
|
||||
- 函数说明:循环集合查找符合条件的对象
|
||||
|
||||
```javascript
|
||||
var list = [{name: 'A'}, {name:'B'}]
|
||||
return list.find(it => it.name == 'A'); // {name: 'A'}
|
||||
```
|
||||
|
||||
## findIndex
|
||||
- 入参:`function`:`Function` 查找函数
|
||||
- 返回值:`Object`
|
||||
- 函数说明:循环集合查找符合条件的对象位置
|
||||
|
||||
```javascript
|
||||
var list = [{name: 'A'}, {name: 'B'}]
|
||||
return list.findIndex(it => it.name == 'A'); // 0
|
||||
```
|
||||
|
||||
## concat
|
||||
- 入参:`Object`,要连接的集合对象,可写多个
|
||||
- 返回值:`Object`
|
||||
- 函数说明:拼接一个或多个集合,返回新的集合
|
||||
|
||||
```javascript
|
||||
var list = [1];
|
||||
return [1].concat([2]); // [1,2] list不变
|
||||
return [1].concat([2],[3, 4]); // [1, 2, 3, 4] list不变
|
||||
```
|
||||
|
||||
## toMap
|
||||
- 入参:`mappingKey`:`Function`,key映射方法
|
||||
- 入参:`mappingValue`:`Function`,value映射方法,可省略,默认为本身
|
||||
|
||||
```javascript
|
||||
var list = [
|
||||
{id : 1, name: 'A'},
|
||||
{id : 2, name: 'B'},
|
||||
{id : 3, name: 'C'},
|
||||
]
|
||||
return list.toMap(k => k.id, v => v.name) // {1: 'A', 2: 'B', 3: 'C'}
|
||||
```
|
||||
|
||||
## skip
|
||||
- 入参:`value` : `int` 跳过的数量
|
||||
- 返回值:`Object`
|
||||
- 函数说明:跳过指定个数截取集合
|
||||
|
||||
```javascript
|
||||
var vals = [1, 2, 3, 4];
|
||||
return vals.skip(2); // [3, 4]
|
||||
```
|
||||
|
||||
## limit
|
||||
- 入参:`value` : `int` 限制的数量
|
||||
- 返回值:`Object`
|
||||
- 函数说明:取指定个数的集合
|
||||
|
||||
```javascript
|
||||
var vals = [1, 2, 3, 4];
|
||||
return vals.limit(3); // [1, 2, 3]
|
||||
```
|
||||
|
||||
## findNotNull
|
||||
- 返回值:`Object`
|
||||
- 函数说明:找到第一个不为`null`的值
|
||||
|
||||
```javascript
|
||||
var vals = [null, null, 3, null];
|
||||
return vals.findNotNull(); // 3
|
||||
```
|
||||
|
||||
## distinct
|
||||
- 返回值:`Object`
|
||||
- 函数说明:去掉重复元素
|
||||
|
||||
```javascript
|
||||
var arr = [1, 2, 2, 3];
|
||||
return arr.distinct(); // [1, 2, 3]
|
||||
```
|
||||
|
||||
## distinct(func)
|
||||
- 入参: 映射函数, 形如`e -> e.id`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:根据函数返回值去重,去掉重复元素
|
||||
|
||||
```javascript
|
||||
var arr = [{id: 1, name: "xiaodong"}, {id:1, name: "magic-api"}];
|
||||
return arr.distinct(e => e.id); // [{id: 1, name: "xiaodong"}]
|
||||
```
|
||||
11
magic-script-skill/references/date-extensions.md
Normal file
11
magic-script-skill/references/date-extensions.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Date扩展方法
|
||||
|
||||
## format
|
||||
- 入参:`pattern`:`String` 格式
|
||||
- 返回值:`String`
|
||||
- 函数说明:将日期格式化
|
||||
|
||||
```javascript
|
||||
var date = new Date();
|
||||
return date.format('yyyy-MM-dd'); // 2020-01-01
|
||||
```
|
||||
36
magic-script-skill/references/date-functions.md
Normal file
36
magic-script-skill/references/date-functions.md
Normal file
@ -0,0 +1,36 @@
|
||||
# 日期函数
|
||||
|
||||
## date_format
|
||||
- 入参:`target`:`Date` 日期
|
||||
- 入参:`pattern`:`String` 格式
|
||||
- 返回值:`String`
|
||||
- 函数说明:日期格式化
|
||||
|
||||
```javascript
|
||||
return date_format(new Date()); // 2020-01-01 20:30:30
|
||||
// return date_format(new Date(),'yyyy-MM-dd'); // 2020-01-01
|
||||
```
|
||||
|
||||
## now
|
||||
- 返回值:`Date`
|
||||
- 函数说明:返回当前日期
|
||||
|
||||
```javascript
|
||||
return now(); // 等同于 new Date();
|
||||
```
|
||||
|
||||
## current_timestamp_millis
|
||||
- 返回值:`long`
|
||||
- 函数说明:取当前时间戳(毫秒)
|
||||
|
||||
```javascript
|
||||
return current_timestamp_millis(); // 等同于 System.currentTimeMillis();
|
||||
```
|
||||
|
||||
## current_timestamp
|
||||
- 返回值:`long`
|
||||
- 函数说明:取当前时间戳(秒)
|
||||
|
||||
```javascript
|
||||
return current_timestamp(); // 等同于 current_timestamp_millis() / 1000;
|
||||
```
|
||||
22
magic-script-skill/references/db-cache.md
Normal file
22
magic-script-skill/references/db-cache.md
Normal file
@ -0,0 +1,22 @@
|
||||
# 缓存操作
|
||||
|
||||
## cache
|
||||
- 入参:`cacheName`:`String`
|
||||
- 入参:`ttl`:`long` 缓存有效期,单位毫秒,可省略,默认为配置的值
|
||||
- 返回值:`db` //返回当前实例,即可以链式调用
|
||||
- 函数说明:使用缓存
|
||||
|
||||
```javascript
|
||||
// 使用缓存名为user的查询
|
||||
return db.cache('user').select('select * from sys_user');
|
||||
```
|
||||
|
||||
## deleteCache
|
||||
- 入参:`cacheName`:`String`
|
||||
- 返回值:`db` //返回当前实例,即可以链式调用
|
||||
- 函数说明:删除名为`cacheName`的缓存
|
||||
|
||||
```javascript
|
||||
// 删除名为user的缓存
|
||||
db.deleteCache('user');
|
||||
```
|
||||
63
magic-script-skill/references/db-query.md
Normal file
63
magic-script-skill/references/db-query.md
Normal file
@ -0,0 +1,63 @@
|
||||
# 数据库查询
|
||||
|
||||
db模块是默认引入的模块,无需import。
|
||||
|
||||
## select
|
||||
- 入参:`sql`:`String`
|
||||
- 返回值:`List<Map<String,Object>>`
|
||||
- 函数说明:查询`List`结果
|
||||
|
||||
```javascript
|
||||
return db.select('select * from sys_user');
|
||||
```
|
||||
|
||||
## selectInt
|
||||
- 入参:`sql`:`String`
|
||||
- 返回值:`Integer`
|
||||
- 函数说明:查询`int`结果
|
||||
|
||||
```javascript
|
||||
// 需要保证结果返回一行一列
|
||||
return db.selectInt('select count(*) from sys_user');
|
||||
```
|
||||
|
||||
## selectOne
|
||||
- 入参:`sql`:`String`
|
||||
- 返回值:`Map<String,Object>`
|
||||
- 函数说明:查询单个对象
|
||||
|
||||
```javascript
|
||||
return db.selectOne('select * from sys_user limit 1');
|
||||
```
|
||||
|
||||
## selectValue
|
||||
- 入参:`sql`:`String`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:查询单个值
|
||||
|
||||
```javascript
|
||||
//需要保证结果返回一行一列
|
||||
return db.selectValue('select user_name from sys_user limit 1');
|
||||
```
|
||||
|
||||
## page
|
||||
- 入参:`sql`:`String`
|
||||
- 入参:`limit` : `long` 可省略
|
||||
- 入参:`offset` : `long` 可省略
|
||||
- 返回值:`Object` 默认返回为Object,如果自定义了分页结果,则返回自定义结果
|
||||
- 函数说明:分页查询
|
||||
|
||||
```javascript
|
||||
return db.page('select * from sys_user');
|
||||
```
|
||||
|
||||
## 列名转换
|
||||
- normal 列名保持原样
|
||||
- camel 列名使用驼峰命名
|
||||
- pascal 列名使用帕斯卡命名
|
||||
- upper 列名保持全大写
|
||||
- lower 列名保持全小写
|
||||
|
||||
```javascript
|
||||
return db.camel().select('select * from sys_user');
|
||||
```
|
||||
23
magic-script-skill/references/db-transaction.md
Normal file
23
magic-script-skill/references/db-transaction.md
Normal file
@ -0,0 +1,23 @@
|
||||
# 事务操作
|
||||
|
||||
## 自动事务
|
||||
```javascript
|
||||
var val = db.transaction(()=>{
|
||||
var v1 = db.update('...');
|
||||
var v2 = db.update('....');
|
||||
return v2;
|
||||
});
|
||||
return val;
|
||||
```
|
||||
|
||||
## 手动事务
|
||||
```javascript
|
||||
var tx = db.transaction(); //开启事务
|
||||
try{
|
||||
var value = db.update('...');
|
||||
tx.commit(); // 提交事务
|
||||
return value;
|
||||
}catch(e){
|
||||
tx.rollback(); // 回滚事务
|
||||
}
|
||||
```
|
||||
49
magic-script-skill/references/db-update.md
Normal file
49
magic-script-skill/references/db-update.md
Normal file
@ -0,0 +1,49 @@
|
||||
# 数据库增删改
|
||||
|
||||
## update
|
||||
- 入参:`sql`:`String`
|
||||
- 返回值:`Integer`
|
||||
- 函数说明:执行增删改操作
|
||||
|
||||
```javascript
|
||||
return db.update('delete from sys_user');
|
||||
```
|
||||
|
||||
## insert
|
||||
- 入参:`sql`:`String`
|
||||
- 入参:`id`:`String`,主键列,可空,如无特殊情况不需要传入
|
||||
- 返回值: `Object`
|
||||
|
||||
```javascript
|
||||
return db.insert("insert into sys_user(username,password) values('admin','admin)");
|
||||
```
|
||||
|
||||
## call
|
||||
- 入参:`sql`: `String`
|
||||
- 返回值:`Map<String,Object>`
|
||||
- 函数说明:调用存储过程
|
||||
|
||||
```javascript
|
||||
// 入参格式: #{参数名}
|
||||
// 出参格式: @{参数名, java.sql.Types的类型字符串}
|
||||
// 出入参格式:@{参数名(值、变量、表达式), java.sql.Types的类型字符串}
|
||||
var cs1 = body.cs1;
|
||||
var cs2 = body.cs2;
|
||||
return db.call("""
|
||||
call test(#{cs1}, @{height(cs2), INTEGER}, @{v_area, VARCHAR})
|
||||
""")
|
||||
// 返回:{height: 10, v_area: "16.85"}
|
||||
```
|
||||
|
||||
## batchUpdate
|
||||
- 入参:`sql`:`String`
|
||||
- 入参:`batchArgs`:`List<Object[]>`数据,占位符和数组下标对应
|
||||
- 返回值: `int`
|
||||
|
||||
```javascript
|
||||
return db.batchUpdate("""
|
||||
update sys_dict set is_del = ? where is_del = ?
|
||||
""", [
|
||||
["1", "0"].toArray()
|
||||
])
|
||||
```
|
||||
18
magic-script-skill/references/env-module.md
Normal file
18
magic-script-skill/references/env-module.md
Normal file
@ -0,0 +1,18 @@
|
||||
# 环境配置模块
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import env;
|
||||
```
|
||||
|
||||
## 使用
|
||||
```javascript
|
||||
import env;
|
||||
return env.get('server.port')
|
||||
```
|
||||
|
||||
## get
|
||||
- 入参:`key`:`String` 配置项
|
||||
- 入参:`defaultValue`:`String` 默认值,可省略
|
||||
- 返回值:`String`
|
||||
- 函数说明:获取`Spring`配置项
|
||||
177
magic-script-skill/references/faq.md
Normal file
177
magic-script-skill/references/faq.md
Normal file
@ -0,0 +1,177 @@
|
||||
# 常见问题
|
||||
|
||||
## 如何配置JSON日期的格式
|
||||
使用`Jackson`的配置如下(`Spring Boot`默认使用`Jackson`):
|
||||
```yaml
|
||||
spring:
|
||||
jackson:
|
||||
time-zone: GMT+8
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
```
|
||||
|
||||
## 出现找不到db模块的错误
|
||||
目前已知两种情况:
|
||||
- 未配置数据源
|
||||
- 未引用`spring-boot-starter-jdbc`
|
||||
|
||||
## 如何获取RequestBody中的参数
|
||||
脚本中使用`body.xxx`获取`RequestBody`中的参数
|
||||
SQL中使用`#{body.xxx}`或`${body.xxx}`获取`RequestBody`中的参数
|
||||
|
||||
## 如何获取Header中的参数
|
||||
脚本中使用`header.xxx`获取`Header`中的参数
|
||||
SQL中使用`#{header.xxx}`或`${header.xxx}`获取`Header`中的参数
|
||||
|
||||
## 如何获取Cookie中的参数
|
||||
脚本使用`cookie.xxx`获取`Cookie`中的参数
|
||||
SQL中使用`#{cookie.xxx}`或`${cookie.xxx}`获取`Cookie`中的参数
|
||||
|
||||
## 如何获取Session中的参数
|
||||
脚本中使用`session.xxx`获取`Session`中的参数
|
||||
SQL中使用`#{session.xxx}`获取`Session`中的参数
|
||||
|
||||
## 如何获取PathVariable中的参数
|
||||
脚本中使用`PathVariableName`或`path.xxxx`获取`PathVariable`中的参数
|
||||
SQL中使用`#{PathVariableName}`或`#{path.xxx}`获取`PathVariable`中的参数
|
||||
|
||||
## 如何获取上传的文件
|
||||
利用Request模块
|
||||
```javascript
|
||||
import request;
|
||||
request.getFile('name');
|
||||
```
|
||||
|
||||
## 如何获取提交的数组参数
|
||||
利用Request模块
|
||||
```javascript
|
||||
import request;
|
||||
return request.getValues('name');
|
||||
```
|
||||
|
||||
## 如何给接口添加权限
|
||||
|
||||
一般情况采用`拦截器`实现。在`接口选项`中配置`permisson`或`role`或自定义选项,随后在拦截器中实现:
|
||||
|
||||
```java
|
||||
@Component
|
||||
@Order(1)
|
||||
public class PermissionInterceptor implements RequestInterceptor {
|
||||
|
||||
@Override
|
||||
public Object preHandle(ApiInfo info, MagicScriptContext context, MagicHttpServletRequest request, MagicHttpServletResponse response) {
|
||||
String permissionCode = info.getOptionValue(Options.PERMISSION);
|
||||
// 执行自己的代码逻辑判断是否有权限
|
||||
if(无权限){
|
||||
return new JsonBean<>(403,"无权访问");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 如何给UI添加权限
|
||||
|
||||
请参考[自定义UI鉴权](https://www.ssssssss.org/magic-api/pages/security/operation/)
|
||||
|
||||
## ${}和#{}的区别
|
||||
主要区别在于`${}`用于拼接SQL(会产生SQL注入问题),`#{}`会替换成占位符(不会产生SQL注入问题),这里的区别与`Mybatis`一致
|
||||
|
||||
## 如何循环拼接参数
|
||||
|
||||
两种办法:
|
||||
- `in (#{ids})`的语法会自动对集合参数展开
|
||||
```javascript
|
||||
var ids = [1,2,3,4,5,6];
|
||||
return db.select('select * from sys_user where id in(#{ids})');
|
||||
//会自动变成select * from sys_user where id in(?,?,?,?,?,?)
|
||||
```
|
||||
- 循环拼接SQL
|
||||
```javascript
|
||||
var list = [1,2,3,4,5];
|
||||
var sql = "select * from sys_user where ";
|
||||
for(index,item in list){
|
||||
sql = sql + 'id = #{list['+index+']}';
|
||||
if(index + 1 < list.size()){
|
||||
sql = sql + ' or ';
|
||||
}
|
||||
}
|
||||
return db.select(sql);
|
||||
```
|
||||
|
||||
## 多数据源如何配置
|
||||
编写java代码如下:
|
||||
```java
|
||||
@Bean
|
||||
public MagicDynamicDataSource magicDynamicDataSource(){
|
||||
MagicDynamicDataSource dynamicDataSource = new MagicDynamicDataSource();
|
||||
dynamicDataSource.setDefault(ds1);
|
||||
dynamicDataSource.add("slave",ds2);
|
||||
return dynamicDataSource;
|
||||
}
|
||||
```
|
||||
|
||||
脚本中使用:
|
||||
```javascript
|
||||
db.select('select * from sys_user'); //使用默认数据源
|
||||
db.slave.select('select * from sys_user'); //使用slave数据源
|
||||
```
|
||||
|
||||
## SQL执行报错java.sql.SQLFeatureNotSupportedException: null
|
||||
|
||||
原因:druid版本过低,升级至最新版后即可。
|
||||
|
||||
## 如何自定义返回结果
|
||||
- 通过配置文件进行配置,具体参考[spring-boot配置](https://www.ssssssss.org/magic-api/pages/config/spring-boot/)
|
||||
- 通过`自定义JSON结果`,具体定义方法查看[自定义JSON结果](https://www.ssssssss.org/magic-api/pages/base/response/)
|
||||
- 通过`自定义拦截器`拦截返回自己想要的格式,具体定义方法查看[自定义拦截器](https://www.ssssssss.org/magic-api/pages/senior/interceptor/)
|
||||
- 通过`spring`的拦截器返回想要的格式,如`ResponseBodyAdvice`,`HandlerMethodReturnValueHandler`(这种方式目前会影响到UI,故不推荐使用)
|
||||
|
||||
## 页面加载缓慢
|
||||
|
||||
由于`monaco-editor`编辑器比较大,建议开启压缩静态资源
|
||||
```yaml
|
||||
server.compression.enabled=true #启用压缩
|
||||
server.compression.min-response-size=256 #大于256kb时压缩
|
||||
```
|
||||
|
||||
## 脚本内容被转义
|
||||
|
||||
出现这种情况,请检查自身项目是否有`XSS`一类的过滤器,需要把`UI`界面对应的后台接口排除掉即可。
|
||||
|
||||
## 执行测试无响应
|
||||
|
||||
目前已知有两种情况:
|
||||
- 使用了Spring Boot 2.3.5版本,升级至2.3.6解决
|
||||
- 使用了`nginx`代理,加一条配置`proxy_buffering off;`解决
|
||||
|
||||
## 访问UI404
|
||||
|
||||
- 请检查访问路径是否正确
|
||||
- 请检查`magic-editor`包是否被引入
|
||||
- 如果是拉源码运行,则需要编译一下前端
|
||||
- 如果以上确定没问题,请检查应用中是否有关于`mvc`的配置,如果有请检查是否是`extends WebMvcConfigurationSupport`的形式,是的话,改成`implements WebMvcConfigurer`的形式
|
||||
- 如以上问题均不存在,请提[ISSUE](https://gitee.com/ssssssss-team/magic-api/issues) 或加群700818216反馈
|
||||
|
||||
## 无法DEBUG或无法查看日志
|
||||
|
||||
由于`DEBUG`和日志是依赖于`WebSocket`实现的,所以需要`WebSocket`支持。
|
||||
- 请检查`Web`容器是否支持`WebSocket`,如果不支持需要引入对应依赖或更换支持`WebSocket`的`Web`容器
|
||||
- 请检查是否使用了`nginx`之类的代理,如果使用了,需要对配置其支持`WebSocket`,样例如下:
|
||||
```nginx
|
||||
location /magic/web/console {
|
||||
proxy_pass http://localhost:9999;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_read_timeout 900s;
|
||||
}
|
||||
```
|
||||
|
||||
## 保存图片(Blob)数据到数据库
|
||||
假设将图片的二进制数据传输到body.img中, sql可以这么写
|
||||
```javascript
|
||||
var sql = """
|
||||
insert into img_table(img)
|
||||
values(#{img::sql('blob')})
|
||||
""";
|
||||
```
|
||||
97
magic-script-skill/references/http-module.md
Normal file
97
magic-script-skill/references/http-module.md
Normal file
@ -0,0 +1,97 @@
|
||||
# HTTP模块
|
||||
|
||||
## 模块说明
|
||||
`http`模块是基于`RestTemplate`封装而来,目前只做了少量的封装。对于一些通用的配置可以使用自定义`RestTemplate`来实现
|
||||
|
||||
```java
|
||||
@Bean
|
||||
public HttpModule magicHttpModule() {
|
||||
RestTemplate template = new RestTemplate();
|
||||
// 对RestTemplate进行配置.
|
||||
return new HttpModule(template);
|
||||
}
|
||||
```
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import http;
|
||||
```
|
||||
|
||||
## connect
|
||||
- 入参:`url`:`string`
|
||||
- 返回值:`HttpModule`
|
||||
- 函数说明:创建新的http请求对象
|
||||
|
||||
```javascript
|
||||
import http;
|
||||
http.connect("http://localhost:9999/sql/select")
|
||||
```
|
||||
|
||||
## 设置URL参数、表单参数、Header
|
||||
```javascript
|
||||
import http;
|
||||
http.param('url_param1','url_param_value1') // 设置URL参数
|
||||
.param({ // 批量设置URL参数
|
||||
url_param_2 : 2,
|
||||
url_param_3 : 3,
|
||||
})
|
||||
.data('form_param1','form_param_value1') // 设置表单参数
|
||||
.data({ // 批量设置表单参数
|
||||
form_param_2 : 2,
|
||||
form_param_3 : 3,
|
||||
})
|
||||
.header('header_param1','header_param_value1') // 设置header参数
|
||||
.header({ // 批量设置header参数
|
||||
header_param_2 : 2,
|
||||
header_param_3 : 3,
|
||||
})
|
||||
```
|
||||
|
||||
## body
|
||||
- 入参:`body`:`Object`
|
||||
- 函数说明:设置请求Body
|
||||
|
||||
```javascript
|
||||
import http;
|
||||
http.connect('..').body({
|
||||
id: 1,
|
||||
name: 'magic-api'
|
||||
});
|
||||
```
|
||||
|
||||
## entity
|
||||
- 入参: `entity`: `HttpEntity`
|
||||
- 函数说明:自定义`HttpEntity`
|
||||
|
||||
```javascript
|
||||
import http;
|
||||
http.connect('..').entity(entity)
|
||||
```
|
||||
|
||||
## contentType
|
||||
- 入参: `contentType`: `String`或`MediaType`
|
||||
- 函数说明:定义请求内容类型
|
||||
|
||||
```javascript
|
||||
import http;
|
||||
http.connect('..').contentType('application/json')
|
||||
```
|
||||
|
||||
## 请求方法
|
||||
- `post()` - POST请求
|
||||
- `get()` - GET请求
|
||||
- `delete()` - DELETE请求
|
||||
- `put()` - PUT请求
|
||||
- `head()` - HEAD请求
|
||||
- `patch()` - PATCH请求
|
||||
- `options()` - OPTIONS请求
|
||||
- `trace()` - TRACE请求
|
||||
|
||||
## execute
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:执行对应的请求
|
||||
|
||||
```javascript
|
||||
import http;
|
||||
return http.connect('http://localhost:9999/sql/select').post().getBody()
|
||||
```
|
||||
42
magic-script-skill/references/java-integration.md
Normal file
42
magic-script-skill/references/java-integration.md
Normal file
@ -0,0 +1,42 @@
|
||||
# 脚本调用Java
|
||||
|
||||
## 注入Spring Bean
|
||||
```javascript
|
||||
// 第一种方式
|
||||
import xx.xxx.xxx.xxx.UserService; // 使用类名
|
||||
return UserService.selectUserList();
|
||||
|
||||
// 第二种方式
|
||||
import "userUservice" as userService; // 使用Bean名
|
||||
return userService.selectUserList();
|
||||
```
|
||||
|
||||
## 调用静态方法
|
||||
```javascript
|
||||
import xxx.xxx.xx.xx.xx.StringUtils;
|
||||
return StringUtils.isBlank("");
|
||||
```
|
||||
|
||||
## 调用普通方法
|
||||
```javascript
|
||||
// 对于java.util、java.lang 包下的类,可以直接使用。
|
||||
return new ArrayList();
|
||||
|
||||
// 对于其他类需要import
|
||||
import "java.text.SimpleDateFormat";
|
||||
return new SimpleDateFormat("yyyy-MM-dd").format(new Date());
|
||||
```
|
||||
|
||||
## 调用magic-api的接口
|
||||
```javascript
|
||||
// 可以在脚本中直接调用,非http方式
|
||||
import "@get:/api/sys/user/list" as userList; // 导入定义的GET请求的 /api/sys/user/list 接口。
|
||||
// 脚本中变量是共享给调用者的。所以无需指定参数传入。只需要在本脚本中定义该变量即可。
|
||||
return userList();
|
||||
```
|
||||
|
||||
## 调用magic-api的函数
|
||||
```javascript
|
||||
import "@/common/encode/md5" as md5; // 导入页面上定义的函数信息
|
||||
return md5('123456');
|
||||
```
|
||||
108
magic-script-skill/references/keywords.md
Normal file
108
magic-script-skill/references/keywords.md
Normal file
@ -0,0 +1,108 @@
|
||||
# 关键字、运算符、数据类型
|
||||
|
||||
## 关键字
|
||||
|
||||
| 关键字 | 含义 |
|
||||
|--------|------|
|
||||
| var | 定义变量 |
|
||||
| if | 条件语句的引导词 |
|
||||
| else | 用在条件语句中,表明当条件不成立时的分支 |
|
||||
| for | for循环语句 |
|
||||
| in | 与for配合使用 |
|
||||
| while | while循环语句 |
|
||||
| continue | 执行下一次循环 |
|
||||
| break | 跳出循环 |
|
||||
| return | 终止当前过程的执行并正常退出到上一个执行过程中 |
|
||||
| exit | 终止当前脚本,并退出返回,如`exit 200,'执行成功',[1,2,3];` |
|
||||
| assert | 断言 |
|
||||
| instanceof | 判断一个对象是否为一个类的实例 |
|
||||
| try | 用于捕获可能发生异常的代码块 |
|
||||
| catch | 与try关键字配合使用,当发生异常时执行 |
|
||||
| finally | 与try关键字配合使用,finally块无论发生异常都会执行 |
|
||||
| import | 导入Java类或导入已定义好的模块 |
|
||||
| as | 与 import 关键字配合使用,用作将导入的 Java类或模块 命名为一个本地变量名 |
|
||||
| new | 创建对象 |
|
||||
| true | 基础类型之一,表示 Boolean 的:真值 |
|
||||
| false | 基础类型之一,表示 Boolean 的:假值 |
|
||||
| null | 基础类型之一,表示 NULL 值 |
|
||||
| async | 异步调用 |
|
||||
|
||||
## 运算符
|
||||
|
||||
### 数学运算
|
||||
| 运算符 | 说明 |
|
||||
|--------|------|
|
||||
| + | 加法 |
|
||||
| - | 减法 |
|
||||
| * | 乘法 |
|
||||
| / | 除法 |
|
||||
| % | 取模 |
|
||||
| ++ | 自增 |
|
||||
| -- | 自减 |
|
||||
| += | 加等于 |
|
||||
| -= | 减等于 |
|
||||
| *= | 乘等于 |
|
||||
| /= | 除等于 |
|
||||
| %= | 取模等于 |
|
||||
|
||||
### 比较运算符
|
||||
| 运算符 | 说明 |
|
||||
|--------|------|
|
||||
| < | 小于 |
|
||||
| <= | 小于等于 |
|
||||
| > | 大于 |
|
||||
| >= | 大于等于 |
|
||||
| == | 等于 |
|
||||
| != | 不等于 |
|
||||
| === | 等于 |
|
||||
| !== | 不等于 |
|
||||
|
||||
### 逻辑运算符
|
||||
| 运算符 | 说明 |
|
||||
|--------|------|
|
||||
| && | 并且 |
|
||||
| \|\| | 或者 |
|
||||
| ! | 取反 |
|
||||
|
||||
### 位运算符
|
||||
| 运算符 | 说明 |
|
||||
|--------|------|
|
||||
| & | 与 |
|
||||
| \| | 或 |
|
||||
| ^ | 异或 |
|
||||
| ~ | 取反 |
|
||||
| << | 左移 |
|
||||
| >> | 右移 |
|
||||
| >>> | 无符号右移 |
|
||||
|
||||
## 数据类型
|
||||
|
||||
| 类型 | 写法 |
|
||||
|------|------|
|
||||
| byte | `123b`、`123B` |
|
||||
| short | `123s`、`123S` |
|
||||
| int | `123` |
|
||||
| long | `123l`、`123L` |
|
||||
| float | `123f`、`123F` |
|
||||
| double | `123d`、`123D` |
|
||||
| BigDecimal | `123m`、`123M` |
|
||||
| boolean | `true`、`false` |
|
||||
| string | `'hello'` 或 `"hello"` |
|
||||
| string | `"""多行文本块,主要用于编写SQL"""` |
|
||||
| Pattern | `/\d+/g`,`/pattern/gimuy` 用于定义正则 |
|
||||
| lambda | `()=>expr`、`(param1,param2....)=>{...}` |
|
||||
| list | `[1,2,3,4,5]` |
|
||||
| map | `{key : value,key1 : value}` 或 `{[key] : "value"}` |
|
||||
|
||||
## 三元运算符
|
||||
|
||||
三元运算符是`if`语句的简写形式,其工作方式类似于Java中,例如`true ? "yes" : "no"`
|
||||
|
||||
增强的`if`和三元运算符,不再强制值必须是布尔类型,可以写`if(xxx)`的形式当`xxx`为以下情况时为`false`、其它情况为`true`:
|
||||
- `null`
|
||||
- 空集合
|
||||
- 空Map
|
||||
- 空数组
|
||||
- 数值==0
|
||||
- 空字符串
|
||||
- `false`
|
||||
102
magic-script-skill/references/lambda-async.md
Normal file
102
magic-script-skill/references/lambda-async.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Lambda表达式与异步调用
|
||||
|
||||
## Lambda表达式
|
||||
|
||||
### 映射(map)
|
||||
```javascript
|
||||
var list = [
|
||||
{sex : 0,name : '小明',age : 19},
|
||||
{sex : 1,name : '小花',age : 18}
|
||||
];
|
||||
var getAge = (age) => age > 18 ? '成人' : '未成年'
|
||||
return list.map(item => {
|
||||
age : getAge(item.age),
|
||||
sex : item.sex == 0 ? '男' : '女',
|
||||
name : item.name
|
||||
});
|
||||
// 结果:[{sex: "男", name: "小明", age: "成人"}, {sex: "女", name: "小花", age: "未成年"}]
|
||||
```
|
||||
|
||||
### 过滤(filter)
|
||||
```javascript
|
||||
var list = [
|
||||
{sex : 0,name : '小明'},
|
||||
{sex : 1,name : '小花'}
|
||||
]
|
||||
return list.filter(item => item.sex == 0);
|
||||
// 结果:[{sex: 0, name: "小明"}]
|
||||
```
|
||||
|
||||
### 过滤+映射(filter + map)
|
||||
```javascript
|
||||
var list = [
|
||||
{sex : 0,name : '小明'},
|
||||
{sex : 1,name : '小花'}
|
||||
]
|
||||
return list.filter(item => item.sex == 0).map(item => {
|
||||
sex : item.sex == 0 ? '男' : '女',
|
||||
name : item.name
|
||||
});
|
||||
// 结果:[{sex: "男", name: "小明"}]
|
||||
```
|
||||
|
||||
### 分组(group)
|
||||
默认聚合为List
|
||||
```javascript
|
||||
var result = [
|
||||
{ xxx : 1, yyy : 2, value : 11},
|
||||
{ xxx : 1, yyy : 2, value : 22},
|
||||
{ xxx : 2, yyy : 2, value : 33}
|
||||
];
|
||||
|
||||
return result.group(item => item.xxx + '_' + item.yyy)
|
||||
// 结果:{"1_2": [{...}, {...}], "2_2": [{...}]}
|
||||
```
|
||||
|
||||
自定义聚合对象
|
||||
```javascript
|
||||
return result.group(item => item.xxx + '_' + item.yyy,list => {
|
||||
count : list.size(),
|
||||
sum : list.map(v=>v.value).sum(),
|
||||
avg : list.map(v=>v.value).avg()
|
||||
})
|
||||
// 结果:{"1_2": {"avg": 16.5, "count": 2, "sum": 33}, "2_2": {"avg": 33, "count": 1, "sum": 33}}
|
||||
```
|
||||
|
||||
### 关联(join)
|
||||
```javascript
|
||||
var year2019 = [
|
||||
{ "pt":2019, "item_code":"code_1", "sum_price":2234 },
|
||||
{ "pt":2019, "item_code":"code_2", "sum_price":234 }
|
||||
];
|
||||
var year2018 = [
|
||||
{ "pt":2018, "item_code":"code_1", "sum_price":1234.0 }
|
||||
];
|
||||
return year2019.join(year2018, (left, right) => left.item_code == right.item_code, (left, right) => {
|
||||
'年份' : left.pt,
|
||||
'编号' : left.item_code,
|
||||
'今年' : left.sum_price,
|
||||
'去年' : right == null ? 'unknow' : right.sum_price
|
||||
});
|
||||
```
|
||||
|
||||
## 异步调用
|
||||
|
||||
### 普通方法
|
||||
```javascript
|
||||
// 使用async关键字,会启动一个线程去执行,返回Future
|
||||
var user1 = async db.select("select * from sys_user where id = 1");
|
||||
var user2 = async db.select("select * from sys_user where id = 2");
|
||||
// 调用get方法表示阻塞等待获取结果
|
||||
return [user1.get(),user2.get()];
|
||||
```
|
||||
|
||||
### lambda
|
||||
```javascript
|
||||
var list = [];
|
||||
for(index in range(1,10)){
|
||||
// 当异步中使用外部变量时,为了确保线程安全的变量,可以将其放在形参中
|
||||
list.add(async (index)=>db.select("select * from sys_user where id = #{index}"));
|
||||
}
|
||||
return list.map(item=>item.get());
|
||||
```
|
||||
76
magic-script-skill/references/linq.md
Normal file
76
magic-script-skill/references/linq.md
Normal file
@ -0,0 +1,76 @@
|
||||
# Linq
|
||||
|
||||
## 基本语法
|
||||
```sql
|
||||
select
|
||||
tableAlias.*|[tableAlias.]field[ columnAlias]
|
||||
[,tableAlias.field2[ columnAlias2][,…]]
|
||||
from expr[,…] tableAlias
|
||||
[[left ]join expr tableAlias2 on condition]
|
||||
[where condition]
|
||||
[group by tableAlias.field[,...]]
|
||||
[having condition]
|
||||
[order by tableAlias.field[asc|desc][,tableAlias.field[asc|desc]]]
|
||||
[limit expr [offset expr]]
|
||||
```
|
||||
|
||||
## 执行步骤
|
||||
- 先从`from`子句创建虚拟表VT1
|
||||
- 处理`join`,创建虚拟表VT2,筛选符合条件`condition`的行加入到虚拟表VT2中
|
||||
- 处理`where` 将符合`condition`的行加入虚拟表VT1中
|
||||
- 处理`group by` 对虚拟表VT1、VT2进行分组操作,将符合`having condition`的值加入虚拟表VT3中
|
||||
- 处理`select` 从VT3中选择指定的列,加入虚拟表VT4中
|
||||
- 处理`order by` 对虚拟表VT4进行排序
|
||||
- 处理`limit`
|
||||
|
||||
## select子句
|
||||
```sql
|
||||
select t.name,sum(t.score) score,t.*
|
||||
```
|
||||
> select 中带有聚合函数的,应该有group by语句,否则不会进行聚合处理
|
||||
|
||||
## from子句
|
||||
```sql
|
||||
-- 以下三种方式均可(别名是必须的)
|
||||
from [{name: 'Gitee'},[name:'Github']] t
|
||||
from results t
|
||||
from {name:'Gitee'} t
|
||||
```
|
||||
> from 跟着的必须是`List`或者`Map`
|
||||
|
||||
## join子句
|
||||
```sql
|
||||
-- 以下三种方式均可(别名是必须的)
|
||||
[left] join [{name: 'Gitee'},[name:'Github']] t1 on t1.name = t.name
|
||||
[left] join results t1 on 1 = 1
|
||||
[left] join {name:'Gitee'} t1 on t1.name = 'Gitee' and 1=1
|
||||
```
|
||||
|
||||
## where子句
|
||||
```sql
|
||||
-- or 等价于|| and 等价于 && 可以混合使用。
|
||||
where t.name = 'Gitee' or t.name = 'Github' and 1=1 && 2=2
|
||||
```
|
||||
|
||||
## group by子句
|
||||
```sql
|
||||
group by t.name, t1.xxx
|
||||
```
|
||||
|
||||
## having 子句
|
||||
```sql
|
||||
having count(t.name) > 1
|
||||
```
|
||||
|
||||
## order by子句
|
||||
```sql
|
||||
-- asc可以不写,默认是asc
|
||||
order by t.name desc,t.xxx
|
||||
```
|
||||
|
||||
## limit 子句
|
||||
```sql
|
||||
limit 1 -- 固定取第一项,返回值会是对象,而非List
|
||||
limit pageSize offset (page - 1) * pageSize
|
||||
limit pageSize
|
||||
```
|
||||
15
magic-script-skill/references/log-module.md
Normal file
15
magic-script-skill/references/log-module.md
Normal file
@ -0,0 +1,15 @@
|
||||
# 日志模块
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import log;
|
||||
```
|
||||
|
||||
## 使用
|
||||
```javascript
|
||||
import log; //org.slf4j.Logger
|
||||
// 使用方法与SLF4J完全一致
|
||||
log.info('Hello');
|
||||
log.info('Hello {}','MagicAPI');
|
||||
log.debug('test');
|
||||
```
|
||||
45
magic-script-skill/references/magic-module.md
Normal file
45
magic-script-skill/references/magic-module.md
Normal file
@ -0,0 +1,45 @@
|
||||
# Magic模块
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import magic;
|
||||
```
|
||||
|
||||
## call
|
||||
- 入参:`method`:`String` 定义的请求方法
|
||||
- 入参:`path`:`String` 定义的路径
|
||||
- 入参:`parameters`:`Map` 变量信息
|
||||
- 返回值:`Object`
|
||||
- 函数说明:执行MagicAPI中的接口,返回值带code和message信息
|
||||
|
||||
```javascript
|
||||
return magic.call('get','execute/sql',{
|
||||
message : 'Hello,Magic API!' //传入参数
|
||||
})
|
||||
```
|
||||
|
||||
## execute
|
||||
- 入参:`method`:`String` 定义的请求方法
|
||||
- 入参:`path`:`String` 定义的请求路径
|
||||
- 入参:`parameters`:`Map` 变量信息
|
||||
- 返回值:`Object`
|
||||
- 函数说明:执行MagicAPI中的接口,返回原始内容,不包含code以及message信息
|
||||
|
||||
```javascript
|
||||
return magic.execute('get','execute/sql',{
|
||||
message : 'Hello,Magic API!' //传入参数
|
||||
})
|
||||
```
|
||||
|
||||
## invoke
|
||||
- 入参:`path`:`String` 函数路径
|
||||
- 入参:`parameters`:`Map` 变量信息
|
||||
- 返回值:`Object`
|
||||
- 函数说明:执行MagicAPI中的函数
|
||||
|
||||
```javascript
|
||||
return magic.invoke('/test/add',{
|
||||
a: 1,
|
||||
b: 2
|
||||
})
|
||||
```
|
||||
39
magic-script-skill/references/math-functions.md
Normal file
39
magic-script-skill/references/math-functions.md
Normal file
@ -0,0 +1,39 @@
|
||||
# 数学函数
|
||||
|
||||
## round
|
||||
- 入参:`number`:`Number` 目标值
|
||||
- 入参:`len`:`int` 要保留的小数位数 可省略,默认0
|
||||
- 返回值:`Number`
|
||||
- 函数说明:四舍五入保留N位小数
|
||||
|
||||
```javascript
|
||||
return round(123.456d,2); //123.46
|
||||
```
|
||||
|
||||
## floor
|
||||
- 入参:`number`:`Number` 目标值
|
||||
- 返回值:`Number`
|
||||
- 函数说明:向下取整
|
||||
|
||||
```javascript
|
||||
return floor(123.456d); // 123;
|
||||
```
|
||||
|
||||
## ceil
|
||||
- 入参:`number`:`Number` 目标值
|
||||
- 返回值:`Number`
|
||||
- 函数说明:向上取整
|
||||
|
||||
```javascript
|
||||
return ceil(123.456d); // 124;
|
||||
```
|
||||
|
||||
## percent
|
||||
- 入参:`number`:`Number` 目标值
|
||||
- 入参:`len`:`int` 要保留的小数 可省略,默认0
|
||||
- 返回值:`String`
|
||||
- 函数说明:将数值转为百分比
|
||||
|
||||
```javascript
|
||||
return percent(0.1289999999,2); // "12.90%"
|
||||
```
|
||||
51
magic-script-skill/references/number-extensions.md
Normal file
51
magic-script-skill/references/number-extensions.md
Normal file
@ -0,0 +1,51 @@
|
||||
# Number扩展方法
|
||||
|
||||
`java.lang.Number`的扩展方法,用于数值类型的扩展
|
||||
|
||||
## round
|
||||
- 入参:`number`:`int` 要保留的小数
|
||||
- 返回值:`Number`
|
||||
- 函数说明:四舍五入保留N位小数
|
||||
|
||||
```javascript
|
||||
var value = 123.456d;
|
||||
return value.round(2); //123.46
|
||||
```
|
||||
|
||||
## toFixed
|
||||
- 入参:`number`:`int` 要保留的小数
|
||||
- 返回值:`String`
|
||||
- 函数说明:四舍五入保留N位小数(和JS一样,强制限制位数)
|
||||
|
||||
```javascript
|
||||
var value = 123.456d;
|
||||
return value.toFixed(10); // "123.4560000000"
|
||||
```
|
||||
|
||||
## floor
|
||||
- 返回值:`Number`
|
||||
- 函数说明:向下取整
|
||||
|
||||
```javascript
|
||||
var value = 123.456d;
|
||||
return value.floor(); // 123;
|
||||
```
|
||||
|
||||
## ceil
|
||||
- 返回值:`Number`
|
||||
- 函数说明:向上取整
|
||||
|
||||
```javascript
|
||||
var value = 123.456d;
|
||||
return value.ceil(); // 124;
|
||||
```
|
||||
|
||||
## asPercent
|
||||
- 入参:`number`:`int` 要保留的小数
|
||||
- 返回值:`String`
|
||||
- 函数说明:将数值转为百分比
|
||||
|
||||
```javascript
|
||||
var value = 0.1289999999;
|
||||
return value.asPercent(2); // "12.90%"
|
||||
```
|
||||
129
magic-script-skill/references/object-extensions.md
Normal file
129
magic-script-skill/references/object-extensions.md
Normal file
@ -0,0 +1,129 @@
|
||||
# Object扩展方法
|
||||
|
||||
## asInt
|
||||
- 入参:`defaultValue`:`int` 选填,当转换失败时返回默认值,默认为`0`
|
||||
- 返回值:`int`
|
||||
- 函数说明:转对象为int类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asInt();
|
||||
//return obj.asInt(1); //转换失败时,返回1
|
||||
```
|
||||
|
||||
## asDouble
|
||||
- 入参:`defaultValue`:`double` 选填,当转换失败时返回默认值,默认为`0.0`
|
||||
- 返回值:`double`
|
||||
- 函数说明:转对象为`double`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asDouble();
|
||||
//return obj.asDouble(1.0d); //转换失败时,返回1.0d
|
||||
```
|
||||
|
||||
## asDecimal
|
||||
- 入参:`defaultValue`:`BigDecimal` 选填,当转换失败时返回默认值,默认为`null`
|
||||
- 返回值:`BigDecimal`
|
||||
- 函数说明:转对象为`BigDecimal`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123.456';
|
||||
return obj.asDecimal();
|
||||
//return obj.asDecimal(1.5m); //转换失败时,返回1.5m
|
||||
```
|
||||
|
||||
## asFloat
|
||||
- 入参:`defaultValue`:`float` 选填,当转换失败时返回默认值,默认为`0.0f`
|
||||
- 返回值:`float`
|
||||
- 函数说明:转对象为`float`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asFloat();
|
||||
//return obj.asFloat(1.0f); //转换失败时,返回1.0f
|
||||
```
|
||||
|
||||
## asLong
|
||||
- 入参:`defaultValue`:`long` 选填,当转换失败时返回默认值,默认为`0L`
|
||||
- 返回值:`long`
|
||||
- 函数说明:转对象为`long`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asLong();
|
||||
//return obj.asLong(1L); //转换失败时,返回1L
|
||||
```
|
||||
|
||||
## asByte
|
||||
- 入参:`defaultValue`:`byte` 选填,当转换失败时返回默认值,默认为`0b`
|
||||
- 返回值:`byte`
|
||||
- 函数说明:转对象为`byte`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asByte();
|
||||
//return obj.asByte(1b); //转换失败时,返回1b
|
||||
```
|
||||
|
||||
## asShort
|
||||
- 入参:`defaultValue`:`short` 选填,当转换失败时返回默认值,默认为`0s`
|
||||
- 返回值:`short`
|
||||
- 函数说明:转对象为`short`类型
|
||||
|
||||
```javascript
|
||||
var obj = '123';
|
||||
return obj.asShort();
|
||||
//return obj.asShort(1s); //转换失败时,返回1s
|
||||
```
|
||||
|
||||
## asDate
|
||||
- 入参:`formats`:`String` 可变参数,日期格式
|
||||
- 返回值:`Date`
|
||||
- 函数说明:转对象为`Date`类型
|
||||
|
||||
```javascript
|
||||
var obj = '2020-01-01 08:00:00';
|
||||
return obj.asDate('yyyy-MM-dd HH:mm:ss','yyyy-MM-dd HH:mm');
|
||||
```
|
||||
|
||||
## asString
|
||||
- 入参:`defaultValue`:`String` 选填,当转换失败时返回默认值,默认为`null`
|
||||
- 返回值:`String`
|
||||
- 函数说明:转对象为`String`类型
|
||||
|
||||
```javascript
|
||||
var obj = 123;
|
||||
return obj.asString();
|
||||
//return obj.asString("empty"); //转换失败时,返回"empty"
|
||||
```
|
||||
|
||||
## is
|
||||
- 入参:`type`:`String/Class` 判断是否该类型
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断是否是指定类型
|
||||
|
||||
```javascript
|
||||
import 'java.util.Date' as Date;
|
||||
var str = 'hello,MagicAPI';
|
||||
return str.is('string'); // true
|
||||
return str.is('java.lang.String'); // true
|
||||
return str.is('java.lang.Integer'); // false
|
||||
return str.is(Date); // false
|
||||
```
|
||||
|
||||
## 类型判断方法
|
||||
- `isString()` - 判断是否是String类型
|
||||
- `isInt()` - 判断是否是int类型
|
||||
- `isLong()` - 判断是否是long类型
|
||||
- `isDouble()` - 判断是否是double类型
|
||||
- `isFloat()` - 判断是否是float类型
|
||||
- `isByte()` - 判断是否是byte类型
|
||||
- `isBoolean()` - 判断是否是boolean类型
|
||||
- `isShort()` - 判断是否是short类型
|
||||
- `isDecimal()` - 判断是否是decimal类型
|
||||
- `isDate()` - 判断是否是Date类型
|
||||
- `isArray()` - 判断是否是数组
|
||||
- `isList()` - 判断是否是List
|
||||
- `isMap()` - 判断是否是Map
|
||||
- `isCollection()` - 判断是否是集合
|
||||
55
magic-script-skill/references/other-functions.md
Normal file
55
magic-script-skill/references/other-functions.md
Normal file
@ -0,0 +1,55 @@
|
||||
# 其它函数
|
||||
|
||||
## print
|
||||
- 入参:`target`:`Object` 要打印的对象
|
||||
- 函数说明:打印
|
||||
|
||||
```javascript
|
||||
print('abc'); // 等同于 System.out.print("abc");
|
||||
```
|
||||
|
||||
## println
|
||||
- 入参:`target`:`Object` 要打印的对象
|
||||
- 函数说明:打印并换行
|
||||
|
||||
```javascript
|
||||
println('abc'); // 等同于 System.out.println("abc");
|
||||
```
|
||||
|
||||
## printf
|
||||
- 入参:`format`:`String` 要打印的对象
|
||||
- 入参:`target`: `Object` 参数值,可以写多个
|
||||
- 函数说明:按照格式打印并换行
|
||||
|
||||
```javascript
|
||||
printf('%s:%s', 'a','b'); // 等同于 System.out.printf("%s:%S", "a", "b");
|
||||
```
|
||||
|
||||
## not_null
|
||||
- 入参:`target` : `Object` 判断的模板
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断值不是`null`
|
||||
|
||||
```javascript
|
||||
return not_null(target); // 等同于 target != null
|
||||
```
|
||||
|
||||
## is_null
|
||||
- 入参:`target` : `Object` 判断的模板
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断值是`null`
|
||||
|
||||
```javascript
|
||||
return is_null(target); // 等同于 target == null
|
||||
```
|
||||
|
||||
## ifnull
|
||||
- 入参:`target`:`Object` 判断的目标
|
||||
- 入参:`trueValue`:`Object` 为空时的值
|
||||
- 返回值:`Object`
|
||||
- 函数说明:对空值进行判断,返回特定值
|
||||
|
||||
```javascript
|
||||
return ifnull(null,1) // 1
|
||||
// return ifnull(0,1) // 0
|
||||
```
|
||||
32
magic-script-skill/references/page.md
Normal file
32
magic-script-skill/references/page.md
Normal file
@ -0,0 +1,32 @@
|
||||
# 分页查询
|
||||
|
||||
## 自动分页
|
||||
`db.page`可从形如`xxx?page=1&size=10`的url中获取分页参数。
|
||||
|
||||
```javascript
|
||||
// 自动从请求参数中获取页码(默认为page)、页大小(默认为size)
|
||||
return db.page("""
|
||||
select * from sys_user
|
||||
""")
|
||||
```
|
||||
|
||||
## 手动分页
|
||||
可手动传入分页参数。
|
||||
|
||||
```javascript
|
||||
return db.page("""
|
||||
select * from sys_user
|
||||
""", 10, 20) // 跳过前20条查10条(limit, offset)
|
||||
```
|
||||
|
||||
## 自定义分页参数
|
||||
可根据需要在自己的项目中,调整以下分页参数。
|
||||
|
||||
```yaml
|
||||
magic-api:
|
||||
page:
|
||||
size: size # 页大小的请求参数名称 缺省时为size
|
||||
page: page # 页码的请求参数名称 缺省时为page
|
||||
default-page: 1 # 自定义默认首页 缺省时为1
|
||||
default-size: 10 # 自定义为默认页大小 缺省时为10
|
||||
```
|
||||
13
magic-script-skill/references/pattern-extensions.md
Normal file
13
magic-script-skill/references/pattern-extensions.md
Normal file
@ -0,0 +1,13 @@
|
||||
# Pattern扩展方法
|
||||
|
||||
`java.util.regex.Pattern`的扩展方法
|
||||
|
||||
## test
|
||||
- 入参:`source`:`String` 目标字符串
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:校验文本是否符合正则
|
||||
|
||||
```javascript
|
||||
var regx = /^\d+$/;
|
||||
return regx.test('123456') // true
|
||||
```
|
||||
125
magic-script-skill/references/quick-crud.md
Normal file
125
magic-script-skill/references/quick-crud.md
Normal file
@ -0,0 +1,125 @@
|
||||
# 增删改查
|
||||
|
||||
## SQL参数
|
||||
|
||||
### #{} 注入参数
|
||||
作用和`mybatis`一致,都是将`#{}`区域替换为占位符`?`
|
||||
```javascript
|
||||
var id = 123;
|
||||
return db.select("""
|
||||
select * from sys_user where id = #{id}
|
||||
""");
|
||||
// 运行时生成的SQL为:select * from sys_user where id = ?
|
||||
```
|
||||
|
||||
### ${} 拼接参数
|
||||
作用和`mybatis`一致,都是将`${}`区域替换为对应的字符串
|
||||
```javascript
|
||||
var id = 123;
|
||||
return db.select("""
|
||||
select * from sys_user where id = ${id}
|
||||
""");
|
||||
// 运行时生成的SQL为:select * from sys_user where id = 123
|
||||
```
|
||||
|
||||
## 动态SQL参数
|
||||
通过`?{condition,expression}`来实现动态拼接`SQL`
|
||||
```javascript
|
||||
return db.select("select * from sys_user ?{id,where id = #{id}}");
|
||||
// 当id有值时,生成SQL:select * from sys_user where id = ?
|
||||
// 当id无值时,生成SQL:select * from sys_user
|
||||
```
|
||||
|
||||
## 切换数据源
|
||||
```javascript
|
||||
// 从数据源key定义为slave的库中查询
|
||||
return db.slave.select("""
|
||||
select * from sys_user
|
||||
""")
|
||||
```
|
||||
|
||||
## SQL缓存
|
||||
```javascript
|
||||
// 将查询结果缓存到名为user_cache的缓存中,有效期1小时
|
||||
return db.cache("user_cache", 3600 * 1000).select("""
|
||||
select * from sys_user
|
||||
""")
|
||||
```
|
||||
|
||||
## 使用事务
|
||||
|
||||
### 自动事务
|
||||
```javascript
|
||||
var val = db.transaction(()=>{
|
||||
var v1 = db.update('...');
|
||||
var v2 = db.update('....');
|
||||
return v2;
|
||||
});
|
||||
return val;
|
||||
```
|
||||
|
||||
### 手动事务
|
||||
```javascript
|
||||
var tx = db.transaction(); //开启事务
|
||||
try{
|
||||
var value = db.update('...');
|
||||
tx.commit(); // 提交事务
|
||||
return value;
|
||||
}catch(e){
|
||||
tx.rollback(); // 回滚事务
|
||||
}
|
||||
```
|
||||
|
||||
## Mybatis语法支持
|
||||
|
||||
### if
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
where 1 = 1
|
||||
<if test="id != null">
|
||||
and id = #{id}
|
||||
</if>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
|
||||
### where
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
<where>
|
||||
<if test="id != null">
|
||||
and id = #{id}
|
||||
</if>
|
||||
</where>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
|
||||
### set、trim
|
||||
```javascript
|
||||
var sql = """
|
||||
update test_data
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name}
|
||||
</if>
|
||||
</set>
|
||||
where `id` = #{id}
|
||||
"""
|
||||
return db.update(sql)
|
||||
```
|
||||
|
||||
### foreach
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
where id in
|
||||
<foreach item='item' index='index' collection='body.ids'
|
||||
open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
47
magic-script-skill/references/quick-param.md
Normal file
47
magic-script-skill/references/quick-param.md
Normal file
@ -0,0 +1,47 @@
|
||||
# 请求参数获取
|
||||
|
||||
## RequestParam
|
||||
```
|
||||
GET http://localhost:9999/xxx/xxx?name=abc&age=49
|
||||
```
|
||||
这样的`URL`参数`magic-api` 会自动将`name`和`age`映射为同名变量。
|
||||
|
||||
## 表单参数
|
||||
```
|
||||
POST http://localhost:9999/xxx/xxx
|
||||
name=abc&age=49
|
||||
```
|
||||
这样的表单参数`magic-api` 也会自动将`name`和`age`映射为同名变量。
|
||||
|
||||
## Request Header参数获取
|
||||
`magic-api` 会对所有`RequestHeader`统一封装为一个名为`header`的变量
|
||||
如要获取 `token` 可以通过`header.token` 来获取
|
||||
|
||||
## Request Body参数获取
|
||||
对于`RequestBody` `magic-api`会将整个请求体映射为`body`变量,如:
|
||||
```json
|
||||
{
|
||||
"name": "magic-api",
|
||||
"version": "9.9.9"
|
||||
}
|
||||
```
|
||||
如要获取`name`属性 则可通过 `body.name` 来获取
|
||||
|
||||
如果提交的body为数组或者List, `body`为数组。
|
||||
|
||||
## Path参数获取
|
||||
主要是针对`URL`定义为`http://localhost:9999/user/{id}` 的类似接口
|
||||
如要获取path路径上的id可通过`path.id` 或 `id`来获取。
|
||||
|
||||
对于请求时使用了`http://localhost:9999/user/1?id=2`的请求, `id`变量的值将是`RequestParam`中的值,此时可以通过`path.id` 来避免冲突。
|
||||
|
||||
## Cookie参数获取
|
||||
`magic-api` 会对所有`Cookie`统一封装为一个名为`cookie`的对象。
|
||||
如要获取 `JSESSIONID` 可以通过`cookie.JSESSIONID` 来获取。
|
||||
|
||||
## Session参数获取
|
||||
`magic-api` 会将`HttpSession`封装为一个名为`session`的变量
|
||||
要获取`session`中的值,可以通过`session.xxx`来获取
|
||||
|
||||
## 注意事项
|
||||
如果脚本自定义变量和参数变量冲突,自定义变量优先。
|
||||
66
magic-script-skill/references/quick-start.md
Normal file
66
magic-script-skill/references/quick-start.md
Normal file
@ -0,0 +1,66 @@
|
||||
# 快速入门
|
||||
|
||||
## 初始化工程
|
||||
创建一个空的`Spring Boot`工程, 以`mysql`作为默认数据库进行演示。
|
||||
|
||||
## 添加依赖
|
||||
引入`Spring Boot Starter`父工程:
|
||||
```xml
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>spring-boot-latest-version</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
```
|
||||
|
||||
引入`magic-api-spring-boot-starter`依赖:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>org.ssssssss</groupId>
|
||||
<artifactId>magic-api-spring-boot-starter</artifactId>
|
||||
<version>magic-api-lastest-version</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## 配置
|
||||
`application.yml`
|
||||
```yaml
|
||||
server:
|
||||
port: 9999
|
||||
magic-api:
|
||||
web: /magic/web
|
||||
resource:
|
||||
location: D:/data/magic-api
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/magic-api-test?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
|
||||
username: root
|
||||
password: test
|
||||
```
|
||||
|
||||
## 访问api管理界面
|
||||
启动项目之后,访问`http://localhost:9999/magic/web` 即可看到Web页面
|
||||
|
||||
## 三分钟写出查询接口
|
||||
**1. 创建分组**
|
||||
点击创建分组按钮后,输入分组信息,点击创建。
|
||||
|
||||
**2. 新建接口**
|
||||
右键分组,点击新建接口。在编辑器输入内容后,填写接口名称和及其路径。
|
||||
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
|
||||
`ctrl+s`保存后,即可访问接口。
|
||||
|
||||
**3.访问接口**
|
||||
```
|
||||
> curl http://localhost:9999/test/test
|
||||
```
|
||||
64
magic-script-skill/references/request-module.md
Normal file
64
magic-script-skill/references/request-module.md
Normal file
@ -0,0 +1,64 @@
|
||||
# Request模块
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import request;
|
||||
```
|
||||
|
||||
## getFile
|
||||
- 入参:`name`:`string`
|
||||
- 返回值:`MultipartFile`
|
||||
- 函数说明:获取上传的文件
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
request.getFile('image');
|
||||
```
|
||||
|
||||
## getFiles
|
||||
- 入参:`name`:`String`
|
||||
- 返回值:`List<MultipartFile>`
|
||||
- 函数说明:获取上传的文件集合
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
request.getFiles('image');
|
||||
```
|
||||
|
||||
## getValues
|
||||
- 入参:`name`:`String`
|
||||
- 返回值:`List<String>`
|
||||
- 函数说明:获取提交的数组参数
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
return request.getValues('name');
|
||||
```
|
||||
|
||||
## getHeaders
|
||||
- 入参:`name`:`String`
|
||||
- 返回值:`List<String>`
|
||||
- 函数说明:获取请求的header数组
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
return request.getHeaders('xxx');
|
||||
```
|
||||
|
||||
## get
|
||||
- 返回值:`MagicHttpServletRequest`
|
||||
- 函数说明:获取`Request`对象
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
request.get();
|
||||
```
|
||||
|
||||
## getClientIP
|
||||
- 返回值:`String`
|
||||
- 函数说明:获取客户端`IP`
|
||||
|
||||
```javascript
|
||||
import request;
|
||||
return request.getClientIP();
|
||||
```
|
||||
141
magic-script-skill/references/response-module.md
Normal file
141
magic-script-skill/references/response-module.md
Normal file
@ -0,0 +1,141 @@
|
||||
# Response模块
|
||||
|
||||
## 引用模块
|
||||
```javascript
|
||||
import response;
|
||||
```
|
||||
|
||||
## page
|
||||
- 入参:`total`:`long`
|
||||
- 入参:`values`:`list`
|
||||
- 返回值:`Object`
|
||||
- 函数说明:构建分页结果
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
//返回: 共计10条,第一页的5条数据
|
||||
return response.page(10,[1,2,3,4,5]);
|
||||
```
|
||||
|
||||
## json
|
||||
- 入参:`value`:`Object`
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:构建Json结果
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
//直接返回该json,不会被包装处理
|
||||
return response.json({
|
||||
success : true,
|
||||
message : '执行成功'
|
||||
});
|
||||
```
|
||||
|
||||
## text
|
||||
- 入参:`value`:`String` 文本内容
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:输出文本
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
//直接返回该text,不会被包装处理
|
||||
return response.text('ok');
|
||||
```
|
||||
|
||||
## redirect
|
||||
- 入参:`url`:`String` 目标网址
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:重定向
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
//重定向到该地址,内部利用HttpServletResponse的sendRedirect方法
|
||||
return response.redirect('/xxx/xx');
|
||||
```
|
||||
|
||||
## download
|
||||
- 入参:`value`:`Object`
|
||||
- 入参:`filename`:`文件名`
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:下载文件
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
return response.download('文件内容','test.txt');
|
||||
```
|
||||
|
||||
## image
|
||||
- 入参:`value`:`Object`
|
||||
- 入参:`mine`:`String`
|
||||
- 返回值:`ResponseEntity`
|
||||
- 函数说明:主要用于输出图片
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
// 输出图片
|
||||
return response.image(bytes,'image/png');
|
||||
```
|
||||
|
||||
## addHeader
|
||||
- 入参:`key`:`string`
|
||||
- 入参:`value`:`String`
|
||||
- 返回值:无返回值
|
||||
- 函数说明:添加Response Header
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
response.addHeader('AccessToken','123');
|
||||
```
|
||||
|
||||
## setHeader
|
||||
- 入参:`key`:`string`
|
||||
- 入参:`value`:`String`
|
||||
- 返回值:无返回值
|
||||
- 函数说明:设置Response Header
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
response.setHeader('AccessToken','123');
|
||||
```
|
||||
|
||||
## addCookie
|
||||
- 入参:`key`:`string`
|
||||
- 入参:`value`:`String`
|
||||
- 入参:`options`:`Map` cookie参数,可选
|
||||
- 返回值:无返回值
|
||||
- 函数说明:添加Cookie
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
response.addCookie('cookieKey','cookieValue');
|
||||
response.addCookie('cookieKey','cookieValue',{
|
||||
path : '/',
|
||||
httpOnly : true,
|
||||
domain : 'ssssssss.org',
|
||||
maxAge : 3600
|
||||
});
|
||||
```
|
||||
|
||||
## addCookies
|
||||
- 入参:`cookies`:`Map` cookie Map,必填
|
||||
- 入参:`options`:`Map` cookie参数,可选
|
||||
- 返回值:无返回值
|
||||
- 函数说明:批量添加Cookie
|
||||
|
||||
```javascript
|
||||
import response;
|
||||
response.addCookies({
|
||||
cookieKey1 : 'cookieValue1',
|
||||
cookieKey2 : 'cookieValue2',
|
||||
});
|
||||
```
|
||||
|
||||
## getOutputStream
|
||||
- 返回值:`OutputStream`
|
||||
- 函数说明:获取`ServletOutputStream`
|
||||
|
||||
注意:在调用`getOutputStream`后 返回值应为`response.end()` 告诉框架无需处理返回值。
|
||||
|
||||
## end
|
||||
- 返回值:无返回值
|
||||
- 函数说明:取消返回默认的json结构,通过其他方式的输出结果(如:调用outputstream输出)
|
||||
163
magic-script-skill/references/script-syntax.md
Normal file
163
magic-script-skill/references/script-syntax.md
Normal file
@ -0,0 +1,163 @@
|
||||
# 脚本语法详解
|
||||
|
||||
## for循环
|
||||
|
||||
### 循环集合
|
||||
```javascript
|
||||
var list = [1,2,3];
|
||||
for(index,item in list){ //如果不需要index,也可以写成for(item in list)
|
||||
println(index + ":" + item);
|
||||
}
|
||||
// 结果:0:1, 1:2, 2:3
|
||||
```
|
||||
|
||||
### 循环指定次数
|
||||
```javascript
|
||||
var sum = 0;
|
||||
for(value in range(0,100)){ //包括0包括100
|
||||
sum = sum + value; //不支持+= -= *= /= ++ -- 这种运算
|
||||
}
|
||||
return sum; // 5050
|
||||
```
|
||||
|
||||
## while循环
|
||||
```javascript
|
||||
var count = 100;
|
||||
var sum = 0;
|
||||
while(count){
|
||||
sum = sum + count;
|
||||
count = count - 1;
|
||||
}
|
||||
return sum; // 5050
|
||||
```
|
||||
|
||||
## 循环map
|
||||
```javascript
|
||||
var map = {
|
||||
key1 : 123,
|
||||
key2 : 456
|
||||
};
|
||||
for(key,value in map){ //如果不需要key,也可以写成for(value in map)
|
||||
println(key + ":" + value);
|
||||
}
|
||||
// 结果:key1:123, key2:456
|
||||
```
|
||||
|
||||
## Import导入
|
||||
|
||||
### 导入Java类
|
||||
```javascript
|
||||
import 'java.lang.System' as System;
|
||||
import 'javax.sql.DataSource' as ds;
|
||||
import 'org.apache.commons.lang3.StringUtils' as string;
|
||||
import 'java.text.*' // 此写法跟Java一致
|
||||
|
||||
System.out.println('调用System打印');
|
||||
System.out.println(ds);
|
||||
System.out.println(string.isBlank(''));
|
||||
System.out.println(new SimpleDateFormat('yyyy-MM-dd').format(new Date()));
|
||||
```
|
||||
|
||||
### 导入已定义的模块
|
||||
```javascript
|
||||
import log; //导入log模块,并定义一个与模块名相同的变量名
|
||||
//import log as logger; //导入log模块,并赋值给变量 logger
|
||||
log.info('Hello {}','Magic API!')
|
||||
```
|
||||
|
||||
## new创建对象
|
||||
```javascript
|
||||
import 'java.util.Date' as Date;//创建之前先导包,不支持.*的操作
|
||||
return new Date();
|
||||
```
|
||||
|
||||
## 异步调用
|
||||
|
||||
### 异步调用方法
|
||||
```javascript
|
||||
var val = async db.select('.....'); // 异步调用,返回Future类型
|
||||
return val.get(); //调用Future的get方法
|
||||
```
|
||||
|
||||
### 异步调用lambda
|
||||
```javascript
|
||||
var list = [];
|
||||
for(index in range(1,10)){
|
||||
list.add(async (index)=>db.selectInt('select #{index}'));
|
||||
}
|
||||
return list.map(item=>item.get()); // 循环获取结果
|
||||
```
|
||||
|
||||
## exit
|
||||
语法格式为 `exit expr[,expr][,expr]....`
|
||||
|
||||
在`magic-api`中只取前三个值,分别对应`code`、`message`、`data`
|
||||
|
||||
如:`exit 400,'参数填写有误'`
|
||||
|
||||
## assert
|
||||
语法格式为 `assert expr : expr[,expr][,expr]....`
|
||||
|
||||
如:`assert a == 1 : 400, 'a的值应为1'` 相当于
|
||||
```javascript
|
||||
if(a != 1){
|
||||
exit 400, 'a的值应为1'
|
||||
}
|
||||
```
|
||||
|
||||
## 类型转换
|
||||
通过`::`进行类型转换,如`xxx::int`、`xxx::double`等,当前支持转换类型有`int`、`double`、`long`、`byte`、`short`、`float`、`date`
|
||||
|
||||
```javascript
|
||||
var a = "1";
|
||||
return {
|
||||
v1: a::int,
|
||||
v2: a::int(0), //转换失败时,值为0
|
||||
v3: "2020-01-01"::date('yyyy-MM-dd') //转为Date
|
||||
}
|
||||
```
|
||||
|
||||
`::sql`支持将数据转换为对应的sql类型,比如:
|
||||
```javascript
|
||||
img::sql('blob')
|
||||
```
|
||||
可传入的参数请参考`java.sql.Types`中定义的常量,不区分大小写。
|
||||
|
||||
## 嵌入其它脚本语言
|
||||
```javascript
|
||||
var name = "hello";
|
||||
var test = ```javascript
|
||||
name + ' ~ world'
|
||||
```;
|
||||
return test();
|
||||
```
|
||||
|
||||
## 可选链操作符
|
||||
可选链操作符(`?.`)允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。
|
||||
|
||||
```javascript
|
||||
var a = null;
|
||||
var b = a?.name; // b = null;
|
||||
var c = a?.getName(); // c = null;
|
||||
```
|
||||
|
||||
## 扩展运算符
|
||||
扩展运算符,又叫展开语法(Spread syntax),是用于将list或map在语法层面展开
|
||||
|
||||
### lambda 调用
|
||||
```javascript
|
||||
var sum = (a,b,c) => a + b + c;
|
||||
System.out.println(sum(...[1,2,3])) // 结果:6
|
||||
```
|
||||
|
||||
### list 展开
|
||||
```javascript
|
||||
var arr = [3,4,5];
|
||||
System.out.println([1,2,...arr,6,7]) // 结果:[1, 2, 3, 4, 5, 6, 7]
|
||||
```
|
||||
|
||||
### map 展开
|
||||
```javascript
|
||||
var map = {key2:2}
|
||||
System.out.println({key1:1,...map,key3:3}) // 结果:{key1=1, key2=2, key3=3}
|
||||
```
|
||||
104
magic-script-skill/references/single-table.md
Normal file
104
magic-script-skill/references/single-table.md
Normal file
@ -0,0 +1,104 @@
|
||||
# 单表操作
|
||||
|
||||
操作入口:`db.table('table_name')`
|
||||
|
||||
## logic
|
||||
- 作用:设置本查询是带有逻辑删除的,在执行`delete`方法时,会转换为`update`语句,在执行`select`相关方法时,会拼接`logic_field <> logic_value`
|
||||
|
||||
## withBlank
|
||||
- 作用:设置后续插入或修改时,不过滤空值。
|
||||
|
||||
## column
|
||||
- 入参:`column`: `String` 列名
|
||||
- 作用:设置要查询列,`select`语句中有效
|
||||
|
||||
## column
|
||||
- 入参:`column`: `String` 列名
|
||||
- 入参:`value` : `Object` 值
|
||||
- 作用:设置要操作的列的值,非`select`语句中有效
|
||||
|
||||
## primary
|
||||
- 入参:`primary`: `String` 主键
|
||||
- 入参:`defaultValue`: `Object` 插入时使用的默认值,可省略
|
||||
- 作用:设置主键列,在`update`中语句有效,或`save`方法判断标准
|
||||
|
||||
## insert
|
||||
- 入参: `data` : `Map` `insert`的列和值,可省略(通过`column`设置)
|
||||
|
||||
```javascript
|
||||
// insert into sys_user(user_name,role) values('李富贵','admin')
|
||||
return db.table('sys_user').insert({ user_name : '李富贵', role : 'admin'})
|
||||
```
|
||||
|
||||
## batchInsert
|
||||
- 入参: `collection` : `Collection` `insert`的列和值的集合
|
||||
- 入参: `batchSize` : `int` batchSize
|
||||
|
||||
```javascript
|
||||
return db.table('sys_user').batchInsert([
|
||||
{ user_name : '李富贵', role : 'admin'},
|
||||
{ user_name : '王二狗', role : 'admin'},
|
||||
{ user_name : '管理员', role : 'super-admin'},
|
||||
])
|
||||
```
|
||||
|
||||
## update
|
||||
- 入参: `data` : `Map` `insert`的列和值,可省略(通过`column`设置)
|
||||
- 入参:`isUpdateBlank`: `boolean` 是否更新空值字段(可省略,默认为`false`)
|
||||
|
||||
```javascript
|
||||
// update sys_user set user_name = '王二狗' where id = 1
|
||||
return db.table('sys_user').primary('id').update({ id: 1, user_name : '王二狗'})
|
||||
```
|
||||
|
||||
## save
|
||||
- 入参: `data` : `Map` `insert`或`update`的列和值,可省略(通过`column`设置)
|
||||
- 入参:`beforeQuery` : `boolean` 是否根据id查询有没有数据,可省略(默认`false`)
|
||||
|
||||
```javascript
|
||||
// insert into sys_user(id,user_name) values('xxx','王二狗');
|
||||
return db.table('sys_user').primary('id', uuid()).save({user_name: '王二狗'});
|
||||
// insert into sys_user(user_name) values('王二狗');
|
||||
return db.table('sys_user').primary('id').save({user_name: '王二狗'});
|
||||
// update sys_user set user_name = '王二狗' where id = 1
|
||||
return db.table('sys_user').primary('id').save({id: 1,user_name: '王二狗'});
|
||||
```
|
||||
|
||||
## select
|
||||
查询list(与db.select 作用相同)
|
||||
|
||||
```javascript
|
||||
// select * from sys_user
|
||||
return db.table('sys_user').select()
|
||||
```
|
||||
|
||||
## page
|
||||
分页查询(与db.page 作用相同)
|
||||
|
||||
```javascript
|
||||
// select * from sys_user
|
||||
return db.table('sys_user').page()
|
||||
```
|
||||
|
||||
## where
|
||||
设置查询条件
|
||||
|
||||
- eq --> `==`
|
||||
- ne --> `<>`
|
||||
- lt --> `<`
|
||||
- gt --> `>`
|
||||
- lte --> `<=`
|
||||
- gte --> `>=`
|
||||
- in --> `in`
|
||||
- notIn --> `not in`
|
||||
- like --> `like`
|
||||
- notLike --> `not like`
|
||||
|
||||
```javascript
|
||||
// select * from sys_user where user_name like '%李富贵%' and role = 'admin'
|
||||
return db.table('sys_user')
|
||||
.where()
|
||||
.like('user_name','%李富贵%')
|
||||
.eq('role','admin')
|
||||
.select()
|
||||
```
|
||||
125
magic-script-skill/references/sql-param.md
Normal file
125
magic-script-skill/references/sql-param.md
Normal file
@ -0,0 +1,125 @@
|
||||
# SQL参数
|
||||
|
||||
## #{} 注入参数
|
||||
作用和`mybatis`一致,都是将`#{}`区域替换为占位符`?`
|
||||
|
||||
```javascript
|
||||
var id = 123;
|
||||
return db.select("""
|
||||
select * from sys_user where id = #{id}
|
||||
""");
|
||||
// 运行时生成的SQL为:select * from sys_user where id = ?
|
||||
```
|
||||
|
||||
此方法可以避免`sql`注入。
|
||||
|
||||
## ${} 拼接参数
|
||||
作用和`mybatis`一致,都是将`${}`区域替换为对应的字符串
|
||||
|
||||
```javascript
|
||||
var id = 123;
|
||||
return db.select("""
|
||||
select * from sys_user where id = ${id}
|
||||
""");
|
||||
// 运行时生成的SQL为:select * from sys_user where id = 123
|
||||
```
|
||||
|
||||
## 动态SQL参数
|
||||
通过`?{condition,expression}`来实现动态拼接`SQL`
|
||||
|
||||
```javascript
|
||||
return db.select("select * from sys_user ?{id,where id = #{id}}");
|
||||
// 当id有值时,生成SQL:select * from sys_user where id = ?
|
||||
// 当id无值时,生成SQL:select * from sys_user
|
||||
|
||||
return db.select("select * from sys_user ?{id!=null&&id.length() > 3,where id = #{id}}");
|
||||
```
|
||||
|
||||
## 循环拼接参数
|
||||
两种办法:
|
||||
|
||||
### in语法自动展开
|
||||
```javascript
|
||||
var ids = [1,2,3,4,5,6];
|
||||
//会自动变成select * from sys_user where id in(?,?,?,?,?,?)
|
||||
return db.select('select * from sys_user where id in(#{ids})');
|
||||
```
|
||||
|
||||
### 循环拼接SQL
|
||||
```javascript
|
||||
var list = [1,2,3,4,5];
|
||||
var sql = "select * from sys_user where ";
|
||||
for(index,item in list){
|
||||
sql = sql + 'id = #{list['+index+']}';
|
||||
if(index + 1 < list.size()){
|
||||
sql = sql + ' or ';
|
||||
}
|
||||
}
|
||||
return db.select(sql);
|
||||
```
|
||||
|
||||
## Mybatis语法支持
|
||||
|
||||
### 支持的关键字
|
||||
- `<if>`
|
||||
- `<elseif>`
|
||||
- `<else>`
|
||||
- `<where>`
|
||||
- `<foreach>`
|
||||
- `<trim>`
|
||||
- `<set>`
|
||||
|
||||
### if
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
where 1 = 1
|
||||
<if test="id != null">
|
||||
and id = #{id}
|
||||
</if>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
|
||||
### where
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
<where>
|
||||
<if test="id != null">
|
||||
and id = #{id}
|
||||
</if>
|
||||
</where>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
|
||||
### set、trim
|
||||
```javascript
|
||||
var sql = """
|
||||
update test_data
|
||||
<set>
|
||||
<if test="name != null">
|
||||
name = #{name}
|
||||
</if>
|
||||
<if test="content != null">
|
||||
content = #{content}
|
||||
</if>
|
||||
</set>
|
||||
where `id` = #{id}
|
||||
"""
|
||||
return db.update(sql)
|
||||
```
|
||||
|
||||
### foreach
|
||||
```javascript
|
||||
var sql = """
|
||||
select * from test_data
|
||||
where id in
|
||||
<foreach item='item' index='index' collection='body.ids'
|
||||
open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
"""
|
||||
return db.select(sql)
|
||||
```
|
||||
26
magic-script-skill/references/string-functions.md
Normal file
26
magic-script-skill/references/string-functions.md
Normal file
@ -0,0 +1,26 @@
|
||||
# 字符串函数
|
||||
|
||||
## uuid
|
||||
- 返回值: `String` `32`位无`-`的`UUID`
|
||||
|
||||
```javascript
|
||||
return uuid(); // 等同于 UUID.randomUUID().toString().replace("-", "");
|
||||
```
|
||||
|
||||
## is_blank
|
||||
- 入参:`target`:`String` 判断的目标
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断字符串是否为空
|
||||
|
||||
```javascript
|
||||
return is_blank(''); // true 等同于 StringUtils.isBlank 一致
|
||||
```
|
||||
|
||||
## not_blank
|
||||
- 入参:`target`:`String` 判断的目标
|
||||
- 返回值:`boolean`
|
||||
- 函数说明:判断字符串是否不为空
|
||||
|
||||
```javascript
|
||||
return not_blank(''); // false 等同于 !is_blank('')
|
||||
```
|
||||
22
magic-script-skill/references/validate.md
Normal file
22
magic-script-skill/references/validate.md
Normal file
@ -0,0 +1,22 @@
|
||||
# 参数校验
|
||||
|
||||
## 自动验证
|
||||
在magic-api的Web界面中,可配置:
|
||||
- 必填验证
|
||||
- 表达式验证
|
||||
- 正则验证
|
||||
|
||||
## 手动验证
|
||||
对于表达式和正则无法实现的可以通过脚本来实现。
|
||||
|
||||
```javascript
|
||||
var count = db.selectInt("""
|
||||
select count(*) from sys_user where phone = #{phone}
|
||||
""")
|
||||
// count 值应该为0,如果不为0则验证不予通过。
|
||||
assert count == 0 : 400, '手机号已存在';
|
||||
// 上述写法可以转换为
|
||||
if(count != 0){
|
||||
exit 400, '手机号已存在'
|
||||
}
|
||||
```
|
||||
Loading…
Reference in New Issue
Block a user