dsh-crwu-workbench 0.0.10
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/CHANGELOG.md +1516 -0
- package/LICENSE +26 -0
- package/README.en.md +204 -0
- package/README.md +521 -0
- package/SECURITY.md +39 -0
- package/bin/darwin-arm64/crwu +0 -0
- package/bin/darwin-arm64/dws +0 -0
- package/bin/darwin-arm64/ossutil +0 -0
- package/bin/manifest.json +82 -0
- package/bin/win32-x64/crwu.exe +0 -0
- package/bin/win32-x64/dws.exe +4 -0
- package/bin/win32-x64/ossutil.exe +0 -0
- package/common/skills/.synced.json +8 -0
- package/common/skills/crwu-dws/SKILL.md +208 -0
- package/common/skills/crwu-dws/references/00-/347/233/256/345/275/225/345/277/253/347/205/247schema.md +113 -0
- package/common/skills/crwu-dws/references/01-/345/256/241/346/240/270/344/270/213/350/275/275/344/270/216manifest/350/247/204/350/214/203.md +115 -0
- package/common/skills/crwu-dws/references/02-/347/274/223/345/255/230/344/270/216/345/205/234/345/272/225/346/237/245/346/211/276/350/247/204/350/214/203.md +119 -0
- package/common/skills/crwu-dws/scripts/test_dws_source_contract.py +493 -0
- package/common/skills/crwu-h3yun-login/SKILL.md +130 -0
- package/common/skills/crwu-h3yun-query/SKILL.md +192 -0
- package/config/crwu-workbench.yml +26 -0
- package/cordis.patch.yml +46 -0
- package/lib/client.js +10346 -0
- package/lib/index.js +11584 -0
- package/package.json +119 -0
- package/scripts/prepare.mjs +59 -0
- package/skills/README.md +26 -0
- package/skills/crwu/crwu-audit/SKILL.md +152 -0
- package/skills/crwu/crwu-audit/references/00-input-and-route-profile.md +232 -0
- package/skills/crwu/crwu-audit/references/01-report-id-resolution.md +13 -0
- package/skills/crwu/crwu-audit/references/02-scope-classification.md +25 -0
- package/skills/crwu/crwu-audit/references/03-asset-classification.md +27 -0
- package/skills/crwu/crwu-audit/references/04-business-classification.md +63 -0
- package/skills/crwu/crwu-audit/references/05-method-classification.md +66 -0
- package/skills/crwu/crwu-audit/references/06-overlay-classification.md +42 -0
- package/skills/crwu/crwu-audit/references/07-skill-registry.md +57 -0
- package/skills/crwu/crwu-audit/references/08-union-dispatch-rules.md +142 -0
- package/skills/crwu/crwu-audit/references/09-review-risk-classification.md +85 -0
- package/skills/crwu/crwu-audit/references/10-capability-gap-proposal.md +68 -0
- package/skills/crwu/crwu-audit/references/11-html-delivery-spec.md +881 -0
- package/skills/crwu/crwu-audit/references/12-leaf-common-contract.md +202 -0
- package/skills/crwu/crwu-audit/references/13-dingtalk-result-publish.md +88 -0
- package/skills/crwu/crwu-audit/references/14-orchestration-workflow.md +52 -0
- package/skills/crwu/crwu-audit/references/99-maintenance.md +62 -0
- package/skills/crwu/crwu-audit/scripts/README.md +157 -0
- package/skills/crwu/crwu-audit/scripts/audit_delivery.py +2736 -0
- package/skills/crwu/crwu-audit/scripts/audit_result.schema.json +1659 -0
- package/skills/crwu/crwu-audit/scripts/examples/audit-result.sample.json +739 -0
- package/skills/crwu/crwu-audit/scripts/fetch_review_records.py +85 -0
- package/skills/crwu/crwu-audit/scripts/media_extract.py +513 -0
- package/skills/crwu/crwu-audit/scripts/prepare_materials.py +1252 -0
- package/skills/crwu/crwu-audit/scripts/test_audit_delivery.py +1678 -0
- package/skills/crwu/crwu-audit/scripts/test_audit_multiaxis_router.py +1339 -0
- package/skills/crwu/crwu-audit/scripts/test_fetch_review_records.py +77 -0
- package/skills/crwu/crwu-audit/scripts/test_media_extract.py +332 -0
- package/skills/crwu/crwu-audit/scripts/test_prepare_materials.py +1081 -0
- package/skills/crwu/crwu-audit/template/audit-report.html +435 -0
- package/skills/crwu/crwu-audit-asset-asset-group-goodwill/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-asset-group-goodwill/references/00-applicability.md +28 -0
- package/skills/crwu/crwu-audit-asset-asset-group-goodwill/references/01-kb-assembly.md +31 -0
- package/skills/crwu/crwu-audit-asset-asset-group-goodwill/references/02-review-focus.md +21 -0
- package/skills/crwu/crwu-audit-asset-asset-group-goodwill/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-debt/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-debt/references/00-applicability.md +40 -0
- package/skills/crwu/crwu-audit-asset-debt/references/01-kb-assembly.md +41 -0
- package/skills/crwu/crwu-audit-asset-debt/references/02-review-focus.md +54 -0
- package/skills/crwu/crwu-audit-asset-debt/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-enterprise-value/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-enterprise-value/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-asset-enterprise-value/references/01-kb-assembly.md +35 -0
- package/skills/crwu/crwu-audit-asset-enterprise-value/references/02-review-focus.md +33 -0
- package/skills/crwu/crwu-audit-asset-enterprise-value/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-equipment/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-equipment/references/00-applicability.md +40 -0
- package/skills/crwu/crwu-audit-asset-equipment/references/01-kb-assembly.md +39 -0
- package/skills/crwu/crwu-audit-asset-equipment/references/02-review-focus.md +52 -0
- package/skills/crwu/crwu-audit-asset-equipment/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-intangible/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-intangible/references/00-applicability.md +36 -0
- package/skills/crwu/crwu-audit-asset-intangible/references/01-kb-assembly.md +40 -0
- package/skills/crwu/crwu-audit-asset-intangible/references/02-review-focus.md +68 -0
- package/skills/crwu/crwu-audit-asset-intangible/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-inventory/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-inventory/references/00-applicability.md +28 -0
- package/skills/crwu/crwu-audit-asset-inventory/references/01-kb-assembly.md +31 -0
- package/skills/crwu/crwu-audit-asset-inventory/references/02-review-focus.md +21 -0
- package/skills/crwu/crwu-audit-asset-inventory/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-mining-right/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-mining-right/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-asset-mining-right/references/01-kb-assembly.md +35 -0
- package/skills/crwu/crwu-audit-asset-mining-right/references/02-review-focus.md +33 -0
- package/skills/crwu/crwu-audit-asset-mining-right/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-other/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-other/references/00-applicability.md +28 -0
- package/skills/crwu/crwu-audit-asset-other/references/01-kb-assembly.md +31 -0
- package/skills/crwu/crwu-audit-asset-other/references/02-review-focus.md +21 -0
- package/skills/crwu/crwu-audit-asset-other/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-portfolio/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-portfolio/references/00-applicability.md +28 -0
- package/skills/crwu/crwu-audit-asset-portfolio/references/01-kb-assembly.md +31 -0
- package/skills/crwu/crwu-audit-asset-portfolio/references/02-review-focus.md +21 -0
- package/skills/crwu/crwu-audit-asset-portfolio/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-realestate/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-realestate/references/00-applicability.md +43 -0
- package/skills/crwu/crwu-audit-asset-realestate/references/01-kb-assembly.md +75 -0
- package/skills/crwu/crwu-audit-asset-realestate/references/02-review-focus.md +93 -0
- package/skills/crwu/crwu-audit-asset-realestate/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-scrap-materials/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-scrap-materials/references/00-applicability.md +28 -0
- package/skills/crwu/crwu-audit-asset-scrap-materials/references/01-kb-assembly.md +31 -0
- package/skills/crwu/crwu-audit-asset-scrap-materials/references/02-review-focus.md +21 -0
- package/skills/crwu/crwu-audit-asset-scrap-materials/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-asset-transport-equipment/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-asset-transport-equipment/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-asset-transport-equipment/references/01-kb-assembly.md +35 -0
- package/skills/crwu/crwu-audit-asset-transport-equipment/references/02-review-focus.md +33 -0
- package/skills/crwu/crwu-audit-asset-transport-equipment/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-asset-operation/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-asset-operation/references/00-applicability.md +30 -0
- package/skills/crwu/crwu-audit-biz-asset-operation/references/01-kb-assembly.md +32 -0
- package/skills/crwu/crwu-audit-biz-asset-operation/references/02-review-focus.md +42 -0
- package/skills/crwu/crwu-audit-biz-asset-operation/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-consulting-review/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-consulting-review/references/00-applicability.md +30 -0
- package/skills/crwu/crwu-audit-biz-consulting-review/references/01-kb-assembly.md +32 -0
- package/skills/crwu/crwu-audit-biz-consulting-review/references/02-review-focus.md +40 -0
- package/skills/crwu/crwu-audit-biz-consulting-review/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-financial-reporting/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-financial-reporting/references/00-applicability.md +41 -0
- package/skills/crwu/crwu-audit-biz-financial-reporting/references/01-kb-assembly.md +40 -0
- package/skills/crwu/crwu-audit-biz-financial-reporting/references/02-review-focus.md +64 -0
- package/skills/crwu/crwu-audit-biz-financial-reporting/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-financing-debt/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-financing-debt/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-biz-financing-debt/references/01-kb-assembly.md +34 -0
- package/skills/crwu/crwu-audit-biz-financing-debt/references/02-review-focus.md +47 -0
- package/skills/crwu/crwu-audit-biz-financing-debt/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-investment-capital/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-investment-capital/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-biz-investment-capital/references/01-kb-assembly.md +34 -0
- package/skills/crwu/crwu-audit-biz-investment-capital/references/02-review-focus.md +47 -0
- package/skills/crwu/crwu-audit-biz-investment-capital/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-judicial-liquidation-compensation/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-judicial-liquidation-compensation/references/00-applicability.md +30 -0
- package/skills/crwu/crwu-audit-biz-judicial-liquidation-compensation/references/01-kb-assembly.md +32 -0
- package/skills/crwu/crwu-audit-biz-judicial-liquidation-compensation/references/02-review-focus.md +40 -0
- package/skills/crwu/crwu-audit-biz-judicial-liquidation-compensation/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-tax-history/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-tax-history/references/00-applicability.md +29 -0
- package/skills/crwu/crwu-audit-biz-tax-history/references/01-kb-assembly.md +30 -0
- package/skills/crwu/crwu-audit-biz-tax-history/references/02-review-focus.md +33 -0
- package/skills/crwu/crwu-audit-biz-tax-history/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-biz-transaction-disposal/SKILL.md +38 -0
- package/skills/crwu/crwu-audit-biz-transaction-disposal/references/00-applicability.md +31 -0
- package/skills/crwu/crwu-audit-biz-transaction-disposal/references/01-kb-assembly.md +34 -0
- package/skills/crwu/crwu-audit-biz-transaction-disposal/references/02-review-focus.md +47 -0
- package/skills/crwu/crwu-audit-biz-transaction-disposal/references/03-common-contract.md +202 -0
- package/skills/crwu/crwu-audit-datacheck/SKILL.md +59 -0
- package/skills/crwu/crwu-audit-datacheck/references/00-KB/350/243/205/351/205/215/350/241/250.md +25 -0
- package/skills/crwu/crwu-audit-datacheck/references/01-runtime-and-check-catalog.md +139 -0
- package/skills/crwu/crwu-audit-datacheck/scripts/recalc_check.py +521 -0
- package/skills/crwu/crwu-audit-datacheck/scripts/test_recalc_check.py +419 -0
- package/skills/crwu/crwu-audit-datacheck/scripts/test_skill_self_containment.py +44 -0
- package/skills/crwu/crwu-audit-external-data/SKILL.md +73 -0
- package/skills/crwu/crwu-audit-external-data/references/00-KB/350/243/205/351/205/215/350/241/250.md +38 -0
- package/skills/crwu/crwu-audit-external-data/references/01-connector-access.md +116 -0
- package/skills/crwu/crwu-audit-external-data/references/02-verification-workflow.md +78 -0
- package/skills/crwu/crwu-audit-external-data/scripts/connector_probe.py +374 -0
- package/skills/crwu/crwu-audit-external-data/scripts/test_connector_probe.py +264 -0
- package/skills/crwu/crwu-audit-output-filter/SKILL.md +34 -0
- package/skills/crwu/crwu-audit-output-filter/references/00-applicability.md +7 -0
- package/skills/crwu/crwu-audit-output-filter/references/01-kb-assembly.md +11 -0
- package/skills/crwu/crwu-audit-output-filter/references/02-review-focus.md +25 -0
- package/skills/crwu/crwu-audit-public-general-standards/SKILL.md +46 -0
- package/skills/crwu/crwu-audit-public-general-standards/references/00-applicability.md +41 -0
- package/skills/crwu/crwu-audit-public-general-standards/references/01-kb-assembly.md +66 -0
- package/skills/crwu/crwu-audit-public-general-standards/references/02-review-focus.md +111 -0
- package/skills/crwu/crwu-audit-public-general-standards/references/03-execution-contract.md +89 -0
- package/skills/crwu/crwu-dev-audit-optimize/SKILL.md +98 -0
- package/skills/crwu/crwu-dev-audit-optimize/references/00-/344/274/230/345/214/226/350/247/204/350/214/203/344/270/216/346/226/207/344/273/266/350/220/275/347/202/271.md +132 -0
- package/skills/crwu/crwu-dev-audit-optimize/references/01-/345/217/215/351/246/210/345/256/232/344/275/215/344/270/216/347/224/273/345/203/217/346/265/201/347/250/213.md +108 -0
- package/skills/crwu/crwu-dev-audit-optimize/references/02-/346/226/271/346/241/210/346/250/241/346/235/277/344/270/216/347/241/256/350/256/244/351/227/250/347/246/201.md +92 -0
- package/skills/crwu/crwu-dev-audit-optimize/references/03-AI/344/272/272/345/267/245/345/267/256/350/267/235/345/210/206/346/236/220/346/265/201/347/250/213.md +95 -0
- package/skills/crwu/crwu-dev-audit-optimize/scripts/examples/gap-analysis.sample.json +116 -0
- package/skills/crwu/crwu-dev-audit-optimize/scripts/gap_analysis.schema.json +33 -0
- package/skills/crwu/crwu-dev-audit-optimize/scripts/gap_analysis_delivery.py +475 -0
- package/skills/crwu/crwu-dev-audit-optimize/scripts/test_gap_analysis_delivery.py +855 -0
- package/skills/crwu/crwu-dev-audit-optimize/template/NOTICE.echarts.txt +7 -0
- package/skills/crwu/crwu-dev-audit-optimize/template/echarts.min.js +45 -0
- package/skills/crwu/crwu-dev-audit-optimize/template/gap-analysis-report.html +71 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/SKILL.md +74 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/00-responsibility-and-modes.md +62 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/01-kb-source-discovery.md +89 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/02-child-skill-contract.md +99 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/03-review-item-execution-contract.md +51 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/04-registry-and-mapping-update.md +73 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/05-validation-and-delivery.md +127 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/06-live-routing-reconciliation.md +136 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/references/07-kb-skill-map.md +411 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/scripts/README.md +200 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/scripts/check_audit_skill_mappings.py +2477 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/scripts/kb_tool.py +577 -0
- package/skills/crwu/crwu-dev-audit-skill-maintainer/scripts/test_audit_skill_maintainer.py +5097 -0
- package/skills/dws/LICENSE +178 -0
- package/skills/dws/NOTICE +17 -0
- package/skills/dws/dingtalk-aisearch/SKILL.md +83 -0
- package/skills/dws/dingtalk-aisearch/references/aisearch.md +249 -0
- package/skills/dws/dingtalk-aisearch/references/intent-guide.md +15 -0
- package/skills/dws/dingtalk-aisearch/references/lite-recipes.md +31 -0
- package/skills/dws/dingtalk-aitable/SKILL.md +139 -0
- package/skills/dws/dingtalk-aitable/references/06-data-analytics.md +11 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-advperm.md +251 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-attachment.md +49 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-best-practices.md +48 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-cell-value.md +346 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-dashboard-chart.md +46 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-data-analysis-sop.md +131 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-datasource.md +272 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-error-recovery.md +128 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-export-import.md +113 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-field-properties.md +238 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-field.md +186 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-filter-sort.md +135 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-form.md +130 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-formula-guide.md +224 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-primary-doc.md +58 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-create.md +52 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-delete.md +20 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-history.md +97 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-name-key.md +47 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-query.md +120 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-share.md +54 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-stats.md +59 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-update.md +66 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-record-upsert.md +89 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-view-config.md +140 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-view-extras.md +195 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-view-types.md +95 -0
- package/skills/dws/dingtalk-aitable/references/aitable/aitable-workflow.md +384 -0
- package/skills/dws/dingtalk-aitable/references/aitable-record-ops.md +80 -0
- package/skills/dws/dingtalk-aitable/references/aitable-section.md +30 -0
- package/skills/dws/dingtalk-aitable/references/aitable.md +59 -0
- package/skills/dws/dingtalk-aitable/references/field-rules.md +17 -0
- package/skills/dws/dingtalk-aitable/references/intent-guide.md +17 -0
- package/skills/dws/dingtalk-aitable/references/recipes/conventions.md +44 -0
- package/skills/dws/dingtalk-aitable/references/url-patterns.md +144 -0
- package/skills/dws/dingtalk-aitable/scripts/aitable_export_via_task.py +210 -0
- package/skills/dws/dingtalk-aitable/scripts/aitable_import_via_task.py +173 -0
- package/skills/dws/dingtalk-aitable/scripts/bulk_add_fields.py +273 -0
- package/skills/dws/dingtalk-aitable/scripts/import_records.py +333 -0
- package/skills/dws/dingtalk-aitable/scripts/upload_attachment.py +190 -0
- package/skills/dws/dingtalk-calendar/SKILL.md +137 -0
- package/skills/dws/dingtalk-calendar/references/03-meeting.md +56 -0
- package/skills/dws/dingtalk-calendar/references/calendar.md +760 -0
- package/skills/dws/dingtalk-calendar/references/intent-guide.md +9 -0
- package/skills/dws/dingtalk-calendar/references/lite-recipes.md +25 -0
- package/skills/dws/dingtalk-calendar/scripts/calendar_free_slot_finder.py +199 -0
- package/skills/dws/dingtalk-calendar/scripts/calendar_schedule_meeting.py +233 -0
- package/skills/dws/dingtalk-calendar/scripts/calendar_today_agenda.py +139 -0
- package/skills/dws/dingtalk-chat/SKILL.md +127 -0
- package/skills/dws/dingtalk-chat/references/01-messaging.md +103 -0
- package/skills/dws/dingtalk-chat/references/card/callback.md +10 -0
- package/skills/dws/dingtalk-chat/references/card/create.md +27 -0
- package/skills/dws/dingtalk-chat/references/card/schema.md +14 -0
- package/skills/dws/dingtalk-chat/references/card/update.md +13 -0
- package/skills/dws/dingtalk-chat/references/chat/chat-bot.md +187 -0
- package/skills/dws/dingtalk-chat/references/chat/chat-conversation.md +165 -0
- package/skills/dws/dingtalk-chat/references/chat/group-admin.md +144 -0
- package/skills/dws/dingtalk-chat/references/chat/group-discovery.md +121 -0
- package/skills/dws/dingtalk-chat/references/chat/message-actions.md +132 -0
- package/skills/dws/dingtalk-chat/references/chat/message-media.md +76 -0
- package/skills/dws/dingtalk-chat/references/chat/message-query.md +135 -0
- package/skills/dws/dingtalk-chat/references/chat/thread.md +46 -0
- package/skills/dws/dingtalk-chat/references/chat-emoji-list.md +216 -0
- package/skills/dws/dingtalk-chat/references/chat.md +140 -0
- package/skills/dws/dingtalk-chat/references/contracts.md +70 -0
- package/skills/dws/dingtalk-chat/references/intent-guide.md +56 -0
- package/skills/dws/dingtalk-contact/SKILL.md +122 -0
- package/skills/dws/dingtalk-contact/references/08-directory.md +51 -0
- package/skills/dws/dingtalk-contact/references/contact.md +595 -0
- package/skills/dws/dingtalk-contact/references/intent-guide.md +14 -0
- package/skills/dws/dingtalk-contact/references/lite-recipes.md +30 -0
- package/skills/dws/dingtalk-contact/references/recipes/conventions.md +44 -0
- package/skills/dws/dingtalk-contact/scripts/contact_dept_members.py +130 -0
- package/skills/dws/dingtalk-doc/SKILL.md +112 -0
- package/skills/dws/dingtalk-doc/references/04-document.md +57 -0
- package/skills/dws/dingtalk-doc/references/contracts.md +40 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-block.md +39 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-comment.md +29 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-create.md +54 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-export.md +30 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-import.md +28 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-info.md +12 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-media.md +46 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-read.md +56 -0
- package/skills/dws/dingtalk-doc/references/doc/doc-update.md +87 -0
- package/skills/dws/dingtalk-doc/references/doc/format/doc-jsonml-cookbook.md +469 -0
- package/skills/dws/dingtalk-doc/references/doc/format/doc-jsonml-schema.json +526 -0
- package/skills/dws/dingtalk-doc/references/doc/format/doc-jsonml-schema.md +711 -0
- package/skills/dws/dingtalk-doc/references/doc/style/doc-create-workflow.md +414 -0
- package/skills/dws/dingtalk-doc/references/doc/style/doc-style-guideline.md +404 -0
- package/skills/dws/dingtalk-doc/references/doc/style/doc-update-workflow.md +316 -0
- package/skills/dws/dingtalk-doc/references/doc.md +82 -0
- package/skills/dws/dingtalk-doc/references/intent-guide.md +20 -0
- package/skills/dws/dingtalk-drive/SKILL.md +128 -0
- package/skills/dws/dingtalk-drive/references/drive.md +126 -0
- package/skills/dws/dingtalk-drive/references/folder-sync.md +40 -0
- package/skills/dws/dingtalk-drive/references/intent-guide.md +22 -0
- package/skills/dws/dingtalk-drive/references/lite-recipes.md +39 -0
- package/skills/dws/dingtalk-event/SKILL.md +106 -0
- package/skills/dws/dingtalk-event/references/event-im-keys.md +54 -0
- package/skills/dws/dingtalk-event/references/event-im-lifecycle.md +35 -0
- package/skills/dws/dingtalk-event/references/event-im-operations.md +52 -0
- package/skills/dws/dingtalk-event/references/event-im-output.md +39 -0
- package/skills/dws/dingtalk-event/references/event-im.md +58 -0
- package/skills/dws/dingtalk-event/references/event-oa.md +155 -0
- package/skills/dws/dingtalk-event/references/event-todo.md +50 -0
- package/skills/dws/dingtalk-event/references/event-voip.md +69 -0
- package/skills/dws/dingtalk-mail/SKILL.md +113 -0
- package/skills/dws/dingtalk-mail/references/09-mail.md +45 -0
- package/skills/dws/dingtalk-mail/references/intent-guide.md +8 -0
- package/skills/dws/dingtalk-mail/references/lite-recipes.md +45 -0
- package/skills/dws/dingtalk-mail/references/mail.md +1889 -0
- package/skills/dws/dingtalk-mail/references/recipes/conventions.md +44 -0
- package/skills/dws/dingtalk-mail/scripts/mail_send_with_cc.py +122 -0
- package/skills/dws/dingtalk-mail/scripts/mail_unread_summary.py +114 -0
- package/skills/dws/dingtalk-minutes/SKILL.md +116 -0
- package/skills/dws/dingtalk-minutes/references/07-minutes.md +149 -0
- package/skills/dws/dingtalk-minutes/references/10-minutes-speaker-match.md +32 -0
- package/skills/dws/dingtalk-minutes/references/11-minutes-speaker-correct.md +40 -0
- package/skills/dws/dingtalk-minutes/references/intent-guide.md +79 -0
- package/skills/dws/dingtalk-minutes/references/lite-recipes.md +25 -0
- package/skills/dws/dingtalk-minutes/references/minutes.md +210 -0
- package/skills/dws/dingtalk-minutes/references/recipes/conventions.md +33 -0
- package/skills/dws/dingtalk-minutes/scripts/minutes_recent_summary.py +196 -0
- package/skills/dws/dingtalk-minutes/scripts/test_minutes_scripts.py +222 -0
- package/skills/dws/dingtalk-misc/SKILL.md +55 -0
- package/skills/dws/dingtalk-misc/references/05-reporting.md +29 -0
- package/skills/dws/dingtalk-misc/references/agoal.md +302 -0
- package/skills/dws/dingtalk-misc/references/attendance-intent-guide.md +7 -0
- package/skills/dws/dingtalk-misc/references/attendance-report.md +109 -0
- package/skills/dws/dingtalk-misc/references/attendance-schedule.md +115 -0
- package/skills/dws/dingtalk-misc/references/attendance-vacation.md +129 -0
- package/skills/dws/dingtalk-misc/references/attendance.md +149 -0
- package/skills/dws/dingtalk-misc/references/dev/app.md +42 -0
- package/skills/dws/dingtalk-misc/references/dev/connect.md +108 -0
- package/skills/dws/dingtalk-misc/references/dev/credentials.md +26 -0
- package/skills/dws/dingtalk-misc/references/dev/dev-index.md +13 -0
- package/skills/dws/dingtalk-misc/references/dev/event.md +47 -0
- package/skills/dws/dingtalk-misc/references/dev/mcp.md +106 -0
- package/skills/dws/dingtalk-misc/references/dev/member.md +19 -0
- package/skills/dws/dingtalk-misc/references/dev/permission.md +56 -0
- package/skills/dws/dingtalk-misc/references/dev/recipes.md +58 -0
- package/skills/dws/dingtalk-misc/references/dev/robot.md +74 -0
- package/skills/dws/dingtalk-misc/references/dev/security.md +21 -0
- package/skills/dws/dingtalk-misc/references/dev/version.md +99 -0
- package/skills/dws/dingtalk-misc/references/dev/webapp.md +22 -0
- package/skills/dws/dingtalk-misc/references/devapp.md +148 -0
- package/skills/dws/dingtalk-misc/references/devdoc-intent-guide.md +7 -0
- package/skills/dws/dingtalk-misc/references/devdoc.md +42 -0
- package/skills/dws/dingtalk-misc/references/ding.md +184 -0
- package/skills/dws/dingtalk-misc/references/hrbrain.md +67 -0
- package/skills/dws/dingtalk-misc/references/live.md +23 -0
- package/skills/dws/dingtalk-misc/references/markdown.md +167 -0
- package/skills/dws/dingtalk-misc/references/oa/oa-form-components.md +345 -0
- package/skills/dws/dingtalk-misc/references/oa/oa-process-nodes.md +374 -0
- package/skills/dws/dingtalk-misc/references/oa.md +1014 -0
- package/skills/dws/dingtalk-misc/references/openapi-explorer.md +47 -0
- package/skills/dws/dingtalk-misc/references/pat.md +52 -0
- package/skills/dws/dingtalk-misc/references/profile.md +41 -0
- package/skills/dws/dingtalk-misc/references/recruit.md +89 -0
- package/skills/dws/dingtalk-misc/references/report-conventions.md +44 -0
- package/skills/dws/dingtalk-misc/references/report-intent-guide.md +11 -0
- package/skills/dws/dingtalk-misc/references/report-lite-recipes.md +25 -0
- package/skills/dws/dingtalk-misc/references/report.md +109 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-batch-operations.md +104 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-chart.md +69 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-comment.md +166 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-conditional-format.md +59 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-dimension-operations.md +60 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-dropdown.md +103 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-export.md +135 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-filter-view.md +51 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-filter.md +181 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-formula.md +192 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-import.md +76 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-media-image.md +263 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-pivot-table.md +292 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-range-operations.md +161 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-read-data.md +60 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-revision-changeset.md +46 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-search-replace.md +120 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-style-format.md +71 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-version.md +84 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-workbook.md +59 -0
- package/skills/dws/dingtalk-misc/references/sheet/sheet-write-data.md +93 -0
- package/skills/dws/dingtalk-misc/references/sheet-conventions.md +44 -0
- package/skills/dws/dingtalk-misc/references/sheet-intent-guide.md +12 -0
- package/skills/dws/dingtalk-misc/references/sheet.md +166 -0
- package/skills/dws/dingtalk-misc/references/skill.md +98 -0
- package/skills/dws/dingtalk-misc/references/unsupported-scripts.md +49 -0
- package/skills/dws/dingtalk-misc/references/url-patterns.md +144 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/compose.md +200 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/01-overview.md +57 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/02-query.md +288 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/03-update.md +249 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/04-text-style.md +395 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/05-shape-frame-group-connector.md +186 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/06-vector-icon-path.md +313 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/07-examples-errors-write-support.md +270 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1/08-catalogs.md +61 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/open-nodes-v1.md +54 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/replace.md +41 -0
- package/skills/dws/dingtalk-misc/references/whiteboard/vector.md +51 -0
- package/skills/dws/dingtalk-misc/references/whiteboard.md +115 -0
- package/skills/dws/dingtalk-misc/scripts/aiapp_create_and_poll.py +138 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_my_record.py +91 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_checkin.py +440 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_common.py +1698 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_daily.py +558 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_detail.py +809 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_monthly.py +758 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_report_record.py +947 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_schedule_export.py +344 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_schedule_import.py +498 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_team_shift.py +89 -0
- package/skills/dws/dingtalk-misc/scripts/attendance_vacation_balance.py +617 -0
- package/skills/dws/dingtalk-misc/scripts/finance_daily_cashflow.py +70 -0
- package/skills/dws/dingtalk-misc/scripts/finance_expense_flow.py +138 -0
- package/skills/dws/dingtalk-misc/scripts/oa_batch_approve.py +158 -0
- package/skills/dws/dingtalk-misc/scripts/oa_pending_review.py +132 -0
- package/skills/dws/dingtalk-misc/scripts/report_received_today.py +315 -0
- package/skills/dws/dingtalk-misc/scripts/yida_custom_page_update.py +401 -0
- package/skills/dws/dingtalk-misc/scripts/yida_form_builder.py +526 -0
- package/skills/dws/dingtalk-misc/scripts/yida_form_fields.py +315 -0
- package/skills/dws/dingtalk-misc/scripts/yida_form_inspector.py +311 -0
- package/skills/dws/dingtalk-misc/scripts/yida_form_update.py +185 -0
- package/skills/dws/dingtalk-misc/scripts/yida_jsx_pipeline.py +1588 -0
- package/skills/dws/dingtalk-misc/scripts/yida_page_compiler.py +1441 -0
- package/skills/dws/dingtalk-misc/scripts/yida_page_generate.py +514 -0
- package/skills/dws/dingtalk-misc/scripts/yida_page_schema.py +519 -0
- package/skills/dws/dingtalk-misc/scripts/yida_page_self_check.py +398 -0
- package/skills/dws/dingtalk-misc/scripts/yida_process_flow.py +1478 -0
- package/skills/dws/dingtalk-misc/scripts/yida_process_update.py +589 -0
- package/skills/dws/dingtalk-misc/scripts/yida_report_builder.py +494 -0
- package/skills/dws/dingtalk-misc/scripts/yida_report_charts.py +1434 -0
- package/skills/dws/dingtalk-misc/scripts/yida_report_update.py +244 -0
- package/skills/dws/dingtalk-misc/scripts/yida_schema_common.py +340 -0
- package/skills/dws/dingtalk-shared/SKILL.md +83 -0
- package/skills/dws/dingtalk-shared/references/capability-limits.md +31 -0
- package/skills/dws/dingtalk-shared/references/channel-login.md +26 -0
- package/skills/dws/dingtalk-shared/references/confirmation.md +59 -0
- package/skills/dws/dingtalk-shared/references/error-codes.md +155 -0
- package/skills/dws/dingtalk-shared/references/global-reference.md +122 -0
- package/skills/dws/dingtalk-shared/references/intent-guide.md +537 -0
- package/skills/dws/dingtalk-shared/references/recipes/conventions.md +45 -0
- package/skills/dws/dingtalk-shared/references/recipes/lite-catalog.md +275 -0
- package/skills/dws/dingtalk-shared/references/recipes/meta.md +67 -0
- package/skills/dws/dingtalk-shared/references/routing.md +52 -0
- package/skills/dws/dingtalk-shared/references/runtime-contract.md +11 -0
- package/skills/dws/dingtalk-shared/references/schema-usage.md +88 -0
- package/skills/dws/dingtalk-shared/references/url-patterns.md +144 -0
- package/skills/dws/dingtalk-shared/references/workflow-routing.md +45 -0
- package/skills/dws/dingtalk-todo/SKILL.md +119 -0
- package/skills/dws/dingtalk-todo/references/02-task.md +70 -0
- package/skills/dws/dingtalk-todo/references/intent-guide.md +15 -0
- package/skills/dws/dingtalk-todo/references/lite-recipes.md +68 -0
- package/skills/dws/dingtalk-todo/references/recipes/conventions.md +44 -0
- package/skills/dws/dingtalk-todo/references/todo.md +517 -0
- package/skills/dws/dingtalk-todo/scripts/todo_batch_create.py +354 -0
- package/skills/dws/dingtalk-todo/scripts/todo_daily_summary.py +153 -0
- package/skills/dws/dingtalk-todo/scripts/todo_overdue_check.py +101 -0
- package/skills/dws/dingtalk-wiki/SKILL.md +117 -0
- package/skills/dws/dingtalk-wiki/references/intent-guide.md +14 -0
- package/skills/dws/dingtalk-wiki/references/lite-recipes.md +44 -0
- package/skills/dws/dingtalk-wiki/references/wiki-members.md +32 -0
- package/skills/dws/dingtalk-wiki/references/wiki-node-ops.md +46 -0
- package/skills/dws/dingtalk-wiki/references/wiki.md +65 -0
- package/skills/dws/provenance.json +27 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""C7 计算链重算验证(crwu-audit-datacheck 能力型脚本,随技能安装)。
|
|
4
|
+
|
|
5
|
+
对 xlsx **可见区**公式做独立重算,与缓存值比对,输出客观差异清单;**只报差异、不下价值判断**。
|
|
6
|
+
|
|
7
|
+
纪律(防自造假阳性):
|
|
8
|
+
- 只读**可见区**(H0);引用到隐藏 sheet/行/列、外部工作簿、不支持的函数、解析失败 → 一律标
|
|
9
|
+
「未重算(原因)」,**绝不判通过、绝不猜值**。
|
|
10
|
+
- 重算结果仅与缓存值做「是否一致」比对;不一致 = 差异(`C7-计算链`),一致 = 已核。引擎自身不判断
|
|
11
|
+
谁对谁错。
|
|
12
|
+
- 支持:算术 `+ - * / ^`、括号、比较 `= <> < <= > >=`、`SUM/PRODUCT/ROUND/IF/MAX/MIN`、
|
|
13
|
+
单元格/绝对引用 `$A$1`、跨表引用 `'表名'!A1`;字符串与 TRUE/FALSE 常量。
|
|
14
|
+
其余(百分比 `%`、文本拼接 `&`、MOD 等未列函数)不实现 → 标「未重算」,绝不猜值。
|
|
15
|
+
|
|
16
|
+
用法:
|
|
17
|
+
python3 scripts/recalc_check.py --workbook <raw.xlsx> [--out <diff.json>]
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import argparse
|
|
22
|
+
import json
|
|
23
|
+
import re
|
|
24
|
+
import sys
|
|
25
|
+
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
|
|
26
|
+
|
|
27
|
+
# `openpyxl` 是**第三方运行时依赖**(DSH 运行时随包提供)。缺它时本脚本 **fail closed**:
|
|
28
|
+
# 不读值、不重算、不产出差异文件,而是清晰非零退出 —— 绝不改用标准库解析 OOXML 去"读值"
|
|
29
|
+
# 继续审核(那既读不可靠、又会把"未核"混成"已核")。
|
|
30
|
+
# openpyxl 的三态(2026-09-26 · R2):只有 `missing` 可以说"缺少"。
|
|
31
|
+
DEPENDENCY_STATE_TEXT = {
|
|
32
|
+
"missing": "缺少第三方运行时依赖 openpyxl",
|
|
33
|
+
"import_failed": "第三方依赖存在但导入失败/不可用",
|
|
34
|
+
"probe_failed": "第三方依赖状态探测失败",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _openpyxl_state() -> tuple:
|
|
39
|
+
"""探测 openpyxl 的三态,返回 `(state, detail)`。
|
|
40
|
+
|
|
41
|
+
只在"import openpyxl 已经失败"之后调用,所以 spec 存在即可判定为 `import_failed`。
|
|
42
|
+
`find_spec` 自身抛异常 = `probe_failed`(无法确认安装状态),**不得**伪装成缺包。
|
|
43
|
+
"""
|
|
44
|
+
import importlib.util as importlib_util
|
|
45
|
+
try:
|
|
46
|
+
spec = importlib_util.find_spec("openpyxl")
|
|
47
|
+
except Exception as exc: # noqa: BLE001 —— 探测本身失败也是一种状态
|
|
48
|
+
return "probe_failed", f"{type(exc).__name__}: {exc}"
|
|
49
|
+
if spec is None:
|
|
50
|
+
return "missing", "find_spec('openpyxl') is None"
|
|
51
|
+
origin = getattr(spec, "origin", None) or "(namespace)"
|
|
52
|
+
return "import_failed", f"find_spec('openpyxl') → {origin}"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
import openpyxl
|
|
57
|
+
from openpyxl.utils import column_index_from_string, get_column_letter
|
|
58
|
+
except ImportError as _openpyxl_error: # pragma: no cover - 由缺包用例覆盖
|
|
59
|
+
openpyxl = None
|
|
60
|
+
column_index_from_string = get_column_letter = None
|
|
61
|
+
_OPENPYXL_ERROR = str(_openpyxl_error)
|
|
62
|
+
_OPENPYXL_STATE, _OPENPYXL_DETAIL = _openpyxl_state()
|
|
63
|
+
else:
|
|
64
|
+
_OPENPYXL_ERROR = None
|
|
65
|
+
_OPENPYXL_STATE = None
|
|
66
|
+
_OPENPYXL_DETAIL = None
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
class Unavailable(Exception):
|
|
70
|
+
"""该格无法重算:携带原因(隐藏区/外部引用/不支持函数/解析失败/缺失)。"""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class EngineError(Unavailable):
|
|
74
|
+
"""引擎**自身**未能处理该格(非"规则上不支持")。
|
|
75
|
+
|
|
76
|
+
单独成类并在摘要里计数,是为了**不让代码缺陷伪装成"该格数据有问题"**:
|
|
77
|
+
若兜底把所有异常都并进普通「未重算」,整表静默降级也看不出来。
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# 单元格值的类型/数值问题:Excel 自己也会报 `#VALUE!`/`#DIV/0!`,
|
|
82
|
+
# 属"该格不可重算",不是引擎缺陷。例:`=A1-B1` 而 A1 是日期、B1 是文本。
|
|
83
|
+
_VALUE_ERRORS = (TypeError, ValueError, ArithmeticError, InvalidOperation)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------- tokenizer
|
|
87
|
+
_CELL = r"\$?[A-Z]{1,3}\$?\d{1,7}"
|
|
88
|
+
_SHEET = r"(?:'(?:[^']|'')+'|[A-Za-z_][A-Za-z0-9_.\u4e00-\u9fff]*)"
|
|
89
|
+
_TOKEN = re.compile(
|
|
90
|
+
r"(?P<ws>\s+)"
|
|
91
|
+
r"|(?P<sheetref>" + _SHEET + r"!)(?=\s*\$?[A-Za-z]{1,3}\$?\d)"
|
|
92
|
+
r"|(?P<cellref>" + _CELL + r")"
|
|
93
|
+
r"|(?P<num>\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)"
|
|
94
|
+
r'|(?P<str>"[^"]*")'
|
|
95
|
+
r"|(?P<func>[A-Za-z_][A-Za-z0-9_.]*)(?=\s*\()"
|
|
96
|
+
r"|(?P<bool>TRUE|FALSE)"
|
|
97
|
+
r"|(?P<op><>|<=|>=|<|>|=|[+\-*/^%&(),:])",
|
|
98
|
+
re.VERBOSE | re.IGNORECASE,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def _tokenize(formula: str):
|
|
103
|
+
tokens = []
|
|
104
|
+
pos = 0
|
|
105
|
+
while pos < len(formula):
|
|
106
|
+
m = _TOKEN.match(formula, pos)
|
|
107
|
+
if not m:
|
|
108
|
+
raise Unavailable("解析失败:无法识别的片段 " + formula[pos:pos + 12].strip())
|
|
109
|
+
kind = m.lastgroup
|
|
110
|
+
if kind == "ws":
|
|
111
|
+
pos = m.end()
|
|
112
|
+
continue
|
|
113
|
+
value = m.group(0)
|
|
114
|
+
if kind == "num":
|
|
115
|
+
tokens.append(("num", float(value)))
|
|
116
|
+
elif kind == "str":
|
|
117
|
+
tokens.append(("str", value[1:-1]))
|
|
118
|
+
elif kind == "bool":
|
|
119
|
+
tokens.append(("bool", value.upper() == "TRUE"))
|
|
120
|
+
elif kind == "cellref":
|
|
121
|
+
tokens.append(("cell", _parse_cell(value)))
|
|
122
|
+
elif kind == "sheetref":
|
|
123
|
+
tokens.append(("sheet", value[:-1].strip("'")))
|
|
124
|
+
elif kind == "func":
|
|
125
|
+
tokens.append(("func", value.upper()))
|
|
126
|
+
elif kind == "op":
|
|
127
|
+
if value == ":":
|
|
128
|
+
tokens.append(("colon", None))
|
|
129
|
+
else:
|
|
130
|
+
tokens.append(("op", value))
|
|
131
|
+
pos = m.end()
|
|
132
|
+
return tokens
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _parse_cell(text: str):
|
|
136
|
+
text = text.replace("$", "")
|
|
137
|
+
i = 0
|
|
138
|
+
while i < len(text) and not text[i].isdigit():
|
|
139
|
+
i += 1
|
|
140
|
+
return (text[:i], int(text[i:]))
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
# ---------------------------------------------------------------- evaluator
|
|
144
|
+
class Evaluator:
|
|
145
|
+
def __init__(self, wbv, wbf, hidden):
|
|
146
|
+
self.wbv = wbv # data_only=True(缓存值)
|
|
147
|
+
self.wbf = wbf # data_only=False(公式串)
|
|
148
|
+
self.hidden = hidden # {hiddenSheets, hiddenRows, hiddenCols}
|
|
149
|
+
self.sheet = None # 当前工作表名
|
|
150
|
+
|
|
151
|
+
# ---- 值获取(H0:隐藏区不可读 → Unavailable) ----
|
|
152
|
+
def _cell_value(self, sheet: str, coord) -> float | str | bool:
|
|
153
|
+
if sheet not in self.wbv.sheetnames:
|
|
154
|
+
raise Unavailable(f"引用不存在的工作表 {sheet}")
|
|
155
|
+
if sheet in self.hidden["hiddenSheets"]:
|
|
156
|
+
raise Unavailable("引用隐藏工作表")
|
|
157
|
+
col_letter, row = coord
|
|
158
|
+
if row in set(self.hidden["hiddenRows"].get(sheet, [])):
|
|
159
|
+
raise Unavailable("引用隐藏行")
|
|
160
|
+
if col_letter in set(self.hidden["hiddenCols"].get(sheet, [])):
|
|
161
|
+
raise Unavailable("引用隐藏列")
|
|
162
|
+
v = self.wbv[sheet].cell(row, column_index_from_string(col_letter)).value
|
|
163
|
+
if v is None:
|
|
164
|
+
return 0.0
|
|
165
|
+
return v
|
|
166
|
+
|
|
167
|
+
def _resolve(self, token_idx, tokens):
|
|
168
|
+
"""token_idx 处为 cell 或 sheet 前缀;返回 (value, 下一个未消费下标)。支持 range。"""
|
|
169
|
+
tok = tokens[token_idx]
|
|
170
|
+
if tok[0] == "sheet":
|
|
171
|
+
return self._resolve_ref(tokens, token_idx + 1, tok[1])
|
|
172
|
+
return self._resolve_ref(tokens, token_idx, self.sheet)
|
|
173
|
+
|
|
174
|
+
def _resolve_ref(self, tokens, i, sheet):
|
|
175
|
+
coord = tokens[i][1]
|
|
176
|
+
nxt = i + 1
|
|
177
|
+
if nxt < len(tokens) and tokens[nxt][0] == "colon":
|
|
178
|
+
end = tokens[nxt + 1][1]
|
|
179
|
+
return self._range(sheet, coord, end), nxt + 2
|
|
180
|
+
return self._cell_value(sheet, coord), nxt
|
|
181
|
+
|
|
182
|
+
def _range(self, sheet, start, end):
|
|
183
|
+
c1, r1 = column_index_from_string(start[0]), start[1]
|
|
184
|
+
c2, r2 = column_index_from_string(end[0]), end[1]
|
|
185
|
+
values = []
|
|
186
|
+
for r in range(min(r1, r2), max(r1, r2) + 1):
|
|
187
|
+
for c in range(min(c1, c2), max(c1, c2) + 1):
|
|
188
|
+
values.append(self._cell_value(sheet, (get_column_letter(c), r)))
|
|
189
|
+
return values
|
|
190
|
+
|
|
191
|
+
# ---- 主入口 ----
|
|
192
|
+
def eval(self, formula: str):
|
|
193
|
+
"""统一兜底:任何异常都必须变成「未重算(原因)」,**绝不让单格打断整表**。
|
|
194
|
+
|
|
195
|
+
契约(本文件 docstring)要求"解析失败/除零/不支持 → 一律标未重算,绝不判通过、绝不猜值"。
|
|
196
|
+
整改前只捕获 `Unavailable`,于是 `=A1-B1`(A1 日期、B1 文本)这类 `TypeError`
|
|
197
|
+
会打穿整个 `run()`(实战:3-资产基础法.xlsx 直接崩,datacheck 整表不可用)。
|
|
198
|
+
"""
|
|
199
|
+
try:
|
|
200
|
+
return self._eval(formula)
|
|
201
|
+
except Unavailable:
|
|
202
|
+
raise
|
|
203
|
+
except _VALUE_ERRORS as exc:
|
|
204
|
+
raise Unavailable(f"类型不匹配或计算失败:{type(exc).__name__}: {exc}") from exc
|
|
205
|
+
except Exception as exc: # 非预期 → 单独成类,摘要中计数暴露
|
|
206
|
+
raise EngineError(f"引擎异常 {type(exc).__name__}: {exc}") from exc
|
|
207
|
+
|
|
208
|
+
def _eval(self, formula: str):
|
|
209
|
+
if re.search(r"\[\d*\]", formula):
|
|
210
|
+
raise Unavailable("引用外部工作簿")
|
|
211
|
+
formula = formula.lstrip()
|
|
212
|
+
if formula.startswith("="):
|
|
213
|
+
formula = formula[1:].lstrip()
|
|
214
|
+
tokens = _tokenize(formula)
|
|
215
|
+
value, nxt = self._expr(tokens, 0)
|
|
216
|
+
if nxt != len(tokens):
|
|
217
|
+
raise Unavailable("解析失败:存在未消费的片段")
|
|
218
|
+
return value
|
|
219
|
+
|
|
220
|
+
def _expr(self, tokens, i):
|
|
221
|
+
return self._comparison(tokens, i)
|
|
222
|
+
|
|
223
|
+
def _comparison(self, tokens, i):
|
|
224
|
+
left, i = self._additive(tokens, i)
|
|
225
|
+
while i < len(tokens) and tokens[i][0] == "op" and tokens[i][1] in ("=", "<>", "<", "<=", ">", ">="):
|
|
226
|
+
op = tokens[i][1]
|
|
227
|
+
right, i = self._additive(tokens, i + 1)
|
|
228
|
+
left = _compare(op, left, right)
|
|
229
|
+
return left, i
|
|
230
|
+
|
|
231
|
+
def _additive(self, tokens, i):
|
|
232
|
+
value, i = self._multiplicative(tokens, i)
|
|
233
|
+
while i < len(tokens) and tokens[i][0] == "op" and tokens[i][1] in ("+", "-"):
|
|
234
|
+
op = tokens[i][1]
|
|
235
|
+
rhs, i = self._multiplicative(tokens, i + 1)
|
|
236
|
+
value = _arith(op, value, rhs)
|
|
237
|
+
return value, i
|
|
238
|
+
|
|
239
|
+
def _multiplicative(self, tokens, i):
|
|
240
|
+
value, i = self._unary(tokens, i)
|
|
241
|
+
while i < len(tokens) and tokens[i][0] == "op" and tokens[i][1] in ("*", "/", "^"):
|
|
242
|
+
op = tokens[i][1]
|
|
243
|
+
rhs, i = self._unary(tokens, i + 1)
|
|
244
|
+
value = _arith(op, value, rhs)
|
|
245
|
+
return value, i
|
|
246
|
+
|
|
247
|
+
def _unary(self, tokens, i):
|
|
248
|
+
if i < len(tokens) and tokens[i][0] == "op" and tokens[i][1] == "-":
|
|
249
|
+
v, i = self._unary(tokens, i + 1)
|
|
250
|
+
return -v, i
|
|
251
|
+
return self._primary(tokens, i)
|
|
252
|
+
|
|
253
|
+
def _primary(self, tokens, i):
|
|
254
|
+
tok = tokens[i]
|
|
255
|
+
kind = tok[0]
|
|
256
|
+
if kind == "num":
|
|
257
|
+
return tok[1], i + 1
|
|
258
|
+
if kind == "str":
|
|
259
|
+
return tok[1], i + 1
|
|
260
|
+
if kind == "bool":
|
|
261
|
+
return tok[1], i + 1
|
|
262
|
+
if kind == "cell":
|
|
263
|
+
return self._resolve(i, tokens)
|
|
264
|
+
if kind == "sheet":
|
|
265
|
+
return self._resolve(i, tokens)
|
|
266
|
+
if kind == "func":
|
|
267
|
+
return self._function(tokens, i)
|
|
268
|
+
if kind == "op" and tok[1] == "(":
|
|
269
|
+
value, i = self._expr(tokens, i + 1)
|
|
270
|
+
if i >= len(tokens) or tokens[i] != ("op", ")"):
|
|
271
|
+
raise Unavailable("解析失败:缺右括号")
|
|
272
|
+
return value, i + 1
|
|
273
|
+
raise Unavailable("解析失败:不支持的语法 " + str(tok))
|
|
274
|
+
|
|
275
|
+
def _function(self, tokens, i):
|
|
276
|
+
name = tokens[i][1]
|
|
277
|
+
j = i + 1
|
|
278
|
+
if j >= len(tokens) or tokens[j] != ("op", "("):
|
|
279
|
+
raise Unavailable("解析失败:函数缺左括号")
|
|
280
|
+
# 收集参数(惰性:把每个参数包成闭包)
|
|
281
|
+
args = []
|
|
282
|
+
j += 1
|
|
283
|
+
depth = 0
|
|
284
|
+
start = j
|
|
285
|
+
while j < len(tokens):
|
|
286
|
+
t = tokens[j]
|
|
287
|
+
if t[0] == "op" and t[1] == "(":
|
|
288
|
+
depth += 1
|
|
289
|
+
elif t[0] == "op" and t[1] == ")":
|
|
290
|
+
if depth == 0:
|
|
291
|
+
if j > start:
|
|
292
|
+
args.append((start, j))
|
|
293
|
+
j += 1
|
|
294
|
+
break
|
|
295
|
+
depth -= 1
|
|
296
|
+
elif t[0] == "op" and t[1] == "," and depth == 0:
|
|
297
|
+
args.append((start, j))
|
|
298
|
+
j += 1
|
|
299
|
+
start = j
|
|
300
|
+
continue
|
|
301
|
+
j += 1
|
|
302
|
+
|
|
303
|
+
def ev(arg):
|
|
304
|
+
s, e = arg
|
|
305
|
+
value, nxt = self._expr(tokens, s)
|
|
306
|
+
if nxt != e:
|
|
307
|
+
# 参数范围内有未消费的 token(未实现的运算符如 `&`/`%`、语法错误)→ 必须报「未重算」。
|
|
308
|
+
# 早期实现直接 `self._expr(tokens, s)[0]` **丢弃了消费位置**,于是
|
|
309
|
+
# `IF(A1&B1="x", a, b)` 只解析了 `A1`、`&B1="x"` 被静默忽略,条件走错分支,
|
|
310
|
+
# 引擎给出一个**自信的错误值**并按"已重算"参与比对
|
|
311
|
+
# (2026-302150-LX9757-BG8677 实测:3,462 条差异中 1,914 条由此产生,属假差异)。
|
|
312
|
+
raise Unavailable("解析失败:函数参数存在未消费的片段 " + str(tokens[nxt:e]))
|
|
313
|
+
return value
|
|
314
|
+
|
|
315
|
+
if name == "IF":
|
|
316
|
+
if len(args) not in (2, 3):
|
|
317
|
+
raise Unavailable("IF 参数个数错误")
|
|
318
|
+
cond = ev(args[0])
|
|
319
|
+
result = ev(args[1]) if _truthy(cond) else (ev(args[2]) if len(args) == 3 else False)
|
|
320
|
+
elif name == "ROUND":
|
|
321
|
+
if len(args) != 2:
|
|
322
|
+
raise Unavailable("ROUND 参数个数错误")
|
|
323
|
+
result = _round_half_away(ev(args[0]), int(ev(args[1])))
|
|
324
|
+
elif name in ("SUM", "PRODUCT", "MAX", "MIN"):
|
|
325
|
+
if not args:
|
|
326
|
+
raise Unavailable(name + " 至少一个参数")
|
|
327
|
+
values = [self._flatten(ev(a)) for a in args]
|
|
328
|
+
flat = [v for grp in values for v in (grp if isinstance(grp, list) else [grp])]
|
|
329
|
+
flat = [float(v) for v in flat]
|
|
330
|
+
if name == "SUM":
|
|
331
|
+
result = sum(flat)
|
|
332
|
+
elif name == "PRODUCT":
|
|
333
|
+
acc = 1.0
|
|
334
|
+
for v in flat:
|
|
335
|
+
acc *= v
|
|
336
|
+
result = acc
|
|
337
|
+
elif name == "MAX":
|
|
338
|
+
result = max(flat)
|
|
339
|
+
else:
|
|
340
|
+
result = min(flat)
|
|
341
|
+
else:
|
|
342
|
+
raise Unavailable("不支持的函数 " + name)
|
|
343
|
+
return result, j
|
|
344
|
+
|
|
345
|
+
@staticmethod
|
|
346
|
+
def _flatten(v):
|
|
347
|
+
return v if isinstance(v, list) else v
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
# ---------------------------------------------------------------- helpers
|
|
351
|
+
def _truthy(v):
|
|
352
|
+
if isinstance(v, (int, float)):
|
|
353
|
+
return v != 0
|
|
354
|
+
if isinstance(v, str):
|
|
355
|
+
return v != ""
|
|
356
|
+
return bool(v)
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
def _compare(op, a, b):
|
|
360
|
+
if op == "=":
|
|
361
|
+
return a == b
|
|
362
|
+
if op == "<>":
|
|
363
|
+
return a != b
|
|
364
|
+
if op == "<":
|
|
365
|
+
return a < b
|
|
366
|
+
if op == "<=":
|
|
367
|
+
return a <= b
|
|
368
|
+
if op == ">":
|
|
369
|
+
return a > b
|
|
370
|
+
return a >= b
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def _arith(op, a, b):
|
|
374
|
+
if op == "+":
|
|
375
|
+
return a + b
|
|
376
|
+
if op == "-":
|
|
377
|
+
return a - b
|
|
378
|
+
if op == "*":
|
|
379
|
+
return a * b
|
|
380
|
+
if op == "/":
|
|
381
|
+
if b == 0:
|
|
382
|
+
raise Unavailable("除零")
|
|
383
|
+
return a / b
|
|
384
|
+
if op == "^":
|
|
385
|
+
return a ** b
|
|
386
|
+
raise Unavailable("不支持的运算符 " + op)
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
def _round_half_away(x, n):
|
|
390
|
+
# 用十进制字符串规避二进制浮点误差(如 ROUND(1.235,2) 应为 1.24,非 1.23)
|
|
391
|
+
d = Decimal(str(x))
|
|
392
|
+
q = Decimal(1).scaleb(-int(n))
|
|
393
|
+
return float(d.quantize(q, rounding=ROUND_HALF_UP))
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def _hidden_metadata(wbv):
|
|
397
|
+
hidden = {"hiddenSheets": [], "hiddenRows": {}, "hiddenCols": {}}
|
|
398
|
+
for ws in wbv.worksheets:
|
|
399
|
+
if ws.sheet_state != "visible":
|
|
400
|
+
hidden["hiddenSheets"].append(ws.title)
|
|
401
|
+
continue
|
|
402
|
+
rows = {r for r, d in ws.row_dimensions.items() if d.hidden}
|
|
403
|
+
cols = {c for c, d in ws.column_dimensions.items() if d.hidden}
|
|
404
|
+
if rows:
|
|
405
|
+
hidden["hiddenRows"][ws.title] = sorted(rows)
|
|
406
|
+
if cols:
|
|
407
|
+
hidden["hiddenCols"][ws.title] = sorted(cols)
|
|
408
|
+
return hidden
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
def _close(a, b) -> bool:
|
|
412
|
+
if a == b:
|
|
413
|
+
return True
|
|
414
|
+
try:
|
|
415
|
+
return abs(float(a) - float(b)) <= 1e-9 * max(1.0, abs(float(a)), abs(float(b)))
|
|
416
|
+
except (TypeError, ValueError):
|
|
417
|
+
return False
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
# ---------------------------------------------------------------- main
|
|
421
|
+
def run(workbook: str):
|
|
422
|
+
wbv = openpyxl.load_workbook(workbook, data_only=True)
|
|
423
|
+
wbf = openpyxl.load_workbook(workbook, data_only=False)
|
|
424
|
+
hidden = _hidden_metadata(wbv)
|
|
425
|
+
ev = Evaluator(wbv, wbf, hidden)
|
|
426
|
+
|
|
427
|
+
differences, not_recomputable = [], []
|
|
428
|
+
formula_cells = recomputed = matched = mismatched = 0
|
|
429
|
+
engine_errors = 0
|
|
430
|
+
|
|
431
|
+
for ws in wbf.worksheets:
|
|
432
|
+
if ws.sheet_state != "visible":
|
|
433
|
+
continue
|
|
434
|
+
hidden_rows = set(hidden["hiddenRows"].get(ws.title, []))
|
|
435
|
+
hidden_cols = set(hidden["hiddenCols"].get(ws.title, []))
|
|
436
|
+
ev.sheet = ws.title
|
|
437
|
+
# 只遍历**实际存在**的格(精确集合),不用 `ws.iter_rows()`——后者按声明 dimension
|
|
438
|
+
# 扫满矩形;原件常带游离的 `has_style=True`、`value=None` 空格(如整列刷格式残留),
|
|
439
|
+
# 会把百万行全走一遍(2026-302135-LX9619-BG8634 实测:单表 1,048,575 行 → 长时间无响应)。
|
|
440
|
+
# 与 crwu-audit 的 prepare_materials.py 同一口径。按 (行, 列) 排序以保持
|
|
441
|
+
# 与原 `iter_rows()` 一致的行优序 —— 差异清单顺序必须可复现。
|
|
442
|
+
for (row_i, col_i), cell in sorted(getattr(ws, "_cells", {}).items()):
|
|
443
|
+
if not (isinstance(row_i, int) and isinstance(col_i, int)):
|
|
444
|
+
continue
|
|
445
|
+
if row_i in hidden_rows or get_column_letter(col_i) in hidden_cols:
|
|
446
|
+
continue
|
|
447
|
+
formula = cell.value
|
|
448
|
+
if not isinstance(formula, str) or not formula.startswith("="):
|
|
449
|
+
continue
|
|
450
|
+
formula_cells += 1
|
|
451
|
+
cached = wbv[ws.title].cell(row_i, col_i).value
|
|
452
|
+
try:
|
|
453
|
+
recalculated = ev.eval(formula)
|
|
454
|
+
except Unavailable as exc:
|
|
455
|
+
entry = {"sheet": ws.title, "cell": cell.coordinate, "formula": formula,
|
|
456
|
+
"reason": str(exc)}
|
|
457
|
+
if isinstance(exc, EngineError):
|
|
458
|
+
entry["engineError"] = True
|
|
459
|
+
engine_errors += 1
|
|
460
|
+
not_recomputable.append(entry)
|
|
461
|
+
continue
|
|
462
|
+
except Exception as exc: # 兜底:任何异常都不得中断整表
|
|
463
|
+
engine_errors += 1
|
|
464
|
+
not_recomputable.append(
|
|
465
|
+
{"sheet": ws.title, "cell": cell.coordinate, "formula": formula,
|
|
466
|
+
"engineError": True,
|
|
467
|
+
"reason": f"引擎异常 {type(exc).__name__}: {exc}"})
|
|
468
|
+
continue
|
|
469
|
+
recomputed += 1
|
|
470
|
+
if cached is None or not _close(recalculated, cached):
|
|
471
|
+
mismatched += 1
|
|
472
|
+
differences.append({
|
|
473
|
+
"sheet": ws.title, "cell": cell.coordinate, "formula": formula,
|
|
474
|
+
"recalculated": recalculated, "cached": cached,
|
|
475
|
+
"note": "重算值与缓存值不一致" if cached is not None else "有公式但无缓存值",
|
|
476
|
+
})
|
|
477
|
+
else:
|
|
478
|
+
matched += 1
|
|
479
|
+
|
|
480
|
+
return {
|
|
481
|
+
"file": workbook,
|
|
482
|
+
"summary": {
|
|
483
|
+
"formulaCells": formula_cells, "recomputed": recomputed,
|
|
484
|
+
"matched": matched, "mismatched": mismatched,
|
|
485
|
+
"notRecomputable": len(not_recomputable),
|
|
486
|
+
# 引擎自身未能处理(类型不匹配等已归入普通未重算;此处只计非预期的引擎异常)。
|
|
487
|
+
# 非 0 表示可能有引擎缺陷,须排查 —— 不得当作"该表数据问题"。
|
|
488
|
+
"engineErrors": engine_errors,
|
|
489
|
+
},
|
|
490
|
+
"differences": differences,
|
|
491
|
+
"notRecomputable": not_recomputable,
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
def main() -> int:
|
|
496
|
+
if _OPENPYXL_ERROR is not None:
|
|
497
|
+
print(
|
|
498
|
+
"错误:" + DEPENDENCY_STATE_TEXT[_OPENPYXL_STATE]
|
|
499
|
+
+ "(" + _OPENPYXL_ERROR + ";" + str(_OPENPYXL_DETAIL) + ")。"
|
|
500
|
+
"无法重算 .xlsx 公式链:本次不读值、不重算、不产出差异结果文件,"
|
|
501
|
+
"按 capability gap 登记(state=" + _OPENPYXL_STATE + ");"
|
|
502
|
+
"不得改用标准库解析 OOXML 读值,也不得自行 pip 安装或切换/回退解释器。",
|
|
503
|
+
file=sys.stderr,
|
|
504
|
+
)
|
|
505
|
+
return 3
|
|
506
|
+
ap = argparse.ArgumentParser(description="C7 计算链重算验证(只报差异、不下判断)")
|
|
507
|
+
ap.add_argument("--workbook", required=True)
|
|
508
|
+
ap.add_argument("--out", default=None)
|
|
509
|
+
args = ap.parse_args()
|
|
510
|
+
result = run(args.workbook)
|
|
511
|
+
if args.out:
|
|
512
|
+
with open(args.out, "w", encoding="utf-8") as fh:
|
|
513
|
+
json.dump(result, fh, ensure_ascii=False, indent=1)
|
|
514
|
+
print(json.dumps(result["summary"], ensure_ascii=False))
|
|
515
|
+
for d in result["differences"]:
|
|
516
|
+
print(f" 差异 {d['sheet']}!{d['cell']} 重算={d['recalculated']} 缓存={d['cached']} | {d['formula']}")
|
|
517
|
+
return 0
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
if __name__ == "__main__":
|
|
521
|
+
raise SystemExit(main())
|