跳到主要内容
版本:2.0.3

介绍

该文档用于外部组件开发和功能集成

SDK 版本跟随 CMS 产品版本

此文档会一直更新为最新版本,版本差异详见【版本升级】

指南

cms 基于 vue3 (3.2.31) 开发,必须使用 vue3 才能兼容使用,且应保持版本一致

安装

安装 cms sdk

npm install syc-cms

通过脚手架创建外部组件项目

请查看《使用模板进行前端开发》文档

使用

引入 cms sdk

import sdk from 'syc-cms'
import 'syc-cms/sdk/style.css'
console.log(sdk.version)

cms 前端模块主要分为两大类,模型(models)、视图(views),详见 【API】

教程

外部组件

独立开发 cms 组件

1.  使用脚手架创建项目

npm init cms-widgets

2.  安装 npm 依赖

npm install

3.  运行

npm run dev

4.  基于示例组件开发新组件。见【组件开发】

src/widgets/
Widget1/index.ts
Widget2/index.ts
index.ts # 打包入口

5.  打包

npm run build
dist/widgets/
Widget1/index.js
Widget2/index.js

6.  将打包结果放置 cms 服务器 wwwroot/widgets 下

wwwroot/widgets/
Widget1/index.js
Widget2/index.js

7.  运行 cms

8.  在组件库中看到自己写的组件即成功

组件开发

组件模型 models/Widget

画布节点模型 models/CanvasNode

用户将组件 Widget 拖拽到画布上时,基座会创建一个画布节点 CanvasNode 添加到 app.current.project.current.page.document.body.children 下

WidgetX/index.ts

// 编写两个 vue 组件
// 一个是画布视图
import X from '../X/X.vue'
// 另一个是设置视图
import XSettings from '../X/X.settings.vue'
// 当 Widget 被拖拽出来时
// 基座创建一个 CanvasNode 实例
// 基座会给两者共享一个 canvasNode , prop 名为 node
// 设置视图主要负责修改 canvasNode.props
// 画布视图则主要使用 canvasNode.props

// 注册组件
// 引用 Widget 模型
const { Widget } = sdk.import('@/models/Widget')

// 创建一个新 Widget
new Widget({
is: 'X',
category: Widget.categories.base.type,
canvasView: X,
settingsView: XSettings,
props: {},
})

// 注册成功
console.log(Widget.store['X'])

功能集成

复用 cms 的能力,将 cms 的功能集成到自己的项目中

1.  创建 vue3 项目

2.  安装 cms

npm install syc-cms

3.  引用 cms

import sdk from 'syc-cms'

4.  修改 cms

const { X } = sdk.import('@/models/X')X

5.  渲染 cms

Your.vue

<template></template>
<script>
// 导入你需要的视图
const VueComponent = sdk.import('@/views/X.vue')
</script>

API

sdk

mount(selector: string)

挂载整个 cms ,如果只需要集成部分功能,则不要调用

selector: css 选择器

sdk.mount('#app')

import(module: string)

导入 cms 模块

复用 npm 包

const X = sdk.import('X')

使用模型

const { X } = sdk.import('@/models/X')

使用视图

const X = sdk.import('@/views/.../X.vue')

version: string

cms 版本号

console.log(sdk.version)

NPM 包

sdk 会提供 cms 使用的主要的 npm 包以复用。开发外部组件时,必须先使用 sdk 提供的包以避免冗余或出错

const X = sdk.import('X')

示例

const { isEmpty } = sdk.import('lodash')

✧ axios

✧ crypto-js

✧ element-plus

✧ echarts

✧ html2canvas

✧ jszip

✧ lodash

✧ vue (是否要排除,待定)

✧ vue-router(是否要排除,待定)

✧ vuex(是否要排除,待定)

模型(M)

模型指 MVC 中的 M ,是对应用结构的描述,是一系列类

models/App

app: App

App 的实例,单例,是整个系统的数据中心

const { app, App, createApp, getApp } = sdk.import('@/models/App')
console.log(app.mode)

// 单例
app === new App() === createApp() === getApp()

class App

construnctor()

初始化应用程序

mode: "editing" | "running"

当前模式,编辑模式(开发版),运行模式(运行版)。组件渲染时在两种模式中可能有区别,取决于组件自身逻辑

editing: boolean

是否编辑模式

running: boolean

是否运行模式

current.project: Project

包含一个 Project 实例,工程项目实例

projectList: Project[]

工程项目列表,每一项都是一个 Project 实例

createApp()

创建应用程序,sdk 已自动创建

getApp()

获取应用程序

models/Project

class Project

对项目工程进行管理和操作,包括变量、页面、语言等内容

constructor(object: any = {})

创建项目

id

项目的 ID

name

项目的名称

pageList: Page[]

项目中的页面列表,存储 Page 类的实例数组

languageList: Language[]

项目中的语言列表,存储 Language 类的实例数组

variableMap:  { [name: Variable['name']]: Variable }

以变量名称为键的对象,存储项目中的变量信息,每个变量是 Variable 类的实例

variableValueMap

以变量名称为键的对象,存储项目中的变量值信息。通过 Proxy,实现了对 variableMap 的值的自动获取和设置

variableOldValueMap

以变量名称为键的对象,存储项目中的变量旧值信息。通过 Proxy,实现了对 variableMap 的旧值的自动获取

current.page: Page

当前页面

current.language: Language

当前语言

current.user: User

当前用户

current.homePageId: string

首页 ID 字符串

blocks: Block[]

全局事件列表,存储 Block 类的实例数组

variableEventConfigList

变量事件配置列表,存储变量事件的配置信息

timerEventConfigList

定时器事件配置列表,存储定时器事件的配置信息

remove()

从 app.projectList 中移除当前项目实例

toast(...args: Parameters<typeof toast>)

显示提示信息。参数与 toast 函数的参数相同

setVariable(name: string, value: string|number|boolean)

设置变量值。参数 name 是变量名,value 是变量值

waiting(time = 0)

等待指定时长。参数 time 是等待的时长(毫秒)。返回一个解析为 true 的 Promise

openVirtualKeyboard()

开启虚拟键盘。通过触发名为 openVirtualKeyboard 的事件实现

closeVirtualKeyboard()

关闭虚拟键盘。通过触发名为 closeVirtualKeyboard 的事件实现

models/Page

class Page

页面管理,它包含了页面的基本属性和方法,以及与其他页面进行交互的功能。

constructor(object: Partial<Page> = {})

创建页面

id

表示页面的唯一标识符

name

表示页面的名称

children: Page[]

表示页面的子页面

document: {body: CanvasNode}

表示页面文档数据,body 是页面渲染在画布上时的根节点

type: number

表示页面的类型。0 表示文件夹,1 表示画面

updateTime: string

表示页面的更新时间

sort: number|null

表示页面在父级页面中的下标(用于排序)。值为 null 时,默认排序将页面追加到父级的最后一个

parent: Page

表示页面的父节点

variableEventConfigList: Map

表示页面的变量事件配置列表

timerEventConfigList: Map

表示页面的定时器事件配置列表

permissions: Array

表示页面的权限控制配置。包含多个具有 id、name 和 subs 属性的对象,id 和 name 分别表示 CanvasNode 的 id 和 name,subs 是一个包含多个具有 id 和 name 属性的对象的数组

static getPageById(id: string)

根据给定的 id 在项目的页面列表中查找页面

static appendPageList(child: Page, sort: number | null = null)

静态方法,将给定的子页面添加到项目的页面列表中

appendChild(child: Page, sort: number | null = null)

向当前页面的子页面列表中添加一个子页面

remove()

从父页面的子页面列表中移除当前页面

getSort()

获取当前页面在父页面子页面列表中的下标

save()

保存当前页面的内容和权限配置

models/PageManager

class PageManager

一个页面控制器,主要用于管理页面的弹窗、页面跳转、导出、打印等功能。

construnctor()

初始化页面控制器

id

类的唯一标识,值为 'PageManager'

name

类的名称,值为 '页面控制器'

topPageZIndex: string

页面顶部的 z-index 属性值,默认为 '99'

dialogPages: Array

存储弹窗页面的数组

miniPagesId: Array<MiniPages>

存储最小化窗口的 id 的数组

currentDialogPageUUID: string

当前选中的弹窗的 UUID

static lastDialogInfo: { timestamp: number, pageId: string }

记录最后一次弹窗的信息,包括时间戳和 pageId

currentPage: any

获取当前选中的弹窗

getDialogPageById(id: string)

根据 id 获取对应的弹窗页面

removeMiniPagesById(id: string)

根据 id 移除最小化窗口

removeDialogPagesById(id: string)

根据 id 移除最大化窗口

jumpRoute(pageId: number)

跳转到指定的页面,支持弹窗内跳转和主体页面跳转

reloadRoute()

刷新当前页面

backRoute()

返回上一个页面

closeRoute()

关闭所有弹窗页面

alertRoute(targetPageId: number | string, title: string, fixedSize: boolean, width: number, height: number, target: string, closeBtn: boolean)

弹出指定页面,包括相关参数(如:目标页面 id、标题、固定尺寸、宽度、高度、目标、关闭按钮等)

exportCurrentPage(pageInfo: any, type: string, filename: string, format: string, orientation: string, specifiedSavePath: string | null, timeout: number = 2000)

导出页面中的图表数据,支持导出为 Excel 格式

printCurrentPage(pageInfo: any, timeout: number = 2000)

打印当前页面

exportChartsData(pageComponent: any, filename: string, type: string, exportContent: Array<string>, specifiedSavePath: string, timeout: number = 1000)

导出页面图表数据

models/CanvasNode

class CanvasNode

用于表示和管理一个画布上的图形元素,每个独立的图形元素都可以看作是一个 CanvasNode 实例。它包含了许多属性和方法,用于描述元素的形状、位置、颜色等特征,以及实现元素的绘制、移动、缩放等操作。

constructor(object: Partial<CanvasNode> = {})

初始化节点

id

节点的唯一标识符,使用日期的 JSON 字符串表示

name

节点的名称,默认为空字符串

tagName: string | undefined

节点的 HTML 标签名,可以是 undefined

style: Partial<CSSStyleDeclaration>

节点根元素的样式数据,是一个包含 CSS 样式声明的对象

langStyleMap: Record<string,Partial<CSSStyleDeclaration>>

一个记录不同语言样式的对象,键值对形式

computedStyle: Partial<CSSStyleDeclaration>

节点根元素已计算的样式,通过 Proxy 进行操作

static computedStyleCache: Record<string,Partial<CSSStyleDeclaration>>

针对 computedStyle 计算样式进行缓存,用于子节点修改样式后能及时反馈给父节点

styleProxy: Partial<CSSStyleDeclaration>

节点根元素样式转换器,将 computedStyle 转换为样式字符串。

is: string

表示一个组件类型,类似于 Vue 的 is 属性

props: Record<string, any>

组件的 props,组件应允许所有 prop 为空

blocks: OnBlocks[]

包含 OnBlock 类型的数组

methods: { [name: string]: Function }

包含方法的对象,方法名作为键,方法作为值

permission: boolean

表示节点是否具有权限,默认为 false

selected: boolean

选中状态的 getter 和 setter,用于判断节点是否被选中

locked: boolean

表示节点是否被锁定,默认为 false

aspectRatioLocked: boolean

表示节点的宽高比是否被锁定,默认为 false

dom: HTMLElement

返回 DOM 元素,根据 id 获取

parentNode: CanvasNode

返回节点的父节点,可能是 undefined

childNodes: CanvasNode[]

节点的子节点数组

children: CanvasNode

返回 childNodes 属性,用于获取子节点

static readonly selectedList: CanvasNode

选中的节点列表,响应式数组

static readonly styleProxy: Partial<CSSStyleDeclaration>

读写当前选中节点的样式的代理对象

static getSelectedOrBodyList()

获取选中的节点或页面主体节点列表

static getUnlockedSelectedList()

获取未锁定的选中节点列表

static getSameStyleProxyValue(nodes: CanvasNode[], key: string)

获取具有相同样式代理值的节点数组

static setSameStyleProxyValue(nodes: CanvasNode[], key: string, value: any)

为具有相同样式代理值的节点数组设置样式值

static getById(id: string)

根据给定的 id 获取 CanvasNode 实例。

static getBody()

获取页面主体节点

toJSON()

返回一个 JSON 对象,包含节点的属性

remove()

从父节点中移除当前节点

appendChild(child: CanvasNode)

将给定的子节点添加到当前节点的 childNodes 数组中

cloneNode()

克隆当前节点及其子节点,返回克隆得到的新节点

isGroup()

判断当前节点是否为组节点

getVariableEvent()

获取变量事件相关的块

setDefaultProps(defaultProps: any)

设置默认的 props

toggleVisible(visibleState: 'show' | 'hide' | '' = '')

切换节点的可见性

addClass(className: string)

给节点添加类名

removeClass(className: string)

移除节点的类名

hasClass(className: string)

判断节点是否具有指定的类名

toggleClass(className: string)

切换节点的类名

toggleEnable(enableState: 'enable' | 'disable' | '' = '')

切换节点的可用性

setOpacity(opacity: number)

设置节点的不透明度

toggleBling(isStarted: boolean, speed: 'slow' | 'medium' | 'fast' = 'fast')

切换节点的闪烁效果

setWidthHeight(mode: 'absolute' | 'percentage', w: number, h: number)

设置节点的宽度和高度

setLetTop(mode: 'relative' | 'absolute', x: number, y: number)

设置节点的左和顶部位置

setRotate(mode: 'relative' | 'absolute', deg: number, originX: number, originY: number)

设置节点的旋转角度和旋转中心点

setTextStyle(color: string, fontSize: number, bold: boolean, italic: boolean, underline: boolean, textAlign: string, letterSpacing: number, lineHeight: number)

设置文本样式

setTextContent(content: string)

设置文本内容

setBackgroundColor(color: string)

设置背景颜色

setBorder(color: string, width: number, style: string)

设置边框样式

setBorderRadius(borderRadius: number)

设置边框圆角

setBoxShadow(mode: 'outset' | 'inset', horizontal: number, vertical: number, blur: number, spread: number, color: string)

设置盒阴影样式

models/Widget

class Widget

表示应用中的可视化组件,这些组件可以在画布上进行组合和编辑,从而实现各种自定义的功能。Widget 类包含了组件的一些基本属性和方法,以及与其他组件进行交互的功能。

constructor(object: Widget)

创建新组件

is: string

组件的唯一标识,类比 vue is 。如果相同将会覆盖。内部组件自动使用文件名

name: string

表示组件的名称

category: string

表示组件所属的分类

icon: string

表示组件的图标

permission: boolean

表示组件是否可以进行权限控制

canvasView: unknown

表示组件在画布上的视图

settingsView: unknown

表示组件的设置视图(如:Name.settings.vue)

props: object

表示组件的默认属性

style: Record<string, boolean>

表示组件可以配置的样式,如果某个样式被禁用,则对应值为 false

onCreate(node: CanvasNode)

当组件实例化为 CanvasNode 时,会调用此函数

static loadExternalWidgets(externalWidgetsAPI: string)

加载外部组件,从给定的 API 获取组件列表并加载

static importExternalWidgets(url: string)

导入外部组件。从给定的 URL 加载外部组件并实例化

static store

以组件类型为键,Widget 实例为值。用于存储所有已创建的 Widget 实例

static get list

获取 store 中的所有 Widget 实例

static sortInfo

指定组件的排序

static categories: {[key:string]: {type:string, label:string}}

组件分类

models/Variable

class Variable

对项目中的变量进行变量管理。它包含了与变量相关的一系列操作,例如获取和设置变量值,发送变量值到后端等。还提供了一些静态方法和属性,以方便访问和操作当前项目中的变量。

constructor(object: any = {}, project = app.current.project)

构造函数,创建变量实例。同一工程多次创建同名变量会复用

project: Project

该变量所属的项目实例

name: string

变量名

dataQuality: number

变量的数据质量

_value

变量的私有值

oldValue

变量的旧值

value

getter 和 setter 用于获取和设置变量值。setter 设置新值时,会自动下发新值

get()

返回变量的值

set(newValue: any)

设置变量值并同步更新本地值

post(newValue: any)

仅下发变量值,不立即更新本地值

static postBufferMap

合并所有变量变更,统一下发

static applyPost(variable: Variable, newValue: any, oldValue: any)

收集变量的变化

static post(map: typeof Variable.postBufferMap)

下发变量值,如果失败则恢复旧值

remove()

从项目中删除此变量

static map

获取当前项目中的变量映射

static valueMap

获取当前项目中的变量值映射

static oldValueMap

获取当前项目中的旧变量值映射

static getByName(name: string, project = app.current.project)

根据变量名和项目获取变量实例

static store

读写变量,仅下发,不更新本地值

static _store

读写变量,不下发,仅更新本地值

static store

读写变量,下发,且同步更新本地值

static start()

启动变量监听

static convertRemoteValue(value: any)

转换推送的值类型

static isVarName(name: string)

判断给定字符串是否为一个合法的变量名

static getExpVars(code: string)

获取给定表达式中的变量名

static expFnCache: Map<string, Function>

用于缓存表达式求值函数的静态属性

static exp(code: string)

通过表达式求值

static watchExp(code: string, callback: (value: any, oldValue: any) => void)

监听表达式的值变化

static expTitleTip: string

表达式输入框 tooltip 提示

models/Language

class Language

用于管理多语言,用于实现在应用中切换不同的语言环境。其属性和方法主要负责获取、设置和翻译文本,以及订阅和触发当前语言环境的变化。

constructor({ lang, running = false }: { lang: Lang; running?: boolean }, project = app.current.project )

初始化语言包

project: Project

存储项目信息

lang: "original" | "auto" | "zh-CN" | "en-US"

存储当前设置的语言

followLang: "original" | "auto" | "zh-CN" | "en-US"

存储实际应用的语言,如果设置为 'auto',则跟随系统的语言设置

map

存储动态语言包的映射,键为原始文本,值为翻译后的文本

staticMap

存储静态(内置)语言包的映射

static isOriginal()

判断当前语言状态是否为原始文本

setLang(lang: "original" | "auto" | "zh-CN" | "en-US")

保存当前设置的语言到本地 localStorage

fetch()

获取当前项目对应语言的翻译数据

handleMap(maps: LangMapItem[])

转换处理后端返回的翻译文本

static initDefautLangInRun(running?: boolean)

在运行时设置默认语言

static t(rawText: string | null | undefined)

收集并翻译动态语言,将原始文本替换为对应的翻译文本

static _t(rawText: string)

翻译内置语言包的文本

static saveRawText(pageId: string)

保存原始文本

static resetStore()

重置状态

static useChange(fn: Function)

订阅当前语言状态的变化,收集监听函数

static trigger(lang: Language)

触发通知订阅函数当前语言状态改变

static remove(fn: Function)

移除订阅

static triggerRenderFn()

改变状态,使 CanvasNode 组件重新渲染并调用 t 函数收集文本依赖

static useElementPlusI18n()

获取当前语言的 element-plus 内置语言包

static getLangReqHeader()

获取当前语言请求头

models/Block

class Block

Block 类是所有具有类别的对象的基类。它提供了一些共享的基本方法和属性,以及一些用于子类继承的基础接口。

constructor(object: any = {})
class: string

每个 Block 实例都有一个 class 属性,其值为构造函数的 class 属性。这用于区分不同类型的块

children: Block[]

存储该 Block 实例的子块数组

id

每个 Block 实例都有一个唯一的 id

createArray(objectArray: any[])

用于将对象数组转换为 Block 实例数组

codeToValue(code: string)

用于将字符串形式的代码转换为 JavaScript 值

valueToCode(value: any)

用于将 JavaScript 值转换为字符串形式的代码

fixValue(value: any)

用于将可能是字符串形式的代码的值转换为 JavaScript 值

toCode()

用于将 Block 实例转换为字符串形式的代码

class OnBlock

OnBlock 类表示注册事件块

constructor(object: any = {})
static class: string

类标识符,对于 OnBlock 实例,其值为 'OnBlock'

event: EventBlock

EventBlock 实例,表示该 OnBlock 实例的事件

isEnable: boolean

布尔值,表示该 OnBlock 实例是否启用

toCode()

用于将 OnBlock 实例及其子块转换为字符串形式的代码

getCallback()

用于获取 OnBlock 实例的回调函数

getCallbackCatch()

用于获取 OnBlock 实例的错误处理回调函数

getOnProp()

用于获取 OnBlock 实例的事件属性

getOnPropList(onBlockList: Block[])

用于从给定的 OnBlock 实例数组中获取事件属性列表

getBlockById(id: string)

用于通过 id 从当前项目的页面中查找 OnBlock 实例

class EventBlock

EventBlock 类表示事件块

constructor(object: any = {})
static class

类标识符,对于 EventBlock 实例,其值为 'EventBlock'

static types

列出了所有可能的事件类型

type: string

字符串,表示该 EventBlock 实例的事件类型

name: string

字符串,表示该 EventBlock 实例的名称

detail

表示该 EventBlock 实例的详细信息

toCode()

用于将 EventBlock 实例转换为字符串形式的代码

class IfBlock

IfBlock 类表示条件块

constructor(object: any = {})
static class

类标识符,对于 IfBlock 实例,其值为 'IfBlock'

expression: string

字符串,表示该 IfBlock 实例的条件表达式

toCode()

用于将 IfBlock 实例及其子块转换为字符串形式的代码

class CallBlock

CallBlock 类可以调用某个方法或函数

constructor(object: any = {})
static class

类标识符,对于 IfBlock 实例,其值为 'CallBlock'

object: ObjectBlock

表示调用的目标对象

method: string

表示被调用的方法的名称

name: string

表示此调用块的名称

arguments: ArgumentBlock[]

表示调用的方法的参数

toCode()

将当前的 CallBlock 实例转化为 JavaScript 代码

static call(blockClass: any, id: string, method: string, args: any[])

用于执行函数调用

static checkCallError()

卡死检测

class MethodBlock

MethodBlock 类表示一个方法块,包含一个方法的信息

constructor(object: any = {})
object: string

表示方法所属的对象的名称

type: string

表示方法的类型

name: string

表示此方法块的名称

method: string

表示方法的名称

arguments: ArgumentBlock[]

表示方法的参数

cloneNode()

克隆当前 MethodBlock 实例的方法

class ArgumentBlock

ArgumentBlock 类表示一个参数块,包含一个参数的信息

constructor(object: any = {})
static class

'ArgumentBlock':表示这是一个 ArgumentBlock 类

name: string

表示此参数块的名称

expression: string

表示参数的表达式

type: string

表示参数的类型,默认为字符串

view: string

表示参数的视视类型,默认为文本输入框

unit: string

表示参数的单位

min: number

表示参数的最小值(数字类型)

max: number

表示参数的最大值(数字类型)

step: number

表示参数的步长(数字类型)

appendVariableEvent: boolean

表示是否附加变量事件

options:{ name: string; expression: string; value: any; [key: string]: any }[]

表示参数的选项列表

toCode()

将当前的 ArgumentBlock 实例转化为 JavaScript 代码

static convertOptions()

用于将参数选项列表转换为特定格式的数据结构

class ObjectBlock

ObjectBlock 类表示对象块,用于存储对象的信息

constructor(object: any = {})
static class

用于标识该类的类型

id

表示对象的标识符

name

表示对象的名称

static privateConfig

{

eventList:存储了 EventBlock 实例

methodList:存储了 MethodBlock 实例

}

static findModel()

根据传入的 blockClass 类型和标识符 id 查找对应的模型。根据不同的 blockClass 类型,返回相应的模型对象

static getMethodInfo()

根据传入的方法名 method 获取方法信息,目前该方法只返回方法名本身

class ProjectBlock

ProjectBlock 类主要用于描述系统对象块

constructor(object: any = {})
static class

'ProjectBlock',用于标识该类的类型

name: string

表示项目的名称,可以在构造函数中进行设置

static eventList

[

{mounted:表示项目启动时的事件},

{unmounted:表示项目退出时的事件},

{variable:表示变量满足某个条件时触发的事件,需要设置条件表达式和条件值},

{timer:表示定时执行的事件,需要设置开始时间、执行频率、结束时间等参数}

{alarm:表示报警触发的事件,需要设置报警点和已选列表}

]

static methodList: MethodBlock[]

私有方法

class PageBlock

页面对象块 对应 Page 配置页面动作信息(Page 中的方法)

constructor(object: any = {})
static class

'PageBlock',用于标识该类的类型

static methodList: MethodBlock[]

私有方法

class PageManagerBlock

PageManagerBlock 类主要用于描述页面管理器模块

constructor(object: any = {})
static class

'PageManagerBlock',用于标识该类的类型

static eventList

事件列表

static methodList: MethodBlock[]

私有方法

class CanvasNodeBlock

组件对象块 对应 CanvasNode 配置组件动作信息(CanvasNode 中的方法)

constructor(object: any = {})
static class

'CanvasNodeBlock',用于标识该类的类型

static privateConfig

私有配置

static eventList

事件列表

static methodList: MethodBlock[]

私有方法

models/Socket

class Socket

基于 SignalR 的 WebSocket 客户端,用于与服务器建立和维护实时双向通信。这个类封装了 SignalR 库的相关方法,提供了一些额外的功能,如事件注册、调用方法、连接管理等。

constructor(object: Partial<Socket> = {})

创建连接

url: string

表示 WebSocket 服务器的 URL 地址

name: string

表示 Socket 类的名称

connection: [signalR.HubConnection](signalR.HubConnection)

表示 SignalR 的 HubConnection 对象,用于与服务器建立和维护连接

callbackMap

用于保存事件回调信息的 Map 对象。当连接断开并重新连接时,会重新注册这些事件

call(...args: Parameters<signalR.HubConnection['invoke']>)

调用服务器端的方法,接受任意数量的参数。这个方法将参数传递给 SignalR 的 invoke 方法

on(type: string, callback: (...args: any[]) => void, params: Record<string, any>)

用于注册事件。接收事件类型(type)、回调函数(callback)和参数(params)作为输入。当事件触发时,会调用回调函数。此方法返回一个用于注销事件的函数

useOn(...args: Parameters<Socket['on']>)

用于 Vue 组件中自动注销事件。当组件卸载时,会自动调用 off 方法注销事件。此方法返回一个用于注销事件的函数

off(type: string, callback: Parameters<Socket['on']>[1])

用于注销事件。接收事件类型(type)和回调函数(callback)作为输入。它会从 callbackMap 中删除指定的回调信息,并取消 SignalR 的事件监听

startCount

表示重新连接的次数

start()

启动 WebSocket 服务。这个方法会尝试建立连接,如果连接失败,会根据重试次数等待一定时间后再次尝试。当首次连接成功时,会返回一个 Promise 对象

static lockWS()

静态方法,使用 Navigator.locks API 请求 WebSocket 锁。这可以确保在同一页面上同时只有一个 WebSocket 连接

static createConnection(url: string)

静态方法,根据给定的 URL 创建一个 SignalR 的 HubConnection 对象

models/Resource

class Resource

表示一个资源对象,如一个设计套件。它包含了与该资源相关的信息,如 id、名称、封面图片以及包含的 CanvasNode(画布节点)对象。

constructor(object: any = {})
id

资源的唯一标识符

name

资源的名称

cover: string

资源的封面图片 URL

canvasNode: CanvasNode

资源包含的画布节点(CanvasNode 对象)。一个资源通常包含一个根画布节点,根节点的子节点表示实际的设计元素

static getImages: string[]

接收一个 CanvasNode 对象作为参数,从中提取图片 URL。它会将 CanvasNode 对象转换为 JSON 字符串,然后使用正则表达式匹配所有的图片 URL。返回一个包含所有图片 URL 的数组,如果没有找到任何图片,则返回 null

models/Request

class Request

AJAX 请求

static get(url: string, config?: RequestConfig)
static post(url: string, data?: any, config?: RequestConfig)
static put(url: string, data?: any, config?: RequestConfig)
static delete(url: string, config?: RequestConfig)
static request(config: AxiosRequestConfig)
static baseURL: string

models/Dialog (TODO)

class Dialog

弹窗基类,仅定义结构,无功能实现

static Component: VueComponent
static async prompt(...args: unkown): Promise<unkown>

class VariableDialog extends Dialog

变量选择弹窗

static Component: VueComponent

vue 组件,覆盖它可实现自定义弹窗

新组件与原组件参数一致时直接覆盖此属性即可,否则需要重写 prompt

static async prompt(options: Record<string, any>): Promise<Variable>

创建弹窗并等待返回一个 Variable 实例

通过 this.Component 创建一个弹窗并等待返回一个结果。类比 window.prompt

class ExpressionDialog extends Dialog

表达式编写弹窗

static Component: VueComponent

同上

static async prompt(options: Record<string, any>): Promise<string>

同上

创建弹窗并等待返回一个表达式字符串

class AlarmDialog extends Dialog

告警点选择弹窗

static Component: VueComponent

同上

static async prompt(options: Record<string, any>): Promise<Alarm>

同上

创建弹窗并等待返回报警点对象

视图(V)

视图是 MVC 中的 V ,是用户界面,是 vue 组件

views/Project/Project.vue

该组件由以下几部分组成:Header.vue(头部)、Pages.vue(页面)

views/Project/Pages/Pages.vue

该组件由以下几部分组成:Sidebar.vue(侧边栏)、Editor.vue(编辑器)

views/Project/Pages/Sidebar/Sidebar.vue

该组件由以下几部分组成:PageList.vue(页面列表)、CanvasNodeList.vue(对象列表)

views/Project/Pages/Sidebar/PageList/PageList.vue

views/Project/Pages/Sidebar/CanvasNodeList/CanvasNodeList.vue

views/Project/Pages/Editor/Editor.vue

该组件由以下几部分组成:Board.vue(画板)、Settings.vue(配置栏)

events

hightLightPages(): 高亮页面功能区

views/Project/Pages/Editor/Board/Board.vue

画板

views/Project/Pages/Editor/Board/Canvas/Canvas.vue

画布

views/Project/Pages/Editor/Board/Canvas/CanvasNode.vue

画布节点

props

{
node: CanvasNode, // 这是要处理的CanvasNode
mode: string, // 模式
editing: boolean, // 是否处于编辑模式
running: boolean, // 是否处于运行模式
collect: boolean, // 是否需要清空收集多语言文本,一般由根节点清空,其他禁止清空(eg:画面容器嵌套)
}

views/Project/Pages/Editor/Board/Selector/Resizer.vue

控制拖动调整大小

views/Project/Pages/Editor/Board/Toolbar/Toolbar.vue

工具栏

views/Project/Pages/Editor/Board/WidgetLib/WidgetLib.vue

部件

views/Project/Pages/Editor/Board/Zoom/Zoom.vue

缩放

props

{
props: {
zoom:表示当前的缩放级别,默认值是1
initialZoom:表示初始化的缩放级别,默认值是1
maxZoom:表示最大的缩放级别,默认值是2
minZoom:表示最小的缩放级别,默认值是0.2
step:表示每次增加或减少的缩放级别的步长,默认值是0.1
}
}

views/Project/Pages/Editor/Board/History/History.vue

历史记录

views/Project/Pages/Editor/Board/Toolbar/LanguageSelect.vue

多语言

views/Project/Pages/Editor/Settings/Settings.vue

右侧栏,该组件由以下几部分组成:Style.vue(样式)、WidgetSettings.vue(控件设置)、Events.vue(事件)

views/Project/Pages/Editor/Settings/Style/Style.vue

样式

views/Project/Pages/Editor/Settings/WidgetSettings/WidgetSettings.vue

控件设置

views/Project/Pages/Editor/Settings/WidgetSettings/Permission.vue

权限控制

props

{
props: {
node: 要处理的CanvasNode
}
}

views/Project/Pages/Editor/Settings/Events/Events.vue

事件

views/Project/Pages/Viewer/Viewer.vue

页面文档渲染器

props

mode: App['mode'] = 'running' // 默认运行模式
document: Page['document'] = app.current.project.current.page.document // 默认渲染当前页面

events


示例

具体场景的使用示例 注入指令和多语言 初始化mount前,需要进行指令、埋点和多语言的初始化

import { sdk } from 'syc-cms'
import { createApp } from 'vue'
import App from './App.vue'
import 'syc-cms/sdk/style.css'

const directives = sdk.import('@/directive/waves/index.ts').default
const track = sdk.import('@/directive/track/index').default
const { Language } = sdk.import('@/models/Language')
const app = createApp(App)

app.use(directives)
app.use(track)
Language.setVueGlobal(app)

挂载整个 CMS

挂载并渲染整个 CMS ,开发外部组件时使用,其它修改应该在渲染前处理。集成部分功能时不要使用

sdk.mount('#app')

移除某个组件

须在视图渲染前

const { Widget } = sdk.import('@/models/Widget') // 移除线条组件
delete Widget.store['Line'] // Widget.store 包含了所有组件信息

获取当前用户信息

用户在工程之下,不同工程用户不同

const { app } = sdk.import('@/models/App')
console.log(app.current.project.current.user)

发送请求

详见 models/Request

const { Request } = sdk.import('@/models/Request')
Request.post('url', { data })

如何只显示红色选中区域效果

需通过引入不同的组件来进行组装

新建 Pages.vue

<template>
<main
class="pages"
v-track:page="{
moduleType: '标准模块',
moduleCode: '自定义画面',
pageCode: '画面编辑',
}"
>
<Sidebar ref="sidebar"></Sidebar>
<Editor @hightLightPages="hightLightPages"></Editor>
</main>
</template>
<script setup lang="ts">
import { ref } from 'vue'
// 侧边栏
const Sidebar = sdk.import('@/views/Project/Pages/Sidebar/Sidebar.vue')
// 编辑区
const Editor = sdk.import('@/views/Project/Pages/Editor/Editor.vue')
const sidebar = ref()
const hightLightPages = () => {
sidebar.value.hightLight(true)
}
</script>
<style lang="scss" scoped>
.pages {
display: flex;
width: 100%;
height: 100%;
background: #101010;
}
</style>

选择指定模块拼接页面

例如这里不想将页面给添加到页面中,只显示如下图所示内容:

新建文件:Siderbar.vue

// Siderbar.vue
<template>
<aside class="sidebar" :class="{ 'active-page': isHightLight }">
<!-- 对象列表 -->
<CanvasNodeList class="CanvasNodeList"> </CanvasNodeList>
</aside>
</template>
<script setup lang="ts">
import { ref } from 'vue' // 对象列表
const CanvasNodeList = sdk.import(
'@/views/Project/Pages/Sidebar/CanvasNodeList/CanvasNodeList.vue'
)
// 高亮
const isHightLight = ref<boolean>(false)
const hightLight = (isActive: boolean) => {
isHightLight.value = isActive
if (isActive) {
setTimeout(() => {
isHightLight.value = false
}, 1500)
}
}
// 暴露出去,供父组件掉用
defineExpose({ hightLight })
</script>
<style lang="scss" scoped>
.sidebar {
flex: none;
width: 230px;
height: 100%;
background: #202020;
& > .CanvasNodeList,
& > .PageList {
width: 100%;
height: 50%;
}
}
.active-page {
border: 1px solid #3d6eff;
background: #252d46;
}
</style>

重新将改造后的 Siderbar.vue 引入到案例一中的 Pages.vue 中,即可实现效果

屏蔽工具栏多语言

通过 css 实现

.editor .toolbar .operation-btn:nth-last-child(2){  display: none;}

如何禁用事件方法和类型和新增事件方法或覆盖

import sdk from 'syc-cms'
import 'syc-cms/sdk/style.css'
const {
PageManagerBlock,
ProjectBlock,
CanvasNodeBlock,
MethodBlock,
ArgumentBlock,
} = sdk.import('@/models/Block.ts')
{
PageManagerBlock: 页面管理器对象块(目标)
ProjectBlock: 系统对象块(目标)
CanvasNodeBlock: 组件对象块(目标)
MethodBlock: 方法块(动作)
ArgumentBlock: 参数块(动作配置)}

禁用事件方法:

PageManagerBlock.methodList.splice(index, 1) // index为想要禁用事件方法的索引

禁用事件类型:

PageManagerBlock.eventList.splice(index, 1) // index为想要禁用事件类型的索引

新增事件方法:

每个动作都是一个 MethodBlock 实例,并可以通过 ArgumentBlock 实例进行配置。如果 arguments 数组为空,则该动作无需配置;如果 arguments 数组不为空,则每个 ArgumentBlock 实例表示一个配置项,用于指定不同的参数值。

PageManagerBlock.methodList.push(
new MethodBlock({
method: 'exportCurrentPage',
name: '导出画面',
arguments: [
new ArgumentBlock({
name: '目标页面',
view: ArgumentBlock.views.currentPage,
// options: exportData.exportTypeList1.map((e: any) => ({ ...e, value: `"${e.value}"` })),
}),
new ArgumentBlock({
name: '格式',
view: ArgumentBlock.views.radio,
options: exportData.exportTypeList1.map((e: any) => ({
...e,
value: `"${e.value}"`,
})),
}),
new ArgumentBlock({
name: '文件命名',
type: ArgumentBlock.types.string,
expression: '""',
}),
new ArgumentBlock({
name: '纸张大小',
view: ArgumentBlock.views.select,
options: paperTypeList().map((e: any) => ({
...e,
value: `"${e.value}"`,
})),
}),
new ArgumentBlock({
name: '布局',
view: ArgumentBlock.views.radio,
options: exportData.layoutList.map((e: any) => ({
...e,
value: `"${e.value}"`,
})),
}),
new ArgumentBlock({
name: '保存路径',
type: ArgumentBlock.types.string,
expression: '""',
}),
],
})
)

覆盖事件方法:

PageManagerBlock.methodList[index] = new MethodBlock({
method: 'reloadRoute',
name: '重载画面',
arguments: [],
})

弹窗替换

详见 models/Dialog

自定义页面保存逻辑

const { Page } = sdk.import('@/models/Page')
Page.prototype.save = function () {
// 当前页面的文档数据
console.log(this.document)
}

使用页面渲染器

<template>
<Viewer :mode="app.mode" :document="document" ></Viewer>
</template>
<script setup lang="ts">
const { app } = sdk.import('@/models/App')
const { Viewer } = sdk.import('@/views/Project/Pages/Viewer/Viewer.vue')
const document = app.current.project.current.page.document
</script>

...

注意

iconfont

cms 使用了 iconfont , css 类名为 .iconfont ,如果需要使用额外的 iconfont 图标库,则 css 类名不能再命名为 .iconfont

版本升级

版本升级会保持外部组件的兼容,功能集成则尽可能保持兼容但仍可能需手动修改小部分使用代码

示例版本 x

models/X

class X

newMethod()

views/.../X.vue

新增

views/path1/Y.vue

移至 views/path2/Y.vue

以下为版本差异部分的文档

2.0.2

起始版本

2.0.3

models/Widget

props

新建 CanvasNode 时作为 canvasNode 的默认 props