动态加载进度条控件原创
金蝶云社区-技术支持与赋能部_ZH
技术支持与赋能部_ZH
4人赞赏了该文章 2,579次浏览 未经作者许可,禁止转载编辑于2022年03月24日 22:05:29

关键词:动态,进度条控件

一、需求背景

说到进度条控件,这个是苍穹标准支持的控件。但往往在实际开发中,控件的数量或者控件的属性是根据实际的数据动态加载的。

比如要统计一个项目的任务完成度,这个项目又有多条任务线,这个需要通过进度条控件来实现。其中的难点是任务线和任务完成情况都是需要根据实际情况动态计算得出的无法提前在单据设计器中预置出来。大家可以通过下面的案例来学习苍穹是如何实现动态加载进度条的

二、思路与方案

向前端动态添加控件配置   

将前端动态增加的控件注册到后端

向表单添加控件添加编程模型实例,并侦听控件的插件事件

根据实际的业务数据为动态创建的进度条赋值

三、实现过程

1、表单注册插件,该插件继承AbstractFormPlugin

 

2、重写loadCustomControlMetas:向前端动态添加控件配置

	/**
	 * 向前端动态增加控件
	 *
	 * @param e
	 */
	@Override
	public void loadCustomControlMetas(LoadCustomControlMetasArgs e) {
		super.loadCustomControlMetas(e);
		FormShowParameter formShowParameter = (FormShowParameter) e.getSource();
		Object pk = formShowParameter.getCustomParam("projectId");
		FlexPanelAp dynamicFlex = this.createDynamicFlex(pk);
		if (dynamicFlex != null) {
			Map<String, Object> mapFlex = new HashMap<>();
			mapFlex.put(ClientProperties.Id, "dmp_dynamicap");//动态控件区域
			mapFlex.put(ClientProperties.Items, dynamicFlex.createControl().get(ClientProperties.Items));
			e.getItems().add(mapFlex);
		}
	}

(1)、在loadCustomControlMetas中创建flex面板,通过业务需求判断预置进度条控件

/**
	 * 创建flex面板
	 * 
	 * @param pk
	 * @return
	 */
	private FlexPanelAp createDynamicFlex(Object pk) {
		QFilter qFilter = new QFilter("dmp_project", QCP.equals, pk);
		DynamicObject[] stages = BusinessDataServiceHelper.load(Constant.KEY_PROGJRCTSTAGE_FORMID,
				Constant.PROGJRCTSTAGE_SELECTFIELD, new QFilter[] { qFilter });
		int size = stages.length;
		if (size == 0) {
			return null;
		}
		FlexPanelAp dynamicFlex = new FlexPanelAp();
		dynamicFlex.setKey("dynamicflex");
		for (int i = size - 1; i >= 0; i--) {
			DynamicObject stage = stages[i];
			String stagePk = stage.getPkValue().toString();
			if (i == size - 1) {
				lastStage=stagePk;
			}
			DynamicObject project = stage.getDynamicObject("dmp_project");
			if (project == null) {
				break;
			}
			log.info("查了第一次数据!!!");
			int length = this.getLength(stagePk, pk);
			// project
			float finished = this.getFinished(stagePk, pk);

			String stageName = stage.getString("name");// Constant.ITERATION_NAME
			//创建需求面板
			FlexPanelAp firstFlex = this.createFirstFlex(stageName, length, finished, i, stagePk);
			//创建进度条
			FlexPanelAp secondFlex = this.createSecondFlex(length, finished, i);
			FlexPanelAp flex = new FlexPanelAp();
			flex.setKey(stagePk);
			flex.setWidth(new LocaleString("100%"));
			flex.setClickable(true);
			Style style = new Style();
			Border border = new Border();
			border.setBottom("1px solid #e2e7ef");
			border.setRight("1px solid #e2e7ef");
			style.setBorder(border);
			flex.setStyle(style);
			flex.getItems().add(firstFlex);
			flex.getItems().add(secondFlex);
			dynamicFlex.getItems().add(flex);
		}
		return dynamicFlex;
	}

(2)、在flex面板中预置进度条控件

private FlexPanelAp createSecondFlex(int length, float finished, int i) {
		DecimalFormat df = new DecimalFormat("0.00%");
		String progress = length != 0 ? df.format(finished / length) : "0.00%";
		FlexPanelAp flex2 = new FlexPanelAp();
		flex2.setKey("flex2" + i);
		flex2.setAlignItems("center");
		flex2.setJustifyContent("space-between");
		flex2.setWidth(new LocaleString("100%"));
		Style flexStyle = new Style();
		Padding flexPadding = new Padding();
		flexPadding.setLeft("14px");
		flexPadding.setBottom("10px");
		flexPadding.setRight("10px");
		flexStyle.setPadding(flexPadding);
		flex2.setStyle(flexStyle);

		// 创建进度条
		ProgressBarAp progressBar = new ProgressBarAp();
		progressBar.setId("progressbar" + i);
		progressBar.setKey("progressbar" + i);
		progressBar.setHeight(new LocaleString("10px"));
		progressBar.setWidth(new LocaleString("160px"));
		flex2.getItems().add(progressBar);

		// 创建进度lab
		LabelAp progressLab = new LabelAp();
		progressLab.setId("progress" + i);
		progressLab.setKey("progress" + i);
		progressLab.setName(new LocaleString(progress));
		flex2.getItems().add(progressLab);
		return flex2;
	}

3、重写beforeBindData:将前端动态增加的控件注册到后端

/**
	 * 将前端动态增加的控件注册到后端
	 *
	 * @param e
	 */
	@Override
	public void beforeBindData(EventObject e) {
		super.beforeBindData(e);
		Object pk = this.getProjectId();
		this.getModel().setValue("dmp_projectid", pk);
		FlexPanelAp dynamicFlex = this.createDynamicFlex(pk);
		if (dynamicFlex != null) {
			Container dynamicAp = this.getControl("dmp_dynamicap");
			dynamicAp.getItems().addAll(dynamicFlex.buildRuntimeControl().getItems());
			this.getView().createControlIndex(dynamicAp.getItems());
		}
	}

4、重写onGetControl:向表单添加控件添加编程模型实例,并侦听控件的插件事件

/**
	 * 向表单添加控件编程模型实例,并侦听控件的插件事件
	 *
	 * @param e
	 */
	@Override
	public void onGetControl(OnGetControlArgs e) {
		String pk = String.valueOf(this.getProjectId());
		QFilter qFilter = new QFilter("dmp_project", QCP.equals, pk);
		Map<Object, DynamicObject> stages = BusinessDataServiceHelper.loadFromCache(Constant.KEY_PROGJRCTSTAGE_FORMID,
				Constant.PROGJRCTSTAGE_SELECTFIELD, new QFilter[] { qFilter });
		if (stages != null) {
			for (DynamicObject stage : stages.values()) {
				String stagePk = stage.getPkValue().toString();
				if (StringUtils.equals(stagePk, e.getKey())) {
					Container container = new Container();
					container.setKey(stagePk);
					container.setView(this.getView());
					container.addClickListener(this);
					e.setControl(container);
					break;
				}
			}
		}

	}

5、重写afterBindData:根据实际的业务数据为动态创建的进度条赋值

/**
	 * 为动态创建的进度条赋值
	 *
	 * @param e
	 */
	@Override
	public void afterBindData(EventObject e) {
		super.afterBindData(e);
		Object pk = this.getModel().getValue("dmp_projectid");
		QFilter qFilter = new QFilter("dmp_project", QCP.equals, pk);
		// 根据项目id去获取项目迭代
		Map<Object, DynamicObject> stages = BusinessDataServiceHelper.loadFromCache(Constant.KEY_PROGJRCTSTAGE_FORMID,
				Constant.PROGJRCTSTAGE_SELECTFIELD, new QFilter[] { qFilter });
		if (stages != null && stages.size() > 0) {
			String cachestage = this.getPageCache().get("cachestage");
			String stageid = null;
			if (cachestage != null && cachestage != "") {
				stageid = cachestage;
			} else {
				stageid = lastStage;
			}
			
			// 展示未完成数量
			String projectId = String.valueOf(pk);
			this.handleCardData(stageid, projectId);
			int size = stages.size();
			setDmpIindex(size);
			int i = 0;
			this.getModel().batchCreateNewEntryRow("dmp_entryentityflex", size);
			for (DynamicObject stage : stages.values()) {
				String stagePk = stage.getPkValue().toString();
				String stageName = stage.getString("name");
				// 给页面初始化单据体dmp_entryentityflex
				this.getModel().setValue("dmp_stageidtext", stagePk, i);
				this.getModel().setValue("dmp_firstflex", i, i);// dmp_stagename
				this.getModel().setValue("dmp_stagename", stageName, i);
				int length = this.getLength(stagePk, String.valueOf(pk));
				float finished = this.getFinished(stagePk, projectId);
				float progress = length != 0 ? (finished / length) * 100 : 0;
				ProgressBar progressBar = this.getControl("progressbar" + i);
				progressBar.setPercent((int) progress);
				i++;
			}
			this.getView().updateView("dmp_entryentityflex");
			// 初始化单据体数据
			this.handleTableData();
			PointLineChart pointLineChart = this.getMainChart();
			this.drawChart(pointLineChart);

		}

	}

四、实现效果

原单:

image.png

动态添加后:

image.png

五、开发环境版本­­­­

4.0.012.0

六、参考资料

【开发平台】指导手册

学习成长中心




赞 4