AppNodeJs/Code:
- 平台根据模板生成通用代码(目前只支持开发环境下面使用)
- 子项替换,mapper里面必须存在common
接口版本:
| 版本号 | 制定人 | 制定日期 | 修订日期 |
|---|---|---|---|
| v3 | 陈碧贵 | 2021-06-28 | xxxx-xx-xx |
请求URL:
请求方式:
- POST
请求头:
| 参数名 | 是否必须 | 类型 | 说明 |
|---|---|---|---|
| XownerId | 是 | string | 项目唯一ID,对应bo_project {ownerId} |
| XsysId | 否 | string | 所属系统 对应 bo_system 表 |
| XuserFromFirstShareId | string | 否 | 一级分享用户ID, bo_user user_id |
| XuserFromSecondShareId | string | 否 | 二级分享用户ID, bo_user user_id |
| XverifyApi | 是 | string | 加密规则encryptByDES(`${newGuid()} |
| XfilterAreaCode | 否 | string | 行政区编码, 对应 bo_sys_area area_code |
| Content-Type: | 是 | string | application/json; charset=utf-8 请求类型 |
| Authorization | 是 | string | 当前用户认证信息,通过登录接口获取 Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6 |
请求参数:
| 参数名 | 是否必须 | 类型 | 说明 |
|---|---|---|---|
| mkey | 是 | string | 模块对应mapper配置文件 |
| field | 是 | string | 对应mapper里面resonseField |
| ignore | 否 | bool | 开发环境忽略验证 |
| ownerId | 是 | string | 所属项目 |
ownerId:bt
sysId:
ignore:true
_nodejs:common-data
//_menuId:bt-deve-bt-20200-7f945562-c725-4a96
mkey:policy-analysis
//wmkey:warn
field:bbrcard
//primaryId:warmId
//primaryIdU:WarmIdUDc
//routerName:data-center-warn
//routerPath:/data-center/warn
请求body参数占位符:
{{params}} 参数来自query请求,以及body里面组合获取
请求body参数(使用规则详见底下源码刨析):
| 参数名 | 是否必须 | 类型 | 说明 |
|---|---|---|---|
| fileRootPath | 是 | string | 来源模板 |
| fileBuildPath | 是 | string | 生成模板路径 |
| columns | 是 | array | 子项模板配置。会把mapper里面common列替换到 fileColumnPath内容,然后重新 赋值给fileRootKey对应的参数,最终fileBuildPath根据配置参数进行合并 |
- field
{
"fileRootPath":"~/App_Data/Templates/AppNodeJs/field.js",
"fileBuildPath":"~/Config/AppNodeJs/{{ownerId}}-plugins/{{mkey}}/{{field}}.js",
"columns":[
{
"fileColumnPath":"",
"fileRootKey":""
}
]
}
- field-query
{
"fileRootPath":"~/App_Data/Templates/AppNodeJs/field-query.js",
"fileBuildPath":"~/Config/AppNodeJs/{{ownerId}}-plugins/{{mkey}}/{{field}}-query.js",
"columns":[
{
"fileColumnPath":"",
"fileRootKey":""
}
]
}
- field-query-body
{
"fileRootPath":"~/App_Data/Templates/AppNodeJs/field-query-body.js",
"fileBuildPath":"~/Config/AppNodeJs/{{ownerId}}-plugins/{{mkey}}/{{field}}-query-body.js",
"columns":[
{
"fileColumnPath":"",
"fileRootKey":""
}
]
}
- columns组合
{
"fileRootPath":"~/App_Data/Templates/app-element/page/content.vue",
"fileBuildPath":"~/App_Temp/Views/{{ownerId}}/{{wmkey}}/content.vue",
"columns":[
{
"fileColumnPath":"~/App_Data/Templates/app-element/page/column.vue",
"fileRootKey":"page-columns"
}
]
}
- 结果二次替换 params主要替换[[field]] 或 {{field}}
{
"fileRootPath":"~/App_Data/Templates/app-element/page/content.vue",
"fileBuildPath":"~/App_Temp/Views/{{ownerId}}/{{wmkey}}/content.vue",
"columns":[
{
"fileColumnPath":"~/App_Data/Templates/app-element/page/column.vue",
"fileRootKey":"page-columns"
}
],
"params":[
{
"key":"",
"value":""
}
]
}
返回示例:
正确时返回:
{
"data": {
"message": "生成成功,生成目录《~/Config/AppNodeJs/bt-plugins/policy-analysis/bbrcard.js》",
"pf": {
"bulkLocal": false,
"cacheSource": "data",
"ownerId": "bt",
"requestModuleType": "Null",
"cacheKey": "btJJJJ"
}
},
"code": "0",
"success": true
}错误时返回:
{
"success": false,
"error":{"errorCode":0,"errorText":""}
}返回参数说明:
| 参数名 | 类型 | 说明 |
|---|---|---|
| data | object | message告诉生成路径地址,可以把生成代码放到实际目录中 |
postman案例:


模板配置案例

模板目标案例

源码说明
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using RG3.DO.Abstractions.Interfaces;
using RG3.PF.Abstractions.Consts;
using RG3.PF.Abstractions.Entity;
using RG3.PF.Abstractions.Exceptions;
using RG3.PF.Utilities;
using RG3.PF.Utilities.Entity;
using RG3.PF.Utilities.Services;
using RG3.PF.Web.Controllers;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Linq;
using NReco.Linq;
using Microsoft.Extensions.Configuration;
using RG3.DO.Mapper.Json.Services;
using RG3.BO.Qu.Services;
using RG3.DO.Abstractions.Entity;
using RG3.BO.BI.Bridge.Entity;
namespace RG3.BO.BI.Bridge.Controller
{
/// <summary>
/// 全平台基础生成工具
/// </summary>
[Route("bo/api/v3/bridge/apptool")]
[ApiController]
[ApiExplorerSettings(IgnoreApi = true)]
public partial class AppCodeToolController : BaseController
{
private readonly IHttpContextAccessor _accessor;
private readonly IMapperProvider _imapperProvider;
private readonly IConfigurationBuilderProvider _configurationBuilderService;
/// <summary>
///
/// </summary>
private readonly SqlConfigService _sqlConfigService;
/// <summary>
/// 配置信息
/// </summary>
private readonly IConfiguration _configuration;
private readonly DetailService _detailService;
/// <summary>
/// 注入服务
/// </summary>
/// <param name="detailService"></param>
/// <param name="accessor"></param>
/// <param name="sqlConfigService"></param>
/// <param name="configuration"></param>
/// <param name="imapperProvider"></param>
/// <param name="configurationBuilderService"></param>
public AppCodeToolController(DetailService detailService, IHttpContextAccessor accessor, SqlConfigService sqlConfigService, IConfiguration configuration, IMapperProvider imapperProvider, IConfigurationBuilderProvider configurationBuilderService)
{
_accessor = accessor;
_imapperProvider = imapperProvider;
_configurationBuilderService = configurationBuilderService;
_sqlConfigService = sqlConfigService;
_detailService = detailService;
_configuration = configuration;
//if (!_configuration.GetValue<bool>("debug:help"))
//{
// throw new BizException(ErrorCodeConst.HTTP_16405.ErrorCode, "【debug:help】已关闭,接口不能使用");
//}
}
/// <summary>
/// 生成工具
/// </summary>
/// <param name="appToolRoot"></param>
/// <param name="mkey"></param>
/// <param name="wmkey"></param>
/// <param name="field"></param>
/// <returns></returns>
[HttpPost("build")]
public async Task<IActionResult> BuildFile([FromBody] AppToolRoot appToolRoot, [FromQuery] string mkey, [FromQuery] string wmkey, string field)
{
var pf = new PFGlobalParameter { OwnerId = RequestPFUtil.GetOwnerId(this.HttpContext), SysId = RequestPFUtil.GetSysId(this.HttpContext) };
string virPath = appToolRoot.FileBuildPath.Replace("{{ownerId}}", pf.OwnerId).Replace("{{mkey}}", mkey).Replace("{{wmkey}}", wmkey).Replace("{{field}}", field);
SetMetaConvert(appToolRoot, wmkey, mkey, field);
return new JsonResult(new ResultDetail<object> { Data = new { message = $"生成成功,生成目录《{virPath}》", pf = pf }, Success = true });
}
private IActionResult SetMetaConvert(AppToolRoot appToolRoot, string wmkey, string mkey, string field)
{
var pf = new PFGlobalParameter { OwnerId = RequestPFUtil.GetOwnerId(this.HttpContext), SysId = RequestPFUtil.GetSysId(this.HttpContext) };
var dicQuery = RequestPFUtil.ConvertHTByReqFormOrParamsS(this.HttpContext);
if (string.IsNullOrEmpty(appToolRoot.FileRootPath))
{
throw new BizException(ErrorCodeConst.FILE_17004.ErrorCode, $"body里面模板【fileRootPath】未传递");
}
if (string.IsNullOrEmpty(appToolRoot.FileBuildPath))
{
throw new BizException(ErrorCodeConst.FILE_17004.ErrorCode, $"body里面生成【fileBuildPath】未传递");
}
string virPath = appToolRoot.FileBuildPath.Replace("{{ownerId}}", pf.OwnerId).Replace("{{mkey}}", mkey).Replace("{{wmkey}}", wmkey).Replace("{{field}}", field);
if (!virPath.Contains("~/App_Temp") && FileUtil.ExistsFilesByVirPath(virPath))
{
throw new BizException(ErrorCodeConst.FILE_17004.ErrorCode, $"文件已存在,生成结果请放在~/App_Temp下面,当前路径【{virPath}】");
}
//组件清单设置 start
SqlConfig sql4 = _sqlConfigService.BuildUseSqlConfigMapper(true, pf, mkey, field);
string fileRootPath = appToolRoot.FileRootPath.Replace("{{{ownerId}", pf.OwnerId).Replace("{{mkey}}", mkey).Replace("{{wmkey}}", wmkey).Replace("{{field}}", field);
StringBuilder sb = new StringBuilder(FileUtil.ReadFileAndContentByVirUrl(fileRootPath));
foreach (var row in appToolRoot.Columns.Where(temp => !string.IsNullOrEmpty(temp.FileColumnPath) && !string.IsNullOrEmpty(temp.FileRootKey)))
{
string fileColumnPath = row.FileColumnPath.Replace("{{ownerId}", pf.OwnerId).Replace("{{mkey}}", mkey).Replace("{{wmkey}}", wmkey).Replace("{{field}}", field);
string fileRootKey = row.FileRootKey;
StringBuilder sbItems = new StringBuilder();
string columnT = FileUtil.ReadFileAndContentByVirUrl(fileColumnPath);
foreach (var item in sql4.ResponseField["common"].Columns.OrderBy(temp => temp.Value.FieldSort))
{
Dictionary<string, string> dicQueryT = new Dictionary<string, string>();
var itemT = sql4.Columns[item.Key];
sbItems.AppendLine(columnT);
dicQueryT["field"] = itemT.Field;
dicQueryT["alias"] = itemT.Alias;
dicQueryT["label"] = itemT.Title;
dicQueryT["unit"] = itemT.Unit;
dicQueryT["datatype"] = itemT.DataType;
dicQueryT["name"] = itemT.Name;
dicQueryT["primary"] = (itemT.IsPrimary == true ? 1 : 0).ToString();
dicQueryT["required"] = (itemT.IsRequired == true ? 1 : 0).ToString();
dicQueryT["identity"] = (itemT.IsIdentity == true ? 1 : 0).ToString();
dicQueryT["sortid"] = (itemT.SortId ?? 9999).ToString();
foreach (var itemC in dicQueryT)
{
if (sbItems.ToString().Contains(itemC.Key))
{
sbItems.Replace("{{" + itemC.Key + "}}", itemC.Value);
}
}
}
//组件清单设置 start
dicQuery[fileRootKey] = sbItems.ToString();
}
foreach (var item in dicQuery)
{
if (sb.ToString().Contains(item.Key))
{
sb.Replace("{{" + item.Key + "}}", item.Value);
}
}
//结果二次替换
foreach (var item in appToolRoot.Params)
{
sb.Replace("[[" + item.Key + "]]", item.Value?.ToString());
}
//结果二次替换
foreach (var item in appToolRoot.Params)
{
sb.Replace("{{" + item.Key + "}}", item.Value?.ToString());
}
FileUtil.CreateFileAndContentVirPath(virPath, sb.ToString());
return new JsonResult(new { data = virPath });
}
}
}
文档更新时间: 2023-03-26 16:04 作者:admin