@gct-paas/word 0.1.47-beta.13 → 0.1.47-beta.14

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.es.js CHANGED
@@ -49743,11 +49743,7 @@ class DataManager {
49743
49743
  }
49744
49744
  /** 收集与字段绑定相关的路径(含 value / label / href 及通配符变体) */
49745
49745
  collectFieldBindingPaths(designValuePath) {
49746
- const bases = [
49747
- designValuePath,
49748
- getLabelPath(designValuePath),
49749
- getHrefPath(designValuePath)
49750
- ];
49746
+ const bases = [designValuePath, getLabelPath(designValuePath), getHrefPath(designValuePath)];
49751
49747
  const wildcardKeys = new Set(bases.map((path) => this.convertPathToWildcard(path)));
49752
49748
  const result = new Set(bases);
49753
49749
  const scanTargets = [
@@ -55132,6 +55128,7 @@ const apiFetchers = {
55132
55128
  const result = await api.apaas.designerCommon.getGetCanBeUsedOrgUser({
55133
55129
  modelKey,
55134
55130
  fieldKey,
55131
+ onlyHasSeat: true,
55135
55132
  pageSize: API_CONFIG.USER_PAGE_SIZE
55136
55133
  });
55137
55134
  const { data = [], totalCount, totalPage } = result || {};
@@ -106364,16 +106361,21 @@ Schema.warning = warning;
106364
106361
  Schema.messages = messages;
106365
106362
  Schema.validators = validators;
106366
106363
  const buildError = (validatorInfo, message) => JSON.stringify({ ...validatorInfo, message });
106367
- const createRule = (validator2, message) => ({
106364
+ const createRule = (validator2, message, trigger = "change") => ({
106368
106365
  required: true,
106369
106366
  validator: validator2,
106370
- message
106367
+ message,
106368
+ trigger
106371
106369
  });
106372
106370
  const requiredRule = (ctx) => {
106373
106371
  if (!ctx.showRequired) return null;
106374
- return createRule((_rule, value, _callback, _source, _options) => {
106375
- return !isEmptyValue$1(value);
106376
- }, buildError(ctx.validatorInfo, "字段为必填项!"));
106372
+ return createRule(
106373
+ (_rule, value, _callback, _source, _options) => {
106374
+ return !isEmptyValue$1(value);
106375
+ },
106376
+ buildError(ctx.validatorInfo, "字段为必填项!"),
106377
+ "manual"
106378
+ );
106377
106379
  };
106378
106380
  const minNumberRule = (ctx) => {
106379
106381
  if (ctx.enableRangeValidate && ctx.minValidateMode === RangeValidateModeTypeConst.Fixed_Number) {
@@ -106403,6 +106405,7 @@ const minNumberFormulaRule = (ctx) => {
106403
106405
  if (ctx.enableRangeValidate && ctx.minValidateMode === RangeValidateModeTypeConst.Variable_Validate && ctx.minFormulaExpr) {
106404
106406
  return {
106405
106407
  required: true,
106408
+ trigger: "change",
106406
106409
  async validator(_rule, value, _callback, _source, _options) {
106407
106410
  const rawData = ctx.getRawData();
106408
106411
  const subRowData = ctx.getSubRowFormData(ctx.validatorInfo.runtimeValuePath);
@@ -106425,6 +106428,7 @@ const maxNumberFormulaRule = (ctx) => {
106425
106428
  if (ctx.enableRangeValidate && ctx.maxValidateMode === RangeValidateModeTypeConst.Variable_Validate && ctx.maxFormulaExpr) {
106426
106429
  return {
106427
106430
  required: true,
106431
+ trigger: "change",
106428
106432
  async validator(_rule, value, _callback, _source, _options) {
106429
106433
  const rawData = ctx.getRawData();
106430
106434
  const subRowData = ctx.getSubRowFormData(ctx.validatorInfo.runtimeValuePath);
@@ -106475,6 +106479,7 @@ const minTimeFormulaRule = (ctx) => {
106475
106479
  if (ctx.enableRangeValidate && ctx.minDateValidateMode === RangeValidateModeTypeConst.Variable_Validate && ctx.minDateFormulaExpr) {
106476
106480
  return {
106477
106481
  required: true,
106482
+ trigger: "change",
106478
106483
  async validator(_rule, value, _callback, _source, _options) {
106479
106484
  const rawData = ctx.getRawData();
106480
106485
  const subRowData = ctx.getSubRowFormData(ctx.validatorInfo.runtimeValuePath);
@@ -106504,6 +106509,7 @@ const maxTimeFormulaRule = (ctx) => {
106504
106509
  if (ctx.enableRangeValidate && ctx.maxDateValidateMode === RangeValidateModeTypeConst.Variable_Validate && ctx.maxDateFormulaExpr) {
106505
106510
  return {
106506
106511
  required: true,
106512
+ trigger: "change",
106507
106513
  async validator(_rule, value, _callback, _source, _options) {
106508
106514
  const rawData = ctx.getRawData();
106509
106515
  const subRowData = ctx.getSubRowFormData(ctx.validatorInfo.runtimeValuePath);
@@ -106529,6 +106535,17 @@ const maxTimeFormulaRule = (ctx) => {
106529
106535
  }
106530
106536
  return null;
106531
106537
  };
106538
+ function filterRulesByTrigger(rules2, trigger) {
106539
+ if (trigger === "all") return rules2;
106540
+ return rules2.filter((rule) => {
106541
+ const ruleTrigger = rule.trigger;
106542
+ if (!ruleTrigger) return trigger === "change";
106543
+ if (trigger === "blur") {
106544
+ return ruleTrigger === "blur" || ruleTrigger === "change";
106545
+ }
106546
+ return ruleTrigger === trigger;
106547
+ });
106548
+ }
106532
106549
  const assembleRules = (ctx) => {
106533
106550
  const rules2 = [
106534
106551
  requiredRule(ctx),
@@ -106569,13 +106586,49 @@ function createValidateAll() {
106569
106586
  }
106570
106587
  };
106571
106588
  }
106589
+ async function waitForDataSettle() {
106590
+ await nextTick();
106591
+ await new Promise((resolve) => setTimeout(resolve, 0));
106592
+ }
106593
+ const DEBOUNCE_MS$1 = 300;
106594
+ const schedulersByDocId = /* @__PURE__ */ new Map();
106595
+ function getScheduler(doc) {
106596
+ let scheduler = schedulersByDocId.get(doc.id);
106597
+ if (!scheduler) {
106598
+ scheduler = { debounceTimer: null, running: false, pendingTrigger: "change" };
106599
+ schedulersByDocId.set(doc.id, scheduler);
106600
+ }
106601
+ return scheduler;
106602
+ }
106603
+ function clearScheduler(doc) {
106604
+ const scheduler = schedulersByDocId.get(doc.id);
106605
+ if (!scheduler) return;
106606
+ if (scheduler.debounceTimer) {
106607
+ clearTimeout(scheduler.debounceTimer);
106608
+ scheduler.debounceTimer = null;
106609
+ }
106610
+ schedulersByDocId.delete(doc.id);
106611
+ }
106612
+ function pruneStaleValidationComments(doc, map) {
106613
+ if (!map) return null;
106614
+ const validPaths = new Set(listWidgetValuePaths(doc));
106615
+ const next = {};
106616
+ for (const [path, errors] of Object.entries(map)) {
106617
+ if (validPaths.has(path)) {
106618
+ next[path] = errors;
106619
+ }
106620
+ }
106621
+ return Object.keys(next).length ? next : null;
106622
+ }
106572
106623
  function showValidationComments(doc, map) {
106573
- doc.eventManager.dispatchCustom("inter:show-validation-comment", map);
106624
+ doc.eventManager.dispatchCustom(
106625
+ "inter:show-validation-comment",
106626
+ pruneStaleValidationComments(doc, map)
106627
+ );
106574
106628
  }
106575
- function hasValidationComments(doc) {
106576
- if (!doc) return false;
106577
- const map = doc.interactionManager.get("validationCommentMap");
106578
- return !!map && Object.keys(map).length > 0;
106629
+ function pruneValidationComments(doc) {
106630
+ const current = doc.interactionManager.get("validationCommentMap");
106631
+ showValidationComments(doc, current);
106579
106632
  }
106580
106633
  function findLayoutNodeByValuePath(doc, runtimeValuePath) {
106581
106634
  let found;
@@ -106656,72 +106709,113 @@ function buildWidgetValidationPayload(doc, widget) {
106656
106709
  rules: rules2
106657
106710
  };
106658
106711
  }
106659
- const validateAllFields = async (doc) => {
106712
+ function clearResolvedManualErrors(doc, map) {
106713
+ if (!map) return map;
106714
+ const next = { ...map };
106715
+ for (const path of Object.keys(next)) {
106716
+ const widget = findLayoutNodeByValuePath(doc, path);
106717
+ const payload = widget ? buildWidgetValidationPayload(doc, widget) : null;
106718
+ if (!payload) continue;
106719
+ const hasManual = filterRulesByTrigger(payload.rules, "manual").length > 0;
106720
+ const hasLive = filterRulesByTrigger(payload.rules, "change").length > 0;
106721
+ if (hasManual && !hasLive && !isEmptyValue$1(payload.value)) {
106722
+ delete next[path];
106723
+ }
106724
+ }
106725
+ return Object.keys(next).length ? next : null;
106726
+ }
106727
+ function mergeLiveValidation(doc, liveResult, livePaths) {
106728
+ const current = doc.interactionManager.get("validationCommentMap");
106729
+ const base = current && Object.keys(current).length ? { ...current } : {};
106730
+ for (const path of livePaths) {
106731
+ if (liveResult?.[path]) {
106732
+ base[path] = liveResult[path];
106733
+ } else {
106734
+ delete base[path];
106735
+ }
106736
+ }
106737
+ const merged = Object.keys(base).length ? base : liveResult;
106738
+ return clearResolvedManualErrors(doc, merged);
106739
+ }
106740
+ async function runValidation(doc, mode) {
106660
106741
  const formState = {};
106661
106742
  const formRules = {};
106743
+ const livePaths = [];
106662
106744
  for (const runtimeValuePath of listWidgetValuePaths(doc)) {
106663
106745
  const widget = findLayoutNodeByValuePath(doc, runtimeValuePath);
106664
106746
  if (!widget) continue;
106665
106747
  const payload = buildWidgetValidationPayload(doc, widget);
106666
106748
  if (!payload) continue;
106749
+ const activeRules = filterRulesByTrigger(payload.rules, mode);
106750
+ if (!activeRules.length) continue;
106667
106751
  formState[payload.runtimeValuePath] = payload.value;
106668
- formRules[payload.runtimeValuePath] = payload.rules;
106752
+ formRules[payload.runtimeValuePath] = activeRules;
106753
+ if (mode !== "all") {
106754
+ livePaths.push(payload.runtimeValuePath);
106755
+ }
106756
+ }
106757
+ if (!Object.keys(formRules).length) {
106758
+ if (mode === "all") {
106759
+ showValidationComments(doc, null);
106760
+ }
106761
+ return null;
106669
106762
  }
106670
106763
  const validateAll = createValidateAll();
106671
106764
  const result = await validateAll(formRules, formState);
106672
106765
  console.log("validateAllFields", result);
106673
- showValidationComments(doc, result);
106766
+ if (mode === "all") {
106767
+ showValidationComments(doc, result);
106768
+ } else {
106769
+ showValidationComments(doc, mergeLiveValidation(doc, result, livePaths));
106770
+ }
106674
106771
  return result;
106675
- };
106676
- const DEBOUNCE_MS$1 = 300;
106677
- const schedulers = /* @__PURE__ */ new WeakMap();
106678
- function registerDocValidationRefresh(doc, options) {
106679
- let debounceTimer = null;
106680
- let running = false;
106681
- const scheduler = {
106682
- schedule(opts) {
106683
- if (options.isSuppressed()) return;
106684
- if (!hasValidationComments(doc)) return;
106685
- if (debounceTimer) {
106686
- clearTimeout(debounceTimer);
106687
- debounceTimer = null;
106688
- }
106689
- const run = async () => {
106690
- if (running || options.isSuppressed()) return;
106691
- running = true;
106692
- try {
106693
- await waitForDataManagerSettle();
106694
- if (!hasValidationComments(doc)) return;
106695
- await validateAllFields(doc);
106696
- } finally {
106697
- running = false;
106698
- }
106699
- };
106700
- if (opts?.immediate) {
106701
- void run();
106702
- return;
106703
- }
106704
- debounceTimer = setTimeout(() => {
106705
- debounceTimer = null;
106706
- void run();
106707
- }, DEBOUNCE_MS$1);
106708
- },
106709
- dispose() {
106710
- if (debounceTimer) {
106711
- clearTimeout(debounceTimer);
106712
- debounceTimer = null;
106713
- }
106772
+ }
106773
+ async function executeValidation(doc, trigger) {
106774
+ const scheduler = getScheduler(doc);
106775
+ if (scheduler.running) {
106776
+ scheduler.pendingTrigger = trigger === "all" ? "all" : trigger;
106777
+ return;
106778
+ }
106779
+ scheduler.running = true;
106780
+ try {
106781
+ await waitForDataSettle();
106782
+ await runValidation(doc, trigger);
106783
+ const pending = scheduler.pendingTrigger;
106784
+ scheduler.pendingTrigger = "change";
106785
+ if (pending !== trigger) {
106786
+ await runValidation(doc, pending);
106714
106787
  }
106715
- };
106716
- schedulers.set(doc, scheduler);
106717
- return () => {
106718
- scheduler.dispose();
106719
- schedulers.delete(doc);
106720
- };
106788
+ } finally {
106789
+ scheduler.running = false;
106790
+ }
106791
+ }
106792
+ function requestFullValidation(doc, options = {}) {
106793
+ const { immediate = false, trigger = "change" } = options;
106794
+ const scheduler = getScheduler(doc);
106795
+ if (immediate) {
106796
+ if (scheduler.debounceTimer) {
106797
+ clearTimeout(scheduler.debounceTimer);
106798
+ scheduler.debounceTimer = null;
106799
+ }
106800
+ void executeValidation(doc, trigger);
106801
+ return;
106802
+ }
106803
+ scheduler.pendingTrigger = trigger;
106804
+ if (scheduler.debounceTimer) {
106805
+ clearTimeout(scheduler.debounceTimer);
106806
+ }
106807
+ scheduler.debounceTimer = setTimeout(() => {
106808
+ scheduler.debounceTimer = null;
106809
+ void executeValidation(doc, scheduler.pendingTrigger);
106810
+ }, DEBOUNCE_MS$1);
106721
106811
  }
106722
- function requestValidationRefresh(doc, immediate = false) {
106723
- schedulers.get(doc)?.schedule({ immediate });
106812
+ function disposeDocValidationScheduler(doc) {
106813
+ clearScheduler(doc);
106724
106814
  }
106815
+ const validateAllFields = async (doc) => {
106816
+ await waitForDataSettle();
106817
+ return runValidation(doc, "all");
106818
+ };
106725
106819
  const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106726
106820
  __name: "overlay-render",
106727
106821
  props: {
@@ -106809,16 +106903,21 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106809
106903
  const showActionIcon = computed(() => !!actionConfig.value.icon);
106810
106904
  watch(
106811
106905
  () => [interCtx.focusModelId, interCtx.focusTick],
106812
- ([modelId], [oldModelId]) => {
106906
+ async ([modelId], [oldModelId]) => {
106813
106907
  const isCurrent = modelId === props.modelId;
106814
106908
  const wasCurrent = oldModelId === props.modelId;
106815
106909
  if (wasCurrent && !isCurrent) {
106816
106910
  console.log("blur");
106817
- props.doc.eventManager.dispatchCustom("ime:commit-validate", {
106818
- valuePath: runtimeValuePath.value,
106819
- formats: buildNumberFormats(widgetProps.value, widgetType.value)
106820
- });
106821
- requestValidationRefresh(props.doc);
106911
+ const commitTasks = props.doc.eventManager.dispatchCustom(
106912
+ "ime:commit-validate",
106913
+ {
106914
+ valuePath: runtimeValuePath.value,
106915
+ formats: buildNumberFormats(widgetProps.value, widgetType.value)
106916
+ }
106917
+ );
106918
+ await Promise.all(commitTasks);
106919
+ await waitForDataManagerSettle();
106920
+ requestFullValidation(props.doc, { immediate: true, trigger: "blur" });
106822
106921
  }
106823
106922
  if (isCurrent) {
106824
106923
  console.log("focus");
@@ -106867,7 +106966,6 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106867
106966
  designCtx.runtime.getMasterSlaveFieldList(props.doc.mainModelKey)
106868
106967
  );
106869
106968
  props.doc.dataManager.setMultiple({ ...payload, ...dataValues });
106870
- requestValidationRefresh(props.doc, true);
106871
106969
  }
106872
106970
  }
106873
106971
  });
@@ -106924,7 +107022,6 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106924
107022
  const savedValue = await bodyRef?.value?.onSave?.();
106925
107023
  if (!savedValue) return;
106926
107024
  props.doc.dataManager.setMultiple(savedValue);
106927
- requestValidationRefresh(props.doc, true);
106928
107025
  close();
106929
107026
  } catch (error) {
106930
107027
  GctMessage.warning("业务处理失败,请联系管理员");
@@ -106947,7 +107044,9 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106947
107044
  if (subFieldValuePath && isNumber(dataIndex)) {
106948
107045
  const parsed = parseValuePath(subFieldValuePath);
106949
107046
  const { parentFieldPath } = parsed;
106950
- const allRegions = props.doc.model?.document.body.children.flatMap((w2) => w2.name === "w:tbl" ? w2.regions : []);
107047
+ const allRegions = props.doc.model?.document.body.children.flatMap(
107048
+ (w2) => w2.name === "w:tbl" ? w2.regions : []
107049
+ );
106951
107050
  const isMaterialConsumeTable = allRegions?.find((r) => r.valuePath === parentFieldPath)?.type === "material-consume-table";
106952
107051
  if (isMaterialConsumeTable && tmplBomCRef?.value) {
106953
107052
  const tableController = tmplBomCRef.value.tableControllers[parentFieldPath];
@@ -106960,7 +107059,6 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
106960
107059
  });
106961
107060
  }
106962
107061
  }
106963
- requestValidationRefresh(props.doc, true);
106964
107062
  }
106965
107063
  return (_ctx, _cache) => {
106966
107064
  return isTargetReady.value ? (openBlock(), createBlock(Teleport, {
@@ -107024,7 +107122,7 @@ const _sfc_main$2O = /* @__PURE__ */ defineComponent({
107024
107122
  };
107025
107123
  }
107026
107124
  });
107027
- const OverlayRender = /* @__PURE__ */ _export_sfc(_sfc_main$2O, [["__scopeId", "data-v-666e31b6"]]);
107125
+ const OverlayRender = /* @__PURE__ */ _export_sfc(_sfc_main$2O, [["__scopeId", "data-v-4da4215f"]]);
107028
107126
  let activeHoverId = 0;
107029
107127
  function useHoverDelay(callback, delay = 120) {
107030
107128
  let timer = null;
@@ -109325,7 +109423,10 @@ const _hoisted_9$a = { class: "item-icon scale-large" };
109325
109423
  const _hoisted_10$7 = { class: "item-label flex-between-center" };
109326
109424
  const _hoisted_11$5 = { class: "item-icon scale-large" };
109327
109425
  const _hoisted_12$4 = { class: "item-label flex-between-center" };
109328
- const _hoisted_13$3 = { class: "action-menu" };
109426
+ const _hoisted_13$3 = {
109427
+ key: 1,
109428
+ class: "action-menu"
109429
+ };
109329
109430
  const _hoisted_14$3 = { class: "item-icon" };
109330
109431
  const _hoisted_15$2 = { class: "more-btn" };
109331
109432
  const _sfc_main$2w = /* @__PURE__ */ defineComponent({
@@ -109372,15 +109473,19 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109372
109473
  const isMaterialConsumeTable = computed(() => {
109373
109474
  return props.cell?.subRenderer?.type === "material-consume-table";
109374
109475
  });
109375
- const isMaterialConsumeTableConfirmed = computed(() => {
109376
- const { subFieldKey } = getCtx();
109377
- const { dataIndex: rowIndex } = props.cell.subRenderer;
109476
+ const computedInfo = computed(() => {
109477
+ const { index: rowIndex, subFieldKey } = getCtx();
109378
109478
  const tableData = docInst.value.dataManager.getRawData()[subFieldKey] ?? [];
109379
- return tableData[rowIndex]?.is_confirmed_;
109479
+ const isDeleteBtnVisible = tableData.length >= 2;
109480
+ const isRowConfirmed = !!tableData[rowIndex]?.is_confirmed_;
109481
+ return {
109482
+ isDeleteBtnVisible,
109483
+ isRowConfirmed
109484
+ };
109380
109485
  });
109381
109486
  const materialMenuList = computed(() => {
109382
109487
  return [
109383
- { icon: "icon-bianji", label: "编辑行", value: "edit", visible: isMaterialConsumeTableConfirmed.value },
109488
+ { icon: "icon-bianji", label: "编辑行", value: "edit", visible: computedInfo.value.isRowConfirmed },
109384
109489
  { icon: "icon-saoyisao", label: "条码扫描", value: "scan", visible: props.isLastGroup },
109385
109490
  { icon: "icon-a-bom11", label: "BOM", value: "bom", visible: props.isLastGroup },
109386
109491
  { icon: "icon-tiaomajiexi", label: "条码解析规则变更", value: "change", visible: props.isLastGroup }
@@ -109390,11 +109495,11 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109390
109495
  if (!tmplBomCRef?.value?.tableControllers || !props.cell?.subRenderer?.valuePath) return;
109391
109496
  const tableController = tmplBomCRef.value.tableControllers[props.cell.subRenderer.valuePath];
109392
109497
  if (!tableController) return;
109393
- const { subFieldKey } = getCtx();
109498
+ const { index: rowIndex, subFieldKey } = getCtx();
109394
109499
  if (!subFieldKey) return;
109395
109500
  const { dataManager } = docInst.value;
109396
109501
  const tableData = dataManager.getRawData()[subFieldKey] ?? [];
109397
- const { dataIndex: rowIndex, tableName } = props.cell.subRenderer;
109502
+ const { tableName } = props.cell.subRenderer;
109398
109503
  let row = tableData[rowIndex];
109399
109504
  const insertEmptyRow = (row2, rowIndex2, cb) => {
109400
109505
  if (!row2) {
@@ -109468,8 +109573,8 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109468
109573
  createElementVNode("div", _hoisted_1$1K, [
109469
109574
  createVNode(unref(_sfc_main$3q), {
109470
109575
  placement: "bottom-end",
109471
- triggers: ["hover"],
109472
- popperTriggers: ["hover"],
109576
+ triggers: ["click"],
109577
+ popperTriggers: ["click"],
109473
109578
  delay: HOVER_DELAY,
109474
109579
  "instant-move": ""
109475
109580
  }, {
@@ -109555,7 +109660,7 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109555
109660
  ])
109556
109661
  ])
109557
109662
  ]),
109558
- createElementVNode("div", _hoisted_13$3, [
109663
+ computedInfo.value.isDeleteBtnVisible ? (openBlock(), createElementBlock("div", _hoisted_13$3, [
109559
109664
  createElementVNode("div", {
109560
109665
  class: "menu-item",
109561
109666
  onClick: _cache[8] || (_cache[8] = ($event) => handleAction("deleteRowCurrent"))
@@ -109565,7 +109670,7 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109565
109670
  ]),
109566
109671
  _cache[16] || (_cache[16] = createElementVNode("div", { class: "item-label" }, " 删除行 ", -1))
109567
109672
  ])
109568
- ])
109673
+ ])) : createCommentVNode("", true)
109569
109674
  ])
109570
109675
  ]),
109571
109676
  default: withCtx(() => [
@@ -109578,7 +109683,7 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109578
109683
  ]),
109579
109684
  _: 1
109580
109685
  }),
109581
- isMaterialConsumeTable.value && __props.isLastGroup && !isMaterialConsumeTableConfirmed.value ? (openBlock(), createElementBlock("div", {
109686
+ isMaterialConsumeTable.value && __props.isLastGroup && !computedInfo.value.isRowConfirmed ? (openBlock(), createElementBlock("div", {
109582
109687
  key: 0,
109583
109688
  class: "confirm-btn",
109584
109689
  onClick: _cache[9] || (_cache[9] = ($event) => handleMaterialConsumeAction("confirm"))
@@ -109594,7 +109699,7 @@ const _sfc_main$2w = /* @__PURE__ */ defineComponent({
109594
109699
  };
109595
109700
  }
109596
109701
  });
109597
- const SubTableAction = /* @__PURE__ */ _export_sfc(_sfc_main$2w, [["__scopeId", "data-v-5e39d20c"]]);
109702
+ const SubTableAction = /* @__PURE__ */ _export_sfc(_sfc_main$2w, [["__scopeId", "data-v-13501110"]]);
109598
109703
  const _sfc_main$2v = /* @__PURE__ */ defineComponent({
109599
109704
  __name: "index",
109600
109705
  props: {
@@ -110493,10 +110598,10 @@ function useDocLooperAutoSaveNotify(factory2, ops, options) {
110493
110598
  function useValidationFullSync(factory2, options) {
110494
110599
  let suppress = true;
110495
110600
  let unsubscribeData = null;
110496
- let unregisterRefresh = null;
110497
110601
  let stopWatchDoc = null;
110498
110602
  let stopWatchTick = null;
110499
110603
  let knownWidgetPaths = /* @__PURE__ */ new Set();
110604
+ let boundDoc = null;
110500
110605
  function isSuppressed() {
110501
110606
  return suppress || !!options?.suppressSignal?.value;
110502
110607
  }
@@ -110506,30 +110611,34 @@ function useValidationFullSync(factory2, options) {
110506
110611
  function disposeSubscriptions() {
110507
110612
  unsubscribeData?.();
110508
110613
  unsubscribeData = null;
110509
- unregisterRefresh?.();
110510
- unregisterRefresh = null;
110511
110614
  stopWatchTick?.();
110512
110615
  stopWatchTick = null;
110616
+ if (boundDoc) {
110617
+ disposeDocValidationScheduler(boundDoc);
110618
+ }
110619
+ boundDoc = null;
110513
110620
  }
110514
110621
  function bindDoc() {
110515
110622
  disposeSubscriptions();
110516
110623
  const doc = factory2.docIns.value;
110517
110624
  if (!doc) return;
110625
+ boundDoc = doc;
110518
110626
  snapshotWidgetPaths(doc);
110519
- unregisterRefresh = registerDocValidationRefresh(doc, { isSuppressed });
110520
110627
  unsubscribeData = doc.dataManager.subscribe("$", () => {
110521
- requestValidationRefresh(doc);
110628
+ if (isSuppressed()) return;
110629
+ requestFullValidation(doc, { trigger: "change" });
110522
110630
  });
110523
110631
  stopWatchTick = watch(
110524
110632
  () => factory2.docInfo.value.updateTick,
110525
110633
  () => {
110526
110634
  const currentDoc = factory2.docIns.value;
110527
- if (!currentDoc || !hasValidationComments(currentDoc)) return;
110635
+ if (!currentDoc || isSuppressed()) return;
110528
110636
  const currentPaths = new Set(listWidgetValuePaths(currentDoc));
110529
110637
  const hasRowStructureChange = [...currentPaths].some((path) => !knownWidgetPaths.has(path)) || [...knownWidgetPaths].some((path) => !currentPaths.has(path));
110530
110638
  if (!hasRowStructureChange) return;
110531
110639
  snapshotWidgetPaths(currentDoc);
110532
- requestValidationRefresh(currentDoc, true);
110640
+ pruneValidationComments(currentDoc);
110641
+ requestFullValidation(currentDoc, { immediate: true, trigger: "change" });
110533
110642
  }
110534
110643
  );
110535
110644
  }
@@ -1,5 +1,7 @@
1
1
  import { Doc } from '../../core';
2
2
  export type ValidateTrigger = 'change' | 'blur' | 'focus' | 'manual';
3
+ /** 按触发时机过滤规则(manual=仅提交,change/blur=编辑时) */
4
+ export declare function filterRulesByTrigger(rules: any[], trigger: ValidateTrigger | 'all'): any[];
3
5
  /** 组装校验 */
4
6
  export declare const assembleRules: (ctx: any) => any;
5
7
  export declare const createValidatorContext: (doc: Doc, ctx: any) => any;
@@ -1,16 +1,28 @@
1
+ import { ValidateTrigger } from './createValidateFactory';
1
2
  import { Doc } from '../../core';
2
3
  export type ValidationCommentMap = Record<string, Array<{
3
4
  field: string;
4
5
  fieldValue: any;
5
6
  message: string;
6
7
  }>> | null;
8
+ export type ValidationRunMode = ValidateTrigger | 'all';
9
+ /** 移除布局中已不存在字段的批注(子表删行等场景) */
10
+ export declare function pruneStaleValidationComments(doc: Doc, map: ValidationCommentMap): ValidationCommentMap;
7
11
  /** 更新校验批注面板 */
8
12
  export declare function showValidationComments(doc: Doc, map: ValidationCommentMap): void;
13
+ /** 立即清理失效批注并刷新面板(子表删行等) */
14
+ export declare function pruneValidationComments(doc: Doc): void;
9
15
  export declare function hasValidationComments(doc: Doc | null | undefined): boolean;
10
16
  /** 按运行时 valuePath 在布局树中查找对应 widget 节点(子表每行 path 唯一) */
11
17
  export declare function findLayoutNodeByValuePath(doc: Doc, runtimeValuePath: string): any;
12
18
  /** 校验批注连线坐标:优先按 valuePath 存取,兼容旧版 modelId */
13
19
  export declare function getValidationCommentPoints(widgetMeta: any, runtimeValuePath: string, modelId?: string): any;
14
20
  export declare function listWidgetValuePaths(doc: Doc): string[];
15
- /** 校验全部字段 */
21
+ /** 请求全量校验(编辑时按 trigger 过滤规则;按钮提交用 mode=all) */
22
+ export declare function requestFullValidation(doc: Doc, options?: {
23
+ immediate?: boolean;
24
+ trigger?: ValidationRunMode;
25
+ }): void;
26
+ export declare function disposeDocValidationScheduler(doc: Doc): void;
27
+ /** 提交校验:执行全部规则(含必填 manual) */
16
28
  export declare const validateAllFields: (doc: Doc) => Promise<any>;
@@ -4,6 +4,6 @@ export interface UseValidationFullSyncOptions {
4
4
  suppressSignal?: ShallowRef<boolean>;
5
5
  }
6
6
  /**
7
- * 批注面板展示期间,在数据变更(防抖)及子表增删行(立即)后自动全量重校验。
7
+ * 文档加载完成后,监听全局数据变更($)并防抖全量重校验;子表增删行后立即全量重校验。
8
8
  */
9
9
  export declare function useValidationFullSync(factory: DocumentFactory, options?: UseValidationFullSyncOptions): () => void;
@@ -19,6 +19,8 @@ interface IDeviceConfig {
19
19
  defaultOrgId: string | undefined;
20
20
  /** 默认的物料查询条件 */
21
21
  defaultProductSearchFields: string;
22
+ /** 是否启用人员字段 false: 不使用 true: 使用;先留着扩展,后续如果需要在字段列表过滤才使用 */
23
+ enableUserField: boolean;
22
24
  }
23
25
  export interface IDocTemplatePayload {
24
26
  /** 渲染模式类型 */
package/dist/word.css CHANGED
@@ -8195,7 +8195,7 @@ textarea[data-v-57fe54a3]::placeholder {
8195
8195
  width: 100%;
8196
8196
  height: 100%;
8197
8197
  }
8198
- .widget-container-action[data-v-666e31b6] {
8198
+ .widget-container-action[data-v-4da4215f] {
8199
8199
  position: absolute;
8200
8200
  inset: 0;
8201
8201
  z-index: 999;
@@ -8203,7 +8203,7 @@ textarea[data-v-57fe54a3]::placeholder {
8203
8203
  height: 0;
8204
8204
  pointer-events: all;
8205
8205
  }
8206
- .picker-trigger[data-v-666e31b6] {
8206
+ .picker-trigger[data-v-4da4215f] {
8207
8207
  width: 100%;
8208
8208
  height: 100%;
8209
8209
  display: flex;
@@ -8215,14 +8215,14 @@ textarea[data-v-57fe54a3]::placeholder {
8215
8215
  border-radius: 2px;
8216
8216
  outline: none;
8217
8217
  }
8218
- .picker-trigger.disabled[data-v-666e31b6] {
8218
+ .picker-trigger.disabled[data-v-4da4215f] {
8219
8219
  cursor: not-allowed;
8220
8220
  border: 1px solid rgba(13, 13, 13, 0.12);
8221
8221
  }
8222
- .picker-trigger.disabled .gct-icon[data-v-666e31b6] {
8222
+ .picker-trigger.disabled .gct-icon[data-v-4da4215f] {
8223
8223
  color: rgba(0, 0, 0, 0.25);
8224
8224
  }
8225
- .picker-trigger.readonly[data-v-666e31b6] {
8225
+ .picker-trigger.readonly[data-v-4da4215f] {
8226
8226
  cursor: default;
8227
8227
  }
8228
8228
  .resize-box[data-v-788ab62c] {
@@ -8680,66 +8680,66 @@ textarea[data-v-57fe54a3]::placeholder {
8680
8680
  .table-action .row-headers .row-header:last-child .row-add-btn[data-v-c40eef9f] .gct-icon.bottom {
8681
8681
  transform: translateY(-100%);
8682
8682
  }
8683
- .sub-table-action-container[data-v-5e39d20c] {
8683
+ .sub-table-action-container[data-v-13501110] {
8684
8684
  position: absolute;
8685
8685
  z-index: 999;
8686
8686
  }
8687
- .sub-table-action-bar[data-v-5e39d20c],
8688
- .sub-table-action-popper[data-v-5e39d20c] {
8687
+ .sub-table-action-bar[data-v-13501110],
8688
+ .sub-table-action-popper[data-v-13501110] {
8689
8689
  pointer-events: auto;
8690
8690
  user-select: none;
8691
8691
  }
8692
- .sub-table-action-bar[data-v-5e39d20c] {
8692
+ .sub-table-action-bar[data-v-13501110] {
8693
8693
  display: flex;
8694
8694
  }
8695
- .sub-table-action-bar .more-btn[data-v-5e39d20c],
8696
- .sub-table-action-bar .confirm-btn[data-v-5e39d20c] {
8695
+ .sub-table-action-bar .more-btn[data-v-13501110],
8696
+ .sub-table-action-bar .confirm-btn[data-v-13501110] {
8697
8697
  display: flex;
8698
8698
  justify-content: center;
8699
8699
  align-items: center;
8700
- width: 26px;
8701
- height: 26px;
8700
+ width: 24px;
8701
+ height: 24px;
8702
8702
  cursor: pointer;
8703
8703
  box-sizing: border-box;
8704
8704
  }
8705
- .sub-table-action-bar .more-btn[data-v-5e39d20c] {
8705
+ .sub-table-action-bar .more-btn[data-v-13501110] {
8706
8706
  width: 10px;
8707
8707
  background: #026ac8;
8708
8708
  border-radius: 0 4px 4px 0;
8709
8709
  }
8710
- .sub-table-action-bar .confirm-btn[data-v-5e39d20c] {
8710
+ .sub-table-action-bar .confirm-btn[data-v-13501110] {
8711
8711
  margin-left: 4px;
8712
8712
  border-radius: 4px;
8713
8713
  border: 1px solid #4ec262;
8714
8714
  }
8715
- .sub-table-action-popper[data-v-5e39d20c] {
8715
+ .sub-table-action-popper[data-v-13501110] {
8716
8716
  padding: 2px 8px;
8717
8717
  }
8718
- .sub-table-action-popper .action-menu[data-v-5e39d20c] {
8718
+ .sub-table-action-popper .action-menu[data-v-13501110] {
8719
8719
  padding: 4px 0;
8720
8720
  width: 220px;
8721
8721
  user-select: none;
8722
8722
  }
8723
- .sub-table-action-popper .action-menu + .action-menu[data-v-5e39d20c] {
8723
+ .sub-table-action-popper .action-menu + .action-menu[data-v-13501110] {
8724
8724
  margin-top: 4px;
8725
8725
  padding-top: 4px;
8726
8726
  border-top: 1px solid #efefef;
8727
8727
  }
8728
- .sub-table-action-popper .action-menu .menu-title[data-v-5e39d20c] {
8728
+ .sub-table-action-popper .action-menu .menu-title[data-v-13501110] {
8729
8729
  color: #bcbcbc;
8730
8730
  margin: 4px 0;
8731
8731
  }
8732
- .sub-table-action-popper .action-menu .menu-item[data-v-5e39d20c] {
8732
+ .sub-table-action-popper .action-menu .menu-item[data-v-13501110] {
8733
8733
  display: flex;
8734
8734
  align-items: center;
8735
8735
  padding: 8px 10px;
8736
8736
  border-radius: 4px;
8737
8737
  }
8738
- .sub-table-action-popper .action-menu .menu-item[data-v-5e39d20c]:hover {
8738
+ .sub-table-action-popper .action-menu .menu-item[data-v-13501110]:hover {
8739
8739
  cursor: pointer;
8740
8740
  background-color: #f2f5f8;
8741
8741
  }
8742
- .sub-table-action-popper .action-menu .menu-item .item-icon[data-v-5e39d20c] {
8742
+ .sub-table-action-popper .action-menu .menu-item .item-icon[data-v-13501110] {
8743
8743
  display: flex;
8744
8744
  align-items: center;
8745
8745
  justify-content: start;
@@ -8747,14 +8747,14 @@ textarea[data-v-57fe54a3]::placeholder {
8747
8747
  width: 20px;
8748
8748
  height: 20px;
8749
8749
  }
8750
- .sub-table-action-popper .action-menu .menu-item .item-icon.scale-large[data-v-5e39d20c] {
8750
+ .sub-table-action-popper .action-menu .menu-item .item-icon.scale-large[data-v-13501110] {
8751
8751
  transform: scale(1.5);
8752
8752
  }
8753
- .sub-table-action-popper .action-menu .menu-item .item-label[data-v-5e39d20c] {
8753
+ .sub-table-action-popper .action-menu .menu-item .item-label[data-v-13501110] {
8754
8754
  flex-grow: 1;
8755
8755
  margin-left: 8px;
8756
8756
  }
8757
- .sub-table-action-popper .action-menu .menu-item .item-label.flex-between-center[data-v-5e39d20c] {
8757
+ .sub-table-action-popper .action-menu .menu-item .item-label.flex-between-center[data-v-13501110] {
8758
8758
  display: flex;
8759
8759
  justify-content: space-between;
8760
8760
  align-items: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gct-paas/word",
3
- "version": "0.1.47-beta.13",
3
+ "version": "0.1.47-beta.14",
4
4
  "description": "GCT 在线 word",
5
5
  "keywords": [
6
6
  "vue",
@@ -1,7 +0,0 @@
1
- import { Doc } from '../../core';
2
- /** 注册文档级防抖全量校验刷新(批注面板已展示时才执行) */
3
- export declare function registerDocValidationRefresh(doc: Doc, options: {
4
- isSuppressed: () => boolean;
5
- }): () => void;
6
- /** 请求在数据/选择/行列变更后刷新全量校验批注 */
7
- export declare function requestValidationRefresh(doc: Doc, immediate?: boolean): void;