系统配置
平台提供了系统配置组件及类库,用于存储及获取配置信息。支持按组织配置,下级组织继承上级组织的配置。并且可以扩展为其他路径配置
配置表结构
系统配置存储在config表中,结构如下,其中配置、分组、路径和服务联合唯一
列 | 模型名 | 字段名 | 说明 |
---|---|---|---|
主键 | id | id | ID |
配置 | name | name | 配置 |
配置名称 | label | label | 配置的描述 |
配置内容 | content | content | 配置的内容,JSON格式,一个配置可以包含多个配置项 |
分组 | grouping | grouping | 用户自定义 |
路径 | path | path | 以/分隔的路径,路径上定义的配置,路径的下级节点可继承该配置 |
路径名称 | pathLabel | path_label | 路径的描述 |
标签 | tag | tag | 用户自定义 |
服务 | service | service | 配置对应的应用名,系统提供的配置大多属于企业门户entry |
配置内容可以通过配置一个配置结构,实现界面编辑,配置结构存储在config_schema表中,结构如下,其中配置和服务联合唯一
列 | 模型名 | 字段名 | 说明 |
---|---|---|---|
主键 | id | id | 主键 |
配置 | name | name | 配置 |
配置名称 | label | label | 配置的描述 |
配置结构 | schemaContent | schema_content | 配置的结构,符合formRender规范的JSON格式 |
标签 | tag | tag | 用户自定义 |
服务 | service | service | 配置对应的应用名,系统提供的配置大多属于企业门户entry |
存储配置
使用config组件存储配置,从市场下载系统配置组件
在页面中添加该组件,同时添加组件中的系统配置数据集
从系统配置数据集刷新后事件中,获取配置信息
//commonConfigData为系统配置数据集
var commonConfigData = this.comp("commonConfigData");
var pageData = this.comp("pageData");
commonConfigData.each(function(option){
var content = option.row.val("content");
if(content){
var json = JSON.parse(content);
if(option.row.val("name")=="portal.commonFunc"){
pageData.setValue("funcCount",json.countfunc);
}
}
});
保存时写入系统配置数据集
var commonConfigData = this.comp("commonConfigData");
var rows = commonConfigData.find(["name"],["portal.commonFunc"]);
if(rows.length==0){
commonConfigData.newData({defaultValues:[{
"name" : "portal.commonFunc",
"content" : JSON.stringify({"countfunc":countfunc}),
"grouping" : "",
"label" : "常用功能配置",
"service" : this.getServiceName()
}]});
}else{
commonConfigData.setValue("content",JSON.stringify({"countfunc":countfunc}));
}
if(commonConfigData.isChanged()){
commonConfigData.saveAllData().then(function(){
justep.Util.hint("常用功能显示个数设置成功!");
},function(err){
throw err
});
}
添加组件后,会自动添加这些配置页面
在门户的统一配置项、统一通用配置等功能中出现的页面就是这些在应用中的配置页面,可以自定义页面,以便进行更贴近应用的配置
由于系统配置页面这个目录的目录名为configDialog,包含dialog,系统不会为其下的w文件生成serviceMetaInfo文件,所以这些页面默认不会显示出来,如果需要单独显示,可以手动增加serviceMetaInfo文件
添加了serviceMetaInfo文件的页面,就能在功能树上显示出来了
获取配置
js库
企业桌面端和移动端引用的js库为 model/UI2/wxsys/lib/base/config.js 经典桌面端的js库为 model/UI2/system/lib/base/config.js
js库提供两个方法
- 获取配置 getConfig(serviceName,name,grouping,path,range)
- 按组织获取 getOrgConfig(serviceName,name,grouping,path,range)
- 参数说明
- serviceName:服务,必填,用于请求路径和sql查询
- name:配置,可以指定为模糊查询。传入123查询name=123的配置,传入123%查询name like 123%的配置
- grouping:分组,用于sql查询
- path:路径,支持传入多个,逗号分隔。作为getOrgConfig的参数时,path指组织的fid或id,如果传入的是人员id,查找配置的顺序为,先找人员的配置,然后找主岗的配置
- range:范围,path参数不为空时生效,self取自身,nearest取最近,all取全部,默认为nearest
- 返回结果为JSON数组
- name:配置
- label:配置名称
- grouping:分组
- content:配置内容,JSON格式
- path:路径
移动端使用案例——获取常用功能个数
import Config from "$UI/wxsys/lib/base/config"
Config.getConfig("entry","portal.commonFunc").then(function(data){
if (data.length > 0){
var content = data[0].content;
if(content && content.countfunc){
self.limit = content.countfunc
}
}
var data = self.comp("countData");
data.refreshData();
},function(error){
throw error;
});
经典桌面端使用案例——获取常用功能个数
var Config = require("$UI/system/lib/base/config");
Config.getConfig("entry","portal.commonFunc").then(function(data){
if(data.length>0){
var content = JSON.parse(data[0].content);
if(content && content.countfunc){
self.limit = content.countfunc;
}
}
var data = self.comp("countData");
data.refreshData();
},function(error){
throw error;
});
java库
java库为 com.justep.util.ConfigUtil,提供两个方法
- 获取配置 JSONArray getConfig(String service,String name,String grouping,String path,String range)
- 按组织获取 JSONArray getOrgConfig(String service,String name,String grouping,String path,String range)
- 参数说明
- service 服务,传null表示获取当前应用的配置
- name:配置,可以指定为模糊查询。传入123查询name=123的配置,传入123%查询name like 123%的配置
- grouping:分组,用于sql查询
- path:路径,支持传入多个,逗号分隔。作为getOrgConfig的参数时,path指组织的fid或id,如果传入的是人员id,查找配置的顺序为,先找人员的配置,然后找主岗的配置
- range:范围,path参数不为空时生效,self取自身,nearest取最近,all取全部,默认为nearest
- 返回结果为JSON数组
- name:配置
- label:配置名称
- grouping:分组
- content:配置内容,JSON格式
- path:路径
获取配置使用案例——获取开启双重认证配置
JSONArray configs = ConfigUtil.getConfig(null,"use-two-factor-login",null,null,null);
if(configs.size()>0) {
JSONObject config = configs.getJSONObject(0);
JSONObject items = config.getJSONObject("content");
Boolean login = items.getBoolean("twoFactorLogin");
return login;
}
按组织获取使用案例——获取当前登录者的双重认证白名单配置
JSONArray configs = ConfigUtil.getOrgConfig(null,"two-factor-login",null,userId,null);
if(configs.size()>0) {
JSONObject config = configs.getJSONObject(0);
JSONObject items = config.getJSONObject("content")
Boolean login = items.getBoolean("twoFactorLogin");
return login;
}
配置项定义
formRender模板
每个配置可以定义不同的配置页面,例如下图为钉钉的配置界面
下图为短信的配置界面
这样的配置页面,是通过JSON数据配置出来的
下面是钉钉的配置JSON
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
"corpId": {
"title": "CorpId",
"type": "string"
},
"loginAppId": {
"title": "单点登录AppId",
"type": "string"
},
"loginAppSecret": {
"title": "单点登录AppSecret",
"type": "string"
},
"appKey": {
"title": "AppKey",
"type": "string"
},
"appSecret": {
"title": "AppSecret",
"type": "string"
},
"agentId": {
"title": "AgentId",
"type": "string"
},
"enableProxy": {
"title": "访问代理",
"type": "boolean",
"default": true,
"ui:widget": "switch"
},
"proxyType": {
"title": "代理类型",
"type": "string",
"default": "HTTP",
"enum": [
"HTTP",
"SOCKS"
],
"ui:widget": "radio"
},
"proxyAddr": {
"title": "代理地址",
"type": "string"
}
}
}
下面是短信的配置JSON
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
"type": {
"title": "短信服务商",
"type": "string",
"ui:widget": "radio",
"items": {
"type": "string"
},
"enum": [
"NEWDAO",
"ALIBABA",
"TENCENT",
"CHUANGLAN",
"EMAY"
],
"enumNames": [
"内置短信(仅限开发,测试部署环境使用)",
"阿里云通信",
"腾讯云短信",
"创蓝短信",
"亿美软通短信"
]
},
"apiKey": {
"title": "Access Key ID",
"description": "验证码API账号,通知API账号",
"type": "string"
},
"apiSecret": {
"title": "Access Key Secret",
"description": "验证码API密码,通知API密码",
"type": "string"
},
"freeSignName": {
"title": "短信签名",
"type": "string"
},
"smsUrl": {
"title": "短信地址",
"type": "string"
},
"sms-user-reg": {
"title": "注册验证码模板(sms-user-reg)",
"type": "string"
},
"sms-password-reset": {
"title": "修改密码验证码模板(sms-password-reset)",
"type": "string"
},
"sms-verify-code": {
"title": "通用验证码模板(sms-verify-code)",
"type": "string"
},
"smsDefines": {
"title": "自定义短信",
"type": "array",
"widget": "tableList",
"items": {
"type": "object",
"properties": {
"smsCode": {
"title": "短信编码",
"type": "string"
},
"templateCode": {
"title": "短信模板编码",
"type": "string"
},
"templateContent": {
"title": "短信模板内容",
"type": "string"
}
}
}
}
}
}
在配置项编辑页面上显示了一个配置结构模板,首次添加配置结构时,将模板内容复制到配置结构中,再进行修改。模板中列出了4种常用的模板(输入、单选、多选、开关),更多模板参考 https://x-render.gitee.io/form-render
平台扩展
在formRender的JSON中,增加ext节点,用来实现扩展能力
- protect:设置受保护的配置项,在前端获取该配置时,获取不到受保护的配置项
- personOption:配置的path存人员id还是人员成员id,有些配置以人为主,不管在哪个岗位下,都使用人员的配置时使用。可选项为person或personMember。不设置表示存人员成员id
- asNamePart:将某个属性的值添加到配置name中,形成name--属性值的新name,用于设置多个同类型的配置
设置protect的案例,设置appSecret和appKey为受保护的配置
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
"appKey": {
"title": "AppKey",
"type": "string"
},
"appSecret": {
"title": "AppSecret",
"type": "string"
},
"agentId": {
"title": "AgentId",
"type": "string"
},
"enableProxy": {
"title": "访问代理",
"type": "boolean",
"default": true,
"ui:widget": "switch"
}
},
"ext":{
"protect":["appKey","appSecret"]
}
}
设置personOption的案例,双重认证白名单将配置设置到人员上
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
"twoFactorLogin": {
"title": "开启双重认证",
"type": "boolean",
"default": false,
"ui:widget":"switch"
}
},
"ext": {
"personOption": "person"
}
}
设置asNamePart的案例,系统支持配置多个微信小程序,每个配置的name为 com.qq.weixin.miniapp--appID的形式
{
"ui:labelWidth": 180,
"type": "object",
"properties": {
"appID": {
"title": "appID",
"type": "string"
},
"appSecret": {
"title": "appSecret",
"type": "string"
},
"token": {
"title": "消息事件消息加解密token",
"type": "string"
},
"encodingAESKey": {
"title": "消息事件消息加解密encodingAESKey",
"type": "string"
},
"notifyUrl": {
"title": "微信推送消息解密后通知地址",
"type": "string"
}
},
"ext":{
"asNamePart":"appID"
}
}
配置后的效果