[TOC]

# 文档说明

本文档主要介绍在 Windows 系统中,基于 EOS 8.2,使用主数据的 starter 进行集成开发涉及的项目创建、依赖配置、关键配置文件、低开示例开发等方面的介绍。

适用对象:基于 EOS 8.2 以及低开平台进行主数据项目二次开发的开发和测试人员。

# 开发场景说明

示例中主要介绍使用低代码开发平台和 EOS Studio 实现主数据模型“企业信息”的数据维护。

# 开发环境、工具及安装介质准备

本文档中使用的开发工具为EOS Platform 8.2 Developer Edition,使用的安装介质为:主数据 7.1 GA Standalone 版本。

# 依赖环境准备

开发环境必须安装的依赖中间件有数据库(以MySQL为例)、Nginx,需要实现安装。其他组件如Redis、Nacos等为非必须,可以按需安装。

# 创建 EOS 项目

在 EOS Studio 中新建“独立应用(standalone)项目”。

21

其中,GroupId为:com.primeton.mdm,ArtifactId为:demo,版本、应用名称、端口等保持默认即可。另外,需要勾选低代码、流程引擎。点击“完成”按钮,完成项目的创建。

22

项目创建完成后,项目结构如下图:

23

# 引入依赖

以下将以示例项目的项目结构为例,介绍微应用部署模式和独立部署模式,如何引入主数据依赖。

主数据基于 AFCenter 8.2.5 进行开发,因此需要在 demo/pom.xml 中确认AFCenter的版本为 8.2.5。另外,需要增加主数据的依赖版本。

project/pom.xml

	<properties>
		<eos.version>8.2.5</eos.version>
		<bps.version>8.2.5</bps.version>
		<afcenter.version>8.2.5</afcenter.version>
		<bfp.version>8.2.5</bfp.version>
		<lowcode.version>8.2.5</lowcode.version>
		<mdm.version>7.1.1</mdm.version>
	</properties>

依赖管理中增加,主数据的依赖。

	<dependencyManagement>
		<dependencies>
			...
			<dependency>
				<groupId>com.primeton.mdm</groupId>
				<artifactId>mdm-starter</artifactId>
				<version>${mdm.version}</version>
			</dependency>
			...
		</dependencies>
	</dependencyManagement>

在 com.primeton.mdm.demo.core/pom.xml 中增加主数据依赖。

	<dependencies>
		<dependency>
			<groupId>com.primeton.mdm</groupId>
			<artifactId>com.primeton.mdm.demo.model</artifactId>
			<version>1.0.0</version>
		</dependency>
		<dependency>
			<groupId>com.primeton.mdm</groupId>
			<artifactId>com.primeton.mdm.demo.api</artifactId>
			<version>1.0.0</version>
		</dependency>
		<dependency>
			<groupId>com.primeton.mdm</groupId>
			<artifactId>mdm-starter</artifactId>
		</dependency>
	</dependencies>

添加依赖之后,右键点击项目,选择“Maven”-“Update Project...”更新项目依赖。EOS Studio 会自动更新项目依赖,并进行编译。

# 初始化数据库

创建 afcenter4standalone 数据库。

CREATE DATABASE `afcenter4standalone` DEFAULT CHARACTER SET utf8mb4;

执行数据库脚本。需要依次执行如下脚本:

server/mdm/db-scripts/eos/Mysql/all.sql
server/mdm/db-scripts/afcenter/Mysql/all.sql
server/mdm/db-scripts/bfp/Mysql/all.sql
server/mdm/db-scripts/lowcode/Mysql/all.sql
server/mdm/db-scripts/mdm/mysql/mdm-afc-all.sql
server/mdm/db-scripts/mdm/mysql/mdm-all.sql
server/mdm/db-scripts/mdm/mysql/mdmpub-all.sql

# 修改配置文件

在 com.primeton.mdm.demo.boot 构建包中增加 application-mdm.properties 配置,可以从主数据 7.1 GA 的安装包中拷贝application-mdm.properties文件到 com.primeton.mdm.demo.boot/src/META-INF 目录下。配置文件内容如下:

eos.mvc.serialize.exclude-packages=com.primeton.mdm

spring.jpa.open-in-view=false
spring.jpa.properties.javax.persistence.validation.mode=none
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=false

## Database Dialect
## MySQL
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
## Oracle
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.Oracle10gDialect
## SQLServer
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
## Dameng
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DmDialect
### GaussDB
#spring.jpa.database=postgresql
#spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
#spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults = false

# unit: millis
mdm.schedule.fixed-delay.mdm-inst-heart-beat=30000
# default : statistic every hour
mdm.report.statistic.interval=0 0 * * * ?
# [file, db]
mdm.data-file.storage-type=file
mdm.data-file.storage-location=./data/data-files
# data model cache
#mdm.data-model-cache.enabled=true
# if set true, and request with a header 'X-MDM-UNIFIED-RESPONSE' = true, mdm will return unified response
mdm.support-unified-response=false
#data record log
mdm.data.record.log.enabled=true
# data-push
mdm.push.enabled=true
# if MDM singleton instance lock disabled, else enabled
mdm.push.lock-enabled=true
mdm.push.thread-pool.corePoolSize=10
mdm.push.thread-pool.maxPoolSize=100
mdm.push.thread-pool.queueCapacity=10000
mdm.push.scan.interval-seconds=60
mdm.push.data-page-size=10
mdm.push.data-step-minutes=30

mdm.push.http.validate-response-body.enabled=true
mdm.push.http.validate-response-body.code-attr=code
mdm.push.http.validate-response-body.msg-attr=message
mdm.push.http.validate-response-body.ok-code=200

# t1, t1 + step, t1 + 2*step, ..., t1 + n*step
# t1 + n*step + mistake < now && lastModifiedAt BETWEEN (t1 + (n-1)*step) AND (t1 + n*step - 1s.)
mdm.push.time-mistake-seconds=30
mdm.push.in-time.event-queue-size=100000

# regular cleanup sequenceDate code maxValue
# default true
mdm.block-sequence-code.clear=true
mdm.block-sequence-code.clear.interval=0 0 2 * * ?

#mdm.op-log.data-query.enabled=true
#mdm.op-log.data-maintain.enabled=false
#mdm.op-log.clean.enabled=false
#mdm.op-log.clean.keep-days=30
mdm.op-log.clean.scheduled=0 0 3 * * ?
#mdm.op-log.clean.scheduled=0/59 * * * * ?

#mill s
mdm.afc.copy.scheduled.time=1000

#email
spring.mail.host=smtp.126.com
spring.mail.username=youremail@email.com
spring.mail.password=XXXXXXXX
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8

修改 com.primeton.mdm.demo.boot/src/META-INF/_srv/config/user-config.xml 文件中的数据源配置。

修改 default 数据源。

    <group name="default">
        <configValue key="Database-Type">MySql</configValue>
        <configValue key="Jdbc-Type"/>
        <configValue key="C3p0-DriverClass">com.mysql.cj.jdbc.Driver</configValue>
        <configValue key="C3p0-Url">jdbc:mysql://127.0.0.1:3306/afcenter4standalone?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8&amp;useSSL=false</configValue>
        <configValue key="C3p0-UserName">root</configValue>
        <configValue key="C3p0-Password">root</configValue>
        <configValue key="C3p0-PoolSize">10</configValue>
        <configValue key="C3p0-MaxPoolSize">50</configValue>
        <configValue key="C3p0-MinPoolSize">10</configValue>
        <!-- //seconds, 0 means connections never expire -->
        <configValue key="C3p0-MaxIdleTime">600</configValue>
        <!-- //idle connections never tested -->
        <configValue key="C3p0-IdleConnectionTestPeriod">900</configValue>
        <configValue key="C3p0-MaxStatements">0</configValue>
        <configValue key="C3p0-NumHelperThreads">1</configValue>
        <configValue key="Transaction-Isolation">ISOLATION_DEFAULT</configValue>
        <configValue key="Test-Connect-Sql">SELECT count(*) from EOS_UNIQUE_TABLE</configValue>
        <configValue key="Retry-Connect-Count">-1</configValue>
    </group>

增加 MDM_PUB 数据源。

    <group name="MDM_PUB">
        <configValue key="Database-Type">MySql</configValue>
        <configValue key="Jdbc-Type"/>
        <configValue key="C3p0-DriverClass">com.mysql.cj.jdbc.Driver</configValue>
        <configValue key="C3p0-Url">jdbc:mysql://127.0.0.1:3306/afcenter4standalone?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8&amp;useSSL=false</configValue>
        <configValue key="C3p0-UserName">root</configValue>
        <configValue key="C3p0-Password">root</configValue>
        <configValue key="C3p0-PoolSize">10</configValue>
        <configValue key="C3p0-MaxPoolSize">50</configValue>
        <configValue key="C3p0-MinPoolSize">10</configValue>
        <!-- //seconds, 0 means connections never expire -->
        <configValue key="C3p0-MaxIdleTime">600</configValue>
        <!-- //idle connections never tested -->
        <configValue key="C3p0-IdleConnectionTestPeriod">900</configValue>
        <configValue key="C3p0-MaxStatements">0</configValue>
        <configValue key="C3p0-NumHelperThreads">1</configValue>
        <configValue key="Transaction-Isolation">ISOLATION_DEFAULT</configValue>
        <configValue key="Test-Connect-Sql">SELECT count(*) from EOS_UNIQUE_TABLE</configValue>
        <configValue key="Retry-Connect-Count">-1</configValue>
    </group>

注意,本示例中 MDM_PUB 数据源使用的数据库与 default 数据源相同。

# 部署前端环境

部署前端静态资源,需要实现部署Nginx。可以使用安装介质中提供的 mdm.conf 部署前端资源。也可以使用如下配置文件进行部署:


#user  nobody;
worker_processes  1;

events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    upstream afcenterapp {
        server 127.0.0.1:28084;
    }

    #gzip  on;

    server {
        listen       18080;
        server_name  localhost;

        client_max_body_size 20M;
        add_header X-Content-Type-Options nosniff;
        add_header X-XSS-Protection "1";
        add_header X-Frame-Options "SAMEORIGIN";
        add_header X-Permitted-Cross-Domain-Policies "master-only";
        add_header X-Download-Options noopen;
        add_header Content-Security-Policy "script-src * 'unsafe-inline' 'unsafe-eval'";
        add_header Strict-Transport-Security "max-age=SECONDS";
        add_header Referrer-Policy "no-referrer" always;

        location ~/"(?-i)MDM"/ {
            rewrite ^/(.*)/api/(.*)$ /api/$2 break;
            proxy_pass http://afcenterapp;
        }

        location ^~/api/ {
            proxy_pass http://afcenterapp;
        }

        location ~/(.*)/api/ {
            rewrite ^/(.*)/api/(.*)$ /api/$2 break;
            proxy_pass http://afcenterapp;
        }

        location / {
            root   C:\Applications\Standalone\web\afcenter;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

    }
}

需要注意的是,Windows环境下是不区分大小写的,因此,location ~/MDM/需要按照正则规则去匹配,即location ~/"(?-i)MDM"/

通过命令行启动Nginx。

nginx.exe -c C:\Applications\nginx-1.22.1\conf\nginx.conf

# 项目开发

本示例中使用低代码开发平台的服务实体调用逻辑流实现对主数据的数据维护。逻辑流通过 EOS Studio 进行编码开发,服务实体在低代码开发平台创建,对应的维护页面也在低代码开发平台中创建和配置。

# 开发主数据的逻辑流

在 com.primeton.mdm.demo.core 构建包中新建 com.primeton.mdm.demo.core.service 包,创建 DataOpsService 类。此类主要封装需要使用的主数据接口。

package com.primeton.mdm.demo.core.service;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import com.primeton.mdm.commons.model.MDMPageRequest;
import com.primeton.mdm.management.service.MDMBizTableService;
import com.primeton.mdm.management.spi.MDMDataModelTableHandler;
import com.primeton.mdm.management.util.MDMDataModelTableHelper;
import com.primeton.mdm.management.vo.MDMQueryParam;

/**
 * @author tianxinhui
 */
@Service
@Qualifier("dataOpsService")
public class DataOpsService {
	@Autowired
	private MDMBizTableService service;

	@Autowired
	private MDMDataModelTableHelper helper;

	public void insertData(String dataModelCode, Map<String, Object> data) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		helper.insert(dataModelCode, data);
	}

	public void insertDataAndRelease(String dataModelCode, Map<String, Object> data) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		helper.insert(dataModelCode, data);
	}

	public void batchInsertData(String dataModelCode, List<Map<String, Object>> data) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		helper.insert(dataModelCode, data);
	}

	public void releaseData(String dataModelCode, String dataId) {
		helper.release(dataModelCode, dataId);
	}

	public void updateData(String dataModelCode, Map<String, Object> data) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (StringUtils.isBlank(String.valueOf(data.get(MDMDataModelTableHandler.RESERVED_FIELD_ID)))) {
			throw new IllegalArgumentException("dataId is null!");
		}
		helper.update(dataModelCode, String.valueOf(data.get(MDMDataModelTableHandler.RESERVED_FIELD_ID)), data, false);
	}

	public void batchUpdataData(String dataModelCode, List<Map<String, Object>> data) {
		helper.update(dataModelCode, data, false);
	}

	public void updateDataAndRelease(String dataModelCode, String dataId, Map<String, Object> data) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (StringUtils.isBlank(dataId)) {
			throw new IllegalArgumentException("dataId is null!");
		}
		helper.updateAndRelease(dataModelCode, dataId, data, false);
	}

	public void deleteData(String dataModelCode, String dataId) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (StringUtils.isBlank(dataId)) {
			throw new IllegalArgumentException("dataId is null!");
		}
		helper.delete(dataModelCode, dataId);
	}

	public void batchDeleteData(String dataModelCode, List<String> dataIds) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (dataIds == null || dataIds.size() == 0) {
			throw new IllegalArgumentException("dataIds is null!");
		}
		helper.delete(dataModelCode, dataIds);
	}

	public Map<String, Object> findDataById(String dataModelCode, String dataId) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (StringUtils.isBlank(dataId)) {
			throw new IllegalArgumentException("dataId is null!");
		}
		MDMQueryParam.Arg arg = new MDMQueryParam.Arg();
		arg.setName(MDMDataModelTableHandler.RESERVED_FIELD_ID);
		arg.setMatchValue(dataId);
		MDMQueryParam.ParseRef parseRef = new MDMQueryParam.ParseRef();
		parseRef.setParseRefReferenceField(true);
		MDMQueryParam param = new MDMQueryParam();
		param.setArgs(Collections.singletonList(arg));
		param.setParseRef(parseRef);
		;
		Page<Map<String, Object>> result = service.findData(dataModelCode, true, param, null, new HashMap<>());
		List<Map<String, Object>> content = result.getContent();
		return content.size() != 0 ? content.get(0) : new HashMap<>();
	}

	public Page<Map<String, Object>> findData(String dataModelCode, MDMQueryParam params, MDMPageRequest page) {
		if (StringUtils.isBlank(dataModelCode)) {
			throw new IllegalArgumentException("dataModelCode is null!");
		}
		if (page == null) {
			page = new MDMPageRequest(0, 10);
		}
		if (params == null) {
			params = new MDMQueryParam();
			params.getParseRef().setParseRefReferenceField(true);
		}
		return service.findData(dataModelCode, true, params, page, new HashMap<>());
	}
}

在 com.primeton.mdm.demo.core 构建包中新建 com.primeton.mdm.demo.core.biz 包,创建 EnterpriseInfoBiz 运算逻辑。

package com.primeton.mdm.demo.core.biz;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import com.eos.spring.BeanFactory;
import com.eos.system.annotation.Bizlet;
import com.eos.system.utility.PageResultList;
import com.primeton.gocom.afcenter.common.model.QueryConditionModel;
import com.primeton.gocom.afcenter.common.model.QueryConditionModel.QueryConditionItem;
import com.primeton.mdm.commons.model.MDMPageRequest;
import com.primeton.mdm.demo.core.service.DataOpsService;
import com.primeton.mdm.demo.core.util.DataObjectUtils;
import com.primeton.mdm.management.vo.MDMQueryParam;
import com.primeton.spring.DefaultBeanFactory;

import commonj.sdo.DataObject;

/**
 * @author tianxinhui
 * @date 2023-04-04 16:27:08
 *
 */
@Service
@Bizlet("EnterpriseInfoBiz")
public class EnterpriseInfoBiz {
	private static final String DATA_MODEL_CODE = "enterprise";

	private BeanFactory factory = new DefaultBeanFactory();

	private DataOpsService service = (DataOpsService) factory.getBean("dataOpsService");

	@Bizlet("addEnterpriseInfo")
	public void addEnterpriseInfo(DataObject data) {
		service.insertData(DATA_MODEL_CODE, DataObjectUtils.toEnterpriseInfo(data));
	}

	@Bizlet("batchInsertEnterpriseInfo")
	public void batchInsertEnterpriseInfo(DataObject[] data) {
		if (data == null || data.length == 0) {
			return;
		}
		List<Map<String, Object>> dataList = new ArrayList<>();
		for (DataObject item : data) {
			dataList.add(DataObjectUtils.toEnterpriseInfo(item));
		}
		service.batchInsertData(DATA_MODEL_CODE, dataList);
	}

	@Bizlet("releaseEnterpriseInfo")
	public void releaseEnterpriseInfo(String dataId) {
		service.releaseData(DATA_MODEL_CODE, dataId);
	}

	@Bizlet("findEnterpriseInfoById")
	public Object findEnterpriseInfoById(String dataId) {
		return service.findDataById(DATA_MODEL_CODE, dataId);
	}

	@Bizlet("findEnterpriseInfo")
	public PageResultList<Object> findEnterpriseInfo(QueryConditionModel query, int pageIndex, int pageSize) {
		QueryConditionItem[] andItems = query.getAnd().getItems();
		MDMQueryParam params = new MDMQueryParam();
		for (QueryConditionItem item : andItems) {
			MDMQueryParam.Arg arg = new MDMQueryParam.Arg();
			arg.setName(item.getPropertyName());
			arg.setMatchValue(String.valueOf(item.getPropertyValue()));
			params.setArgs(Arrays.asList(arg));
		}

		MDMPageRequest page = new MDMPageRequest();
		page.setPageIndex(pageIndex);
		page.setPageSize(pageSize);
		Page<Map<String, Object>> result = service.findData(DATA_MODEL_CODE, params, page);

		List<Map<String, Object>> content = result.getContent();

		PageResultList pageResult = new PageResultList<>();
		pageResult.setData(content);
		pageResult.setTotal((int) result.getTotalElements());
		return pageResult;
	}

	@Bizlet("updateEnterpriseInfo")
	public void updateEnterpriseInfo(DataObject data) {
		service.updateData(DATA_MODEL_CODE, DataObjectUtils.toEnterpriseInfo(data));
	}

	@Bizlet("batchUpdateEnterpriseInfo")
	public void batchUpdateEnterpriseInfo(DataObject[] data) {
		if (data == null || data.length == 0) {
			return;
		}
		List<Map<String, Object>> dataList = new ArrayList<>();
		for (DataObject item : data) {
			dataList.add(DataObjectUtils.toEnterpriseInfo(item));
		}
		service.batchUpdataData(DATA_MODEL_CODE, dataList);
	}

	@Bizlet("deleteEnterpriseInfo")
	public void deleteEnterpriseInfo(String dataId) {
		service.deleteData(DATA_MODEL_CODE, dataId);
	}

	@Bizlet("batchDeleteEnterpriseInfo")
	public Object[] batchDeleteEnterpriseInfo(String[] dataIds) {
		if (dataIds == null || dataIds.length == 0) {
			return new Object[0];
		}
		// 用于返回结果,也可以不返回
		Object[] result = new Object[dataIds.length];
		try {
			service.batchDeleteData(DATA_MODEL_CODE, Arrays.asList(dataIds));
			for (int i = 0; i < result.length; i++) {
				Map<String, Object> data = new HashMap<>();
				data.put("M_ID", dataIds[i]);
				result[i] = data;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

在 com.primeton.mdm.demo.core 构建包中新建 com.primeton.mdm.demo.core.biz 包,创建逻辑构件 EnterpriseInfoManager。在此逻辑构件下创建如下逻辑流。在开发环境启动后,在低开IDE的离线资源中可以看到这些逻辑流服务。

注意,创建、更新、删除、查询接口参数需要和服务实体的接口保持一致,详情可以参考服务实体接口说明 (opens new window)

24

以调试模式启动后端服务。后端服务默认端口为 28084。

# 开发服务实体和维护页面

访问 http://127.0.0.1:8080,登录AFCenter。

授权主数据权限

在“组织权限中心-帐号管理”中为 admin 用户授权主数据的“主数据管理员”角色。

创建主数据模型

在“公共资源管理-主题管理”中创建主题“物资”,主题编号:materials,主题名称:物资。

在“主数据-数据模型-模型管理”中同步数据主题“物资”,将主题负责人设置为admin。在物资主题下创建“企业信息”数据模型并发布数据模型。模型名称:“企业信息”,模型编码"enterprise"。数据模型字段如下:

字段编码 字段名称 (简体中文) 数据类型 长度
ENTERPRISE_ID 企业ID STRING 36
MDM_CODE 主数据编码 STRING 64
ENTERPRISE_CODE 企业编号 STRING 36
ENTERPRISE_NAME 企业名称 STRING 256
ENTERPRISE_NATURE 企业性质 STRING 60
ENTERPRISE_TYPE 企业类型 STRING 60
SUPPLIER_TYPE 供应商类型 STRING 128

配置数据权限

在“主数据-权限管理-数据角色”中配置一个数据角色,这里新增角色名称为“默认角色”,角色编码为“DefaultRole”。创建完成后,点击“授权”,为admin用户授权。

选择“主数据-数据模型-模型管理”,点击“enterprise”进入模型管理。选择“权限配置-数据授权”菜单,点击“新增授权”按钮,"角色"选择“默认角色”,勾选“读权限”、“写权限”、“查询条件”、“查询表单”,点击“提交”。

创建应用

在“组织权限中心-应用管理”中创建应用,应用名称“EOS-DEMO-SYS”,应用编号“EOS-DEMO-SYS”。在开发中心的应用列表中,点击“开发”,打开低开IDE。

在左侧资源视图中,创建“com.primeton.mdm.demo.materials”构建包。在此构建包中,创建数据集“dataset”,在数据集中创建服务实体“企业信息”,如下图。

25

服务实体的实体属性信息如下:

26

服务实体的服务配置中有“根据主键查询服务”、“分页查询服务”、“新增服务”、“删除服务”、“删除服务”。所选择的逻辑流服务即在EnterpriseInfoManager中开发的逻辑流服务。

27

配置完成后,点击“保存”按钮。

创建页面

新建页面“form1”,页面编码为“form1”,页面显示名称为“form1”,页面实体选择之前创建的服务实体“EnterpriseInfo”,点击“保存”。

28

创建完成后,进入表单编辑页面。

29

点击默认视图,可以看到低开自动创建的数据维护页面。如果之前设置的逻辑流服务没有错误,页面中将会查询已有数据并展示。

30

在此页面中,可以多“企业信息”模型的数据进行维护。

后续步骤可以参考低代码开发平台的开发文档,完成后续的应用的启动、部署等操作。

# 示例代码及低开构建包

以上示例的代码可以这里下载:demo.zip

低开构建包可以在从这里下载:afc_lowcode_project_contribution_EOS-DEMO-SYS.zip