Skip to content
本页目录

核心扩展包 mas-core

核心扩展包负责构建前端基础框架,引入前端框架Vue、状态管理库Vuex,封装本地缓存Cache、消息推送WebSocket、服务接口API及Vue框架扩展等,为前端开发提供基础封装、能力支持。

核心扩展包不包含UI相关内容,可以同时支持PC端、移动端等

为平台扩展的能力

  • 状态管理(Vuex)
  • Ajax请求(Axios)
  • 服务接口
  • 本地缓存(localStorage、sessionStorage)
  • WebSocket
  • 前端消息总线
  • 当前微应用与上下文获取
  • 权限判断
  • 异步资源加载
  • 树形数据合并工具
  • 时间、数字、金额等格式化工具方法

引入的框架

Vue框架

Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。MAUI系统采用外部依赖Vue方式,由前端底座负责载入,当前版本为 2.6.12。 具体文档可查看 Vue2官网

说明

Vue 由前端底座统一引入,各微应用设置为外部依赖后打包发布。

Vuex库

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 当前版本为 3.6.2,具体文档可查看 Vuex3官网

Axios库

Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js,使用简单,包尺寸小且提供了易于扩展的接口。当前版本为 0.21.4,具体文档可查看 Axios 官方文档

封装的对象

本地缓存

注意

直接采用localStoragesessionStorage操作数据将出现租户、站点数据污染,务必使用封装的缓存对象操作。

本地缓存通过分装localStoragesessionStorage实现,分别提供localsession对象,分别提供 getsetremove方法,具体如下:

js
// 设置缓存
set(key, value) {}

// 读取缓存
get(key, defaultValue) {}

// 移除缓存数据
remove(key) {}

说明

local对象使用localStorage存储,不随浏览器的关闭而消失,但它的存储空间较小(一般为5M),而且缺少安全机制,因此不宜存储敏感信息和大量信息

WebSocket 消息推送

通过封装WebSocket对象,提供 connopenclosesend 等方法,具体如下:

js
class WSClient {
  // 地址默认从window.location中获取,默认为:hostname:port/ws
  url,
  // 断网是否重连
  reconn : true
  // 是否禁用
  disableWebSocket: true
  // 连接
  conn(url) { }
  // 根据上下文,打开WebSocket连接
  open(ctx) { }
  // 关闭连接
  close() { }
  // 发送消息
  send(msg) { }
}

url 默认从网页中计算获得,计算规则为: hostname:port/ws

可以通过上下文的 disableWebSocket 属性,设置是否禁用 WebSocket 连接

对微应用能力的扩展

状态管理

平台基于Vuex实现状态管理,分为全局状态管理和各微应用的模块化状态管理两个部分。

全局状态管理

全局状态管理由核心扩展模块定义,各微应用可以通过 this.$app.ctx.store 方式调用,具体如下:

js
{
  state: {
    // 是否锁屏
    locked: false,
    // 当前页面访问路径
    path: '/',
    // 公开页面路径集合
    publics: new Set(),
    // 会话ID
    sessionId: "",
    // 用户信息
    user: {
      // 登录名
      username: "",
      // 是否登录
      auth: false,
      // 头像
      avatar: ''
    },
    // 站点配置信息
    setting: {},
    // 会话超时重新登录后需要自动发起的请求
    reloads: [],
    // 登录错误信息
    error: "",
    // 当前用户权限信息
    powers: {
      r: {},
      p: {}
    },
    // 业务菜单
    navs: [],
    // 系统菜单
    sysNavs: [],
    // 有权限访问的路径集合
    paths: new Set(),
    // 登录后的首页
    home: "/",
    // 表格建议高度
    tableBodyHeight: 0,
    // 是否全屏
    fullscreen: false,
    printAll: true,
    showTenantGuide: false,
    badge: {},
    isShowMessages: false,
    messagesContet: ''
  },
  mutations: {
    // 设置租户配置信息(用于租户标识请求获取时)
    config(state, { setting, tenant }) {},
    // 设置租户配置信息(用于设置缓存读取时)
    setting(state, setting) {},
    // 锁定屏幕
    lockscreen(state) {},
    // 解锁屏幕
    unlockscreen(state) {},
    // 强制要求身份认证
    auth(state) {},
    // 设置会话ID
    sessionId(state, sessionId) {},
    // 设置用户信息,并重新计算菜单
    user(state, user) {},
    // 重新计算菜单
    navs(state) {},
    setNavs(state, navs) {},
    // 退出
    logout(state) {},
    // 重新请求服务
    reload(state, request) {},
    // 设置错误信息
    error(state, error) {},
    // 设置默认打开页面
    home(state, home) {},
    tableBodyHeight(state, tableBodyHeight) {},
    fullscreen(state, fullscreen) {},
    printAllChanged(state) {},
    showTenantGuide(state, flag) {},
    clearBadge(state) {},
    setBadge(state, obj) {},
    showMessage(state) {},
    hideMessage(state) {},
    hideIsNeedChangePwd(state) {},
    hideForceChangePassword(state) {},
    setMessage(state, content) {}
  },
  actions: {
    // 判断路由页面是否有权限
    access(context, router) {},
    // 重新发起请求
    reload(context, request) {},
    // 登出系统
    logout(context) {},
    // 账号密码登录
    login(context, { username, password, reload }) {},
    // 扫码登录
    qrLogin(context, { qrCode, reload }) {},
    // 政务钉登录
    ddLogin(context, { code, reload }) {},
    // 锁定页面
    lockscreen(context) {},
    // 解锁页面
    unlockscreen(context, {
      username,
      password
    }) {},
    changePwd(context, changeForm) {}
  },
  getters: {
    auth(state) {},
    user(state) {},
    setting(state) {},
    reloads(state) {},
    error(state) {},
    navs(state) {},
    sysNavs(state) {},
    home(state) {},
    powers(state) {},
    locked(state) {},
    tableBodyHeight(state) {},
    fullscreen(state) {},
    printAll(state) {},
    showTenantGuide(state) {},
    badge: (state) => (names) => {},
    showMessage(state) {},
    getMessage(state) {},

  },
  // 根据各应用定义的store属性,生成并注册模块
  modules
}

微应用的模块化状态管理

各微应用可以以模块化方式定义自己的状态对象,通过 this.$app.store 方式调用,可通过在Application参数对象中定义 store 属性,属性值参考如下:

js
{
  // 默认采用独立命名空间模式,空间名为应用的name属性值
  // namespaced: false,
  state: () => ({ ... }),
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

每个应用的状态管理对象采用独立命名空间模式注册,空间名为应用的 name 属性值,如不想使用独立命名空间模式时,可将 namespaced 设置为 false

模块模式的状态管理用法,参考 Vuex 模块

Ajax请求

平台通过Axios库来实现前后端请求交互,可通过 this.$app.axios 获取每个微应用的 Axios 实例,此实例提供缓存、统一的异常处理等

缓存

所有 get 请求,只要在请求参数对象中,设置 cache > 0,就会开启用缓存,在设定的时间范围内,多次请求均只会根据第一次返回的结果来返回,避免频繁请求后台导致的性能问题。

axios(config)

json
{
  ...
  // 缓存时间,以秒为单位,大于0时启用缓存
  cache,  
  // 仅为GET方法启用缓存
  method, 
  // 如果没有cacheKey属性,缓存以url作为唯一性标识
  url, 
  // 如果多个不同请求参数有差异,但url相同,
  // 需要开启缓存的话,必须设置cacheKey代替url作为可区分的唯一性标识
  cacheKey 
}

错误处理

401身份认证错误

针对会话超时,需要重新登录的情况,统一弹出登录窗口,并在登录成功后对原始请求实现重发。

TODO

此处可以优化,需要重新加载的请求无需放入状态管理。

其他错误

平台提供默认的错误显示功能,特殊请求中如不需要平台接手并显示错误信息,可在 config配置对象中增加 systemErrorShow 属性并设置为 false 即可。

服务接口

服务接口是通过配置方式来简化Ajax调用的一种便捷方式。各微应用可通过在配置参数中增加 apis 属性,定义后台接口,应用页面中可通过 this.$app.$api_<api_name> 方式调用,具体定义格式如下:

js
{
  // 定义基础路径,作为api路径的前缀自动拼接
  base: '/api',
  // 字符串模式,默认get模式
  userInfo: "/user-info",
  // post模式
  addUser: "post:/user-add",
  // 对象模式定义
  delUser: {
    method: "post",
    url: "/user-del",
    ...
  }
}

微应用服务接口可以通过字符串和对象两种模式定义。字符串模式定义时,key 为接口名称 <api_name>,值为 <url> 或者 <method>:<url><method> 未定义时为 get;对象模式时,结构同 Axios 请求的 config 对象。

定义的服务接口,会自动以 $api_<api_name>(config) (get时) 或 $api_<api_name>(data, config) (post/put/option等) 方法,绑定在 Application 实例上,页面中可以 `this.$app.$api_<api_name>方式调用。

说明

每个微应用拥有一个独立的Axios实例

用户登入/退出事件

当微应用中需要监听用户登入/退出事件时,只需要在应用定义中实现 "logged-in"(user)"logged-out"() 方法即可,设置如下:

js
{
  ...
  "logged-in": function(user) {
    // 用户登入后运行,user为用户信息对象
  },
  "logged-out": function() {
    // 用户退出系统后运行
  }
}

对上下文对象的扩展

为上下文增加WebSocket连接、合并树形数据、本地缓存和状态管理能力

js
{
  // WebSocket连接
  ws,
  // 合并带插槽特性的树形参数,并做节点转换
  _mergeTreeSlots(name, defaultSlot, rootSlot, handler){},
  // 合并
  _mergeTree(name, sameAttrName, mergeFunc, itemFunc){},
  // 基于localStorage的缓存
  local,
  // 基于sessionStorage的缓存
  session,
  // 平台全局状态管理对象,基于Vuex
  store,
}

_mergeTreeSlots_mergeTree 两个方法用于应用配置对象树形数据的合并。前者支持插槽机制,可以灵活组装树型数据;后者合并树形数据,无插槽机制,效率更高。

对Vue原型的扩展

当前微应用

页面中可通过 this.$app 获取当前页面所在微应用实例对象

说明

此处采用 Vueprovide/inject 机制,实现父子继承方式,传递微应用实例对象

权限判断

页面中可通过 this.$auth(rightExp) 校验登录用户的权限信息是否具备,true 表示用户具备表达式所述权限。

其中 rightExp 为权限表达式,可采用 r.<role_code>p.<permission_code> 分别代表指定code的角色和权限项,还可以使用 &&||()等,分别表示与、或和优先计算,举例如下:

js
// 管理员角色
r.admin
// 修改用户或删除用户权限
p.edit_user || p.del_user
// 管理员,或者具备删除用户权限的子管理员
r.admin || (r.sub_admin && p.del_user)

本地缓存

页面可通过 this.$local 访问 localStorage 缓存封装对象 本地缓存,同 this.$app.ctx.local

会话缓存

页面可通过 this.$session 访问 sessionStorage 缓存封装对象 本地缓存,同 this.$app.ctx.session

异步加载资源文件

js
$js(moduleName, url).then(module=>{
  // moduleName 为js文件中定义的模块名称,如echarts,此名称必须和js中定义的
  // url 为js文件地址,如https://unpkg.zhimg.com/echarts@5.0.2/dist/echarts.common.min.js,js文件中必须把需要加载的模块,定义为window[moduleName]
  // module 为加载后的模块
  ... // 此处代码为css加载成功后执行
})
$loadJs(moduleName, url).then(module=>{
  // 同$js方法
})
$css(url, id, reload).then(()=> {
  // url 为需要加载的css文件地址
  // id 为页面加载对象的唯一编号,用于删除和重新加载,单次加载可不指定
  // reload 强制重新加载,默认首次加载即缓存,设置为true后,会再次加载并覆盖原先相同id的css文件
  ... // 此处代码为css加载成功后执行
})
$loadStyle(url, id, reload).then(()=> {
  // 同$css方法
})
$removeStyle(id) // 根据id,删除css加载对象,加载的css文件内容将失效

可以通过以上方法,异步加载js文件、css文件等

WebSocket

js
$ws // 提供WebSocket封装对象的引用

前端消息

js
$eventbus // 提供Vue内置的前端消息引擎

系统时间

js
$now() // 当前时间,"YYYY-MM-DD HH:mm:ss"
$today() // 今天,"YYYY-MM-DD"
$CNToday() // 今天,"YYYY年MM月DD日"
$datetime(time) // 格式化为"YYYY-MM-DD HH:mm:ss"
$MDTime(time) // 格式化为"MM-DD HH:mm:ss"
$date(time) // 格式化为"YYYY-MM-DD"
$weekday(time) // 格式化为"星期?"
$time(time) // 格式化为"HH:mm:ss"
$CNDate(time) // 格式化为"YYYY年MM月DD日"
$CNYearMonth(time) // 格式化为"YYYY年MM月"
$90days() // 获取最近90天的起止时间,返回"YYYY-MM-DD HH:mm:ss"格式的字符串数组[start, end]
$360days() // 获取最近360天的起止时间,返回"YYYY-MM-DD HH:mm:ss"格式的字符串数组[start, end]

数字

js
$number(value, pattern) // value为数字, pattern为格式,如“0,000.00”,将数字格式化为字符串
valuepatternString
10000'0,0.0000'10,000.0000
10000.23'0,0'10,000
10000.23'+0,0'+10,000
-10000'0,0.0'-10,000.0
10000.1234'0.000'10000.123
100.1234'00000'00100
1000.1234'000000,0'001,000
10'000.00'010.00
10000.1234'0[.]00000'10000.12340
-10000'(0,0.0000)'(10,000.0000)
-0.23'.00'-.23
-0.23'(.00)'(.23)
0.23'0.00000'0.23000
0.23'0.0[0000]'0.23
1230974'0.0a'1.2m
1460'0 a'1 k
-104000'0a'-104k
1'0%'100%
0.974878234'0.000%'97.488%
-0.43'0 %'-43 %
0.43'(0.000 %)'43.000 %

金额

js
$CNY(number) // number为分的整数,格式化为中文的元角分
$money(number) // number为分的整数,格式化为"0,000.00"

具体使用可参考 websocket-消息推送

全部角色、权限项

扩展应用配置对象,通过增加 rolespermissions 分别定义微应用所需的角色和权限项,平台通过合并获取全部的角色、权限项及角色与权限项之间的关系。

此信息用于初始化,不作为登录用户的权限数据

内部资料,请勿外传