1.1 Oinone的萌芽

在信息化时代,中国并没有涌现出一家世界知名的软件公司。这是因为像SAP、Oracle、IBM、Salesforce、NetSuite、Odoo等西方巨头所拥有的最佳实践在业务、技术和模式方面,给予了它们在企业信息化建设中高额利润的优势。中国软件业在这个时代的角色是学习和追随者,而最优秀的追随者是金蝶和用友,它们能在国家推行会计电算化的机遇中占据领先地位。但是,追随者始终只是追随者,没有真正的突破。

我自己进入软件行业的经历可以追溯到2015年。当时资本市场非常热门,大家都在创业。我认为这是一个时代的机会,就像国家改革开放一样。于是,我和很多同事一起开始了创业之旅。在数式之前,我加入并创办了三家公司:500mi、数列和端点。整个过程给了我宝贵的经验和启示,帮助我找到了最终想要的方向。

在500mi公司时,我从技术岗位转型为业务经营,起步并不顺利。然而,我从这份经历中获得了一堂重要的课:做自己擅长的事情,有助于渡过创业启动期最艰难的阶段。同时,市场调研为我提供了一个信号:传统企业对于IT的需求正逐渐向互联网靠拢。这个信号像注入了一剂强心剂,激励我继续前行。

2016年,我和三个曾在阿里工作的同事一起创办了一家新公司——数列,我们决定专注于我们最擅长的领域,即软件服务商。在没有任何商务资源的情况下,我们第一年就完成了1000多万的合同,这相较之前是一个非常成功的开端。然而,对于公司未来的发展方向,我们花费了长达大半年的时间进行思考:应该坚持做底层的PaaS还是专注于企业可见的上层应用和业务产品?我倾向于后者。尽管我们持续存在分歧,但凭借着多年的革命友情,最终我们友好地分道扬镳。数列此前的成功让我更加坚信:在数字化时代,软件需求将会有井喷式的增长,数字化软件服务将是未来5-10年的重要方向。而在这个领域,专业的技能将是应对未来不确定性的真正力量。

提到数字化,就不得不提阿里巴巴提出的中台理念。中台理念在15年前被阿里巴巴提出,当时引起了广泛的关注和讨论。企业之所以认同中台理念,是因为他们的核心需求已经从内部转向外部:从关注管理、流程、效率的提升,转向关注外部协同、运营、创新。他们已经不再只担心企业的效率和成本,而是担心自己是否有能力跟上时代的快速变化。现今做生意的渠道已经不再是单一的线下渠道,而是包括淘宝、天猫、京东、拼多多、抖音、快手等多个线上渠道,以及海外市场,这种变化速度非常快。而中台的核心理念是敏捷响应、低成本快速创新,正好解决了企业主的核心焦虑。

企业的视角正在从内部管理向业务在线和生态在线(协同)转变,这种转变带来了一系列新的需求(如下图1-1所示)。这种转变不仅是为了支持现有业务的发展,也为企业未来的业务发展和创新提供了支持,并将变化实时反映到上下游合作伙伴中。

image.png

图1-1 企业视角转变带来一系列新的诉求

在2017年下半年,阿里云收购了端点科技,打算重启阿里软件。那个时候,市场上涌现出一批中台厂商,整个行业也比较混乱,很多人对互联网架构本身的理解不够深入,快速学习拿到阿里云认证后就开始做定制化的中台架构开发,但最终的效果无法达到预期。因此,阿里云和端点科技的联姻是为了弥补阿里云没有向外输出上层应用产品能力的缺陷。多年来,软件市场一直被国外厂商掌控,中国一直缺乏一个强大的本土软件公司。阿里收购端点,承载着无数中国人的软件梦想。在这种背景下,我回到了阿里体系,加入了端点科技。后来,我参与了许多中台项目,深刻地认识到搭建中台技术架构和一些基础能力,为上层应用场景落地并不难。但是,当客户接手扩展中台能力和新的上层应用场景时,效果往往不尽如人意,这并不是中台架构理念的问题,而是因为传统企业客户的IT能力大多较弱,这是一个硬伤。许多文章都在讲述中台战略,长篇大论地描述组织中台、技术中台、业务中台、数据中台,我们不去评论这些方法论的对错,从技术角度回到初衷,我们只关注一个问题:技术是为商业服务的,中台如何快速满足企业业务多变的需求?

我们经历了多个行业的中台建设,每次都向客户强调第一阶段是打好基础,因此需要较长的周期,并且每个项目都需要顶级架构师来把控整体项目。如何找到互联网架构与传统软件良好结合点,降低对组织的要求,实现中台架构的标准化输出?这是我回归阿里后致力于解决的问题。然而,随着阿里云对端点战略发展思路的变化,阿里不再提供SaaS服务,而只愿意做平台被其他企业集成。因此,我离开了端点,并决定把自己的技术思考转化为现实,于是数式科技诞生了。

在数字化时代,无论是业务、技术还是商业模式的最佳实践,都源自中国。中国已经从追随者转变为互联网领域的全面引领者。我们有理由相信,中国一定会崛起一家世界级的软件公司,而Oinone将始终以此为愿景。

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

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

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

相关推荐

  • 文件

    文件应用下包含“导入/导出模版、导入任务、导出任务”三个菜单。其中导入/导出任务菜单比较常用。 导入/导出模版 当前版本会为租户的表格视图自动创建导出模版,此处可进行编辑、查看详情的操作。 导入任务 导入任务可以下载导入文档,点击详情可以查看该条记录的导入结果,任务信息分组中可以查看错误信息。 导出任务 和导入任务一致,导出任务菜单中可以下载导出文档,点击详情可以查看该条记录的导出结果,任务信息分组中可以查看错误信息。

    2024年6月20日
    1.0K00
  • 3.5.6.4 动作的配置

    在3.5.3【Action的类型】一文中,我们介绍Action的几种类型,以及组合动作。 通用配置 配置项 可选值 默认值 作用 name 动作名称 label 显示名称 icon 图标 type primary defaultlink primary 按钮类型样式,支持主要样式、次要样式以及链接样式。 bizStyle defaultsuccesswarningdangerinfo default 按钮业务样式,支持成功(green)、警告(yellow)、危险(red)、信息(grey)四种样式。 invisible truefalse condition false 展示规则,有简单的true/false显隐,也支持复杂的表达式 disabled truefalse condition 根据动作上下文类型进行自动推断 是否禁用自动推断规则:当上下文类型为【单行】时,相当于使用表达式LIST_COUNT(context.activeRecords) != 1当上下文类型为【多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) <= 1当上下文类型为【单行或多行】时,相当于使用表达式LIST_COUNT(context.activeRecords) == 0 disabledTitle string 根据动作上下文类型进行自动推断 禁用悬浮提示 表3-5-6-12 动作通用配置 二次确认配置 二次确认框默认支持两种模式,对话框和气泡框; 对话框 图3-5-6-51 对话框提示 气泡框 图3-5-6-52 气泡框警告 配置项 配置项 可选值 默认值 作用 备注 confirm string 二次确认提示文字 配置后开启二次确认 confirmType POPPER(气泡提示框) MODAL(对话框) POPPER 确认框类型 confirmPosition TM(按钮上方) BM(按钮下方) LM(按钮左侧) RM(按钮右侧) BM 确认框位置 气泡框该配置生效 enterText 确定 确定按钮文字 cancelText 取消 取消按钮文字 表3-5-6-13 配置项 弹出层动作配置(窗口动作ViewAction) 目前平台对于弹出层支持了两种展示形式。弹窗(modal/dialog)和抽屉(drawer) 支持两种配置方式【内嵌视图配置】和【引用已有页面】,内嵌视图配置优先于引用已有页面。 内嵌视图配置 该配置对于弹窗和抽屉均适用。 <action name="窗口动作名称" label="创建"> <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> </action> 图3-5-6-53 内嵌视图配置 引用已有页面配置 该配置对于弹窗和抽屉均适用。 <view model="模型编码" type="form"> <template slot="form" widget="form"> <field data="id" invisible="true" /> <field data="code" label="编码" widget="Input" /> <field data="name" label="名称" widget="Input" /> </template> <template slot="footer"> <action name="$$internal_DialogCancel" label="关闭" type="default" /> <action name="create" label="确定" /> </template> </view> 图3-5-6-54 引用已有页面示例 <action name="窗口动作名称" label="创建" resViewName="$viewName$" /> 图3-5-6-55 引用已有页面 弹窗 当窗口动作的路由方式(target)为dialog时,内嵌视图/引用页面将以弹窗形式展示在页面上。 配置项 配置项 可选值 默认值 作用 title…

    2024年5月23日
    99000
  • 通知类

    1.通知类 1.1 站内信 当流程节点需要向用户发送消息或提示时使用站内信这个节点动作。接收人的选取类似审批节点的审批人,通知内容必填,配置完成,保存即可。 节点触发后,接收人会在全渠道运营平台-工作台-我的消息中查看到站内信。 1.2 邮件 当需要向指定邮箱发送邮件时使用邮件这个节点动作。可直接输入邮箱号,或者按照员工、部门、角色来选择,给接收人登记的邮箱发送邮件,也可以选择模型中的邮箱来发送邮件,若人员重复时只会发送一次邮件。填写主题,填写正文时可以调用当前流程中的一些模型字段的变量。 1.3 短信 发送短信需要在工作流-系统设置-短信模板中创建一个短信模板,阿里云模版新增需要一段时间审核,审核通过后就可以正常使用短信节点。短信的接收人与邮件的操作方式一致,之后选择短信模板,并且确定好变量的对应关系即可。

    2024年6月20日
    1.5K00
  • 4.1.9 函数之元位指令

    元位指令系统是通过给请求上下文的指令位字段作按位与标记来对函数处理下发对应指令的系统。 一、元位指令介绍 元位指令系统是通过给请求上下文的指令位字段作按位与标记来对函数处理下发对应指令的系统。 元位指令系统分为请求上下文指令和数据指令两种。 数据指令 数据指令基本都是系统内核指令。业务开发时用不到这里就不介绍了。前20位都是系统内核预留 请求上下文指令 请求上下文指令:使用session上下文中非持久化META_BIT属性设置指令。 位 指令 指令名 前端默认值 后端默认值 描述 20 builtAction 内建动作 否 否 是否是平台内置定义的服务器动作对应操作:PamirsSession.directive().disableBuiltAction(); PamirsSession.directive().enableBuiltAction(); 21 unlock 失效乐观锁 否 否 系统对带有乐观锁模型默认使用乐观锁对应操作:PamirsSession.directive().enableOptimisticLocker(); PamirsSession.directive().disableOptimisticLocker(); 22 check 数据校验 是 否 系统后端操作默认不进行数据校验,标记后生效数据校验对应操作:PamirsSession.directive().enableCheck(); PamirsSession.directive().disableCheck(); 23 defaultValue 默认值计算 是 否 是否自动填充默认值对应操作:PamirsSession.directive().enableDefaultValue(); PamirsSession.directive().disableDefaultValue(); 24 extPoint 执行扩展点 是 否 前端请求默认执行扩展点,可以标记忽略扩展点。后端编程式调用数据管理器默认不执行扩展点对应操作:PamirsSession.directive().enableExtPoint(); PamirsSession.directive().disableExtPoint(); 25 hook 拦截 是 否 是否进行函数调用拦截对应操作:PamirsSession.directive().enableHook(); PamirsSession.directive().disableHook(); 26 authenticate 鉴权 是 否 系统默认进行权限校验与过滤,标记后使用权限校验对应操作:PamirsSession.directive().sudo(); PamirsSession.directive().disableSudo(); 27 ormColumn ORM字段别名 否 否 系统指令,请勿设置 28 usePkStrategy 使用PK策略 是 否 使用PK是否空作为采用新增还是更新的持久化策略对应操作:PamirsSession.directive().enableUsePkStrategy(); PamirsSession.directive().disableUsePkStrategy(); 29 fromClient 是否客户端调用 是 否 是否客户端(前端)调用对应操作:PamirsSession.directive().enableFromClient(); PamirsSession.directive().disableFromClient(); 30 sync 同步执行函数 否 否 异步执行函数强制使用同步方式执行(仅对Spring Bean有效) 31 ignoreFunManagement 忽略函数管理 否 否 忽略函数管理器处理,防止Spring调用重复拦截对应操作:PamirsSession.directive().enableIgnoreFunManagement(); PamirsSession.directive().disableIgnoreFunManagement(); 表4-1-9-1 请求上下文指令 二、使用指令 普通模式 PamirsSession.directive().disableOptimisticLocker(); try{ 更新逻辑 } finally { PamirsSession.directive().enableOptimisticLocker(); } 图4-1-9-1 普通模式代码示意 批量设置模式 Models.directive().run(() -> {此处添加逻辑}, SystemDirectiveEnum.AUTHENTICATE) 图4-1-9-2 批量设置模式代码示意 三、使用举例 我们在4.1.5【模型之持久层配置】一文中提到过失效乐观锁,我们在这里就尝试下吧。 Step1 修改PetItemInventroyAction 手动失效乐观锁 package pro.shushi.pamirs.demo.core.action; import org.springframework.stereotype.Component; import pro.shushi.pamirs.demo.api.model.PetItemInventroy; import pro.shushi.pamirs.meta.annotation.Function; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.meta.constant.FunctionConstants; import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum; import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum; import java.util.ArrayList; import java.util.List; @Model.model(PetItemInventroy.MODEL_MODEL) @Component public class PetItemInventroyAction { @Function.Advanced(type= FunctionTypeEnum.UPDATE) @Function.fun(FunctionConstants.update) @Function(openLevel = {FunctionOpenEnum.API}) public PetItemInventroy update(PetItemInventroy data){ List<PetItemInventroy> inventroys = new ArrayList<>(); inventroys.add(data); PamirsSession.directive().disableOptimisticLocker(); try{ //批量更新会,自动抛错 int i = data.updateBatch(inventroys); //单记录更新,不自动抛售需要自行判断 // int i = data.updateById();…

    2024年5月23日
    93300
  • 4.1.19 框架之网关协议-后端占位符

    在我们日常开发中会有碰到一些特殊场景,需要由前端来传一些如“当前用户Id”、“当前用户code”诸如此类只有后端才知道值的参数,那么后端占位符就是来解决类似问题的。如前端传${currentUserId},后端会自动替换为当前用户Id。 Step1 后端定义占位符 我们新建一个UserPlaceHolder继承AbstractPlaceHolderParser,用namespace来定义一个“currentUserId”的占位符,其对应值由value()决定为“PamirsSession.getUserId().toString()”,active要为真才有效,priority为优先级 package pro.shushi.pamirs.demo.core.placeholder; import org.springframework.stereotype.Component; import pro.shushi.pamirs.meta.api.session.PamirsSession; import pro.shushi.pamirs.user.api.AbstractPlaceHolderParser; @Component public class UserPlaceHolder extends AbstractPlaceHolderParser { @Override protected String value() { return PamirsSession.getUserId().toString(); } @Override public Integer priority() { return 10; } @Override public Boolean active() { return Boolean.TRUE; } @Override public String namespace() { return "currentUserId"; } } 图4-1-19-1 后端定义占位符 Step2 前端使用后端占位符 我们经常在o2m和m2m中会设置domain来过滤数据,这里案例就是在field中设置来过滤条件,domain="createUid == $#{currentUserId}",注意这里用的是$#{currentUserId} 而不是${currentUserId},这是前端为了区分真正变量和后端占位符,提交的时候会把#过滤掉提交。修改宠物达人表格视图的Template中search部分 <template slot="search" cols="4"> <field data="name" label="达人"/> <field data="petTalentSex" multi="true" label="达人性别"/> <field data="creater" /> <!– <field data="petShops" label="宠物商店" domain="createUid == ${activeRecord.creater.id}"/>–> <field data="petShops" label="宠物商店" domain="createUid == $#{currentUserId}"/> <field data="dataStatus" label="数据状态" multi="true"> <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 data="createDate" label="创建时间"/> <field data="unStore" /> </template> 图4-1-19-2 前端使用后端占位符 Step3 重启看效果 请求上都带上了createUid==${currentUserId} 图4-1-19-3 示例效果

    2024年5月23日
    1.4K00

Leave a Reply

登录后才能评论