@steedos-widgets/amis-lib 3.6.2-beta.10 → 3.6.2-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.esm.js CHANGED
@@ -1281,6 +1281,7 @@ var frontend_notifications$1 = "Notifications";
1281
1281
  var frontend_notifications_allread$1 = "Mark all as read";
1282
1282
  var frontend_notifications_allread_message$1 = "All marked as read";
1283
1283
  var frontend_profile$1 = "Profile";
1284
+ var switch_space$1 = "Switch Space";
1284
1285
  var frontend_about$1 = "About";
1285
1286
  var frontend_log_out$1 = "Log out";
1286
1287
  var frontend_listview_warning_start$1 = "The current ";
@@ -1368,6 +1369,7 @@ var en_us = {
1368
1369
  frontend_notifications_allread: frontend_notifications_allread$1,
1369
1370
  frontend_notifications_allread_message: frontend_notifications_allread_message$1,
1370
1371
  frontend_profile: frontend_profile$1,
1372
+ switch_space: switch_space$1,
1371
1373
  frontend_about: frontend_about$1,
1372
1374
  frontend_log_out: frontend_log_out$1,
1373
1375
  frontend_listview_warning_start: frontend_listview_warning_start$1,
@@ -1457,6 +1459,7 @@ var frontend_notifications = "通知";
1457
1459
  var frontend_notifications_allread = "全部标记为已读";
1458
1460
  var frontend_notifications_allread_message = "已全部标记为已读";
1459
1461
  var frontend_profile = "个人资料";
1462
+ var switch_space = "切换工作区";
1460
1463
  var frontend_about = "关于";
1461
1464
  var frontend_log_out = "注销";
1462
1465
  var frontend_listview_warning_start = "当前";
@@ -1545,6 +1548,7 @@ var zh_cn = {
1545
1548
  frontend_notifications_allread: frontend_notifications_allread,
1546
1549
  frontend_notifications_allread_message: frontend_notifications_allread_message,
1547
1550
  frontend_profile: frontend_profile,
1551
+ switch_space: switch_space,
1548
1552
  frontend_about: frontend_about,
1549
1553
  frontend_log_out: frontend_log_out,
1550
1554
  frontend_listview_warning_start: frontend_listview_warning_start,
@@ -12923,13 +12927,83 @@ async function getFormBody(permissionFields, formFields, ctx){
12923
12927
  return await getSections(permissionFields, formFields, ctx);
12924
12928
  }
12925
12929
 
12930
+ /*
12931
+ * @Author: 殷亮辉 yinlianghui@hotoa.com
12932
+ * @Date: 2024-01-18 15:12:41
12933
+ * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
12934
+ * @LastEditTime: 2024-01-18 15:12:49
12935
+ */
12936
+ /**
12937
+ * 生成符合标准uuid格式的36位满足唯一性的随机串
12938
+ * @returns uuid
12939
+ */
12940
+ function uuidv4() {
12941
+ return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c =>
12942
+ (c ^ window.crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
12943
+ );
12944
+ }
12945
+
12926
12946
  /*
12927
12947
  * @Author: 殷亮辉 yinlianghui@hotoa.com
12928
12948
  * @Date: 2023-11-15 09:50:22
12929
12949
  * @LastEditors: 殷亮辉 yinlianghui@hotoa.com
12930
- * @LastEditTime: 2024-01-18 10:29:57
12950
+ * @LastEditTime: 2024-01-21 23:40:13
12931
12951
  */
12932
12952
 
12953
+ function getTablePrimaryKey(props){
12954
+ return props.primaryKey || "_id";
12955
+ }
12956
+
12957
+ /**
12958
+ * 子表组件字段值中每行数据的补上唯一标识字段值,其值为随机uuid
12959
+ * @param {*} value 子表组件字段值,数组
12960
+ * @param {*} primaryKey 主键字段名,一般为_id
12961
+ * @returns 转换后的子表组件字段值
12962
+ */
12963
+ function getTableValueWithPrimaryKeyValue(value, primaryKey){
12964
+ if(!primaryKey){
12965
+ return value;
12966
+ }
12967
+ return (value || []).map((itemValue)=>{
12968
+ //这里不clone的话,会造成在pipeIn函数执行该函数后像pipeOut一样最终输出到表单项中,即库里把primaryKey字段值保存了
12969
+ const newItemValue = clone(itemValue);
12970
+ if(newItemValue[primaryKey]){
12971
+ if(newItemValue.children){
12972
+ newItemValue.children = getTableValueWithPrimaryKeyValue(newItemValue.children, primaryKey);
12973
+ }
12974
+ return newItemValue;
12975
+ }
12976
+ else {
12977
+ newItemValue[primaryKey] = uuidv4();
12978
+ if(newItemValue.children){
12979
+ newItemValue.children = getTableValueWithPrimaryKeyValue(newItemValue.children, primaryKey);
12980
+ }
12981
+ return newItemValue;
12982
+ }
12983
+ });
12984
+ }
12985
+
12986
+ /**
12987
+ * 子表组件字段值中每行数据的移除唯一标识字段值,因为该字段值一般只作临时标记,不存库
12988
+ * @param {*} value 子表组件字段值,数组
12989
+ * @param {*} primaryKey 主键字段名,一般为_id
12990
+ * @returns 转换后的子表组件字段值
12991
+ */
12992
+ function getTableValueWithoutPrimaryKeyValue(value, primaryKey){
12993
+ if(!primaryKey){
12994
+ return value;
12995
+ }
12996
+ return (value || []).map((itemValue)=>{
12997
+ //这里clone只是为了保险,不是必须的,每次修改子表数据是否都会生成新的primaryKey字段值是由pipeOut中识别autoGeneratePrimaryKeyValue决定的,跟这里没关系
12998
+ const newItemValue = clone(itemValue);
12999
+ if(newItemValue.children){
13000
+ newItemValue.children = getTableValueWithoutPrimaryKeyValue(newItemValue.children, primaryKey);
13001
+ }
13002
+ delete newItemValue[primaryKey];
13003
+ return newItemValue;
13004
+ });
13005
+ }
13006
+
12933
13007
  /**
12934
13008
  * 子表组件字段值中每行数据的键值key移除指定前缀
12935
13009
  * @param {*} value 子表组件字段值,数组
@@ -12941,7 +13015,9 @@ function getTableValueWithoutFieldPrefix(value, fieldPrefix){
12941
13015
  (value || []).forEach((itemValue)=>{
12942
13016
  var newItemValue = {};
12943
13017
  for(let n in itemValue){
12944
- newItemValue[n.replace(new RegExp(`^${fieldPrefix}`), "")] = itemValue[n];
13018
+ if(itemValue.hasOwnProperty(n)){
13019
+ newItemValue[n.replace(new RegExp(`^${fieldPrefix}`), "")] = itemValue[n];
13020
+ }
12945
13021
  }
12946
13022
  convertedValue.push(newItemValue);
12947
13023
  });
@@ -12954,15 +13030,18 @@ function getTableValueWithoutFieldPrefix(value, fieldPrefix){
12954
13030
  * @param {*} fieldPrefix 字段前缀
12955
13031
  * @returns 转换后的子表组件字段值
12956
13032
  */
12957
- function getTableValuePrependFieldPrefix(value, fieldPrefix){
13033
+ function getTableValuePrependFieldPrefix(value, fieldPrefix, primaryKey){
12958
13034
  let convertedValue = [];
12959
13035
  (value || []).forEach((itemValue)=>{
12960
13036
  var newItemValue = {};
12961
13037
  for(let n in itemValue){
12962
- if(typeof itemValue[n] !== undefined){
13038
+ if(itemValue.hasOwnProperty(n) && typeof itemValue[n] !== undefined && n !== primaryKey){
12963
13039
  newItemValue[`${fieldPrefix}${n}`] = itemValue[n];
12964
13040
  }
12965
13041
  }
13042
+ if(primaryKey && itemValue[primaryKey]){
13043
+ newItemValue[primaryKey] = itemValue[primaryKey];
13044
+ }
12966
13045
  convertedValue.push(newItemValue);
12967
13046
  });
12968
13047
  return convertedValue;
@@ -12987,7 +13066,12 @@ function getTableFieldsWithoutFieldPrefix(fields, fieldPrefix){
12987
13066
  * @param {*} mode edit/new/readonly
12988
13067
  */
12989
13068
  function getFormFields(props, mode = "edit") {
12990
- return (props.fields || []).map(function (item) {
13069
+ let fieldPrefix = props.fieldPrefix;
13070
+ let fields = props.fields || [];
13071
+ if (fieldPrefix) {
13072
+ fields = getTableFieldsWithoutFieldPrefix(fields, fieldPrefix);
13073
+ }
13074
+ return (fields || []).map(function (item) {
12991
13075
  let formItem = {
12992
13076
  "type": "steedos-field",
12993
13077
  "name": item.name,
@@ -13059,7 +13143,12 @@ async function getInputTableColumns(props) {
13059
13143
  let inlineEditMode = props.inlineEditMode;
13060
13144
  let showAsInlineEditMode = inlineEditMode && props.editable;
13061
13145
  // 实测过,直接不生成对应的隐藏column并不会对input-table值造成丢失问题,隐藏的列字段值能正常维护
13062
- let fields = props.fields;
13146
+
13147
+ let fieldPrefix = props.fieldPrefix;
13148
+ let fields = props.fields || [];
13149
+ if (fieldPrefix) {
13150
+ fields = getTableFieldsWithoutFieldPrefix(fields, fieldPrefix);
13151
+ }
13063
13152
  if (columns && columns.length) {
13064
13153
  return columns.map(function (column) {
13065
13154
  let field, extendColumnProps = {};
@@ -13128,6 +13217,8 @@ function getFormPagination(props, mode) {
13128
13217
  let currentIndex = event.data.index;
13129
13218
  // 翻页到下一页之前需要先把当前页改动的内容保存到中间变量__tableItems中
13130
13219
  let currentFormValues = scope.getComponentById(__formId).getValues();
13220
+ // 这里不clone的话,其值会带上__super属性
13221
+ currentFormValues = _.clone(currentFormValues);
13131
13222
  var parent = event.data.parent;
13132
13223
  var __parentIndex = event.data.__parentIndex;
13133
13224
  if(parent){
@@ -13247,6 +13338,7 @@ function getFormPaginationWrapper(props, form, mode) {
13247
13338
  // console.log("==getFormPaginationWrapper===", props, mode);
13248
13339
  let serviceId = getComponentId("form_pagination", props.id);
13249
13340
  let tableServiceId = getComponentId("table_service", props.id);
13341
+ let primaryKey = getTablePrimaryKey(props);
13250
13342
  let innerForm = Object.assign({}, form, {
13251
13343
  "data": {
13252
13344
  // 这里加__super前缀是因为__parentForm变量(即主表单)中可能会正好有名为index的字段
@@ -13274,7 +13366,6 @@ function getFormPaginationWrapper(props, form, mode) {
13274
13366
  }
13275
13367
  ];
13276
13368
  let onServiceInitedScript = `
13277
-
13278
13369
  // 以下脚本解决了有时弹出编辑表单时,表单中的值比最后一次编辑保存的值会延迟一拍。
13279
13370
  // 比如:inlineEditMode模式时,用户在表格单元格中直接修改数据,然后弹出的表单form中并没有包含单元格中修改的内容
13280
13371
  // 另外有的地方在非inlineEditMode模式时也会有这种延迟一拍问题,比如对象字段中下拉框类型字段的”选择项“属性
@@ -13288,13 +13379,13 @@ function getFormPaginationWrapper(props, form, mode) {
13288
13379
  // 这里不可以用event.data["${props.name}"]因为amis input talbe有一层单独的作用域,其值会延迟一拍
13289
13380
  // 这里如果不.clone的话,在弹出窗口中显示的子表组件,添加行后点窗口的取消按钮关闭窗口后无法把之前的操作还原,即把之前添加的行自动移除
13290
13381
  let lastestFieldValue = _.clone(wrapperServiceData["${props.name}"] || []);
13291
- let fieldPrefix = "${props.fieldPrefix}";
13382
+ let fieldPrefix = "${props.fieldPrefix || ''}";
13292
13383
  if(fieldPrefix){
13293
13384
  let getTableValueWithoutFieldPrefix = new Function('v', 'f', "return (" + ${getTableValueWithoutFieldPrefix.toString()} + ")(v, f)");
13294
13385
  lastestFieldValue = getTableValueWithoutFieldPrefix(lastestFieldValue, fieldPrefix);
13295
13386
  }
13296
13387
  //不可以直接像event.data.__tableItems = lastestFieldValue; 这样整个赋值,否则作用域会断
13297
- let mode = "${mode}";
13388
+ let mode = "${mode || ''}";
13298
13389
  if(mode === "new"){
13299
13390
  // 点击子表组件底部新增按钮时新增一条空白行并自动翻页到新增行
13300
13391
  // 注意点击弹出的子表行详细表单中的新增按钮不会进此service init事件函数中
@@ -13320,10 +13411,20 @@ function getFormPaginationWrapper(props, form, mode) {
13320
13411
  var fieldValue = event.data.__tableItems;
13321
13412
  if(parent){
13322
13413
  // 如果是子行,即在节点嵌套情况下,当前节点如果是children属性下的子节点时,则算出其所属父行的索引值
13323
- var primaryKey = "${props.primaryKey}";
13414
+ var primaryKey = "${primaryKey}";
13324
13415
  event.data.__parentIndex = _.findIndex(fieldValue, function(item){
13325
13416
  return item[primaryKey] == parent[primaryKey];
13326
13417
  });
13418
+ if(event.data.__parentIndex < 0){
13419
+ let tableId = "${props.id}";
13420
+ let table = scope.getComponentById(tableId)
13421
+ // autoGeneratePrimaryKeyValue不为true的情况下,即子表组件input-table的pipeOut函数中会移除表单了子表字段的primaryKey字段值,
13422
+ // 此时行primaryKey字段值为空,但是pipeIn函数中已经为input-table自动生成过primaryKey字段值了,只是没有输出到表单字段值中而已
13423
+ // 所以上面从表单字段值中没找到__parentIndex,是因为此时行primaryKey字段值只经过pipeIn保存到table组件内而没有保存到tableService
13424
+ event.data.__parentIndex = _.findIndex(table.props.value, function(item){
13425
+ return item[primaryKey] == parent[primaryKey];
13426
+ });
13427
+ }
13327
13428
  }
13328
13429
  `;
13329
13430
  let schema = {
@@ -13372,6 +13473,7 @@ function getFormPaginationWrapper(props, form, mode) {
13372
13473
  async function getForm(props, mode = "edit", formId) {
13373
13474
  let formFields = getFormFields(props, mode);
13374
13475
  let body = await getFormBody(null, formFields);
13476
+ let primaryKey = getTablePrimaryKey(props);
13375
13477
  if (!formId) {
13376
13478
  formId = getComponentId("form", props.id);
13377
13479
  }
@@ -13390,6 +13492,18 @@ async function getForm(props, mode = "edit", formId) {
13390
13492
  // 新增行弹出编辑行表单,在弹出之前已经不用先增加一行,因为在翻页service初始化的时候会判断mode为new时自动新增一行
13391
13493
  let onEditItemSubmitScript = `
13392
13494
  // let fieldValue = _.cloneDeep(event.data["${props.name}"]);
13495
+ let removeEmptyItems = function(items){
13496
+ let i = _.findIndex(items, function(item){
13497
+ return item === undefined
13498
+ });
13499
+ if(i > -1){
13500
+ items.splice(i, 1);
13501
+ removeEmptyItems(items);
13502
+ }
13503
+ }
13504
+ // 因为删除时只是把input-table组件中的行数据删除了,并没有把父层service中的行删除,所以__tableItems会有值为undefined的数据,需要移除掉
13505
+ // 不用event.data.__tableItems = _.compact(event.data.__tableItems)是因为会把__tableItems变量保存到表单中
13506
+ removeEmptyItems(event.data.__tableItems);
13393
13507
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13394
13508
  //这里加__super.__super前缀是因为__parentForm变量(即主表单)中可能会正好有名为index的字段
13395
13509
  // 比如“对象字段”对象options字段是一个子表字段,但是主表(即“对象字段”对象)中正好有一个名为index的字段
@@ -13398,6 +13512,8 @@ async function getForm(props, mode = "edit", formId) {
13398
13512
  var currentFormValues = JSON.parse(JSON.stringify(event.data));
13399
13513
  var parent = event.data.__super.__super.parent;
13400
13514
  var __parentIndex = event.data.__super.__super.__parentIndex;
13515
+ let uuidv4 = new Function("return (" + ${uuidv4.toString()} + ")()");
13516
+ var primaryKey = "${primaryKey}";
13401
13517
  if(parent){
13402
13518
  fieldValue[__parentIndex].children[currentIndex] = currentFormValues;
13403
13519
  // 重写父节点,并且改变其某个属性以让子节点修改的内容回显到界面上
@@ -13407,6 +13523,8 @@ async function getForm(props, mode = "edit", formId) {
13407
13523
  });
13408
13524
  }
13409
13525
  else{
13526
+ // 这里currentFormValues中如果没有primaryKey字段值不用处理,因为组件的pipeIn/pipeOut中会为每行自动生成
13527
+ // 也不用担心复制行时_id会重复,因为点击复制按钮时已经处理过了
13410
13528
  fieldValue[currentIndex] = currentFormValues;
13411
13529
  }
13412
13530
  doAction({
@@ -13504,6 +13622,7 @@ async function getForm(props, mode = "edit", formId) {
13504
13622
  */
13505
13623
  async function getButtonActions(props, mode) {
13506
13624
  let actions = [];
13625
+ let primaryKey = getTablePrimaryKey(props);
13507
13626
  let formId = getComponentId("form", props.id);
13508
13627
  let dialogId = getComponentId("dialog", props.id);
13509
13628
  let buttonNextId = getComponentId("button_next", props.id);
@@ -13546,13 +13665,35 @@ async function getButtonActions(props, mode) {
13546
13665
  // };
13547
13666
  let onSaveAndNewItemScript = `
13548
13667
  let scope = event.context.scoped;
13668
+ let removeEmptyItems = function(items){
13669
+ let i = _.findIndex(items, function(item){
13670
+ return item === undefined
13671
+ });
13672
+ if(i > -1){
13673
+ items.splice(i, 1);
13674
+ removeEmptyItems(items);
13675
+ }
13676
+ }
13677
+ // 因为删除时只是把input-table组件中的行数据删除了,并没有把父层service中的行删除,所以__tableItems会有值为undefined的数据,需要移除掉
13678
+ // 不用event.data.__tableItems = _.compact(event.data.__tableItems)是因为会把__tableItems变量保存到表单中
13679
+ removeEmptyItems(event.data.__tableItems);
13549
13680
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13550
13681
  // 新建一条空白行并保存到子表组件
13551
13682
  var parent = event.data.__super.parent;
13552
- var primaryKey = "${props.primaryKey}";
13683
+ var primaryKey = "${primaryKey}";
13553
13684
  var __parentIndex = parent && _.findIndex(fieldValue, function(item){
13554
13685
  return item[primaryKey] == parent[primaryKey];
13555
13686
  });
13687
+ if(parent && __parentIndex < 0){
13688
+ let tableId = "${props.id}";
13689
+ let table = scope.getComponentById(tableId)
13690
+ // autoGeneratePrimaryKeyValue不为true的情况下,即子表组件input-table的pipeOut函数中会移除表单了子表字段的primaryKey字段值,
13691
+ // 此时行primaryKey字段值为空,但是pipeIn函数中已经为input-table自动生成过primaryKey字段值了,只是没有输出到表单字段值中而已
13692
+ // 所以上面从表单字段值中没找到__parentIndex,是因为此时行primaryKey字段值只经过pipeIn保存到table组件内而没有保存到tableService
13693
+ __parentIndex = _.findIndex(table.props.value, function(item){
13694
+ return item[primaryKey] == parent[primaryKey];
13695
+ });
13696
+ }
13556
13697
  if(parent){
13557
13698
  fieldValue[__parentIndex].children.push({});
13558
13699
  // 这里实测不需要fieldValue[__parentIndex] = ... 来重写整个父行让子表回显,所以没加相关代码
@@ -13586,14 +13727,42 @@ async function getButtonActions(props, mode) {
13586
13727
  let __formId = "${formId}";
13587
13728
  // let newItem = JSON.parse(JSON.stringify(event.data));
13588
13729
  let newItem = scope.getComponentById(__formId).getValues();//这里不可以用event.data,因为其拿到的是弹出表单时的初始值,不是用户实时填写的数据
13730
+ newItem = _.clone(newItem);
13731
+ let removeEmptyItems = function(items){
13732
+ let i = _.findIndex(items, function(item){
13733
+ return item === undefined
13734
+ });
13735
+ if(i > -1){
13736
+ items.splice(i, 1);
13737
+ removeEmptyItems(items);
13738
+ }
13739
+ }
13740
+ // 因为删除时只是把input-table组件中的行数据删除了,并没有把父层service中的行删除,所以__tableItems会有值为undefined的数据,需要移除掉
13741
+ // 不用event.data.__tableItems = _.compact(event.data.__tableItems)是因为会把__tableItems变量保存到表单中
13742
+ removeEmptyItems(event.data.__tableItems);
13589
13743
  let fieldValue = event.data.__tableItems;//这里不可以_.cloneDeep,因为翻页form中用的是event.data.__tableItems,直接变更其值即可改变表单中的值
13590
13744
  // 复制当前页数据到新建行并保存到子表组件
13591
13745
  // fieldValue.push(newItem);
13592
13746
  var parent = event.data.__super.parent;
13593
- var primaryKey = "${props.primaryKey}";
13747
+ var primaryKey = "${primaryKey}";
13594
13748
  var __parentIndex = parent && _.findIndex(fieldValue, function(item){
13595
13749
  return item[primaryKey] == parent[primaryKey];
13596
13750
  });
13751
+ if(parent && __parentIndex < 0){
13752
+ let tableId = "${props.id}";
13753
+ let table = scope.getComponentById(tableId)
13754
+ // autoGeneratePrimaryKeyValue不为true的情况下,即子表组件input-table的pipeOut函数中会移除表单了子表字段的primaryKey字段值,
13755
+ // 此时行primaryKey字段值为空,但是pipeIn函数中已经为input-table自动生成过primaryKey字段值了,只是没有输出到表单字段值中而已
13756
+ // 所以上面从表单字段值中没找到__parentIndex,是因为此时行primaryKey字段值只经过pipeIn保存到table组件内而没有保存到tableService
13757
+ __parentIndex = _.findIndex(table.props.value, function(item){
13758
+ return item[primaryKey] == parent[primaryKey];
13759
+ });
13760
+ }
13761
+ if(newItem[primaryKey]){
13762
+ // 如果newItem已经有主键字段值,则重新生成新的主键值,否则会重复。
13763
+ let uuidv4 = new Function("return (" + ${uuidv4.toString()} + ")()");
13764
+ newItem[primaryKey] = uuidv4();
13765
+ }
13597
13766
  if(parent){
13598
13767
  fieldValue[__parentIndex].children.push(newItem);
13599
13768
  // 这里实测不需要fieldValue[__parentIndex] = ... 来重写整个父行让子表回显,所以没加相关代码
@@ -13817,13 +13986,24 @@ async function getButtonActions(props, mode) {
13817
13986
  let wrapperServiceData = wrapperService.getData();
13818
13987
  // 这里不可以用event.data["${props.name}"]因为amis input talbe有一层单独的作用域,其值会延迟一拍
13819
13988
  // 这里_.clone是因为字段设计布局设置分组这种弹出窗口中的子表组件,直接删除后,点取消无法还原
13989
+ // 也因为这里clone没有直接删除,所以弹出编辑表单提交事件中event.data.__tableItems中取到的值会有被删除的行数据为undefined
13820
13990
  let lastestFieldValue = _.clone(wrapperServiceData["${props.name}"]);
13821
13991
  var currentIndex = event.data.index;
13822
13992
  var parent = event.data.__super.parent;
13823
- var primaryKey = "${props.primaryKey}";
13993
+ var primaryKey = "${primaryKey}";
13824
13994
  var __parentIndex = parent && _.findIndex(lastestFieldValue, function(item){
13825
13995
  return item[primaryKey] == parent[primaryKey];
13826
13996
  });
13997
+ if(parent && __parentIndex < 0){
13998
+ let tableId = "${props.id}";
13999
+ let table = scope.getComponentById(tableId)
14000
+ // autoGeneratePrimaryKeyValue不为true的情况下,即子表组件input-table的pipeOut函数中会移除表单了子表字段的primaryKey字段值,
14001
+ // 此时行primaryKey字段值为空,但是pipeIn函数中已经为input-table自动生成过primaryKey字段值了,只是没有输出到表单字段值中而已
14002
+ // 所以上面从表单字段值中没找到__parentIndex,是因为此时行primaryKey字段值只经过pipeIn保存到table组件内而没有保存到tableService
14003
+ __parentIndex = _.findIndex(table.props.value, function(item){
14004
+ return item[primaryKey] == parent[primaryKey];
14005
+ });
14006
+ }
13827
14007
  if(parent){
13828
14008
  lastestFieldValue[__parentIndex].children.splice(currentIndex, 1);
13829
14009
  // 重写父节点,并且改变其某个属性以让子节点修改的内容回显到界面上
@@ -13835,6 +14015,11 @@ async function getButtonActions(props, mode) {
13835
14015
  else{
13836
14016
  lastestFieldValue.splice(currentIndex, 1);
13837
14017
  }
14018
+ let fieldPrefix = "${props.fieldPrefix || ''}";
14019
+ if(fieldPrefix){
14020
+ let getTableValueWithoutFieldPrefix = new Function('v', 'f', "return (" + ${getTableValueWithoutFieldPrefix.toString()} + ")(v, f)");
14021
+ lastestFieldValue = getTableValueWithoutFieldPrefix(lastestFieldValue, fieldPrefix);
14022
+ }
13838
14023
  doAction({
13839
14024
  "componentId": "${props.id}",
13840
14025
  "actionType": "setValue",
@@ -13920,16 +14105,15 @@ const getAmisInputTableSchema = async (props) => {
13920
14105
  if (!props.id) {
13921
14106
  props.id = "steedos_input_table_" + props.name + "_" + Math.random().toString(36).substr(2, 9);
13922
14107
  }
13923
- if (!props.primaryKey) {
13924
- props.primaryKey = "_id";
13925
- }
14108
+ let primaryKey = getTablePrimaryKey(props);
13926
14109
  let showOperation = props.showOperation;
13927
14110
  if(showOperation !== false){
13928
14111
  showOperation = true;
13929
14112
  }
13930
- // props.fieldPrefix = "project_milestone_";
13931
- if (props.fieldPrefix) {
13932
- props.fields = getTableFieldsWithoutFieldPrefix(props.fields, props.fieldPrefix);
14113
+ let fieldPrefix = props.fieldPrefix;
14114
+ let fields = props.fields || [];
14115
+ if (fieldPrefix) {
14116
+ fields = getTableFieldsWithoutFieldPrefix(fields, fieldPrefix);
13933
14117
  }
13934
14118
  let serviceId = getComponentId("table_service", props.id);
13935
14119
  let buttonsForColumnOperations = [];
@@ -13942,7 +14126,7 @@ const getAmisInputTableSchema = async (props) => {
13942
14126
  // 始终显示弹出子表表单按钮,如果需要判断只在有列被隐藏时才需要显示弹出表单按钮放开下面的if逻辑就好
13943
14127
  showEditButton = true;
13944
14128
  // // inline edit模式下只在有列被隐藏时才需要显示编辑按钮
13945
- // if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length) {
14129
+ // if (props.columns && props.columns.length > 0 && props.columns.length < fields.length) {
13946
14130
  // showEditButton = true;
13947
14131
  // }
13948
14132
  // else {
@@ -13957,7 +14141,7 @@ const getAmisInputTableSchema = async (props) => {
13957
14141
  }
13958
14142
  else {
13959
14143
  // 只读时显示查看按钮
13960
- // 如果想只在有列被隐藏时才需要显示查看按钮可以加上判断:if (props.columns && props.columns.length > 0 && props.columns.length < props.fields.length)
14144
+ // 如果想只在有列被隐藏时才需要显示查看按钮可以加上判断:if (props.columns && props.columns.length > 0 && props.columns.length < fields.length)
13961
14145
  let buttonViewSchema = await getButtonView(props);
13962
14146
  buttonsForColumnOperations.push(buttonViewSchema);
13963
14147
  }
@@ -13966,7 +14150,7 @@ const getAmisInputTableSchema = async (props) => {
13966
14150
  buttonsForColumnOperations.push(buttonDeleteSchema);
13967
14151
  }
13968
14152
  }
13969
- let amis = props["input-table"] || props.amis;//额外支持"input-table"代替amis属性,是因为在字段yml文件中用amis作为key不好理解
14153
+ let amis = props["input-table"] || props.amis || {};//额外支持"input-table"代替amis属性,是因为在字段yml文件中用amis作为key不好理解
13970
14154
  let inputTableSchema = {
13971
14155
  "type": "input-table",
13972
14156
  "label": props.label,
@@ -13985,13 +14169,42 @@ const getAmisInputTableSchema = async (props) => {
13985
14169
  "showTableAddBtn": false,
13986
14170
  "showFooterAddBtn": false,
13987
14171
  "className": props.tableClassName,
14172
+ "pipeIn": (value, data) => {
14173
+ if(fieldPrefix){
14174
+ value = getTableValueWithoutFieldPrefix(value, fieldPrefix);
14175
+ }
14176
+ if(primaryKey){
14177
+ // 这里临时给每行数据补上primaryKey字段值,如果库里不需要保存这里补上的字段值,pipeOut中会识别autoGeneratePrimaryKeyValue属性选择最终移除这里补上的字段值
14178
+ // 这里始终自动生成primaryKey字段值,而不是只在pipeOut输出整个子表字段值时才生成,是因为要支持当数据库里保存的子表字段行数据没有primaryKey字段值时的行嵌套模式(即节点的children属性)功能
14179
+ // 这里要注意,流程详细设置界面的字段设置功能中的子表组件中,数据库里保存的子表字段行数据是有primaryKey字段值的,它不依赖这里自动生成行primaryKey值功能
14180
+ value = getTableValueWithPrimaryKeyValue(value, primaryKey);
14181
+ }
14182
+ if(amis.pipeIn){
14183
+ if(typeof amis.pipeIn === 'function'){
14184
+ return amis.pipeIn(value, data);
14185
+ }
14186
+ }
14187
+ return value;
14188
+ },
13988
14189
  "pipeOut": (value, data) => {
13989
14190
  value = (value || []).map(function(item){
13990
14191
  delete item.__fix_rerender_after_children_modified_tag;
13991
14192
  return item;
13992
14193
  });
13993
- if(props.fieldPrefix){
13994
- value = getTableValuePrependFieldPrefix(value, props.fieldPrefix);
14194
+ if(fieldPrefix){
14195
+ value = getTableValuePrependFieldPrefix(value, fieldPrefix, primaryKey);
14196
+ }
14197
+ if(props.autoGeneratePrimaryKeyValue === true){
14198
+ // 如果需要把自动生成的primaryKey值输出保存的库中,则补全所有行中的primaryKey值
14199
+ // 这里如果不全部补全的话,初始从库里返回的字段值中拿到的行没primaryKey值的话就不会自动补上
14200
+ value = getTableValueWithPrimaryKeyValue(value, primaryKey);
14201
+ }
14202
+ else {
14203
+ // 默认情况下,也就是没有配置autoGeneratePrimaryKey时,最终输出的字段值要移除行中的primaryKey值
14204
+ // 需要注意如果没有配置autoGeneratePrimaryKey时,因为每次弹出行编辑窗口保存后都会先后进入pipeOut和pipeIn,
14205
+ // 这里删除掉了primaryKey值,所以primaryKey值每次弹出编辑窗口保存后都会给每行重新生成新的primaryKey值
14206
+ // 只有autoGeneratePrimaryKey配置为true时,每行的primaryKey字段值才会始终保持不变
14207
+ value = getTableValueWithoutPrimaryKeyValue(value, primaryKey);
13995
14208
  }
13996
14209
  if(amis.pipeOut){
13997
14210
  if(typeof amis.pipeOut === 'function'){
@@ -14001,20 +14214,6 @@ const getAmisInputTableSchema = async (props) => {
14001
14214
  return value;
14002
14215
  }
14003
14216
  };
14004
- if(amis.pipeIn){
14005
- inputTableSchema.pipeIn = amis.pipeIn;
14006
- }
14007
- if(props.fieldPrefix){
14008
- inputTableSchema.pipeIn = (value, data) => {
14009
- value = getTableValueWithoutFieldPrefix(value, props.fieldPrefix);
14010
- if(amis.pipeIn){
14011
- if(typeof amis.pipeIn === 'function'){
14012
- return amis.pipeIn(value, data);
14013
- }
14014
- }
14015
- return value;
14016
- };
14017
- }
14018
14217
  if (buttonsForColumnOperations.length) {
14019
14218
  inputTableSchema.columns.push({
14020
14219
  "name": "__op__",
@@ -14033,7 +14232,7 @@ const getAmisInputTableSchema = async (props) => {
14033
14232
  delete amis.pipeOut;//该属性在上面合并过了
14034
14233
  Object.assign(inputTableSchema, amis);
14035
14234
  }
14036
- const isAnyFieldHasDependOn = (props.fields || []).find(function (item) {
14235
+ const isAnyFieldHasDependOn = (fields || []).find(function (item) {
14037
14236
  return item.depend_on;
14038
14237
  });
14039
14238
  if (isAnyFieldHasDependOn) {