3.5.5 设计器的结合(改)

在页面开发的时候,直接通过前端组件和视图xml进行开发虽然开放性是很大的、但我们经常会忘记视图的配置属性,同时用xml配置的页面因为缺少设计数据,导致无法直接在设计器中复制,自定义页面得从头设计。今天就带大家一起来学习如何结合无代码设计器来完成页面开发,并把设计后的页面元数据装载为标准产品的一部分。

1 安装Docker

如果没有Docker的话,请自行到官网下载:https://www.docker.com/get-started/

2 下载Docker 镜像,并导入镜像

Step2.1 镜像下载

v.4.6.28.3-allinone-full 版本说明 前后端以及中间件一体
镜像地址 docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-full
下载结构包 oinone-op-ds-all-full.zip(17 KB)
v.4.6.28.3-allinone-mini 版本说明 前后端一体支持外部中间件
镜像地址 docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-mini
下载结构包 oinone-op-ds-all-mini.zip(14 KB)
v.4.7.9-allinone-full 版本说明 前后端以及中间件一体
镜像地址 docker pull harbor.oinone.top/oinone/designer:4.7.9-allinone-full
下载结构包 oinone-op-ds-all-full.zip(17 KB)
v.4.7.9-allinone-mini 版本说明 前后端一体支持外部中间件
镜像地址 docker pull harbor.oinone.top/oinone/designer:4.7.9-allinone-mini
下载结构包 oinone-op-ds-all-mini.zip(14 KB)

Step2.1.2 镜像下载用户与密码

需要商业版镜像需要加入Oinone商业版本伙伴专属群,向Oinone技术支持获取用户名与密码,镜像会定时更新并通知大家。

#注意:docker镜像拉取的账号密码请联系数式技术
docker login --username=用户名 harbor.oinone.top
docker pull docker pull harbor.oinone.top/oinone/designer:4.6.28.3-allinone-full

Step2.1.3 镜像和版本选择

目前有2个版本可供选择,包含中间件以及不包含中间件2个版本,下载结构包以后注意修改startup.sh和startup.cmd中对应镜像地址的版本号。

Step2.1.4 本地结构说明

下载结构包并解压

3.5.5 设计器的结合(改)

  1. config是放application.yml的目录,可以在application.yml配置需要启动的自有模块同时修改对应其他中间件配置项

  2. lib是放自有模块的jar包以及其对应的依赖包比如:pamirs-demo-api-1.0.0-SNAPSHOT.jar和pamirs-demo-core-1.0.0-SNAPSHOT.jar

  3. nginx:前端运行的nginx站点配置文件

  4. mq:消息配置,再使用低无一体时需要指定mq的broker的IP

  5. run:容器运行中间件的脚本,可以对个别中间件是否启动进行设置,(注释掉运行脚本,容器启动时就不会启动该中间件)

  6. logs是运行时系统日志目录

Step2.2 修改startup.sh中的路径

Step2.2.1 linux环境修改参数

在文件中找到如下 configDir=/opt/docker/oinone-op-ds-all-full version=4.6.28.3 IP=192.168.0.121

  • 修改configDir的路径(下载oinone-op-ds-xx.zip解压后的路径)

  • 修改对应的镜像版本号

  • 修改对应的IP为docker宿主机IP

#!/bin/bash
configDir=/opt/docker/oinone-op-ds-all-full
version=4.6.28.3
IP=192.168.0.121
docker run -d --name designer-allinone \
-e DUBBO_IP_TO_REGISTRY=$IP \
-e DUBBO_PORT_TO_REGISTRY=20880 \
-p 8099:8091 \
-p 3307:3306 \
-p 2182:2181 \
-p 6378:6379 \
-p 19876:9876 \
-p 10991:10991 \
-p 15555:15555 \
-p 20880:20880 \
-p 88:80 \
-v $configDir/config/:/opt/pamirs/ext \
-v $configDir/nginx:/opt/pamirs/nginx/vhost \
-v $configDir/logs:/opt/pamirs/logs \
-v $configDir/mq/broker.conf:/opt/mq/conf/broker.conf \
-v $configDir/run/run.sh:/opt/pamirs/run/run.sh \
-v $configDir/lib:/opt/pamirs/outlib harbor.oinone.top/oinone/designer:$version-allinone-full

Step2.2.3 window环境修改参数

在文件中找到如下 set configDir=/d/shushi/docker/oinone-op-ds-all-full set version=4.6.28.3 set IP=192.168.0.121

  • 修改configDir的路径((下载oinone-op-ds-xx.zip解压后的路径)

  • 修改对应的镜像版本号

  • 修改对应的IP为docker宿主机IP

@echo off
set configDir=/d/shushi/docker/oinone-op-ds-all-full
set version=4.6.28.3
set IP=192.168.0.121
docker run -d --name designer-allinone ^
-e DUBBO_IP_TO_REGISTRY=%IP% ^
-e DUBBO_PORT_TO_REGISTRY=20880 ^
-p 8099:8091 ^
-p 3307:3306 ^
-p 2182:2181 ^
-p 6378:6379 ^
-p 19876:9876 ^
-p 10991:10991 ^
-p 15555:15555 ^
-p 88:80  ^
-v %configDir%/config/:/opt/pamirs/ext   ^
-v %configDir%/nginx:/opt/pamirs/nginx/vhost ^
-v %configDir%/logs:/opt/pamirs/logs ^
-v %configDir%/mq/broker.conf:/opt/mq/conf/broker.conf ^
-v %configDir%/run/run.sh:/opt/pamirs/run/run.sh ^
-v %configDir%/lib:/opt/pamirs/outlib harbor.oinone.top/oinone/designer:%version%-allinone-full

3 不包含中间件的application.yml配置示例

修改结构包目录下config/application.yml

  • 要把192.168.0.121换成非127.0.0.1的机器分配IP:通过ifconfig(mac)或ipconfig(windows)命令查询
  • 数据库换成自己demo工程的数据库,demo6_v3 --> demo
dubbo:
  #dubbo的配置
server:
  address: 0.0.0.0
  port: 8091
  sessionTimeout: 3600
spring:
  redis:
  #redis的配置
logging:
        #日志的配置
pamirs:
  framework:
    system:
      system-ds-key: base
      system-models: base.WorkerNode
    data:
      default-ds-key: pamirs
      ds-map:
        base: base
    gateway:
      statistics: true
      show-doc: true
    meta:
      dynamic: false
  persistence:
    global:
      auto-create-database: true
      auto-create-table: true
  datasource:
    pamirs:
      driverClassName: com.mysql.cj.jdbc.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&allowPublicKeyRetrieval=true&useServerPrepStmts=true&cachePrepStmts=true&useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&autoReconnect=true&allowMultiQueries=true
      username: root
      password: oinone
            #............
      asyncInit: true
  #............
  boot:
    init: true
    sync: true
    modules:
      - base
      #-其他module
      - demo_core
    tenants:
      - pamirs
  auth:
      #权限过滤配置
  eip:
    #eip配置

我们前面中间件所绑定的IP都是127.0.0.1,因为我们这里使用了docker来访问,需要让中间件支持真正机器分配IP访问

Step3.1 检查mysql

  1. 确保yml文件中配置的用户可以通过机器IP来访问,例子中我们是用的是root用户,按以下步骤检查
mysql -u root -p
use mysql

3.5.5 设计器的结合(改)

select User,authentication_string,Host from user;

3.5.5 设计器的结合(改)

update user set Host='%' where user='root';
flush privileges;

Step3.2 检查redis

找到redis安装目录,编辑redis.conf,bind 从127.0.0.1改成0.0.0.0或对应本机IP,重启redis。

3.5.5 设计器的结合(改)

如果redis访问有问题,可以尝试在启动命令中增加 “--protected-mode no” 参数

nohup redis-server --protected-mode no & 

Step3.3 检查RocketMq

检查broker节点配置IP,如果有配置不能用127.0.0.1

Step3.4 检查Zookeeper

如果本地搭集群方式需要检查IP,如果有配置不能用127.0.0.1

4 包含中间件的application.yml以及其他配置示例

  • 对应中间件的配置:指定对应IP和端口或密码,把其中192.168.0.121改为宿主机IP
    • zookeeper
    • mysql
    • rocket-mq
    • redis
    • 阿里云oss配置

Step4.1 修改nginx/default.conf

如在docker和业务应用共同中间件实现低无一体时,如想在设计器中访问业务应用需要配置业务应用的nginx转发

location /pamirs/DemoCore {
    # 对应额外工程部署的IP,端口为额外工程后端的端口
    proxy_pass  http://192.168.0.121:8190
    proxy_set_header    Host    $host;
    proxy_set_header    X-Real-IP   $remote_addr;
    proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
}

修改以后可进容器重启nginx直接生效

进入docker容器
docker exec -it designer-allinone /bin/bash
docker镜像中重启nginx
/usr/local/nginx/sbin/nginx -s reload

Step4.2 修改mq/broker.conf

修改其中brokerIP1的IP从192.168.0.121改成宿主机IP

brokerClusterName = DefaultCluster
namesrvAddr=192.168.0.121:19876
brokerIP1=192.168.0.121
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
autoCreateTopicEnable=true
listenPort=10991
transactionCheckInterval=1000
#存储使用率阀值,当使用率超过阀值时,将拒绝发送消息请求
diskMaxUsedSpaceRatio=98
#磁盘空间警戒阈值,超过这个值则停止接受消息,默认值90
diskSpaceWarningLevelRatio=99
#强制删除文件阈值,默认85
diskSpaceCleanForciblyRatio=97

5. 启动Docker

Step5.1 linux环境启动

  • 在终端执行 sh startup.sh

Step5.2 window环境启动

  • 用PowerShell 执行 .\startup.cmd

Step5.3 查看日志,检查是否启动成功

在logs目录下可看到生成的日志文件,第一次启动时间会相对长一些,等看到日志文件中输出 启动耗时 。。。等字样,代表启动成功

6 体验并设计页面

输入http://localhost/访问,通过App Finder 切换时多了设计器一项

3.5.5 设计器的结合(改)

7 导出数据,并固化数据到产品中

Step7.1通过接口导出数据

设计器数据导出

Step7.2 导入数据到项目中

  1. pom依赖:

    pro.shushi.pamirs.metadata.manager
    pamirs-metadata-manager
  1. 将第二步下载后的文件放入项目中(注意文件放置的位置)。放置工程的resources下面。例如:

3.5.5 设计器的结合(改)

3、 项目启动过程中,将文件中的数据导入(通常放在core模型的init包下面)。示例代码:

package pro.shushi.pamirs.sys.setting.enmu;

import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand;
import pro.shushi.pamirs.boot.common.api.init.LifecycleCompletedAllInit;
import pro.shushi.pamirs.boot.common.extend.MetaDataEditor;
import pro.shushi.pamirs.core.common.InitializationUtil;
import pro.shushi.pamirs.meta.annotation.fun.extern.Slf4j;
import pro.shushi.pamirs.meta.api.dto.meta.Meta;
import pro.shushi.pamirs.meta.domain.module.ModuleDefinition;
import pro.shushi.pamirs.metadata.manager.core.helper.DesignerInstallHelper;
import pro.shushi.pamirs.metadata.manager.core.helper.WidgetInstallHelper;

import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class DemoAppMetaInstall implements MetaDataEditor, LifecycleCompletedAllInit {

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public void edit(AppLifecycleCommand command, Map metaMap) {
        if (!doImport()) {
            return;
        }
        log.info("[设计器业务元数据导入]");
        InitializationUtil bizInitializationUtil = InitializationUtil.get(metaMap, DemoModule.MODULE_MODULE/***改成自己的Module*/, DemoModule.MODULE_NAME/***改成自己的Module*/);
        DesignerInstallHelper.mateInitialization(bizInitializationUtil, "install/meta.json");

        log.info("[自定义组件元数据导入]");
//        写法1: 将组件元数据导入到页面设计器. 只有在安装设计器的服务中执行才有效果
        WidgetInstallHelper.mateInitialization(metaMap, "install/widget.json");

//        写法2: 与写法1相同效果
        InitializationUtil uiInitializationUtil = InitializationUtil.get(metaMap, "ui_designer", "uiDesigner");
        if (uiInitializationUtil != null) {
            DesignerInstallHelper.mateInitialization(uiInitializationUtil, "install/widget.json");
        }

//        写法3: 业务工程和设计器分布式部署,且希望通过业务工程导入自定义组件元数据. 业务模块需要依赖页面设计器模块,然后指定业务模块导入
        DesignerInstallHelper.mateInitialization(bizInitializationUtil, "install/widget.json");
    }

    @Override
    public void process(AppLifecycleCommand command, Map runModuleMap) {
        if (!doImport()) {
            return;
        }

        log.info("[设计器业务数据导入]");
//        支持远程调用,但是执行的生命周期必须是LifecycleCompletedAllInit或之后. 本地如果安装了设计器,则没有要求
        DesignerInstallHelper.bizInitialization("install/meta.json");

        log.info("[自定义组件业务数据导入]");
//        当开发环境和导入环境的文件服务不互通时, 可通过指定js和css的文件压缩包,自动上传到导入环境,并替换导入组件数据中的文件url
//        WidgetInstallHelper.bizInitialization("install/widget.json", "install/widget.zip");
        WidgetInstallHelper.bizInitialization("install/widget.json");
        return;
    }

    private boolean doImport() {
        // 自定义导入判断. 避免用于设计的开发环境执行导入逻辑
        String[] envs = applicationContext.getEnvironment().getActiveProfiles();
        List envList = Lists.newArrayList(envs);
        return CollectionUtils.isNotEmpty(envList) && (envList.contains("prod"));
    }

}

常见异常问题

启动失败现象

启动设计器的Docker容器,lib包中增加自定义的Jar启动报错,错误信息为:

3.5.5 设计器的结合(改)

问题原因

自定义Jar的包路径不是系统默认扫描路径。 目前系统默认的包扫描路径是:pro.shushi.pamirs 和 pro.shushi.oinone。 自定义扫描路径Spring加载不到

问题解决方法

资料参考:https://itcn.blog/p/214153911.html

  1. 业务工程API模块 新建一个ScanConfig, resources目录下创建META-INF目录,然后创建spring.factories文件。上述两个文件目录参考如下:

3.5.5 设计器的结合(改)

  1. 文件内容参考

2.1. WangxianConfigScanConfig,根据自己的实际情况修改 命名类和包扫描路径

package com.ss.wangxian.xjj.project.api.config;

import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;

@ComponentScans(value =
                {@ComponentScan(value = com.ss.wangxian)})
    @EntityScan(basePackages = {com.ss.wangxian})
    @Configuration
    public class WangxianConfigScanConfig implements EnvironmentAware {

        @Override
        public void setEnvironment(Environment environment) {
            System.out.println(#####初始化 BeanConfigScan #############);
        }

    }

2.2. spring.factories,根据实际情况修改类名和路径

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ss.wangxian.xjj.project.api.config.WangxianConfigScanConfig
  1. API工程重新打包,然后放入到docker文档中指定的lib包下,重新启动容器。

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

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

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

相关推荐

  • 报表

    1. 业务场景 报表不局限于表格的样式,还能以各式各样的图表形式展现各项汇总数据 这有利于管理者更为直观地了解公司的经营情况,便于后续进行分析,提高对公司的管理水平。 2. 操作流程 1)进入数据可视化,进入报表tab,维护分组信息; 2)在二级分组名称后点击“+”【添加报表】,对报表进行编辑设计; 3)创建完成后可以【编辑】报表标题、备注; 4)需要通过【选择图表、创建图表】完善报表内容; 5)完善后可以点击【发布】报表,则报表此时可以被引用; 6)如果报表有更新,则可以点击【更新发布】,使业务系统引用对报表变为最新的报表信息; 7)如果报表数据不再可以公开使用,则需要通过【隐藏】功能将报表的引用权限收起,此时数据大屏、前端业务系统均不可再引用该报表,但不影响已被引用的报表; 8)隐藏后可以【取消隐藏】,报表恢复隐藏前的状态和功能,可以被引用。 3. 操作流程图解 3.1 创建分组 1)操作流程:创建分组 2)操作路径:数据可视化-报表-创建分组 3)点击搜索框后的「+」创建一级分组,输入一级分组名称后,点击一级分组后的「+」创建二级分组,输入二级分组名称后,此时分组创建完成,可以在二级分组下创建报表 3.2 编辑分组名称 1)操作流程:选择分组-编辑分组名称 2)操作路径:数据可视化-报表-编辑分组名称 3)鼠标移动至需要修改的分组上,点击出现的「编辑图标」,可以修改分组名称,修改后分组名称实时更新 3.3 删除分组 1)操作流程:选择分组-删除分组 2)操作路径:数据可视化-报表-删除分组 3)鼠标移动至需要删除的分组上,当分组下无报表时出现「删除图标」,可以点击图标后删除分组,删除一级分组时对应所有的二级分组也会被删除,删除后消失,只要分组下没有报表的分组才能直接删除成功 3.4 创建报表 1)操作流程:选择二级分组-创建报表 2)操作路径:数据可视化-报表-二级分组-创建报表 3)鼠标移动至需要创建报表的二级分组上,出现「+」,点击图标后=需要填写报表标题; a. 报表标题:最大支持20个字,支持汉字、数字、大小写字母、-;同个一级分组下不允许重复; 4)创建后可以选择报表需要展示的图表 3.5 删除报表 1)操作流程:选择报表-删除报表 2)操作路径:数据可视化-报表-二级分组-报表名称-删除图表 3)未发布或者已发布但没有被隐藏的报表,并且没被前端或者数据大屏引用,才展示报表菜单名称后的删除图标 4)删除报表后报表消失 3.6 选择图表 1)操作流程:选择报表-为报表选择图表 2)操作路径:数据可视化-报表-二级分组-报表名称-选择图表 3)选择单个未发布或者已发布但没有被隐藏的报表,点击【选择图表】,弹出“选择图表”弹窗,对该报表需要展示的图表进行选择 a. 需要选择图表的一级分组后才能选择图表; b. 可以多选图表,选择的图表只能是已选一级分组下的未隐藏的未被选择的图表;选择一个二级分组时,默认该二级分组下的图表会全部被选中,图表会按照选中的顺序展示在报表列表; 4)选择图表后,报表信息保持展示图表的最新效果;如果图表更新了,但是报表没有发布最新,则报表在前端展示的仍为最近发布的版本; 5)如果图表中存在超过一行的图内筛选项,则在报表处原始的图表尺寸只能查看一行图内筛选项,需要根据图表在报表处的等比拖动效果展示更多的图内筛选项 3.7 创建图表 1)操作流程:选择报表-创建图表 2)操作路径:数据可视化-报表-二级分组-创建图表 3)选择单个未发布或者已发布但没有被隐藏的报表,点击【创建图表】,弹出“创建图表”弹窗,需要填写图表标题、模型、方法; a. 图表标题:最大支持20个字,支持汉字、数字、大小写字母、-;同个一级分组下不允许重复; b. 模型:需要选择来源数据对应的模型; c. 方法:选择模型后需要选择方法,方法是用来提取模型数据的逻辑; 4)选择成功后进入图表设计页面,创建图表保存后返回,返回到当前报表页面,新创建的图表展示在报表的第一个位置 3.8 拖拽图表 1)操作流程:选择报表-拖拽图表 2) 操作路径:数据可视化-报表-二级分组-报表名称-拖拽图表 3)所有的报表均可拖拽图表,拖拽时需要选择图表,可以上下左右等比拖动,图表的内容也会根据拖动的比例进行缩放,展示全部的被遮挡图表内容 4)拖拽后实时生效,报表信息保持展示最新效果 3.9 移除图表 1)操作流程:选择报表-移除图表 2)操作路径:数据可视化-报表-二级分组-报表名称-移除图表 3)未发布或者已发布但没有被隐藏的报表,并且没被前端或者数据大屏引用,此时可以针对不需要的图表进行移除 4)选择移除后不展示在报表中,不影响原图表 5)报表移除图表后实时更新,更新发布后,前端可以展示最新的报表信息,如果未发布,则仅数据大屏可展示最新的报表信息,前端仍为最近发布的报表 3.10 设置报表筛选项 1)操作流程:选择报表-设置报表筛选项 2)操作路径:数据可视化-报表-二级分组-报表名称-更多-报表筛选项-添加 3)添加时选择筛选项字段的类型,关联每个图表对应的字段,一个图表只能关联一个 4)关联后可以按关联字段查询图表数据 3.11 发布 1)操作流程:选择报表-发布报表 2)操作路径:数据可视化-图表-二级分组-报表-发布 3)选择单个未发布且没有被隐藏的报表,点击【发布】按钮,报表发布后可以被前端引用,报表状态变为已发布,展示最近发布时间; 4)如果报表发布后有更新内容,会展示的更新类型:更新报表信息/更新图表内容/选择图表/移除图表 3.12 查看最近一次发布的版本 1)操作流程:选择报表-查看最近一次发布的版本 2)操作路径:数据可视化-报表-二级分组-报表名称-查看最近一次发布的版本 3)当报表发布后有更新,在最近发布时间左侧展示【查看】,在最近发布时间下展示更新的类型,点击查看可以查看最近发布的版 3.13 更新发布 1)操作流程:选择报表-更新发布报表 2)操作路径:数据可视化-报表-二级分组-报表名称-更新发布报表 3)选择单个已发布且没有被隐藏的报表,并且该报表在上次发布后有所更新,可以点击【更新发布】按钮,将最新的报表内容发布至业务系统,业务系统引用的报表为最新内容; 4)如果更新了内容,但未点击更新发布,则前端业务系统查看的报表仍为最近发布的报表 3.14 隐藏 1)操作流程:选择报表-隐藏报表 2)操作路径:数据可视化-报表-二级分组-报表名称-隐藏报表 3)报表默认不隐藏,可以切换是否隐藏=是 a. 未发布的报表,较隐藏前,不可以操作【发布】,可以【取消隐藏】; b. 已发布的图表,较隐藏前,只能操作【导出图片、导出excel、取消隐藏】; c. 隐藏后的报表不可以被引用,但不影响已经被引用的数据 3.15 取消隐藏 1) 操作流程:选择报表-取消隐藏报表 2) 操作路径:数据可视化-报表-二级分组-报表名称-取消隐藏报表 3) 隐藏后的报表可以取消隐藏,切换是否隐藏=否,取消隐藏后,报表恢复隐藏前的状态和功能,可以被引用 3.16 查看引用 1)流程:选择报表-查看被哪些页面引用 2)操作路径:数据可视化-报表-二级分组-报表-更多-查看引用 3)选择具体的报表,查看当前报表被引用的所有信息 3.17 不允许别人编辑 1)流程:选择报表-不允许别人编辑 2)操作路径:数据可视化-报表-二级分组-报表-更多-不允许别人编辑 3)选择自己创建的报表,对报表是否允许其他人编辑进行设置;如果设置为不允许,则其他人无法编辑报表 3.18 不允许别人引用 1)流程:选择图表-更多-不允许别人引用 2)操作路径:数据可视化-报表-二级分组-报表-更多-不允许别人引用 3)选择自己创建的报表,对报表是否允许他人引用进行设置;如果设置为不允许,则其他人无法引用到该报表 3.19 导出图片 1) 操作流程:选择报表-导出图片 2) 操作路径:数据可视化-报表-二级分组-报表名称-导出图片 3) 选择报表后,点击【导出图片】按钮可以将当前报表导出为图片 3.20 导出EXCEL 1)操作流程:选择报表-导出EXCEL 2)操作路径:数据可视化-报表-二级分组-报表名称-报表导出EXCEL 3)选择报表后,点击【导出EXCEL】按钮可以将当前报表导出为EXCEL

    2024年6月20日
    1.7K00
  • 6.3 数据审计(改)

    在业务应用中我们经常需要为一些核心数据的变更做审计追踪,记录字段的前后变化、操作IP、操作人、操作地址等等。数据审计模块为此提供了支撑和统一管理。它在成熟的企业的核心业务系统中,需求是比较旺盛的。接下来我们开始学习下数据审计模块 准备工作 pamirs-demo-core的pom文件中引入pamirs-data-audit-api包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-data-audit-api</artifactId> </dependency> pamirs-demo-boot的pom文件中引入pamirs-data-audit-core和pamirs-third-party-map-core包依赖,数据审计会记录操作人的地址信息,所以也依赖了pamirs-third-party-map-core <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-data-audit-core</artifactId> </dependency> <dependency> <groupId>pro.shushi.pamirs.core.map</groupId> <artifactId>pamirs-third-party-map-core</artifactId> </dependency> pamirs-demo-boot的application-dev.yml文件中增加配置pamirs.boot.modules增加data_audit 和third_party_map,即在启动模块中增加data_audit和third_party_map模块 pamirs: boot: modules: – data_audit – tp_map 为third_party_map模块增加高德接口api,下面e439dda234467b07709f28b57f0a9bd5换成自己的key pamirs: eip: map: gd: key: e439dda234467b07709f28b57f0a9bd5 数据审计 注解式(举例) Step1 新增PetTalentDataAudit数据审计定义类 package pro.shushi.pamirs.demo.core.init.audit; import pro.shushi.pamirs.data.audit.api.annotation.DataAudit; import pro.shushi.pamirs.demo.api.model.PetTalent; @DataAudit( model = PetTalent.MODEL_MODEL,//需要审计的模型 modelName = "宠物达人" ,//模型名称,默认模型对应的displayName //操作名称 optTypes = {PetTalentDataAudit.PETTALENT_CREATE,PetTalentDataAudit.PETTALENT_UDPATE}, fields={"nick","picList.id","picList.url","petShops.id","petShops.shopName"}//需要审计的字段,关系字段用"."连结 ) public class PetTalentDataAudit { public static final String PETTALENT_CREATE ="宠物达人创建"; public static final String PETTALENT_UDPATE ="宠物达人修改"; Step2 修改PetTalentAction的update方法 做审计日志埋点:手工调用 OperationLogBuilder.newInstance().record()方法。需要注意的是这里需要把原有记录的数据值先查出来做对比 @Function.Advanced(type= FunctionTypeEnum.UPDATE) @Function.fun(FunctionConstants.update) @Function(openLevel = {FunctionOpenEnum.API}) public PetTalent update(PetTalent data){ //记录日志 OperationLogBuilder.newInstance(PetTalent.MODEL_MODEL, PetTalentDataAudit.PETTALENT_UDPATE).record(data.queryById().fieldQuery(PetTalent::getPicList).fieldQuery(PetTalent::getPetShops),data); PetTalent existPetTalent = new PetTalent().queryById(data.getId()); if(existPetTalent !=null){ existPetTalent.fieldQuery(PetTalent::getPicList); existPetTalent.fieldQuery(PetTalent::getPetShops); existPetTalent.relationDelete(PetTalent::getPicList); existPetTalent.relationDelete(PetTalent::getPetShops); } data.updateById(); data.fieldSave(PetTalent::getPicList); data.fieldSave(PetTalent::getPetShops); return data; } Step3 重启看效果 修改宠物达人记录对应的字段,然后进入审计模块查看日志

    2024年5月23日
    1.2K00
  • 4.1.3 模块之生命周期

    了解oinone的启动生命周期过程,对于理解oinone或者开发高级功能都有非常大的帮助 一、生命周期大图 图4-1-3-1 生命周期大图 二、平台扩展说明 平台节点通过SPI机制进行扩展,本书籍暂不展开,更多详情请见可关注数式Oinone公众号中的Oinone内核揭秘系列文章。 三、业务扩展说明 接口 说明 使用场景 LifecycleBeginAllInit 系统进入生命周期前置逻辑注:不能有任何数据库操作 系统级别的信息收集上报 LifecycleCompletedAllInit 系统生命周期完结后置逻辑 系统级别的信息收集上报、生命周期过程中的数据或上下文清理 LifecycleBeginInit 模块进入生命周期前置逻辑注:不能有任何数据库操作 预留,能做的事情比较少 LifecycleCompletedInit 模块生命周期完结后置逻辑 本模块需等待其他模块初始化完毕以后进行初始化的逻辑。比如:1.集成模块的初始化2.权限缓存的初始化…… MetaDataEditor 元数据编辑注:不能有任何数据库操作 这个在第3章Oinone的基础入门中已经多次提及,核心场景是向系统主动注册如Action、Menu、View等元数据 ExtendBuildInit 系统构建前置处理逻辑 预留,能做的事情比较少,做一些跟模块无关的事情 ExtendAfterBuilderInit 系统构建后置处理逻辑 预留,能做的事情比较少,做一些跟模块无关的事情 InstallDataInit 模块在初次安装时的初始化逻辑 根据模块启动指令来进行选择执行逻辑,一般用于初始化业务数据。应用启动参数与指令转化逻辑详见4.1.2【模块之启动指令】一文 UpgradeDataInit 模块在升级时的初始化逻辑注:根据启动指令来执行,是否执行一次业务自己控制 ReloadDataInit 模块在重启时的初始化逻辑注:根据启动指令来执行,是否执行一次业务自己控制 表4-1-3-1 业务拓展说明 四、常用生命周期举例 Install\Upgrade\Reload的业务初始化(举例) Step1 新建DemoModuleBizInit DemoModuleBizInit实现InstallDataInit, UpgradeDataInit, ReloadDataInit a. InstallDataInit 对应 init b. UpgradeDataInit 对应 upgrade c. ReloadDataInit 对应 reload modules方法代表改初始化类与哪些模块匹配,以模块编码为准 priority 执行优先级 package pro.shushi.pamirs.demo.core.init; import org.springframework.stereotype.Component; import pro.shushi.pamirs.boot.common.api.command.AppLifecycleCommand; import pro.shushi.pamirs.boot.common.api.init.InstallDataInit; import pro.shushi.pamirs.boot.common.api.init.ReloadDataInit; import pro.shushi.pamirs.boot.common.api.init.UpgradeDataInit; import pro.shushi.pamirs.demo.api.DemoModule; import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate; import pro.shushi.pamirs.meta.common.exception.PamirsException; import java.util.Collections; import java.util.List; @Component public class DemoModuleBizInit implements InstallDataInit, UpgradeDataInit, ReloadDataInit { @Override public boolean init(AppLifecycleCommand command, String version) { throw PamirsException.construct(DemoExpEnumerate.SYSTEM_ERROR).appendMsg("DemoModuleBizInit: install").errThrow(); //安装指令执行逻辑 // return Boolean.TRUE; } @Override public boolean reload(AppLifecycleCommand command, String version) { throw PamirsException.construct(DemoExpEnumerate.SYSTEM_ERROR).appendMsg("DemoModuleBizInit: reload").errThrow(); //重启指令执行逻辑 // return Boolean.TRUE; } @Override public boolean upgrade(AppLifecycleCommand command, String version, String existVersion) { throw PamirsException.construct(DemoExpEnumerate.SYSTEM_ERROR).appendMsg("DemoModuleBizInit: upgrade").errThrow(); //升级指令执行逻辑 // return Boolean.TRUE; } @Override public List<String> modules() { return Collections.singletonList(DemoModule.MODULE_MODULE); } @Override public int priority() { return 0; } } 图4-1-3-2 新建DemoModuleBizInit Step2 重启看效果 启动指令为-Plifecycle=INSTALL,转化指令为 install为AUTO;upgrade为FORCE 因为DemoModule我们已经执行过好多次了,所以会进入upgrade逻辑。系统重启的效果跟我们预期的结果一致,确实执行了DemoModuleBizInit的upgrade方法 图4-1-3-3 系统重启执行DemoModuleBizInit的upgrade方法 MetaDataEditor 回顾使用情况 最早在3.3.2【模型的类型】一文中介绍“传输模型”时,初始化ViewAction窗口动作时使用到,这里不过多介绍。下面主要介绍下InitializationUtil的工具类包含方法。 注:模块上报元数据只能通过注解或者实现MetaDataEditor接口并使用InitializationUtil工具来进行,更建议用注解方式

    2024年5月23日
    1.4K00
  • 构件类

    1.构件类 1.1 延时 当下一个节点动作需要一段时间之后再发生时,可以使用延时节点。延时节点包含两种延时方式:1、延至指定日期,2、延时一段时间。 选择延至指定日期时,可以选择延至模型字段的时间或自定义时间,如果模型字段只包含日期则必填指定时辰。如果选择自定义则需要分别指定日期和时辰。 选择延时一段时间时,至少需要填“天、小时、分钟”中的一项。 1.2 条件分支 使不同条件的数据执行不同的分支流程。需要设置分支条件、添加满足条件的动作、也可以增删条件分支。 必须将分支条件填写完整流程才能正常进行。当只有两个分支时点击删除任一分支会删除整个条件分支。 1.3 审批分支 审批分支是一种特殊的条件分支。审批分支只能添加在审批节点下方。因为审批只存在通过和拒绝两种条件,所以无法添加其他条件,并且点击任意条件的叉都会删除整个条件分支。同时若审批节点被删除,审批分支也会同时删除。 1.4 子流程 一些高度重复的流程节点可以创建成子流程,在主流程中引用子流程,减少流程的重复配置。选择子流程时只能选择当前流程中有用到的模型下并且在启用状态的子流程,也可以在创建子流程节点处设置新增子流程。子流程的执行方式有两种:子流程可以和后续节点同时执行,也可以设置子流程执行完后再执行后续节点。 子流程与普通正常流程不同,不包含触发方式,普通流程流转到子流程节点即为子流程的触发条件,添加完节点动作之后发布即可。在不新增数据的情况下,子流程中只能使用该子流程对应模型的字段数据。

    2024年5月23日
    1.6K00
  • 4.1.14 Search之非存储字段条件

    search默认查询的是模型的queryPage函数,但我们有时候需要替换调用的函数,这个特性会在下个版本支持。其核心场景为当搜索条件中有非存储字段,如果直接用queryPage函数的rsql拼接就会报错,所以非存储字段不会增加在rsql中。本文介绍一个比较友好的临时替代方案。 非存储字段条件(举例) Step1 为PetTalent新增一个非存储字段unStore @Field(displayName = "非存储字段测试",store = NullableBoolEnum.FALSE) private String unStore; 图4-1-14-1 为PetTalent新增一个非存储字段unStore Step2 修改PetTalent的Table视图的Template 在标签内增加一个查询条件 <field data="unStore" /> 图4-1-14-2 修改PetTalent的Table视图的Template Step3 重启看效果 进入宠物达人列表页,在搜索框【非存储字段测试】输入查询内容,点击搜索跟无条件一致 Step4 修改PetTalentAction的queryPage方法 package pro.shushi.pamirs.demo.core.action; …… 引入依赖类 @Model.model(PetTalent.MODEL_MODEL) @Component public class PetTalentAction { ……其他代码 @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.API}) public Pagination<PetTalent> queryPage(Pagination<PetTalent> page, IWrapper<PetTalent> queryWrapper){ QueryWrapper<PetTalent> queryWrapper1 = (QueryWrapper<PetTalent>) queryWrapper; Map<String, Object> queryData = queryWrapper.getQueryData(); String unStore = (String) queryData.get(LambdaUtil.fetchFieldName(PetTalent::getUnStore)); if (StringUtils.isNotEmpty(unStore)) { //转换查询条件 queryWrapper1.like( 图4-1-14-3 修改PetTalentAction的queryPage方法 Step5 重启看效果 在搜索框【非存储字段测试】输入查询内容,跟通过【达人】字段搜索的效果是一致的 图4-1-14-4 示例效果

    2024年5月23日
    1.4K00

Leave a Reply

登录后才能评论