3.5.6.3 布局的配置

布局是将页面拆分成一个一个的小单元,按照上下中左右进行排列。

前沿

在前端领域中,布局可以分为三大块「Float、Flex、Grid 」,Float可以说的上是上古时期的布局了,如今市面还是很少见的,除了一些古老的网站。

目前,平台主要支持通过配置XML上面的cols和span来进行布局。平台也同样支持自由布局,合理的使用row、col、containers和container四个布局容器相关组件,将可以实现各种类型的布局样式,换句话说,平台实现的自由布局功能是Flex和Grid的结合体。

这里主要是讲解Flex和Grid布局,以及目前新的模板布局实现的思路。

Flex布局

Flex布局采用的是一维布局,那么什么是一维布局呢,所谓的一维布局就是只有一个方向、没有体积、面积,比如一条直线。它适合做局部布局,就像我们原来的顶部菜单、面包屑导航,以及现在的主视图字段配置。

image.png

图3-5-6-19 Flex布局示意

image.png

图3-5-6-20 Flex布局示意

image.png

图3-5-6-21 Flex布局示意

从上图可以看看出,Flex布局只能在X、Y轴进行转换,它无法对上下左右四个方向同时处理,因为它没“面积”的概念。所以它最适合做局部布局。

优点

image.png

图3-5-6-22 Flex兼容性

Flex的兼容性,可以看得出来,目前主流的浏览器都支持该属性。所以Flex兼容性强,如果你想对局部做布局处理,Flex是最好选择。

缺陷

刚刚也提到了,用户想要的布局是千奇百怪的,如果他想要的布局在现有的功能中无法实现怎么办?让用户放弃?还是说服他使用现在的布局。

Grid布局

Grid布局系统采用的是二维布局,二维布局有四个方向:上、下、左、右,它只有面积没有体积,比如一张纸、网格。

Grid布局
<div id="grid-container-one">
  <div class="one-1">Grid Item 1</div>
  <div>Grid Item 2</div>
  <div>Grid Item 3</div>
  <div>Grid Item 4</div>
  <div>Grid Item 5</div>
  <div class="one-6">Grid Item 6</div>
</div>

<div id="grid-container-two">
  <div class="tow-1">Grid Item 1</div>
  <div class="tow-2">Grid Item 2</div>
  <div>Grid Item 3</div>
  <div>Grid Item 4</div>
  <div>Grid Item 5</div>
  <div>Grid Item 6</div>
</div>

<div id="grid-container-three">
  <div>Grid Item 1</div>
  <div>Grid Item 2</div>
  <div class="grid">Grid Item 3</div>
  <div class="grid-column">Grid Item 4</div>
  <div>Grid Item 5</div>
  <div>Grid Item 6</div>
  <div>Grid Item 7</div>
  <div class="grid-column">Grid Item 8</div>
</div>
HTML CSSResult Skip Results Iframe
EDIT ON
* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  line-height: 1.5;
  font-weight: bold;
  text-align: center;
}

#grid-container-one{
  background-color: black;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(2, 50px);
  gap: 10px;
  border: solid black 2px;
  margin-bottom: 20px;
  color: salmon;
}

#grid-container-one div {
  border: solid white 2px;
  padding: 10px;

}

#grid-container-one .one-1 {
    grid-area: span 1/span 3;
    text-aligin: center
}

#grid-container-one .one-6 {
    grid-column: 3 /4;
}

#grid-container-two{
  background-color: CADETBLUE;
  display: grid;
  grid-template-columns: 15% repeat(2, 1fr);
  grid-template-rows: 100px;
  text-shadow: 1px 1px 3px black;
  margin-bottom: 20px;
  color: salmon;
}

.tow-1 {
  grid-area: span 3 / span 1
}
.tow-2 {
  grid-area: span 1 / span 2
}

#grid-container-two div{
  border: solid white 2px;
  padding: 10px;
}

#grid-container-three{
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: 25%;
  grid-auto-rows: 200px; 
  grid-auto-columns: 100px;
  gap: 2px;
  color: black;
  text-decoration: underline;
  margin-bottom: 2%;
}

#grid-container-three div{
  background-color: salmon;
  border: solid black 5px;
  padding: 10px;
}

.grid-column{
  grid-column: 5 / 7;
}

.grid{
  grid-row: 1 /1;
  grid-column: 4 / 5;
}

.grid-container-inline{
  display: inline-grid;
  grid-template-columns: repeat(2, 200px);
  grid-template-rows: 100px 100px;
  gap: 2px;
  margin-bottom: 20px;
}

.grid-container-inline div{
  padding: 35px;
  border: solid black 2px;
  background-color: PINK;
}

Resources1× 0.5× 0.25×Rerun

3.5.6.3 布局的配置

图3-5-6-23 Grid布局示意

从上面的代码可以看出,Grid天生的支持整体布局,它甚至可以移行换位,它的强大之处可以颠覆你对布局的认知。

缺陷

虽然Grid很强大,但是它有一个致命的缺陷,那就是兼容性。

image.png

图3-5-6-24 Grid兼容性

从上图可以看出,IE10以下、Chrome56以下、Firefox51以下等等都不支持该属性。

平台布局

名词解释

-布局容器相关组件:rowcolcontainerscontainer这四个组件的统称。

-基础布局属性:包括colscolSpanspanoffset

概述

一般的,我们对大多数组件提供了基本的布局属性配置,包括:

  • cols:将内容区中的每行拆分的列数;当前元素未配置该属性时,将取离当前元素最近父元素属性。默认:1
  • colSpan:当前元素相对于父元素在每行中所占列比例;优先于span。默认:FULL
    • FULL:1
    • HALF:1/2
    • THIRD:1/3
    • TWO_THIRDS:2/3
    • QUARTER:1/4
    • THREE_QUARTERS:3/4
  • span:当前元素相对于父元素在每行中所占列数。默认:cols
  • offset:当前元素相对于原所在列的偏移列数。

我们规定了默认栅格数为24,基础布局属性均是相对于默认栅格数而言的。

在使用基础布局属性时,请尽可能保证公式 (24 / cols) * span 以及以下列举的公式,其计算结果为整数,否则可能出现不符合预期的结果。

在使用colSpan时,span的计算公式为:span = cols * colSpan

在使用offset时,offset的计算公式为:offset = (24 / cols) * offset

平台内置组件

下面列举了平台内置组件在FormDetail视图中使用时所支持的布局相关属性,包括可能影响部分区域显隐的相关属性。

表头说明:

  • tag:xml配置标签
  • widget:组件名称;xml属性;多个值属于别称。如:widget="form"
  • 配置项:xml属性名称。
  • 可选值:声明支持的配置项属性类型,不可识别或不可解析时将采用默认值。
  • 作用:对配置项的简单描述,部分布局属性在上方进行了描述,不再赘述。
tag widget 配置项 可选值 默认值 作用
view cols number 1
element form cols number 1
colSpan enum FULL
span number cols
offset number
detail cols number 1
colSpan enum FULL
span number cols
offset number
DateTimeRangePicker colSpan enum FULL
span number cols
offset number
DateRangePicker colSpan enum FULL
span number cols
offset number
TimeRangePicker colSpan enum FULL
span number cols
offset number
colSpan enum FULL
YearRangePicker span number cols
offset number
field 任意 colSpan enum FULL
span number cols
offset number
pack fieldset/group cols number 1
colSpan enum FULL
span number cols
offset number
title string 分组 标题;空字符串或不填,则隐藏标题区;
tabs cols number 1
colSpan enum FULL
span number cols
offset number
tab cols number 1
title string 选项页 标题;必填;空字符串或不填则显示默认值;
row cols number 1
align top/middle/bottom 垂直对齐方式
justify start/end/center/space-around/space-between 水平对齐方式
gutter number,number?示例:24 = 24,2412,12 24,24 水平/垂直间距
wrap boolean true 是否允许换行
col cols number 1
colSpan enum FULL
span number cols
offset number 偏移单元格数
mode/widthType manual/full manual 列模式;手动/自动填充;使用自动填充时,将忽略span、offset属性;
containers cols number 1
align top/middle/bottom 垂直对齐方式
justify start/end/center/space-around/space-between 水平对齐方式
gutter number,number?示例:24 = 24,2412,12 0,24 水平/垂直间距
wrap boolean true 是否允许换行
container cols number 1
colSpan enum FULL
span number cols
offset number 偏移单元格数
align top/middle/bottom 垂直对齐方式
justify start/end/center/space-around/space-between 水平对齐方式
gutter number,number?示例:24 = 24,2412,12 0,24 水平/垂直间距
wrap boolean true 是否允许换行
mode/widthType manual/full full 列模式;手动/自动填充;使用自动填充时,将忽略span、offset属性;

表3-5-6-11 平台内置组件

基础布局

    基础布局提供了在不使用任何布局容器相关组件的情况下,仅使用cols、span、offset这三个属性控制行列的布局能力。

    其本质上是flex布局的扩展,但依旧无法脱离flex布局本身的限制,即元素始终是自上而下、自左向右紧凑的。

    下面将使用fieldset和tabs/tab组件来介绍各个属性在实际场景中的使用。

示例1:默认撑满一行

<pack widget="fieldset" title="示例1">
    <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
    <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
</pack>

图3-5-6-25 示例1:默认撑满一行

结果展示

image.png

图3-5-6-26 示例效果

示例2:一行两列:cols=2; colSpan=HALF/span=1

<pack widget="fieldset" title="示例2" cols="2">
    <field data="code" widget="Input" colSpan="HALF" label="编码" placeholder="请输入" required="true" />
    <field data="name" widget="Input" colSpan="HALF" label="名称" placeholder="请输入" required="true" />
</pack>
------------------------------ 或 ------------------------------
<pack widget="fieldset" title="示例2" cols="2">
    <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    <field data="name" widget="Input" span="1" label="名称" placeholder="请输入" required="true" />
</pack>

图3-5-6-27 示例2代码

结果展示

image.png

图3-5-6-28 示例效果

示例3:使用offset实现中间空一个字段空间的布局

<pack widget="fieldset" title="示例3" cols="3">
    <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    <field data="name" widget="Input" span="1" offset="1" label="名称" placeholder="请输入" required="true" />
</pack>

PS:offset的作用有限,offset最优实践的前提是在同一行中进行偏移,要实现特殊布局功能,请使用自由布局相关布局能力。

图3-5-6-29 使用offset实现中间空一个字段空间的布局

结果展示

image.png

图3-5-6-30 示例效果

示例4:属性cols就近取值

<!-- 所有tab将使用cols="2"属性 -->
<pack widget="tabs" cols="2">
    <pack widget="tab" title="示例4-1">
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    </pack>
    <pack widget="tab" title="示例4-2">
        <field data="name" widget="Input" span="1" label="名称" placeholder="请输入" required="true" />
    </pack>
</pack>

图3-5-6-31 示例4:属性cols就近取值

结果展示

image.png

图3-5-6-32 示例效果

image.png

图3-5-6-33 示例效果

<!-- 所有tab将使用cols="2"属性 -->
<pack widget="tabs" cols="2">
    <!-- 特指该tab使用cols="1"属性,其他tab继续使用tabs配置的cols="2"属性 -->
    <pack widget="tab" title="示例4-1" cols="1">
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    </pack>
    <pack widget="tab" title="示例4-2">
        <field data="name" widget="Input" span="1" label="名称" placeholder="请输入" required="true" />
    </pack>
</pack>

图3-5-6-34 实例4:tab属性生效

结果展示

image.png

图3-5-6-35 示例效果

image.png

图3-5-6-36 示例效果

自由布局

自由布局提供了无法通过基础布局能力实现的其他布局能力,总的来说,自由布局是对grid布局和flex布局的结合,它既拥有grid布局对页面进行单元格拆/合的能力,在每个单元格中,使用flex布局进行紧凑排列。

下面将使用fieldset组件介绍各个属性在实际场景中的使用。

组件组合

row/col:两个组件共同形成行和列,在一行中拆分成24个栅格,每个列的跨度不超过24。当一行中,所有列的跨度和超过24时,将会自动换行。

containers/row/container:三个组件共同形成一个二维网格,以此实现grid布局的基本能力。每个单元格(container)中使用flex布局。

PS:以下示例为了体现布局效果,可能会出现重复字段定义,业务上在使用时需要避免这种定义。

示例1:仅使用1/2左侧空间

小贴士:在使用row和col组合时,如果在一个col中有且仅有一个子元素,则col可以缺省。col相关属性可以配置在该子元素上。

<pack widget="fieldset" title="示例1">
    <pack widget="row" cols="2">
        <!-- 此处显式定义col组件,field标签上的基础布局属性将失效 -->
        <pack widget="col" span="1">
            <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
        </pack>
    </pack>
    <pack widget="row" cols="2">
        <pack widget="col" span="1">
            <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
        </pack>
    </pack>
</pack>
------------------------------ 或 ------------------------------
<pack widget="fieldset" title="示例1">
    <pack widget="row" cols="2">
        <!-- 此处缺省col组件,field标签上的基础布局属性可生效 -->
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    </pack>
    <pack widget="row" cols="2">
        <field data="name" widget="Input" span="1" label="名称" placeholder="请输入" required="true" />
    </pack>
</pack>

图3-5-6-37 仅使用1/2左侧空间

结果展示

image.png

图3-5-6-38 示例效果

示例2:使用布局容器实现中间空一个字段空间的布局

<pack widget="fieldset" title="示例2">
    <pack widget="containers">
        <pack widget="row">
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container"></pack>
            <pack widget="container">
                <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
            </pack>
        </pack>
    </pack>
</pack>

图3-5-6-39 使用布局容器实现中间空一个字段空间的布局

结果展示

image.png

图3-5-6-40 示例效果

示例3:一行5列(基础布局属性公式无法计算出整数的情况)

<pack widget="fieldset" title="示例3">
    <pack widget="containers">
        <pack widget="row">
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
                <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
              <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
              <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
              <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
        </pack>
    </pack>
</pack>

图3-5-6-41 一行5列(基础布局属性公式无法计算出整数的情况)

结果展示

image.png

图3-5-6-42 示例效果

示例4:共2行,其中1行未3列,另1行为2列

该示例可以使用任何一种组件组合都可以实现,结果一致。

<!-- 使用containers/row/container -->
<pack widget="fieldset" title="示例4">
    <pack widget="containers">
        <pack widget="row">
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
                <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
        </pack>
        <pack widget="row">
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
        </pack>
    </pack>
</pack>
------------------------------ 或 ------------------------------
<!-- 使用row/col,其中col缺省 -->
<pack widget="fieldset" title="示例4">
    <pack widget="row" cols="3">
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
        <field data="name" widget="Input" span="1" label="名称" placeholder="请输入" required="true" />
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    </pack>
    <pack widget="row" cols="2">
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
        <field data="code" widget="Input" span="1" label="编码" placeholder="请输入" required="true" />
    </pack>
</pack>

图3-5-6-43 示例为共2行,其中1行未3列,另1行为2列

结果展示

image.png

图3-5-6-44 示例效果

示例5:布局容器的垂直居中

左侧容器高度被子元素撑开,右侧容器在垂直方向居中

<pack widget="fieldset" title="示例5">
    <pack widget="containers">
        <pack widget="row">
            <pack widget="container">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
                <field data="name" widget="Input" label="名称" placeholder="请输入" required="true" />
            </pack>
            <pack widget="container" align="middle">
                <field data="code" widget="Input" label="编码" placeholder="请输入" required="true" />
            </pack>
        </pack>
    </pack>
</pack>

图3-5-6-45 设置布局容器的垂直居中

结果展示

image.png

图3-5-6-46 示例效果

举例

这里拿PetTalent举例,仿造教程上面效果,除了例子中的效果,自己可以做更多的尝试

Step1 修改PetTalent的form视图如下

给creater字段增加一个属性配置 offset="1"

<field data="creater" widget="SSConstructSelect" offset="1" submitFields="creater,name" responseFields="name"/>

图3-5-6-47 给creater字段增加一个属性配置 offset="1"

Step2 重启看效果

image.png

图3-5-6-48 示例效果

Step3 修改PetTalent的form视图如下

给【基础信息】增加一个属性cols="4",给name字段增加一个属性span="2",给creater和nick字段增加一个属性span="1":

<pack widget="group" title="基础信息" cols="4">
    <field invisible="true" data="id" label="ID" readonly="true"/>
    <field data="name" label="达人" required ="true" span="2"/>
    <field data="nick" compute="activeRecord.name" readonly = "true" span="1"/>
    <field data="creater" widget="SSConstructSelect"  submitFields="creater,name" responseFields="name" span="1"/>
    <field data="dataStatus" label="数据状态" >
        <options>
            <!-- option name="DRAFT" displayName="草稿" value="DRAFT" state="ACTIVE"/ -->
            <option name="NOT_ENABLED" displayName="未启用" value="NOT_ENABLED" state="ACTIVE"/>
            <option name="ENABLED" displayName="已启用" value="ENABLED" state="ACTIVE"/>
            <option name="DISABLED" displayName="已禁用" value="DISABLED" state="ACTIVE"/>
        </options>
    </field>
    <field invisible="true" data="createDate" label="创建时间" readonly="true"/>
    <field invisible="true" data="writeDate" label="更新时间" readonly="true"/>
    <field data="createUid" label="创建人id"/>
    <field data="writeUid" label="更新人id"/>
</pack>

图3-5-6-49 修改PetTalent的form视图

Step4 重启看效果

image.png

图3-5-6-50 示例效果

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9262.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

(0)
史, 昂的头像史, 昂数式管理员
上一篇 2024年5月23日 am9:16
下一篇 2024年5月23日 am9:18

相关推荐

  • 3.6 问题排查工具

    当前端发起对应用的访问时,如果出现错误,那么我们可以通过以下方式进行简易排查,如果排查不出来,则也可以把排查工具给出的信息发送给Oinone官方售后进行进一步分析。本文将通过模拟异常信息,来介绍排查工具,提供了哪些辅助信息帮我们来快速定位问题。 排查工具基础介绍 通过前端页面的 /debug 路由路径访问调试工具的页面,假设我们的前端页面访问地址为http://localhost:6800,那么我们的排查工具请求路径就是 http://localhost:6800/debug排查工具可以帮我们排查前端页面元数据异常和后端接口的异常 排查前端页面元数据 将问题页面浏览器地址栏内 page 后的部分复制到调试工具的 debug 路由后重新发起请求,如图可以看到调试工具展示的信息,可以根据这些信息排查问题。 排查后端接口 后端接口出现问题后,打开(在原页面)浏览器的调试工具,切换到“网络”的标签页,在左侧的历史请求列表中找到需要调试的请求,右键会弹出菜单,点击菜单中的 “复制”,再次展开该菜单,点击二级菜单中的“以 fetch 格式复制”,这样可以复制到调试所需要的信息 2.复制调试信息到“接口调试”标签页内的文本框内,点击“发起请求”按钮获取调试结果 我们可以看到页面展示了该接口的各种调试信息,我们可以据此排查问题。 场景化的排查思路 业务代码中存在代码bug 报错后发起调试请求,我们可以看到,调试工具直接给出了异常抛出的具体代码所在位置,此时再切换到“全部堆栈”下,可以看到是业务类的233行导致的空指针异常,查看代码后分析可得是data.getName().eqauls方法在调用前未做条件判断补全该判断后代码可以正常执行 业务代码中没有直接的错误,异常在平台代码中抛出 报错后发起调试请求可以看到异常不在业务代码内再切换到“全部堆栈”,可以看到具体异常信息,提示core_demo_item表出现了重复的主键,该表是DemoItem模型的我们还可以切换到“sql调试”的标签页,可以看到出错的具体sql语句经过分析可以得知是240行的data.create()�重复创建数据导致的。 三、排查工具无法定位怎么办 当我们通过排查工具还是没有定位到问题的时候,可以通过调试页面的“下载全部调试数据”和“下载调试数据”按钮将调试信息的数据发送给官方售后人员帮助我们定位排查问题。 点击页面最顶部的“下载全部调试数据”按钮,可以下载页面调试数据和接口调试数据点击“调试接口”标签页内的“下载调试数据”按钮,可以下载接口调试数据 四、排查工具细节

    2024年5月23日
    1.6K00
  • 7.1 设计器总览

    设计器转为非专业研发设计,在Oinone3.0版本中已经完成元数据完整在线化,真正做到低无一体。对于设计器的定位我们开篇就介绍过,它是LCDP的产品化呈现,是冰山露在外面大家看得到的,核心还是在LCDP本身。我们先目睹下设计器的一些产品页面,如您有想体验,可以在Oinone官网注册 模型设计器 Oinone以模型为驱动,当有模型、数据字典、数据编码等设计功能,我们就可以完整地定义产品数据模型,模型设计器整体呈现区别于普通ER图,以当前模型为核心视角展开,可以点击关联模型切换主视角。这样的好处在于突出当前设计,聚焦设计本身。同时模型上预留了几个核心入口如:分类管理、继承拓扑图、页面设计、逻辑设计等。另外我们在体验上区分了专家模式和经典模式,顾名思义,专家模式的功能会更加丰富,对专业知识的要求也会更高。专家模式下一般会增加一些跟业务无关的配置如:索引设置等调优行为 逻辑设计器 从图灵完备的角度上说,要支持功能越完备,使用越复杂。我们优先从图灵完备的角度出发,所以我们第一版逻辑设计器相对比较复杂,第二版本规划中会类似模型设计器推出专家版和经典版。 界面设计器 界面设计器第一版会先支撑后端页面在线自定义,后边将陆续推出前端页面、多端能力。为了支持多端和2C页面的设计,我们对前后端协议做了比较大的改造。目前设计器已经支持完全基于V3的前后端协议。 数据可视化 数据可视化支持从内部系统模型获取数据内容后,根据业务需求自定义图表,目的是为企业提供更高效的数据分析工具。 与市场同类产品相比,我们的数据可视化产品:不需要前置维护数据源、进行数据转换;可智取业务系统模型,系统自动解析选择的模型、接口、表格中的字段后进行数据分析;降低对数据分析人员研发能力要求的同时,也提升了数据分析的效率。 流程设计器 Oinone流程设计器为业务流程和审批流程提供了可自动执行的流程模型:通过定义流转过程中的各个动作、规则,以此实现流程自动化。在Oinone流程设计器中,流程可以跨应用设计,不同应用的模型之间可以通过同一流程执行。

    2024年5月23日
    1.5K00
  • 2.1 数字化时代软件业的另一个本质变化

    随着企业从信息化向数字化转变,软件公司提供的产品也由传统的企业管理软件向企业商业支撑软件发展。这一变化带来了许多技术上的挑战和机遇。在之前的章节中,我们提到企业的视角已经从内部管理转向业务在线和生态在线协同,这也带来了一系列新的需求。但是,我们常常会忽视这一变化所带来的对系统要求的变化。在本章中,我们将探讨这些技术上的变化,以及这些变化所带来的机遇和挑战。 图2-1 从信息化到数字化软件本质变化 在信息化时代,企业的业务围绕着内部管理效率展开,借鉴国外优秀的管理经验,企业将其管理流程固化下来,典型的例子是ERP项目。这类项目上线后往往长期稳定,不轻易更改,因此信息化时代软件的技术流派侧重于通过模型对业务进行全面支持。例如,SAP具有丰富的配置能力,将已有企业管理思想抽象到极致。其功能基本上可以通过配置来实现,因此其模型设计特别复杂。但是,我们也应该清楚地了解到,配置是面向已知问题的。在数字化时代,创新和业务迭代速度非常快,这种方法可能就不太适合了。我们知道,模型抽象是在设计时具有前瞻性的,一旦不适合,修改起来就会异常困难。 随着数字化时代的到来,企业主的关注点已经从单一企业内部管理转变为了围绕企业上下游价值链的协同展开。这种变化给企业信息化系统提出了更高的要求,例如业务需求的响应速度、系统性能和用户体验等方面。现在,企业对软件不仅是管理需求的承载,更是业务在线化的承载。传统的重模型设计软件模式已经不再适用,因为业务本身不断创新和变化。因此,数字化时代需要新的软件技术流派,这种流派必须是轻模型加上低代码技术的结合体。通过模型抽象80%的通用场景,剩余的20%个性化需求可以通过技术手段来完成。这样的设计可以让每家企业的研发人员轻松理解模型,而不像ERP模型那样异常复杂,无法进行修改。此外,配合低代码技术可以快速研发和上线。如果说配置化是面向已知问题的,那么低代码就是面向未知问题设计的。虽然低代码的概念可以追溯到上个世纪80年代,当时是为了满足企业内部部门之间有协同需求,但又没有专业软件支撑,定制化开发又不划算的辅助场景。但现在它的核心原因是企业数字化的核心场景不稳定,变化很快,每家企业都有强烈的个性化需求。因此,低代码成为解决这些问题的核心手段,数字化时代的低代码需要具备处理复杂场景的能力,而不仅仅是围绕着内部管理展开。 企业在数字化转型的过程中需要考虑到不仅是成熟的全链路业务解决方案,还要应对数字化场景的快速变化和持续创新的需求。为此,Oinone打造了一站式低代码商业支撑平台,从业务与技术两个维度来帮助企业建立开放、链接、安全的数字化平台。这将在水平和垂直两个维度上全面推动企业数字化转型。 另外,低代码的另一个好处是完成了软件本身的数字化建设。通过基于元数据设计,元数据成为软件中数据、逻辑和交互的数据,软件结合AI可以有更多的创造可能。想象一下,AI了解软件的元数据后可以自我运作,人在极少情况下才需要参与,人机交互也会发生大的改变。未来的软件交互不再需要研发提前预设,而是能够实现用户所需即所呈现的效果。作为一家帮助企业进行数字化转型的软件公司,请问您的数字化转型是否已经完成呢?

    2024年5月23日
    1.3K00
  • 流程

    1. 流程介绍 日常工作和生活中到处都存在各种各样的流程,例如业务开展中的产品研发流程、产品制作流程、订单发货流程等,也有管控分险的费用报销流程、员工请假审批流程、项目立项流程等。流程设计器可以帮助公司实现流程的数字化,规范流程操作,减少人工操作并留存痕迹,提高工作效率和安全性。 2. 流程的组成 流程设计器主要包含基本操作和流程设计两个部分。前者包含了流程的新增、删除、复制、停用/启用、编辑、搜索。后者包含单一流程的基础信息修改、流程设计、参数配置、保存、发布。 2.1 流程的基本操作 流程页面有两种显示方式,默认为平铺显示的模式,可以点击切换为列表详情显示的模式。 2.1.1 新增 平铺显示和列表详情模式下点击左上角的创建按钮即可新增一个流程,点击后进入流程设计页面,流程名默认为“未命名流程”,可自行修改。 2.1.2 删除 遇到流程创建有误,没有使用过且将来也不会使用该流程,可以删除流程。需要注意的是,删除流程的前提是该流程已停用,并且该流程从未执行过。 2.1.3 复制 遇到流程节点动作相似度较高的情况可以使用复制流程的功能,点击按钮后生成一个“原流程名-复制”的流程,并且进入新流程的流程设计界面。 2.1.4 停用/启用 流程需要更新或暂时不用时可以使用停用功能。流程停用后将不会执行流程中的动作,正在执行中的流程不受停用影响,会正常执行直到流程结束。 点击启用按钮,流程恢复启用状态,可正常触发。 2.1.5 编辑 点击编辑进入该流程的设计页面。 2.1.6 搜索 页面最上方的是搜索区,可以按照流程名称、触发方式、启用状态、更新状态进行筛选搜素,点击重置按钮修改搜索条件。

    2024年1月20日
    1.6K00
  • 3.3.4 模型的继承

    在我们的很多项目中,客户都是有个性化需求的,就像我们不能找到两件一模一样的东西,何况是企业的经营与管理思路,多少都会有差异。常规的方式只能去修改标准产品的逻辑来适配客户的需求。导致后续标品维护非常困难。而在介绍完这节以后是不是让你更加清晰认知到我们2.4.2【oinone独特性之每一个需求都可以是一个模块】一文中所表达的特性带来的好处呢? 一、继承方式 继承方式可以分为五种: 抽象基类ABSTRACT,只保存不希望为每个子模型重复键入的信息的模型,抽象基类模型不生成数据表存储数据,只供其他模型继承模型可继承域使用,抽象基类可以继承抽象基类。 扩展继承EXTENDS,子模型与父模型的数据表相同,子模型继承父模型的字段与函数。存储模型之间的继承默认为扩展继承。 多表继承MULTI_TABLE,父模型不变,子模型获得父模型的可继承域生成新的模型;父子模型不同表,子模型会建立与父模型的一对一关联关系字段(而不是交叉表),使用主键关联,同时子模型会通过一对一关联关系引用父模型的所有字段。多表继承父模型需要使用@Model.MultiTable来标识,子模型需要使用@Model.MultiTableInherited来标识。 代理继承PROXY,为原始模型创建代理,可以增删改查代理模型的实体数据,就像使用原始(非代理)模型一样。不同之处在于代理继承并不关注更改字段,可以更改代理中的元信息、函数和动作,而无需更改原始内容。一个代理模型必须仅能继承一个非抽象模型类。一个代理模型可以继承任意数量的没有定义任何模型字段的抽象模型类。一个代理模型也可以继承任意数量继承相同父类的代理模型。 临时继承TRANSIENT,将父模型作为传输模型使用,并可以添加传输字段。 二、继承约束 通用约束 对于扩展继承,查询的时候,父模型只能查询到父模型字段的数据,子模型可以查询出父模型及子模型的字段数据(因为派生关系所以子模型复刻了一份父模型的字段到子模型中)。 系统不会为抽象基类创建实际的数据库表,它们也没有默认的数据管理器,不能被实例化也无法直接保存,它们就是用来被继承的。抽象基类完全就是用来保存子模型们共有的内容部分,达到重用的目的。当它们被继承时,它们的字段会全部复制到子模型中。 系统不支持非jar包依赖模型的继承。 多表继承具有阻断效应,子模型无法继承多表继承父模型的存储父模型的字段,需要使用@Model.Advanced注解的inherited属性显示声明继承父模型的父模型。但是可以继承多表继承父模型的抽象父模型的字段。 可以使用@Model.Advanced的unInheritedFields和unInheritedFunctions属性设置不从父类继承的字段和函数。 跨模块继承约束 如果模型间的继承是跨模块继承,应该与模型所属模块建立依赖关系;如果模块间有互斥关系,则不允许建立模块依赖关系,同理模型间也不允许存在继承关系。 跨模块代理继承,对代理模型的非inJvm函数调用将使用远程调用方式;跨模块扩展(同表)继承将使用本地调用方式,如果是数据管理器函数,将直连数据源。 模型类型与继承约束 抽象模型可继承:抽象模型(Abstract) 临时模型可继承:抽象模型(Abstract)、传输模型(Transient) 存储模型可继承:抽象模型(Abstract)、存储模型(Store)、存储模型(多表,Multi-table Store),不可继承多个Store或Multi-table Store 多表存储模型(父)可继承:同扩展继承 多表存储模型(子)在继承单个Multi-table Store后可继承:抽象模型(Abstract)、存储模型(Store),不可继承多个Store 代理模型可继承: 抽象模型(Abstract),须搭配继承Store、Multi-table Store或Proxy 存储模型(Store),不可继承多个Store或Multi-table Store 存储模型(多表,Multi-table Store),不可继承多个Store或Multi-table Store 代理模型(Proxy),可继承多个Proxy,但多个父Proxy须继承自同一个Store或Multi-table Store,且不能再继承其他Store或Multi-table Store 同名字段以模型自身字段为有效配置,若模型自身不存在该字段,继承字段以第一个加载的字段为有效配置,所以在多重继承的情况下,未避免继承同名父模型字段的不确定性,在自身模型配置同名字段来确定生效配置。 三、继承的使用场景 模型的继承可以继承父模型的元信息、字段、数据管理器和函数 抽象基类 解决公用字段问题 扩展继承 解决开放封闭原则、跨模块扩展等问题 多表继承 解决多型派生类字段差异问题和前端多存储模型组合外观问题 代理继承 解决同一模型在不同场景下的多态问题(一表多态) 临时继承 解决使用现有模型进行数据传输问题 举例,前端多存储模型组合外观问题可通过多表继承的子模型,并一对一关联到关联模型,同时使用排除继承字段去掉不需要继承的字段。子模型通过默认模型管理器提供查询功能给前端,默认查询会查询子模型数据列表并在列表行内根据一对一关系查出关联模型数据合并,关联模型数据展现形态在行内是平铺还是折叠,在详情是分组还是选项卡可以自定义view进行配置 扩展继承 父子同表,模型在所有场景都有一致化的表现,意味着原模型被扩展成了新模型,父子模型的表名一致,模型编码不同,可覆盖父模型的模型管理器、数据排序规则、函数 多表继承 父子多表,父子间有隐式一对一关系,即父子模型都增加了一对一关联关系字段,同时父模型的字段被引用到子模型,且引用字段为只读字段,意味着子模型不可以直接更改父模型的字段值,子模型不继承父模型的模型管理器、数据排序规则、函数,子模型拥有自己的默认模型管理器、数据排序规则、函数。多表继承具有阻断效应,子模型无法自动多表继承父模型的存储父模型,需要显式声明多表继承父模型的存储父模型。 代理继承 代理模型继承并可覆盖父模型的模型管理器、数据排序规则、函数,同时可以使用排除继承字段和函数来达到不同场景不同视觉交互的效果。 图3-3-4-1 继承的使用场景 四、抽象基类(举例) 参考前文中3.3.2【模型的类型】一文中关于抽象模型的介绍 五、多表继承(举例) 场景设计如下 图3-3-4-2 多表继承设计场景 Step1 新建宠物品种、宠狗品种和萌猫品种模型 新建宠物品种模型,用@Model.MultiTable(typeField = "kind"),申明为可多表继承父类,typeField指定为kind字段 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.base.IdModel; @Model.MultiTable(typeField = "kind") @Model.model(PetType.MODEL_MODEL) @Model(displayName="品种",labelFields = {"name"}) public class PetType extends IdModel { public static final String MODEL_MODEL="demo.PetType"; @Field(displayName = "品种名") private String name; @Field(displayName = "宠物分类") private String kind; } 图3-3-4-3 多表继承示例代码 新建宠狗品种模型,用@Model.MultiTableInherited(type = PetDogType.KIND_DOG),申明以多表继承模式继承PetType,覆盖kind字段(用defaultValue设置默认值,用invisible = true设置为前端不展示),更多模块元数据以及模型字段元数据配置详见4.1.6【模型之元数据详解】一文 package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; @Model.MultiTableInherited(type = PetDogType.KIND_DOG) @Model.model(PetDogType.MODEL_MODEL) @Model(displayName="宠狗品种",labelFields = {"name"}) public class PetDogType extends PetType { public static final String MODEL_MODEL="demo.PetDogType"; public static final String KIND_DOG="DOG"; @Field(displayName = "宠物分类",defaultValue = PetDogType.KIND_DOG,invisible = true) private String kind; } 图3-3-4-4 多表继承示例代码 新建萌猫品种模型,用@Model.MultiTableInherited(type = PetCatType.KIND_CAT),申明以多表继承模式继承PetType,覆盖kind字段(用defaultValue设置默认值,用invisible = true设置为前端不展示),并新增一个CatShapeEnum枚举类型的字段shape package pro.shushi.pamirs.demo.api.enumeration; import pro.shushi.pamirs.meta.annotation.Dict; import pro.shushi.pamirs.meta.common.enmu.BaseEnum; @Dict(dictionary = CatShapeEnum.DICTIONARY,displayName = "萌猫体型") public class CatShapeEnum extends BaseEnum<CatShapeEnum,Integer>…

    2024年5月23日
    1.5K00

Leave a Reply

登录后才能评论