Skip to content

Latest commit

 

History

History
483 lines (368 loc) · 15.2 KB

File metadata and controls

483 lines (368 loc) · 15.2 KB

Microi吾码 V8引擎 API 知识库

此文件由 Microi吾码 VS Code 插件自动生成,为 AI 编程助手提供 V8 引擎 API 上下文。

概述

Microi吾码是一个开源 AI 低代码平台(.NET10 + Vue3 + Redis),V8引擎(基于 Jint,.NET 上的 JavaScript 解释器)是其核心脚本引擎。 用户在"接口引擎"和"表单引擎V8事件"中编写 JavaScript 代码,通过全局对象 V8 访问后端能力。

接口引擎

接口引擎允许用户用 JavaScript 编写后端 API 逻辑。每个接口引擎有唯一的 ApiEngineKey。 在线编写,保存即生效,支持 Get/Post 请求,支持 form/json/url 三种参数格式。

返回值方式:

return { Code: 1, Data: [1,2,3] };       // JSON(Code=1自动提交事务,Code≠1自动回滚)
return '字符串';                           // 直接返回字符串
return '<html>...</html>';                 // 返回HTML
// 返回文件(需开启"响应文件")
return { Code:1, Data:{ FileName:'a.png', ContentType:'image/png', FileByteBase64: base64 } };

配置项: StopHttp(禁止外部调用)、ApiAddress(自定义地址)、分布式锁、允许匿名调用、响应文件

异步执行:

setTimeout(function() {
    V8.FormEngine.UptFormData('table', { Id:'xxx', Field:'value' });
}, 1000);

V8.FormEngine — 表单引擎 CRUD

所有方法第一个参数为表名或表Key(不区分大小写),第二个参数为查询/操作条件对象。

// 获取单条数据(Code=2表示数据不存在)
var result = V8.FormEngine.GetFormData('Sys_User', {
  _Where: [['Account', '=', 'admin']],
  _SelectFields: ['Id', 'Account', 'Name']
});

// 获取列表(分页)
var result = V8.FormEngine.GetTableData('Sys_User', {
  Ids: [1,2,3],                              // 按Id列表查
  _Where: [['Status', '=', 1]],
  _SelectFields: ['Id', 'Account', 'Name'],
  _OrderBy: 'CreateTime',
  _OrderByType: 'DESC',
  _OrderBys: { 'Account':'asc', 'Phone':'desc' },  // 多字段排序
  _PageIndex: 1,
  _PageSize: 20
});

// 匿名查询(无需登录)
var result = V8.FormEngine.GetTableDataAnonymous('Article', { _PageSize: 10 });

// 获取总数
var result = V8.FormEngine.GetTableDataCount('Sys_User', { _Where: [['Status', '=', 1]] });

// 获取树形数据
var result = V8.FormEngine.GetTableDataTree('Department', {});

// 新增数据
var result = V8.FormEngine.AddFormData('Sys_User', { Account: 'test', Name: '测试' });

// 批量新增
var addList = [{ FormEngineKey:'表名', Age:18 }, { FormEngineKey:'表名', Age:20 }];
V8.FormEngine.AddTableData(addList);

// 更新数据(需传Id)
var result = V8.FormEngine.UptFormData('Sys_User', {
  Id: 'xxx', Name: '新名字',
  _NotSaveField: ['字段1'],    // 忽略字段不更新
  _NoLineForAdd: true,         // 不存在则新增
  _ForceUpt: true              // 强制修改自动编号字段
});

// 按条件更新
var result = V8.FormEngine.UptFormDataByWhere('Sys_User', {
  _Where: [['Account', '=', 'test']],
  Status: 0
});

// 删除(单条 / 批量)
var result = V8.FormEngine.DelFormData('Sys_User', { Id: 'xxx' });
var result = V8.FormEngine.DelFormData('Sys_User', { Ids: [1,2,3] });

// 按条件删除
var result = V8.FormEngine.DelFormDataByWhere('Sys_User', {
  _Where: [['Status', '=', 0]]
});

// 使用 _InvokeType: 'Client' 触发表单V8事件
var result = V8.FormEngine.UptFormData('TableName', { Id: 'x', Field: 'val', _InvokeType: 'Client' });

// 新增字段(动态建表)
V8.FormEngine.AddField({
  TableName:'Diy_Test', Name:'Age', Type:'int',
  Label:'年龄', Component:'NumberText', TableWidth:'100', Visible:1
});

_Where 条件语法

参数化查询,无 SQL 注入风险。支持 MySQL、Oracle、SqlServer。

// 基本用法:[字段, 操作符, 值]
_Where: [['Account', '=', 'test']]

// AND/OR 条件:[AndOr, 字段, 操作符, 值]
_Where: [['Account', '=', 'test'], ['OR', 'Name', 'Like', '张']]

// 分组(括号)
_Where: [
  ['Name', 'Like', '张'],
  ['AND', '(', 'Age', '>', 18],
  ['OR', 'Status', '=', 'active', ')']
]

// In 查询
_Where: [['Id', 'In', ['id1', 'id2', 'id3']]]

// NULL 判断
_Where: [['Field', '=', null]]    // IS NULL
_Where: [['Field', '<>', null]]   // IS NOT NULL

// 日期查询
_Where: [['CreateTime', '>', DateFormat(new Date(), 'yyyy-MM-dd HH:mm:ss')]]

支持的操作符: =, ==, <>, !=, >, >=, <, <=, Like, NotLike, StartLike, EndLike, NotStartLike, NotEndLike, In, NotIn


V8.Db / V8.DbRead — 数据库操作

V8.Db 为主库(读写),V8.DbRead 为从库(只读),均使用参数化 SQL(@p0, @p1 占位符)。

// 查询列表
var list = V8.Db.FromSql('SELECT * FROM Sys_User WHERE Status = @p0', 1).ToArray();

// 查询单条
var user = V8.Db.FromSql('SELECT * FROM Sys_User WHERE Id = @p0', userId).First();

// 执行非查询
var affected = V8.Db.FromSql('UPDATE Sys_User SET Status = @p0 WHERE Id = @p1', 0, userId).ExecuteNonQuery();

// 执行标量
var count = V8.Db.FromSql('SELECT COUNT(*) FROM Sys_User').ToScalar();

// 事务:接口引擎中 return Code=1 自动提交,Code≠1 自动回滚,禁止手动 Commit/Rollback
// 表单V8事件中:可共享事务
var result = V8.FormEngine.GetFormData('table', { Id: V8.Form.Id }, V8.DbTrans);

// 跨数据库(扩展库)
var dataList = V8.Dbs.OracleDB1.FromSql('SELECT * FROM table').ToArray();
// 扩展库独立事务
var exTrans = V8.Dbs.EmptyEx.BeginTransaction();
exTrans.FromSql("DELETE FROM table WHERE Id = @p0", id).ExecuteNonQuery();
exTrans.Commit();
exTrans.Close();

V8.Cache — Redis 缓存

V8.Cache.Set('key', 'value', 3600);            // 秒数过期
V8.Cache.Set('key', 'value', '0.00:00:59');    // d.HH:mm:ss 格式
var val = V8.Cache.Get('key');
V8.Cache.Remove('key');
var exists = V8.Cache.Exists('key');
// Key命名规范:Microi:${V8.OsClient}:{分类}:{Key}

V8.Http — HTTP 请求

// 简洁格式
var result = V8.Http.Get('https://api.example.com/data');
var result = V8.Http.Post('https://api.example.com/data',
  JSON.stringify({ key: 'value' }),
  { 'Content-Type': 'application/json' }
);

// 对象格式(完整参数)
var result = V8.Http.Post({
  Url: 'https://api.example.com/data',
  PostParam: { key: 'value' },
  ParamType: 'json',              // 'json' | 'form'
  Timeout: 5,                     // 秒
  Headers: { token: 'xxx' },
  FilesByteBase64: {}             // 上传文件
});

// 获取完整响应(含响应头、状态码)
var resp = V8.Http.PostResponse('https://api.example.com/data', body, headers);
// resp.Content, resp.Headers, resp.StatusCode

// 下载文件(获取字节)
var resp = V8.Http.GetResponse({ Url: 'https://example.com/file.png' });
var imgByte = resp.RawBytes;

V8.ApiEngine — 调用其他接口引擎

var result = V8.ApiEngine.Run('otherApiEngineKey', { param1: 'value1' });
// 共享事务(在表单V8事件中)
var result = V8.ApiEngine.Run('key', { Form: V8.Form }, V8.DbTrans);

V8.MongoDb — MongoDB 操作

参数格式为对象,包含 DbName、TableName 字段。

V8.MongoDb.AddFormData({ DbName:'mydb', TableName:'users', _FormData:{ name:'张三', age:25 } });
var doc = V8.MongoDb.GetFormData({ DbName:'mydb', TableName:'users', Id:'xxx' });
var docs = V8.MongoDb.GetTableData({ DbName:'mydb', TableName:'users', _Where:[['age','>',18]] });
V8.MongoDb.UptFormData({ DbName:'mydb', TableName:'users', Id:'xxx', _FormData:{ age:26 } });
V8.MongoDb.DelFormData({ DbName:'mydb', TableName:'users', Id:'xxx' });

V8.Method — 内置方法

var token = V8.Method.GetCurrentToken(token, osClient);   // 返回 {OsClient,CurrentUser,Token}
V8.Method.RefreshLoginUser(userId, osClient);
var url = V8.Method.GetPrivateFileUrl({ FilePathName:'...' });
V8.Method.AddSysLog({ Type:'', Title:'', Content:'', Level:1 });
var guid = V8.Method.NewGuid();
var snowId = V8.Method.SnowflakeId();
var oldWhere = V8.Method.ParseWhere(V8.Param._Where);     // 新版→旧版Where转换
// 文件上传
var upResult = V8.Method.Upload({
  FilesByteBase64: V8.FilesByteBase64,
  Limit: false, Preview: false, Path: '/test-upload', OsClient: V8.OsClient
});

V8.EncryptHelper — 加密

V8.EncryptHelper.MD5Encrypt('text');
V8.EncryptHelper.SHA256Encrypt('text');
V8.EncryptHelper.Sha256Hex('text');
V8.EncryptHelper.HmacSha256(key, data);
V8.EncryptHelper.AESEncrypt('text', 'key');
V8.EncryptHelper.AESDecrypt(encrypted, 'key');
V8.EncryptHelper.DESEncode('text');            // DES加密
V8.EncryptHelper.DESDecode('cipher');          // DES解密

V8.Base64

V8.Base64.StringToBase64('Hello');       // 编码
V8.Base64.Base64ToString('SGVsbG8=');    // 解码

V8.Office

V8.Office.SendEmail({
  SmtpServer:'smtp.qq.com', SmtpPort:587, EnableSSL:true,
  SystemEmail:'admin@itdos.com', SystemEmailPwd:'...',
  EmailSubject:'标题', EmailBody:'<b>HTML内容</b>',
  Receivers:['a@qq.com']
});
// 自定义导出Excel
var excelResult = V8.Office.ExportExcel({
  OsClient: V8.OsClient,
  ExcelData: dataList,
  ExcelHeader: [{Name:'字段名',Label:'显示名',Component:'Text',Config:{}}]
});

V8.MQ — 消息队列 (RabbitMQ)

V8.MQ.SendMsg('queue_name', { ProductId:'123', Count:2 });
// 消费者接口引擎中:
var message = V8.Param.Message;   // object类型

V8.TranslateEngine — 翻译引擎

V8.TranslateEngine.Translate('张三', 'en');           // 翻译为英文
V8.TranslateEngine.Translate('love', 'cn', 'en');     // 英→中
V8.TranslateEngine.GetLang('NoAuth');                  // 从diy_lang缓存获取

MQTT 引擎

var eventName = V8.EventName;
// StartServer / Connected / Disconnected / MessageReceived / StopServer
if (eventName == 'MessageReceived') {
  var clientId = V8.MQTT.ClientId;
  var topic = V8.MQTT.Topic;
  var payload = V8.MQTT.Payload;
}

表单V8事件体系

V8事件类型及执行顺序

事件文件 运行端 触发时机 说明
InFormV8.js 前端 表单打开时 初始化字段显隐、默认值
SubmitFormV8.js 前端 表单提交时 前端校验(Postman不触发)
SubmitBeforeServerV8.js 后端 数据写入DB前(事务中) 服务端校验、数据加工
SubmitAfterServerV8.js 后端 数据写入DB后(仍在事务中) 触发通知、同步其它表
OutFormV8.js 前端 表单关闭后 刷新列表、跳转
DataFilterV8.js 后端 获取数据后每行执行 数据脱敏、字段加工

后端V8事件特有变量

  • V8.Form — 即将写入的数据
  • V8.OldForm — 修改前的旧数据
  • V8.FormSubmitAction — 'Add' / 'Upt' / 'Del'
  • V8.DbTrans — 共享事务(提交前/后事件都可用)
  • V8.NotSaveField — 指定不保存的字段(数据脱敏)
  • V8.CacheData — DataFilter中的缓存数据
  • V8.RowIndex — 当前行索引

后端事件中阻止提交(自动回滚事务)

return { Code: 0, Msg: '错误信息!' };

后端事件中共享事务操作其它表

V8.FormEngine.UptFormData('other_table', { Id:'x', Field:'val' }, V8.DbTrans);
V8.ApiEngine.Run('key', { Form: V8.Form }, V8.DbTrans);
V8.FormEngine.GetFormData('this_table', { Id: V8.Form.Id }, V8.DbTrans);

工作流V8事件

// 条件判断V8(决定流程走向)
if (V8.Form.Money <= 100) { V8.LineValue = 1; } else { V8.LineValue = 2; }
// 节点V8中可用
V8.WF.ApprovalType    // Agree/Disagree/Recall/Auto
V8.WF.ApprovalIdea    // 审批意见
V8.WF.CurrentNode     // 当前节点
V8.WF.NextNode        // 下一节点
V8.WF.NextTodoUsers   // 接收人

上下文变量

变量 说明
V8.Param 前端传入的请求参数(统一接收form/json/url三种)
V8.Header 请求头
V8.CurrentUser 当前用户(Id, Account, Name, RoleIds, RoleName, DeptId, DeptIds, DeptName, Level)
V8.OsClient 当前应用标识
V8.SysConfig 系统配置(SysTitle, ApiBase, FileServer等)
V8.OsClientModel SaaS引擎敏感配置
V8.Form 当前表单数据(V8事件中)
V8.OldForm 提交前的旧数据(V8事件中)
V8.TableModel 当前diy_table信息(V8事件中)
V8.FormSubmitAction 提交动作:Add / Upt / Del
V8.EventName 事件名称
V8.InvokeType 调用类型:Server / Client
V8.Result 赋值后作为接口返回值
V8.Action GetDateTimeNow(), GetTimestamp(), Sleep(ms)
V8.FilesByteBase64 接收上传的文件数据

DosResult 标准返回格式

{ Code: 1, Data: {}, DataCount: 0, Msg: '', DataAppend: {} }
// Code: 1=成功, 0=失败, 2=GetFormData数据不存在, 1001=Token失效, 1002=身份验证失败

SaaS引擎 — 三参数模型

接口引擎区分租户:

// 方式1:传token自动识别
// 方式2:URL参数 /apiengine/test?OsClient=veken
// 方式3:特殊格式 /apiengine/test--OsClient--veken--

System 命名空间(.NET 互操作)

var now = System.DateTime.Now.ToString('yyyy-MM-dd HH:mm:ss');
var guid = System.Guid.NewGuid().ToString();
var num = System.Convert.ToInt32('123');
var rounded = System.Math.Round(3.14159, 2);
System.Threading.Thread.Sleep(1000);

全局函数

DateNow('yyyy-MM-dd HH:mm:ss')                        // 当前日期时间
DateFormat(dateObj, 'yyyy-MM-dd')                       // 日期格式化
DateAdd(date, 'd', 1, 'yyyy-MM-dd')                    // 日期加减(支持s/m/h/d/w/q/M/y)
console.log('调试信息')                                  // 控制台输出(docker logs查看)

接口引擎注意事项

  • 数组参数:Array.isArray(V8.Param.arr) 返回 false,但 arr.lengtharr[0] 正常
  • 事务管理:接口引擎中禁止手动 Commit/Rollback,return Code=1 自动提交,Code≠1 自动回滚
  • _InvokeType: 'Client':FormEngine调用时触发表单V8事件(默认Server模式不触发)

数据库结构

编写 V8.FormEngineV8.Db 代码时,请参考当前编辑文件所属 OsClient 目录下的 .microi-db-schema.md 获取表名和字段信息。

数据库结构文件列表:

  • microi-v8-engine/Microi吾码 (api.itdos.com)/iTdos.Product.Internal/.microi-db-schema.md
  • microi-v8-engine/浙江任亿科技有限公司 (api.renyikj.cn)/renyi.Product.Internal/.microi-db-schema.md

V8 引擎编码最佳实践(Skills)

编写 V8 引擎代码时,参考以下 Skill 文件获取代码模板和安全规范:

  • microi.skills/v8-crud-api/SKILL.md — 增删改查(含批量操作)
  • microi.skills/v8-table-event/SKILL.md — 表单事件(含 DataFilter、前后端事件)
  • microi.skills/v8-sql-query/SKILL.md — SQL 查询(参数化、事务)
  • microi.skills/v8-http-integration/SKILL.md — HTTP 集成(对象参数格式)
  • microi.skills/v8-cache-pattern/SKILL.md — Redis 缓存
  • microi.skills/v8-security/SKILL.md — 安全规范
  • microi.skills/v8-workflow/SKILL.md — 工作流审批事件
  • microi.skills/v8-mongodb/SKILL.md — MongoDB 操作
  • microi.skills/v8-mq-mqtt/SKILL.md — 消息队列与 MQTT