npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

bpm-generateform-ui

v2.10.33

Published

bpm-generateform-ui 表单生成器

Downloads

80

Readme

name

bpm-generateform-ui 表单生成器

安装依赖

npm install

本地启动

npm run dev

编译

npm run build

Lints and fixes files

npm run lint

Customize configuration

See Configuration Reference.

应用

应用在bpm工作台pc端网站

用法

安装

在 main.js 中导入和注册vue组件;

import wgForm from 'bpm-generateform-ui';
import i18n from './i18n';
import 'bpm-generateform-ui/dist/generateform.css';

Vue.use(wgForm, { i18n: (key, value) => i18n.t(key, value) });

基本模块

<template>
  <wg-form :jsonData="jsonData"
    :value="value"
    :loading="loading"
    :remote="remote"
    :debug="debug"
    @on-upload="handleUplod"
    ref="dyForm">
  </wg-form>
</template>

<script>
import formMixin from './formMixin';

export default {
  mixins: [formMixin],
};
</script>

wg-form 组件的属性值,动态组件中获取 表单数据和结果,向下传递给 ;

事件模块

<template>
  <wg-form :jsonData="jsonData"
    :value="value"
    :loading="loading"
    :remote="remote"
    :debug="debug"
    @on-department-change="handleDepartment"
    @on-biz_fin_audit_material_detailList-row-change="handle_table_row_Change"
    @on-biz_fin_audit_material_detailList-layout-change="handleProductionTableLayout"
    @on-biz_fin_audit_material_detailList-delRow="handle_table_delRow"
    @on-upload="handleUplod"
    ref="dyForm">
    <!--只要关心wg-form组件事件-->
  </wg-form>
</template>

只要关注事件和对应的回调方法,属性赋值不用关注,项目中已做好赋值; 颗粒度:针对每个表单项; 事件名称规则:@on-[name]-change;

wg-form组件 props 属性

| 属性 | 类型 | 默认值 | 说明 | |--------|--------|--------|--------| |debug | Boolean| false | 是否是调试模式,调试模式页面会有些调试信息输出 | |loading | Boolean| false | 是否显示loading效果 | |jsonData | Object| {list: [], config: {}} | form动态结构数据 | |value | Object| {} | 表单数据 | |remote | Object| {} | 远程数据获取方法 |

这些配置属性,项目中无需关注,上一层调用者使用props方式赋值;

我们的关注点在事件定义回调处理业务逻辑;

jsonData例子

JSONData:

{
	"list": [
		{
			"type": "input",
			"icon": "icon-input",
			"name": "编码",
			"options": {
				"width": "100%",
				"defaultValue": "",
				"required": false,
				"dataType": "",
				"pattern": "",
				"placeholder": "请输入...",
				"customClass": "",
				"disabled": false,
				"hidden": false,
				"dataBind": true,
				"remoteFunc": "",
				"remoteOption": "",
				"tooltip": "",
				"maxlength": null,
				"minlength": null,
				"fixedlength": null,
				"span": 12
			},
			"rules": [],
			"key": "1619509006000_30277",
			"model": "bm",
			"langTitle": [
				{
					"label": "zh_CN",
					"value": "编码"
				},
				{
					"label": "en_US",
					"value": "Bm"
				}
			],
			"langPlaceholder": [
				{
					"label": "zh_CN",
					"value": "请输入..."
				},
				{
					"label": "en_US",
					"value": "Please input..."
				}
			]
		}
	],
	"config": {
		"labelWidth": 140,
		"labelPosition": "right",
		"size": "small",
		"customClass": "",
		"model": "test_obj"
	}
}

以上定义了一个文本框,标题是编码,字段名称是 bm;业务对象 test_obj;

收集的表单数据:

{
	"test_obj": {
		"bm": "A0005"
	}
}

wg-form组件 事件

事件名称是动态的,没有固定名,我们给每个表单项目(字段)定义的事件;

| 事件名称 | 说明 | 回调参数 | |--------|--------|--------| |on-[fieldName]-change | 输入后、选择后触发,文本框、下拉框、单选框、日历等都具有此事件| Function({value,...other})| |on-[fieldName]-confirm | 应用在对话框dialog组件 ,选择完对话框数据确定时| Function({value,...other})| |on-[fieldName]-row-change | 应用在表格组件,某行上组件change事件;| Function({value,...other})| |on-[fieldName]-delRow | 应用在表格组件,删除一行表格数据时触发;| Function({value,...other})| |on-[fieldName]-layout-change | 应用在表格组件,切换显示布局方式时触发;| Function({value,...other})|

wg-form组件 方法

| 名称 | 说明 | 参数 |例子| |--------|--------|--------|--------| | setFieldsValue | 给表单指定字段设置值| Function(values:Object)| this.$refs.dyForm.setFieldsValue({ official_seal: 'demo' });| | getFieldsValue | 获取表单中指定字段值| Function(fields:Array)| this.$refs.dyForm.getFieldsValue(['official_seal']);| | showFields | 显示一组字段,不常用,会影响布局,页面抖动| Function(fields: Array)| this.$refs.dyForm.showFields(['official_seal']);| | hideFields | 隐藏一组字段,不常用,会影响布局,页面抖动| Function(fields: Array)| this.$refs.dyForm.hideFields(['official_seal']);| | addRule | 给某个字段绑定自定义数据校验规则| Function(field: String,ruleId: String,rule: Object)| | | removeRule | 删除自定义的校验器规则| Function(field: String, ruleId: String)| 使用参数 ruleId 寻找,因此需要与addRule 中的ruleId 匹配;|

3.实例

页面状态

当前表单所处状态;

  • create: 发起新流程
  • approval: 处于审批中
  • view: 处于查看页面,比如【我的申请】

4.例子

判断当前是发起页面

if (this.action === this.actionEnum.create){
  // TODO code
}

判断当前是发起和退回重新提交

const { nodeId } = this.routeParam;
      if (this.action === this.actionEnum.create || (this.action === this.actionEnum.approval && nodeId === 'UserStart')) {
  // TODO code
}

判断当前是审批页面

if (this.action === this.actionEnum.approval){
  // TODO code
}

判断当前所处节点位置

const { nodeId } = this.routeParam;
if (nodeId === 'UserTask12') {
  // TODO code
}

url 参数 nodeId 存储了节点名称;

获取某些字段值

const val = dyForm.getFieldsValue(['travel_total', 'entertain_total', 'other_total','biz_ceo_reimbursement_travel_detailList']);

根据条件,设置字段必填和禁用

 handleIsRDProject(param) {
  if (param.value === 'Y') {
    const enFields = ['project_name'];
    const disFields = ['travel_total'];
    this.setFieldStatus(enFields, disFields);
  } else {
    const enFields = ['travel_total'];
    const disFields = ['project_name'];
    this.setFieldStatus(enFields, disFields);
  }
}

setFieldStatus反复的第一个参数表单要设置必填字段;第二个字段设置禁用字段;

给表单设置值


this.$refs.dyForm.setFieldsValue({ official_seal: 'demo',foo:null });

一般不会主动赋值,基本是设置null,来清除值;

根据条件,显示或隐藏一组字段

 const { dyForm } = this.$refs;
  if (param.value === 'Y') {
    dyForm.showFields(['card_origin']);
  } else {
    dyForm.hideFields(['card_origin']);
  }

添加自定义校验规则


initNumberRules() {
  if (this.action === this.actionEnum.create) {
  // 给start_date字段设置自定义校验,由方法this.checkDate处理
    this.$refs.dyForm.addRule('start_date', 'checkDate', { validator: this.checkDate });
    this.$refs.dyForm.addRule('end_date', 'checkDate', { validator: this.checkDate });
  }
},
checkDate(rule, value, callback) {
  const { start_date: startDate, end_date: endDate } = this.$refs.dyForm.getFieldsValue(['start_date', 'end_date']);
  if (startDate && endDate) {
    const start = moment(startDate);
    const end = moment(endDate);
    const days = end.diff(start, 'days');
    if (days > 365) {
      callback('最大周期应小于1年');
      return;
    } if (days < 0) {
      callback('开始日期应小于结束日期');
      return;
    }
    callback();
  }
  callback();
},

设置select框选项,二级联动

 handleContractStyle(param) {
    this.$refs.dyForm.form.setFieldsValue({
      contract_type: '',
    });
    this.$refs.dyForm.formItems.contract_type.initOptions({ typeCode: param.value });
    this.contractRequire();
  },

字段 contract_type 的下拉框集合是动态的,当 contract_type 字段变动值确定入参;

转化为大写金额 smallToBig

handle_toBig(param) {
  this.$refs.dyForm.setFieldsValue({ amount_upper: smallToBig(param.value) });
}

同一行计算

使用 plus 函数

handle_travel_table_row_Change(param) {
  // 人员单价、人员天数,相乘计算总费用
  if (['plane_ticket', 'train_tickets', 'oil_cost', 'road_toll', 'hotel_expense', 'city_traffic_expense', 'entertain_expenses', 'other_expenses', 'subsidy'].includes(param.field)) {
    const {
      plane_ticket = 0, train_tickets = 0, oil_cost = 0, road_toll = 0, hotel_expense = 0, city_traffic_expense = 0, entertain_expenses = 0, other_expenses = 0, subsidy,
    } = param.row;
    const total = plus(plane_ticket, train_tickets, oil_cost, road_toll, hotel_expense, city_traffic_expense, entertain_expenses, other_expenses, subsidy);
    const subtotal = this.getItemName(param.parentField, 'subtotal', param.rowIndex);
    this.$refs.dyForm.setFieldsValue({ [subtotal]: total });
  }
}

行计算

handle_table_row_Change(param) {
      const { row } = param;
      row.c = row.a + row.b;
      this.$refs.dyForm.form.setFieldsValue({
        [`${param.parentField}[${param.index}]`]: row,
      });
    },

远程方法

表单设计器中下拉框组件,当设置远程数据源时,实际是设置一个唯一的方法名,该方法具有远程获取数据能力;

方法名需要预先准备,设计两个文件:

方法名文件:src/components/remoteOption.js

数据请求文件:src/api/bpm/remoteFunc.js

数据接口无参数

在文件 src/components/remoteOption.js 中增加方法名

 getFooList(cb) {
    bpm.getFooList().then((res) => {
      const data = res.list.map(item => ({
        label: item.name,
        value: item.code,
        item,
      }));
      cb(data);
    });
  },

在 src/api/bpm/remoteFunc.js 实现 bpm.getFooList 数据接口;

数据接口 有参数

在文件 src/components/remoteOption.js 中增加方法名

  getParamFooList(cb, { args = [], otherArgs = {} }) {
    // 参数名称,调用和使用对应上
    let [barId] = args;
    if (barId === '') {
      cb([]);
      return;
    }
    bpm.getParamFooList({ barId, otherArgs }).then((res) => {
      const data = res.list.map(item => ({
        label: `(${item.code})${item.name}`,
        value: item.code,
        item,
      }));
      cb(data);
    });
  },

在 src/api/bpm/remoteFunc.js 实现 bpm.getParamFooList 数据接口;

附件字段

{
  "file": "[{\"uid\":\"142fb161-858d-42b5-873f-33aa263d32ab.png\",\"name\":\"bpm.png\",\"status\":\"done\",\"url\":\"https://download-test.ecarxgroup.com/minio-fileserver/minio/file/download/bpm/142fb161-858d-42b5-873f-33aa263d32ab.png\",\"contentType\":\"image/png\",\"suffix\":\".png\"}]"
  "其他字段":"这个一个字符串字段"
}

如果第三方系统需要向BPM推送数据,附件字段是序列化的字符串,字段名和格式如上;

发布

发布脚本

sh npm-publish.sh
  1. 工程以 npm 公有包 向外发布;
  2. 为什么要对外发布,此包并非仅自己使用,多个公司或客户在使用,处于维护期;

发布前调试

$npm link

npm包在测试阶段调试需要了解 npm link 命令的使用; 作用是,创建全局软链接;

应用此组件的项目使用

$npm link bpm-generateform-ui