一、FaaS 与通用服务介绍
自动化脚本融合了 FaaS(函数即服务)与 Serverless 架构,帮助开发者摆脱服务器管理、集群运维、弹性扩容等基础设施负担,仅需聚焦业务逻辑,用 JavaScript 编写微服务脚本即可快速扩展后端能力。通用服务作为 FaaS 体系的核心模块,专注于表格数据的全生命周期管理,覆盖数据增删改查、复杂业务执行、多条件联动查询等场景。
通用服务的核心优势在于低代码配置 + 全链路脚本支撑:无需从零搭建后端数据库与接口,通过可视化配置即可定义数据表格、查询条件、操作按钮;同时支持自定义 JS 脚本处理复杂业务逻辑,兼容 Java 后端系统对接,兼顾开发效率与扩展性。下文从核心能力、配置流程、源码实现、实战场景四个维度,全面讲解通用服务的使用与开发。
二、通用服务核心能力与应用场景
(一)核心能力
- 数据 CRUD 一体化:基于自定义表格,支持数据新增、查询、编辑、删除、批量操作,内置数据库交互函数,无需编写原生 SQL。
- 多类型参数支持:查询与操作参数兼容整数、浮点数、布尔、字符串、文件、下拉选项(静态 / 动态),动态选项可通过 FaaS 脚本实时获取数据。
- 联动查询配置 :支持参数间依赖关联(如设备选择后联动加载对应账户),通过
next/previous属性实现级联过滤。 - 自定义业务逻辑:所有数据操作(新增 / 编辑 / 删除 / 查询)均支持绑定自定义 JS 函数,可实现数据校验、格式转换、跨表关联、第三方接口调用等复杂逻辑。
- 多端无缝对接 :移动端通过
callMicroService调用,网页端直接嵌入服务界面,第三方系统通过 OpenAPI 接口访问,全场景覆盖数据交互需求。
(二)典型应用场景
- 移动端数据管理:APP 内实现用户信息、设备数据、业务记录的增删改查,无需搭建独立后端。
- 网页端后台系统:快速搭建轻量化管理后台,如订单管理、设备调度、数据录入平台,低代码配置即可上线。
- 第三方系统对接:Java 后端系统通过 OpenAPI 调用冰狐通用服务,实现跨系统数据同步与业务协同。
- 自动化业务流程:结合冰狐移动端自动化脚本,实现 "数据查询 - 条件判断 - 自动操作 - 结果更新" 的全流程自动化。
三、通用服务可视化配置流程
在编写脚本前,需先完成通用服务的基础配置,核心包括表格定义、参数配置、数据列映射、操作按钮绑定四大步骤,以下为详细配置流程:
(一)新建通用服务
- 登录冰狐智能辅助平台,进入【云服务】→【通用服务】,点击右上角 "+ 服务",输入服务名称(如 "设备管理服务"),选择关联的数据库表(如
device_info)。 - 配置基础信息:设置服务描述、访问权限(公开 / 私有)、分页条数(默认 10 条),保存后生成服务唯一标识。
(二)配置查询参数
查询参数用于定义数据过滤条件,支持静态参数与动态联动参数,示例配置如下:
表格
| 参数名 | ID | 类型 | 默认值 | 关联关系 | 描述 |
|---|---|---|---|---|---|
| 设备 UUID | uuid | select | {"functionName":"getDevice"} | next:"account" | 选择设备后联动加载账户 |
| 账户名称 | account | select | {"functionName":"getAccount"} | previous:"device" | 依赖设备参数过滤账户 |
| 设备状态 | status | string | 空 | 无 | 按设备状态筛选(在线 / 离线) |
- 静态选项 :直接硬编码,格式
名称:值,名称:值,如在线:1,离线:0。 - 动态选项 :绑定 FaaS 脚本函数,实时获取数据,格式
{"scriptName":"设备脚本","functionName":"getDevice"}。
(三)配置数据列
数据列用于定义表格展示字段,列 ID 必须与数据库表字段 / 脚本返回数据 Key 一致,否则无法正常显示,示例配置:
表格
| 列名 | ID | 宽度 | 排序 | 描述 |
|---|---|---|---|---|
| 设备 UUID | uuid | 200px | 是 | 设备唯一标识 |
| 设备名称 | name | 150px | 是 | 设备自定义名称 |
| 在线状态 | status | 120px | 是 | 1 = 在线,0 = 离线 |
| 创建时间 | create_time | 180px | 是 | 设备绑定时间 |
(四)配置数据操作
数据操作定义表格行的功能按钮(新增 / 编辑 / 删除 / 执行),每个按钮绑定对应的 FaaS 处理函数,核心配置包括按钮文本、图标、确认弹窗、处理函数:
- 新增按钮 :文本 "新增设备",图标
plus,弹窗显示参数输入框(名称 / 状态),绑定confirmAdd函数。 - 编辑按钮 :文本 "编辑",图标
edit,弹窗回显当前行数据,绑定confirmEdit函数。 - 删除按钮 :文本 "删除",图标
trash,弹窗提示 "确认删除该设备?",绑定confirmDelete函数。 - 批量操作 :支持多选数据行,配置 "批量删除" 按钮,绑定
confirmBatchDelete函数。
四、冰狐 JS 脚本实战
通用服务的业务逻辑通过冰狐 JS 脚本实现,需在【云服务】→【云服务脚本】中新建脚本(如device_service.js),关联通用服务后即可生效。以下为设备管理通用服务的完整源码,包含动态选项、查询、新增、编辑、删除、批量操作六大核心函数。
(一)动态选项函数(联动查询)
javascript
// 获取设备列表(动态选项:设备UUID→设备名称)
function getDevice() {
// 获取当前用户的设备列表(平台内置函数:deviceList())
let list = deviceList(rsOpenId);
let ret = [];
for (let item of list) {
// 返回格式:[{name:"显示名称", value:"实际值"}]
ret.push({ name: item.name, value: item.uuid });
}
return ret;
}
// 根据设备UUID获取关联账户(联动查询)
function getAccount(uuid) {
let ret = [{ name: "全部", value: "" }]; // 默认"全部"选项
let arr = [];
if (strIsNotEmpty(uuid)) {
// 按设备UUID查询账户表(dbQuery:平台内置数据库查询函数)
arr = dbQuery("account_table", "*", [`uuid='${uuid}'`]);
} else {
// 无设备筛选时查询所有账户
arr = dbQuery("account_table", "*", [`id>0`]);
}
for (let item of arr) {
ret.push({ name: item.account_name, value: item.account_name });
}
return ret;
}
(二)数据查询函数(分页 + 多条件过滤)
javascript
/**
* 数据查询核心函数
* @param {boolean} fetchCountOnly - 是否仅获取数据总数
* @param {Array} conditions - 查询条件([{name:"参数名", value:"参数值"}])
* @param {number} startIndex - 分页起始索引
* @param {number} itemCount - 每页条数
* @returns {Array|number} 数据列表或总数
*/
function query(fetchCountOnly, conditions, startIndex, itemCount) {
let params = [];
// 解析查询条件,拼接SQL过滤参数
for (let item of conditions) {
if (item.name === "uuid" && strIsNotEmpty(item.value)) {
params.push(`uuid="${item.value}"`);
}
if (item.name === "account" && strIsNotEmpty(item.value)) {
params.push(`account_name="${item.value}"`);
}
if (item.name === "status" && strIsNotEmpty(item.value)) {
params.push(`status=${item.value}`);
}
}
// 仅获取总数(用于分页)
if (fetchCountOnly) {
let countRet = dbQuery("device_info", "count(id) as count", params);
return countRet[0].count;
}
// 获取分页数据
else {
let dataRet = dbQuery(
"device_info",
"*",
params,
"id DESC", // 排序规则:按ID倒序
startIndex,
itemCount
);
return dataRet;
}
}
(三)数据新增函数
javascript
/**
* 新增设备
* @param {Array} itemIds - 选中数据ID(新增时为空)
* @param {Array} params - 表单参数([{name:"参数名", value:"参数值", type:"参数类型"}])
* @returns {boolean} 新增结果
*/
function confirmAdd(itemIds, params) {
console.log("新增设备参数:", params);
let obj = {};
// 格式化参数,构建数据库插入对象
for (let p of params) {
obj[p.name] = p.value;
}
// 补充创建时间与用户ID
obj.create_time = new Date().getTime();
obj.creator_openid = rsOpenId;
// 数据库插入(dbInsert:平台内置函数)
let ret = dbInsert("device_info", obj);
console.log("新增结果:", ret);
return ret > 0; // 返回是否成功
}
(四)数据编辑函数
javascript
/**
* 编辑设备
* @param {Array} itemIds - 选中数据ID(单条)
* @param {Array} params - 表单参数
* @returns {boolean} 编辑结果
*/
function confirmEdit(itemIds, params) {
console.log("编辑设备ID:", itemIds, "参数:", params);
let sets = [];
// 拼接更新字段
for (let item of params) {
let fieldName = item.name === "device" ? "uuid" : item.name;
let setStr = `${fieldName}=`;
// 字符串类型加引号,数值类型不加
if (item.type === "string") {
setStr += `"${item.value}"`;
} else {
setStr += item.value;
}
sets.push(setStr);
}
// 数据库更新(dbUpdate:平台内置函数)
let success = false;
for (let id of itemIds) {
success = dbUpdate("device_info", sets, [`id=${id}`]);
}
console.log("编辑结果:", success);
return success;
}
(五)数据删除与批量删除函数
javascript
/**
* 删除单条设备
* @param {Array} itemIds - 选中数据ID
* @param {Array} params - 无需参数
* @returns {boolean} 删除结果
*/
function confirmDelete(itemIds, params) {
console.log("删除设备ID:", itemIds);
let success = false;
for (let id of itemIds) {
// 数据库删除(dbDelete:平台内置函数)
success = dbDelete("device_info", [`id=${id}`]);
}
return success;
}
/**
* 批量删除设备
* @param {Array} itemIds - 选中数据ID列表
* @param {Array} params - 无需参数
* @returns {boolean} 批量删除结果
*/
function confirmBatchDelete(itemIds, params) {
console.log("批量删除设备ID:", itemIds);
let success = true;
for (let id of itemIds) {
if (!dbDelete("device_info", [`id=${id}`])) {
success = false;
break;
}
}
return success;
}
五、Java 后端对接冰狐通用服务源码
冰狐通用服务支持第三方系统通过OpenAPI 接口 调用,Java 后端可通过 HTTP 请求对接,实现数据查询、新增、编辑、删除等操作。以下为 Java(SpringBoot)对接示例,包含接口调用工具类、数据查询、新增设备三大核心模块。
(一)配置冰狐平台参数
XML
# application.properties 冰狐平台配置
aznfz.openapi.url=https://aznfz.com/api/call_micro_service
aznfz.openapi.client-key=你的客户端密钥(平台获取)
aznfz.openapi.access-token=你的访问令牌(平台获取)
aznfz.openapi.script-name=device_service // FaaS脚本名称
aznfz.openapi.is-dev=true // 开发环境:true,生产环境:false
(二)HTTP 请求工具类
java
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 冰狐OpenAPI调用工具类
*/
@Component
public class AznfzOpenApiUtil {
@Value("${aznfz.openapi.url}")
private String apiUrl;
@Value("${aznfz.openapi.client-key}")
private String clientKey;
@Value("${aznfz.openapi.access-token}")
private String accessToken;
@Value("${aznfz.openapi.script-name}")
private String scriptName;
@Value("${aznfz.openapi.is-dev}")
private boolean isDev;
private final RestTemplate restTemplate = new RestTemplate();
/**
* 调用冰狐FaaS函数
* @param functionName 函数名
* @param params 函数参数
* @return 接口返回结果
*/
public String callFaaSFunction(String functionName, List<Object> params) {
// 构建请求参数
Map<String, Object> requestParams = new HashMap<>();
requestParams.put("clientKey", clientKey);
requestParams.put("accessToken", accessToken);
requestParams.put("name", scriptName);
requestParams.put("functionName", functionName);
requestParams.put("isDev", isDev);
requestParams.put("params", JSON.toJSONString(params));
// 发送GET请求(冰狐OpenAPI支持GET/POST)
return restTemplate.getForObject(apiUrl + "?clientKey={clientKey}&accessToken={accessToken}&name={name}&functionName={functionName}&isDev={isDev}¶ms={params}",
String.class, requestParams);
}
}
(三)设备管理业务接口
java
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* 设备管理Java接口(对接冰狐通用服务)
*/
@RestController
@RequestMapping("/device")
public class DeviceController {
private final AznfzOpenApiUtil aznfzOpenApiUtil;
// 构造注入
public DeviceController(AznfzOpenApiUtil aznfzOpenApiUtil) {
this.aznfzOpenApiUtil = aznfzOpenApiUtil;
}
/**
* 查询设备列表
* @param status 设备状态(可选)
* @param startIndex 分页起始索引
* @param itemCount 每页条数
* @return 设备列表
*/
@GetMapping("/list")
public List<Map<String, Object>> getDeviceList(
@RequestParam(required = false) String status,
@RequestParam(defaultValue = "0") Integer startIndex,
@RequestParam(defaultValue = "10") Integer itemCount) {
// 构建查询条件
List<Object> params = List.of(
false, // fetchCountOnly:false(查询数据)
List.of(Map.of("name", "status", "value", status)), // 条件
startIndex,
itemCount
);
// 调用冰狐query函数
String result = aznfzOpenApiUtil.callFaaSFunction("query", params);
// 解析返回结果
return JSON.parseObject(result, new TypeReference<List<Map<String, Object>>>() {});
}
/**
* 新增设备
* @param device 设备信息
* @return 新增结果
*/
@PostMapping("/add")
public boolean addDevice(@RequestBody Map<String, Object> device) {
// 构建参数:itemIds(空)、params(设备信息)
List<Object> params = List.of(
List.of(), // itemIds:新增时为空
List.of(
Map.of("name", "name", "value", device.get("name"), "type", "string"),
Map.of("name", "status", "value", device.get("status"), "type", "int")
)
);
// 调用冰狐confirmAdd函数
String result = aznfzOpenApiUtil.callFaaSFunction("confirmAdd", params);
return Boolean.parseBoolean(result);
}
}
六、实战总结与扩展建议
(一)实战总结
FaaS 通用服务以低代码配置 + Serverless 架构 + 多端适配为核心,开发者无需管理服务器、无需编写复杂 SQL、无需搭建独立后端,通过可视化配置定义数据结构与操作逻辑,用少量 JS 脚本处理复杂业务,即可快速实现数据管理系统。特别适合移动端辅助工具、轻量化管理后台、自动化业务流程等场景。