dsh-data-cleaning-agent 0.9.6 → 0.9.8
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 +14 -0
- package/README.en.md +4 -2
- package/README.md +5 -3
- package/docs/RELEASE-0.9.8.md +68 -0
- package/lib/client.js +765 -174
- package/lib/image-workflow.js +1 -0
- package/lib/qcc-safety.js +1 -0
- package/lib/qcc.js +18 -2
- package/lib/web.js +4 -0
- package/lib/workflow-contract.js +13 -1
- package/lib/workflow-execution.js +1 -1
- package/lib/workflow.js +13 -0
- package/package.json +2 -1
package/lib/client.js
CHANGED
|
@@ -157,12 +157,7 @@ window.__ModuleLoader__.load({
|
|
|
157
157
|
box-sizing: border-box; display: flex; flex-direction: column;
|
|
158
158
|
width: 100%; height: 100%; min-width: 0; min-height: 0; overflow: hidden;
|
|
159
159
|
background: var(--dc-surface); color: var(--dc-text);
|
|
160
|
-
container
|
|
161
|
-
}
|
|
162
|
-
@container (max-width: 520px) {
|
|
163
|
-
.dcAgentRulesGrid, .dcAgentMappingRow { grid-template-columns: 1fr; }
|
|
164
|
-
.dcAgentMappingRow > b { display: none; }
|
|
165
|
-
.dcAgentCandidate { grid-template-columns: 1fr; }
|
|
160
|
+
container: dc-agent-workbench / inline-size;
|
|
166
161
|
}
|
|
167
162
|
.dcAgentCapabilities {
|
|
168
163
|
display: flex;
|
|
@@ -515,8 +510,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
515
510
|
|
|
516
511
|
.dcAgentWbBody {
|
|
517
512
|
flex: 1 1 auto;
|
|
513
|
+
display: flex;
|
|
514
|
+
flex-direction: column;
|
|
515
|
+
gap: 14px;
|
|
518
516
|
overflow: auto;
|
|
519
517
|
padding: 18px;
|
|
518
|
+
background: var(--dc-page);
|
|
519
|
+
scrollbar-gutter: stable;
|
|
520
520
|
}
|
|
521
521
|
|
|
522
522
|
.dcAgentPane { display: flex; flex-direction: column; gap: 14px; }
|
|
@@ -569,7 +569,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
569
569
|
|
|
570
570
|
.dcAgentGrid {
|
|
571
571
|
display: grid;
|
|
572
|
-
grid-template-columns: repeat(auto-
|
|
572
|
+
grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
|
|
573
573
|
gap: 10px;
|
|
574
574
|
}
|
|
575
575
|
|
|
@@ -718,10 +718,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
718
718
|
color: var(--dc-text);
|
|
719
719
|
}
|
|
720
720
|
.dcAgentHistoryTask { border: 1px solid var(--dc-border); border-radius: 6px; background: var(--dc-surface); color: inherit; font: inherit; cursor: pointer; }
|
|
721
|
-
.dcAgentWizardNav { display: grid; grid-template-columns: repeat(4, 1fr); gap:
|
|
722
|
-
.dcAgentWizardStep { display: flex; align-items: center; gap: 6px; padding:
|
|
721
|
+
.dcAgentWizardNav { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 16px; padding-bottom: 10px; border-bottom: 1px solid var(--dc-border); }
|
|
722
|
+
.dcAgentWizardStep { display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 6px; border: 0; border-bottom: 2px solid transparent; border-radius: 0; background: transparent; color: var(--dc-muted); font: inherit; font-size: 12px; cursor: pointer; }
|
|
723
723
|
.dcAgentWizardStep b { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--dc-border); color: var(--dc-muted); }
|
|
724
|
-
.dcAgentWizardStep.is-active { border-color: var(--dc-action); background:
|
|
724
|
+
.dcAgentWizardStep.is-active { border-bottom-color: var(--dc-action); background: transparent; color: var(--dc-action); }
|
|
725
725
|
.dcAgentWizardStep.is-active b { background: var(--dc-action); color: var(--dc-on-action); }
|
|
726
726
|
.dcAgentWizardPane { min-height: 230px; }
|
|
727
727
|
.dcAgentWizardPane h4 { margin: 0 0 3px; font-size: 14px; }
|
|
@@ -730,14 +730,158 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
730
730
|
.dcAgentPromptRules label { font-size: 12px; }
|
|
731
731
|
.dcAgentPromptPreview { max-height: 260px; overflow: auto; margin: 10px 0 0; padding: 12px; border-radius: 8px; background: var(--dc-page); white-space: pre-wrap; word-break: break-word; font: inherit; font-size: 12px; line-height: 18px; }
|
|
732
732
|
.dcAgentFormField { display: grid; gap: 6px; font-size: 12px; font-weight: 600; }
|
|
733
|
-
.
|
|
734
|
-
.
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
733
|
+
.dcAgentMappingSection { padding: 0; }
|
|
734
|
+
.dcAgentMappingHeader {
|
|
735
|
+
display: grid;
|
|
736
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
737
|
+
align-items: start;
|
|
738
|
+
gap: 12px 20px;
|
|
739
|
+
padding: 14px 16px;
|
|
740
|
+
border-bottom: 1px solid var(--dc-border);
|
|
741
|
+
}
|
|
742
|
+
.dcAgentMappingHeader h3 { margin: 0; font-size: 14px; }
|
|
743
|
+
.dcAgentMappingHeader .dcAgentHint { margin-top: 4px; }
|
|
744
|
+
.dcAgentMappingProgress {
|
|
745
|
+
display: inline-flex;
|
|
746
|
+
align-items: baseline;
|
|
747
|
+
gap: 4px;
|
|
748
|
+
min-width: 108px;
|
|
749
|
+
padding: 8px 10px;
|
|
750
|
+
border: 1px solid var(--dc-border);
|
|
751
|
+
border-radius: 6px;
|
|
752
|
+
background: var(--dc-page);
|
|
753
|
+
color: var(--dc-muted);
|
|
754
|
+
font-size: 12px;
|
|
755
|
+
white-space: nowrap;
|
|
756
|
+
}
|
|
757
|
+
.dcAgentMappingProgress b { color: var(--dc-action); font-size: 16px; font-variant-numeric: tabular-nums; }
|
|
758
|
+
.dcAgentMappingToolbar {
|
|
759
|
+
display: flex;
|
|
760
|
+
align-items: center;
|
|
761
|
+
justify-content: space-between;
|
|
762
|
+
gap: 10px 16px;
|
|
763
|
+
padding: 10px 16px;
|
|
764
|
+
border-bottom: 1px solid var(--dc-border);
|
|
765
|
+
background: var(--dc-page);
|
|
766
|
+
}
|
|
767
|
+
.dcAgentMappingLegend { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 14px; color: var(--dc-muted); font-size: 12px; }
|
|
768
|
+
.dcAgentMappingLegendItem { display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
|
|
769
|
+
.dcAgentMappingLegendItem::before { width: 7px; height: 7px; border-radius: 50%; background: var(--dc-border); content: ''; }
|
|
770
|
+
.dcAgentMappingLegendItem[data-status="confirmed"]::before { background: light-dark(#15803d, #86efac); }
|
|
771
|
+
.dcAgentMappingLegendItem[data-status="review"]::before { background: light-dark(#a16207, #fcd34d); }
|
|
772
|
+
.dcAgentMappingLegendItem[data-status="unmatched"]::before { background: light-dark(#b91c1c, #fca5a5); }
|
|
773
|
+
.dcAgentMappingAuto { flex: 0 0 auto; padding: 6px 10px; font-size: 12px; }
|
|
774
|
+
.dcAgentMappingNote { padding: 10px 16px; border-bottom: 1px solid var(--dc-border); }
|
|
775
|
+
.dcAgentMappingListHead,
|
|
776
|
+
.dcAgentMappingSummary,
|
|
777
|
+
.dcAgentMappingMeta {
|
|
778
|
+
display: grid;
|
|
779
|
+
grid-template-columns: minmax(120px, 0.8fr) 24px minmax(220px, 1.2fr);
|
|
780
|
+
align-items: center;
|
|
781
|
+
gap: 8px;
|
|
782
|
+
}
|
|
783
|
+
.dcAgentMappingListHead {
|
|
784
|
+
padding: 8px 16px;
|
|
785
|
+
border-bottom: 1px solid var(--dc-border);
|
|
786
|
+
background: var(--dc-page);
|
|
787
|
+
color: var(--dc-muted);
|
|
788
|
+
font-size: 11px;
|
|
789
|
+
font-weight: 600;
|
|
790
|
+
}
|
|
791
|
+
.dcAgentMappingListHead > span:last-child { grid-column: 3; }
|
|
792
|
+
.dcAgentMappingRow { font-size: 12px; }
|
|
793
|
+
.dcAgentMappingRow + .dcAgentMappingRow { border-top: 1px solid var(--dc-border); }
|
|
794
|
+
.dcAgentMappingPicker { display: block; }
|
|
795
|
+
.dcAgentMappingSummary {
|
|
796
|
+
min-height: 52px;
|
|
797
|
+
padding: 8px 16px;
|
|
798
|
+
cursor: pointer;
|
|
799
|
+
list-style: none;
|
|
800
|
+
}
|
|
801
|
+
.dcAgentMappingSummary::-webkit-details-marker { display: none; }
|
|
802
|
+
.dcAgentMappingSummary:hover { background: var(--dc-page); }
|
|
803
|
+
.dcAgentMappingPicker[open] > .dcAgentMappingSummary { background: var(--dc-selected); }
|
|
804
|
+
.dcAgentMappingSource { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
|
|
805
|
+
.dcAgentMappingSummary > b { text-align: center; color: light-dark(#8792a3, #8290a5); }
|
|
806
|
+
.dcAgentMappingValue {
|
|
807
|
+
display: flex;
|
|
808
|
+
align-items: center;
|
|
809
|
+
justify-content: space-between;
|
|
810
|
+
gap: 10px;
|
|
811
|
+
min-width: 0;
|
|
812
|
+
min-height: 36px;
|
|
813
|
+
padding: 7px 10px;
|
|
814
|
+
border: 1px solid var(--dc-border);
|
|
815
|
+
border-radius: 6px;
|
|
816
|
+
background: var(--dc-surface);
|
|
817
|
+
font-size: 14px;
|
|
818
|
+
font-weight: 500;
|
|
819
|
+
overflow-wrap: anywhere;
|
|
820
|
+
}
|
|
821
|
+
.dcAgentMappingValue::after {
|
|
822
|
+
flex: 0 0 auto;
|
|
823
|
+
width: 7px;
|
|
824
|
+
height: 7px;
|
|
825
|
+
border-right: 1.5px solid currentColor;
|
|
826
|
+
border-bottom: 1.5px solid currentColor;
|
|
827
|
+
content: '';
|
|
828
|
+
transform: rotate(45deg) translate(-2px, 2px);
|
|
829
|
+
transition: transform 120ms ease;
|
|
830
|
+
}
|
|
831
|
+
.dcAgentMappingPicker[open] .dcAgentMappingValue::after { transform: rotate(225deg); }
|
|
832
|
+
.dcAgentMappingPickerPanel {
|
|
833
|
+
display: grid;
|
|
834
|
+
gap: 8px;
|
|
835
|
+
padding: 12px 16px 14px;
|
|
836
|
+
border-top: 1px solid var(--dc-border);
|
|
837
|
+
border-bottom: 1px solid var(--dc-border);
|
|
838
|
+
background: var(--dc-page);
|
|
839
|
+
}
|
|
840
|
+
.dcAgentMappingPickerFilters { display: grid; grid-template-columns: minmax(0, 1fr) minmax(150px, 0.42fr); gap: 8px; }
|
|
841
|
+
.dcAgentMappingPickerPanel .dcAgentField { box-sizing: border-box; width: 100%; max-width: 100%; min-width: 0; margin: 0; }
|
|
842
|
+
.dcAgentMappingOptionGroups {
|
|
843
|
+
max-height: 286px;
|
|
844
|
+
overflow: auto;
|
|
845
|
+
padding-right: 4px;
|
|
846
|
+
scrollbar-gutter: stable;
|
|
847
|
+
}
|
|
848
|
+
.dcAgentMappingClearOption,
|
|
849
|
+
.dcAgentMappingOption {
|
|
850
|
+
display: flex;
|
|
851
|
+
align-items: center;
|
|
852
|
+
gap: 8px;
|
|
853
|
+
min-width: 0;
|
|
854
|
+
min-height: 36px;
|
|
855
|
+
padding: 6px 8px;
|
|
856
|
+
border-radius: 4px;
|
|
857
|
+
cursor: pointer;
|
|
858
|
+
}
|
|
859
|
+
.dcAgentMappingClearOption {
|
|
860
|
+
position: sticky;
|
|
861
|
+
top: 0;
|
|
862
|
+
z-index: 1;
|
|
863
|
+
border-bottom: 1px solid var(--dc-border);
|
|
864
|
+
border-radius: 0;
|
|
865
|
+
background: var(--dc-page);
|
|
866
|
+
color: var(--dc-muted);
|
|
867
|
+
}
|
|
868
|
+
.dcAgentMappingOption:hover,
|
|
869
|
+
.dcAgentMappingOption:has(input:checked) { background: var(--dc-selected); color: var(--dc-action); }
|
|
870
|
+
.dcAgentMappingOption:has(input:disabled) { opacity: 0.52; cursor: not-allowed; }
|
|
871
|
+
.dcAgentMappingClearOption input,
|
|
872
|
+
.dcAgentMappingOption input { flex: 0 0 auto; width: 16px; height: 16px; margin: 0; accent-color: var(--dc-action); }
|
|
873
|
+
.dcAgentMappingOption > span { min-width: 0; overflow-wrap: anywhere; }
|
|
874
|
+
.dcAgentMappingRow .dcAgentMappingOption > small { margin: 0 0 0 auto; color: var(--dc-muted); white-space: nowrap; }
|
|
875
|
+
.dcAgentMappingOptionGroup { margin-top: 12px; }
|
|
876
|
+
.dcAgentMappingOptionGroupTitle { margin: 0 0 6px; color: var(--dc-muted); font-size: 12px; font-weight: 600; }
|
|
877
|
+
.dcAgentMappingOptionGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 4px 8px; }
|
|
878
|
+
.dcAgentMappingCurrentNotice { margin: 8px 0 0; padding: 7px 8px; background: var(--dc-surface); color: var(--dc-muted); font-size: 12px; }
|
|
879
|
+
.dcAgentMappingMatch { margin: 0; }
|
|
880
|
+
.dcAgentMappingMeta { padding: 7px 16px 10px; }
|
|
881
|
+
.dcAgentMappingMeta > * { grid-column: 3; min-width: 0; }
|
|
882
|
+
.dcAgentMappingMeta > .dcAgentHint { margin: 0; }
|
|
739
883
|
.dcAgentMappingRow .dcAgentButton { max-width: 100%; white-space: normal; overflow-wrap: anywhere; }
|
|
740
|
-
.dcAgentMappingRow small { display: block; margin:
|
|
884
|
+
.dcAgentMappingRow small { display: block; margin: 0; overflow-wrap: anywhere; }
|
|
741
885
|
.dcAgentMappingStatus[data-status="confirmed"] { color: light-dark(#15803d, #86efac); }
|
|
742
886
|
.dcAgentMappingStatus[data-status="review"] { color: light-dark(#a16207, #fcd34d); }
|
|
743
887
|
.dcAgentMappingStatus[data-status="unmatched"] { color: light-dark(#b91c1c, #fca5a5); }
|
|
@@ -786,8 +930,175 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
786
930
|
.dcAgentPreviewTable > .dcAgentTable th {
|
|
787
931
|
position: sticky; top: 0; z-index: 2; background: var(--dc-table-head);
|
|
788
932
|
}
|
|
933
|
+
.dcAgentDatasetPreview {
|
|
934
|
+
padding: 0;
|
|
935
|
+
overflow: hidden;
|
|
936
|
+
}
|
|
937
|
+
.dcAgentDatasetHeader {
|
|
938
|
+
display: flex;
|
|
939
|
+
align-items: baseline;
|
|
940
|
+
justify-content: space-between;
|
|
941
|
+
gap: 8px 16px;
|
|
942
|
+
padding: 14px 16px 12px;
|
|
943
|
+
border-bottom: 1px solid var(--dc-border);
|
|
944
|
+
}
|
|
945
|
+
.dcAgentDatasetHeader h3 { margin: 0; font-size: 14px; }
|
|
946
|
+
.dcAgentDatasetHeader .dcAgentHint { text-align: right; }
|
|
947
|
+
.dcAgentDatasetPreview > .dcAgentPreviewTable {
|
|
948
|
+
margin: 0;
|
|
949
|
+
border: 0;
|
|
950
|
+
border-radius: 0;
|
|
951
|
+
}
|
|
952
|
+
.dcAgentDatasetPreview > .dcAgentPreviewTable > .dcAgentTable :is(th, td):last-child { border-right: 0; }
|
|
953
|
+
.dcAgentDatasetPreview > .dcAgentPreviewTable > .dcAgentTable tbody tr:last-child > td { border-bottom: 0; }
|
|
954
|
+
.dcAgentDatasetPreview > .dcAgentPreviewTable > .dcAgentTable :is(th, td):first-child {
|
|
955
|
+
width: 72px;
|
|
956
|
+
min-width: 72px;
|
|
957
|
+
max-width: 72px;
|
|
958
|
+
text-align: center;
|
|
959
|
+
color: var(--dc-muted);
|
|
960
|
+
font-variant-numeric: tabular-nums;
|
|
961
|
+
}
|
|
962
|
+
.dcAgentDatasetFooter {
|
|
963
|
+
display: grid;
|
|
964
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
965
|
+
align-items: center;
|
|
966
|
+
gap: 10px 16px;
|
|
967
|
+
padding: 12px 16px;
|
|
968
|
+
border-top: 1px solid var(--dc-border);
|
|
969
|
+
background: var(--dc-page);
|
|
970
|
+
}
|
|
971
|
+
.dcAgentDatasetPagination,
|
|
972
|
+
.dcAgentDatasetDownloads {
|
|
973
|
+
display: flex;
|
|
974
|
+
align-items: center;
|
|
975
|
+
gap: 8px;
|
|
976
|
+
min-width: 0;
|
|
977
|
+
}
|
|
978
|
+
.dcAgentDatasetDownloads { justify-content: flex-end; }
|
|
979
|
+
.dcAgentDatasetPreview .dcAgentButton {
|
|
980
|
+
display: inline-flex;
|
|
981
|
+
align-items: center;
|
|
982
|
+
justify-content: center;
|
|
983
|
+
gap: 6px;
|
|
984
|
+
min-height: 32px;
|
|
985
|
+
padding: 6px 10px;
|
|
986
|
+
line-height: 18px;
|
|
987
|
+
}
|
|
988
|
+
.dcAgentDatasetPage {
|
|
989
|
+
min-width: 72px;
|
|
990
|
+
padding: 6px 8px;
|
|
991
|
+
border: 1px solid var(--dc-border);
|
|
992
|
+
border-radius: 6px;
|
|
993
|
+
background: var(--dc-surface);
|
|
994
|
+
font-size: 12px;
|
|
995
|
+
font-variant-numeric: tabular-nums;
|
|
996
|
+
font-weight: 600;
|
|
997
|
+
text-align: center;
|
|
998
|
+
white-space: nowrap;
|
|
999
|
+
}
|
|
1000
|
+
.dcAgentDatasetFooterNote {
|
|
1001
|
+
grid-column: 1 / -1;
|
|
1002
|
+
padding-top: 10px;
|
|
1003
|
+
border-top: 1px solid var(--dc-border);
|
|
1004
|
+
font-size: 12px;
|
|
1005
|
+
line-height: 1.55;
|
|
1006
|
+
}
|
|
1007
|
+
.dcAgentIntakeSummary { padding: 0; overflow: hidden; }
|
|
1008
|
+
.dcAgentIntakeSummaryHead {
|
|
1009
|
+
padding: 14px 16px 10px;
|
|
1010
|
+
}
|
|
1011
|
+
.dcAgentIntakeSummaryHead > div { min-width: 0; }
|
|
1012
|
+
.dcAgentIntakeSummaryHead h3 { margin-bottom: 4px; }
|
|
1013
|
+
.dcAgentIntakeSummary > .dcAgentHint { padding: 0 16px 14px; }
|
|
1014
|
+
.dcAgentIntakeEditor { padding: 0; overflow: hidden; }
|
|
1015
|
+
.dcAgentIntakeEditorHeader { padding: 14px 16px 10px; border-bottom: 1px solid var(--dc-border); }
|
|
1016
|
+
.dcAgentIntakeEditorHeader h3 { margin-bottom: 4px; }
|
|
1017
|
+
.dcAgentIntakeSourceActions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; padding: 12px 16px; }
|
|
1018
|
+
.dcAgentIntakePaste { padding: 0 16px 12px; }
|
|
1019
|
+
.dcAgentIntakePaste .dcAgentTextarea { min-height: 116px; }
|
|
1020
|
+
.dcAgentIntakeEditorActions { display: flex; align-items: center; gap: 10px; padding: 12px 16px; border-top: 1px solid var(--dc-border); }
|
|
1021
|
+
.dcAgentUploadActions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; }
|
|
789
1022
|
.dcAgentHistoryTask { display: block; width: 100%; padding: 10px; text-align: left; }
|
|
790
1023
|
.dcAgentHistoryTask h3 { margin: 0; font-size: 12px; }
|
|
1024
|
+
.dcAgentViewTabs {
|
|
1025
|
+
display: flex;
|
|
1026
|
+
align-items: center;
|
|
1027
|
+
gap: 20px;
|
|
1028
|
+
min-height: 34px;
|
|
1029
|
+
padding: 0 4px;
|
|
1030
|
+
border-bottom: 1px solid var(--dc-border);
|
|
1031
|
+
}
|
|
1032
|
+
.dcAgentViewTabs .dcAgentButton {
|
|
1033
|
+
align-self: stretch;
|
|
1034
|
+
padding: 6px 2px;
|
|
1035
|
+
border: 0;
|
|
1036
|
+
border-bottom: 2px solid transparent;
|
|
1037
|
+
border-radius: 0;
|
|
1038
|
+
background: transparent;
|
|
1039
|
+
color: var(--dc-muted);
|
|
1040
|
+
font-size: 12px;
|
|
1041
|
+
}
|
|
1042
|
+
.dcAgentViewTabs .dcAgentButton[aria-pressed="true"] { border-bottom-color: var(--dc-action); color: var(--dc-action); font-weight: 600; }
|
|
1043
|
+
.dcAgentProfilePane { flex: 1 0 auto; min-height: 320px; }
|
|
1044
|
+
.dcAgentProfileSurface {
|
|
1045
|
+
flex: 1 0 auto;
|
|
1046
|
+
display: flex;
|
|
1047
|
+
flex-direction: column;
|
|
1048
|
+
min-height: 320px;
|
|
1049
|
+
padding: 0;
|
|
1050
|
+
overflow: hidden;
|
|
1051
|
+
}
|
|
1052
|
+
.dcAgentProfileHeader { padding: 14px 16px; border-bottom: 1px solid var(--dc-border); }
|
|
1053
|
+
.dcAgentProfileHeader h3 { margin: 0; font-size: 14px; }
|
|
1054
|
+
.dcAgentProfileHeader .dcAgentHint { margin-top: 4px; }
|
|
1055
|
+
.dcAgentProfileReport { flex: 1 0 auto; display: flex; flex-direction: column; gap: 14px; padding: 14px 16px; }
|
|
1056
|
+
.dcAgentProfileMetrics { grid-template-columns: repeat(auto-fit, minmax(112px, 1fr)); }
|
|
1057
|
+
.dcAgentProfileMetrics .dcAgentCard { padding: 10px 12px; background: var(--dc-page); }
|
|
1058
|
+
.dcAgentProfileMetrics .dcAgentCard b { font-size: 17px; }
|
|
1059
|
+
.dcAgentProfileTableSection { min-width: 0; }
|
|
1060
|
+
.dcAgentProfileTableHead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 8px; }
|
|
1061
|
+
.dcAgentProfileTableHead h4 { margin: 0; font-size: 13px; }
|
|
1062
|
+
.dcAgentProfileTableWrap { max-width: 100%; max-height: 360px; overflow: auto; border: 1px solid var(--dc-border); border-radius: 6px; scrollbar-gutter: stable; }
|
|
1063
|
+
.dcAgentProfileTableWrap .dcAgentTable { min-width: 420px; border-collapse: separate; border-spacing: 0; }
|
|
1064
|
+
.dcAgentProfileTableWrap .dcAgentTable th { position: sticky; top: 0; z-index: 1; }
|
|
1065
|
+
.dcAgentProfileTableWrap .dcAgentTable :is(th, td):last-child { border-right: 0; }
|
|
1066
|
+
.dcAgentProfileTableWrap .dcAgentTable tbody tr:last-child > td { border-bottom: 0; }
|
|
1067
|
+
.dcAgentProfileTableWrap .dcAgentTable :is(th, td):not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }
|
|
1068
|
+
.dcAgentProfileActions { display: flex; justify-content: flex-end; margin-top: auto; padding-top: 14px; border-top: 1px solid var(--dc-border); }
|
|
1069
|
+
.dcAgentProfileEmpty { flex: 1 0 auto; display: flex; align-items: center; justify-content: center; padding: 24px 16px; }
|
|
1070
|
+
.dcAgentMatchPane { flex: 0 0 auto; }
|
|
1071
|
+
.dcAgentMatchSurface {
|
|
1072
|
+
flex: 0 0 auto;
|
|
1073
|
+
display: flex;
|
|
1074
|
+
flex-direction: column;
|
|
1075
|
+
padding: 0;
|
|
1076
|
+
overflow: hidden;
|
|
1077
|
+
}
|
|
1078
|
+
.dcAgentMatchHeader { padding: 14px 16px; border-bottom: 1px solid var(--dc-border); }
|
|
1079
|
+
.dcAgentMatchHeader h3 { margin: 0; font-size: 14px; }
|
|
1080
|
+
.dcAgentMatchHeader .dcAgentHint { margin-top: 4px; }
|
|
1081
|
+
.dcAgentMatchContent {
|
|
1082
|
+
display: grid;
|
|
1083
|
+
grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
|
|
1084
|
+
align-items: stretch;
|
|
1085
|
+
}
|
|
1086
|
+
.dcAgentMatchBlock { min-width: 0; padding: 16px; }
|
|
1087
|
+
.dcAgentMatchBlock + .dcAgentMatchBlock { border-left: 1px solid var(--dc-border); }
|
|
1088
|
+
.dcAgentMatchBlockHead { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 10px; }
|
|
1089
|
+
.dcAgentMatchBlockHead h4 { margin: 0; font-size: 13px; }
|
|
1090
|
+
.dcAgentMatchBlock .dcAgentChips { margin-bottom: 8px; }
|
|
1091
|
+
.dcAgentMatchBlock .dcAgentHint + .dcAgentHint { margin-top: 6px; }
|
|
1092
|
+
.dcAgentMatchScope {
|
|
1093
|
+
display: inline-flex;
|
|
1094
|
+
align-items: baseline;
|
|
1095
|
+
gap: 5px;
|
|
1096
|
+
color: var(--dc-muted);
|
|
1097
|
+
font-size: 12px;
|
|
1098
|
+
white-space: nowrap;
|
|
1099
|
+
}
|
|
1100
|
+
.dcAgentMatchScope b { color: var(--dc-text); font-size: 14px; font-variant-numeric: tabular-nums; }
|
|
1101
|
+
.dcAgentMatchActions { display: flex; justify-content: flex-end; margin: 0 16px; padding: 14px 0; border-top: 1px solid var(--dc-border); }
|
|
791
1102
|
@media (max-width: 760px) {
|
|
792
1103
|
.dcAgentQccBadge, .dcAgentJobsPill { display: none; }
|
|
793
1104
|
.dcAgentCandidate { grid-template-columns: 1fr; }
|
|
@@ -797,8 +1108,11 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
797
1108
|
.dcAgentPromptPanel { width: 100%; height: 100dvh; max-height: 100dvh; border-radius: 0; }
|
|
798
1109
|
.dcAgentWizardNav { grid-template-columns: repeat(2, 1fr); }
|
|
799
1110
|
.dcAgentRulesGrid { grid-template-columns: 1fr; }
|
|
800
|
-
.
|
|
801
|
-
.
|
|
1111
|
+
.dcAgentMappingListHead { display: none; }
|
|
1112
|
+
.dcAgentMappingSummary, .dcAgentMappingMeta { grid-template-columns: 1fr; }
|
|
1113
|
+
.dcAgentMappingSummary > b { display: none; }
|
|
1114
|
+
.dcAgentMappingPickerFilters { grid-template-columns: 1fr; }
|
|
1115
|
+
.dcAgentMappingMeta > * { grid-column: 1; }
|
|
802
1116
|
}
|
|
803
1117
|
@media (min-width: 761px) and (max-width: 1040px) {
|
|
804
1118
|
.dcAgentQccBadge, .dcAgentJobsPill { display: none; }
|
|
@@ -820,6 +1134,58 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
820
1134
|
.dcAgentTable th, .dcAgentTable td { height: 44px; box-sizing: border-box; font-size: 13px; }
|
|
821
1135
|
.dcAgentTable tbody tr:hover { background: var(--dc-selected); }
|
|
822
1136
|
.dcAgentSection, .dcAgentCard { background: var(--dc-surface); }
|
|
1137
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] {
|
|
1138
|
+
display: grid;
|
|
1139
|
+
grid-template-columns: minmax(0, 1fr) auto auto;
|
|
1140
|
+
align-items: center;
|
|
1141
|
+
gap: 6px 10px;
|
|
1142
|
+
padding: 14px 16px;
|
|
1143
|
+
}
|
|
1144
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > h3 {
|
|
1145
|
+
grid-column: 1;
|
|
1146
|
+
grid-row: 1;
|
|
1147
|
+
min-width: 0;
|
|
1148
|
+
margin: 0;
|
|
1149
|
+
overflow-wrap: anywhere;
|
|
1150
|
+
font-size: 14px;
|
|
1151
|
+
}
|
|
1152
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > b {
|
|
1153
|
+
grid-column: 2;
|
|
1154
|
+
grid-row: 1;
|
|
1155
|
+
padding: 2px 8px;
|
|
1156
|
+
border: 1px solid var(--dc-border);
|
|
1157
|
+
border-radius: 4px;
|
|
1158
|
+
background: var(--dc-page);
|
|
1159
|
+
color: var(--dc-muted);
|
|
1160
|
+
font-size: 12px;
|
|
1161
|
+
font-weight: 600;
|
|
1162
|
+
white-space: nowrap;
|
|
1163
|
+
}
|
|
1164
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > details {
|
|
1165
|
+
grid-column: 3;
|
|
1166
|
+
grid-row: 1;
|
|
1167
|
+
color: var(--dc-muted);
|
|
1168
|
+
font-size: 12px;
|
|
1169
|
+
}
|
|
1170
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > :is(p, progress) { grid-column: 1 / -1; }
|
|
1171
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > p { margin: 0; }
|
|
1172
|
+
.dcAgentWbBody > .dcAgentSection[role="status"]:not([aria-label]) {
|
|
1173
|
+
min-height: 156px;
|
|
1174
|
+
display: flex;
|
|
1175
|
+
flex-direction: column;
|
|
1176
|
+
align-items: center;
|
|
1177
|
+
justify-content: center;
|
|
1178
|
+
gap: 12px;
|
|
1179
|
+
border: 0;
|
|
1180
|
+
background: transparent;
|
|
1181
|
+
text-align: center;
|
|
1182
|
+
}
|
|
1183
|
+
.dcAgentWbBody > .dcAgentSection[role="status"]:not([aria-label]) > p {
|
|
1184
|
+
max-width: 440px;
|
|
1185
|
+
margin: 0;
|
|
1186
|
+
color: var(--dc-muted);
|
|
1187
|
+
}
|
|
1188
|
+
.dcAgentPane > .dcAgentArtifactList { margin-top: 0; }
|
|
823
1189
|
.dcAgentFieldGroup { background: var(--dc-page); padding: 12px; border-radius: 8px; }
|
|
824
1190
|
.dcAgentPromptFieldGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 8px; margin-top: 10px; }
|
|
825
1191
|
.dcAgentPromptFieldGrid .dcAgentPromptChoice { border: 0; border-radius: 4px; min-width: 0; align-items: flex-start; font-size: 13px; }
|
|
@@ -830,6 +1196,66 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
830
1196
|
.dcAgentPromptAction.is-primary:hover:not(:disabled) { background: var(--dc-hover); }
|
|
831
1197
|
:is(.dcAgentWorkbenchContent, .dcAgentPromptPanel, .dcAgentCapabilities, .dcAgentPromptLayer) :is(button, input, select, textarea, summary):focus-visible,
|
|
832
1198
|
.dcAgentLauncher:focus-visible { outline: 2px solid var(--dc-action); outline-offset: 2px; }
|
|
1199
|
+
@container dc-agent-workbench (max-width: 640px) {
|
|
1200
|
+
.dcAgentRulesGrid { grid-template-columns: 1fr; }
|
|
1201
|
+
.dcAgentCandidate { grid-template-columns: 1fr; }
|
|
1202
|
+
}
|
|
1203
|
+
@container dc-agent-workbench (max-width: 570px) {
|
|
1204
|
+
.dcAgentGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
1205
|
+
.dcAgentGrid > .dcAgentCard:last-child:nth-child(odd) { grid-column: 1 / -1; }
|
|
1206
|
+
}
|
|
1207
|
+
@container dc-agent-workbench (max-width: 520px) {
|
|
1208
|
+
.dcAgentMappingHeader { grid-template-columns: 1fr; }
|
|
1209
|
+
.dcAgentMappingProgress { justify-self: start; }
|
|
1210
|
+
.dcAgentMappingToolbar { align-items: flex-start; flex-direction: column; }
|
|
1211
|
+
.dcAgentMappingListHead { display: none; }
|
|
1212
|
+
.dcAgentMappingSummary, .dcAgentMappingMeta { grid-template-columns: 1fr; }
|
|
1213
|
+
.dcAgentMappingSummary > b { display: none; }
|
|
1214
|
+
.dcAgentMappingPickerFilters { grid-template-columns: 1fr; }
|
|
1215
|
+
.dcAgentMappingMeta > * { grid-column: 1; }
|
|
1216
|
+
.dcAgentStep { gap: 6px; padding: 10px 3px; font-size: 11px; }
|
|
1217
|
+
.dcAgentStepIcon { width: 26px; height: 26px; }
|
|
1218
|
+
.dcAgentStepLabel {
|
|
1219
|
+
display: -webkit-box;
|
|
1220
|
+
min-height: 32px;
|
|
1221
|
+
line-height: 16px;
|
|
1222
|
+
white-space: normal;
|
|
1223
|
+
-webkit-box-orient: vertical;
|
|
1224
|
+
-webkit-line-clamp: 2;
|
|
1225
|
+
}
|
|
1226
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] { grid-template-columns: minmax(0, 1fr) auto; }
|
|
1227
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > h3 { grid-column: 1 / -1; }
|
|
1228
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > b { grid-column: 1; grid-row: 2; justify-self: start; }
|
|
1229
|
+
.dcAgentWbBody > .dcAgentSection[aria-label="当前任务进展"] > details { grid-column: 2; grid-row: 2; }
|
|
1230
|
+
.dcAgentDatasetHeader { display: grid; }
|
|
1231
|
+
.dcAgentDatasetHeader .dcAgentHint { text-align: left; }
|
|
1232
|
+
.dcAgentDatasetFooter { grid-template-columns: 1fr; }
|
|
1233
|
+
.dcAgentDatasetPagination,
|
|
1234
|
+
.dcAgentDatasetDownloads { justify-content: flex-start; flex-wrap: wrap; }
|
|
1235
|
+
.dcAgentDatasetFooterNote { grid-column: 1; }
|
|
1236
|
+
.dcAgentProfileHeader, .dcAgentProfileReport { padding-inline: 12px; }
|
|
1237
|
+
.dcAgentProfileMetrics { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
1238
|
+
}
|
|
1239
|
+
@container dc-agent-workbench (max-width: 640px) {
|
|
1240
|
+
.dcAgentMatchContent { grid-template-columns: 1fr; }
|
|
1241
|
+
.dcAgentMatchBlock + .dcAgentMatchBlock { border-top: 1px solid var(--dc-border); border-left: 0; }
|
|
1242
|
+
}
|
|
1243
|
+
@container dc-agent-workbench (max-width: 420px) {
|
|
1244
|
+
.dcAgentIntakeSummaryHead { padding-inline: 12px; }
|
|
1245
|
+
.dcAgentIntakeSummary > .dcAgentHint,
|
|
1246
|
+
.dcAgentIntakeEditorHeader,
|
|
1247
|
+
.dcAgentIntakeSourceActions,
|
|
1248
|
+
.dcAgentIntakePaste,
|
|
1249
|
+
.dcAgentIntakeEditorActions { padding-inline: 12px; }
|
|
1250
|
+
.dcAgentIntakeSourceActions .dcAgentButton { flex: 1 1 100%; }
|
|
1251
|
+
.dcAgentUploadActions .dcAgentButton { flex: 1 1 100%; }
|
|
1252
|
+
.dcAgentMatchHeader, .dcAgentMatchBlock { padding-inline: 12px; }
|
|
1253
|
+
.dcAgentMatchActions { margin-inline: 12px; }
|
|
1254
|
+
.dcAgentMatchActions .dcAgentButton { width: 100%; }
|
|
1255
|
+
}
|
|
1256
|
+
@container dc-agent-workbench (max-width: 360px) {
|
|
1257
|
+
.dcAgentDatasetDownloads > .dcAgentButton { flex: 1 1 100%; }
|
|
1258
|
+
}
|
|
833
1259
|
@media (max-width: 760px) {
|
|
834
1260
|
[data-dc-agent-hero-title="true"] { font-size: 20px; }
|
|
835
1261
|
.dcAgentHeroLogo { width: 40px; height: 40px; border-radius: 8px; }
|
|
@@ -1354,41 +1780,60 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1354
1780
|
const occupied = (id) => isAnchorField(id) && mappings.some((item) => item.sourceField !== sourceField && item.targetField === id);
|
|
1355
1781
|
const fields = groups.flatMap(([, , items]) => items);
|
|
1356
1782
|
const label = fields.find(([id]) => id === value)?.[1] || '不参与匹配 / 补全';
|
|
1357
|
-
const
|
|
1783
|
+
const normalizedQuery = normalizeMappingLabel(query);
|
|
1784
|
+
const matches = (id, name) => normalizeMappingLabel([id, name, ...(MAPPING_ALIASES[id] || []), ...Object.entries(MAPPING_HINTS).filter(([, ids]) => ids.includes(id)).map(([hint]) => hint)].join(' ')).includes(normalizedQuery);
|
|
1358
1785
|
const filteredGroups = groups.filter(([id]) => !category || id === category)
|
|
1359
|
-
.map(([id, title, items
|
|
1786
|
+
.map(([id, title, items, tool]) => {
|
|
1787
|
+
const groupMatches = normalizeMappingLabel([id, title, tool || ''].join(' ')).includes(normalizedQuery);
|
|
1788
|
+
return [id, title, groupMatches ? items : items.filter(([key, name]) => matches(key, name))];
|
|
1789
|
+
})
|
|
1360
1790
|
.filter(([, , items]) => items.length);
|
|
1361
1791
|
const filteredFields = filteredGroups.flatMap(([, , items]) => items);
|
|
1362
1792
|
const hiddenSelection = value && !filteredFields.some(([id]) => id === value);
|
|
1793
|
+
const selectMapping = (event) => {
|
|
1794
|
+
onChange(sourceField, event.currentTarget.value);
|
|
1795
|
+
const details = event.currentTarget.closest('details');
|
|
1796
|
+
if (details) { details.open = false; details.querySelector('summary')?.focus(); }
|
|
1797
|
+
};
|
|
1363
1798
|
return h('div', { className: 'dcAgentMappingRow' },
|
|
1364
|
-
h('
|
|
1365
|
-
h('div', { style: { minWidth: 0 } },
|
|
1366
|
-
h('details', { className: 'dcAgentMappingPicker', onKeyDown: (event) => {
|
|
1799
|
+
h('details', { className: 'dcAgentMappingPicker', onKeyDown: (event) => {
|
|
1367
1800
|
if (event.key === 'Escape' && event.currentTarget.open) {
|
|
1368
1801
|
event.preventDefault(); event.stopPropagation();
|
|
1369
1802
|
event.currentTarget.open = false; event.currentTarget.querySelector('summary')?.focus();
|
|
1370
1803
|
}
|
|
1371
1804
|
} },
|
|
1372
|
-
|
|
1373
|
-
h('
|
|
1374
|
-
h('
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
hiddenSelection ? h('option', { value, disabled: true }, `当前选择:${label}(不符合筛选,保持不变)`) : null,
|
|
1384
|
-
filteredGroups.map(([id, title, items]) => h('optgroup', { key: id, label: title }, items.map(([key, name]) =>
|
|
1385
|
-
h('option', { key, value: key, disabled: occupied(key) }, `${name}${occupied(key) ? '(已被其他列使用)' : ''}`)))),
|
|
1805
|
+
h('summary', { className: 'dcAgentMappingSummary', 'aria-label': `${sourceField} 当前映射` },
|
|
1806
|
+
h('span', { className: 'dcAgentMappingSource', title: sourceField }, sourceField),
|
|
1807
|
+
h('b', { 'aria-hidden': 'true' }, '→'),
|
|
1808
|
+
h('span', { className: 'dcAgentMappingValue' }, label),
|
|
1809
|
+
),
|
|
1810
|
+
h('div', { className: 'dcAgentMappingPickerPanel' },
|
|
1811
|
+
h('div', { className: 'dcAgentMappingPickerFilters' },
|
|
1812
|
+
h('input', { className: 'dcAgentField', value: query, placeholder: '模糊搜索字段名称 / 英文键 / 别名', 'aria-label': `${sourceField} 搜索映射字段`, onChange: (event) => setQuery(event.target.value) }),
|
|
1813
|
+
h('select', { className: 'dcAgentField', value: category, 'aria-label': `${sourceField} 映射大类`, onChange: (event) => setCategory(event.target.value) },
|
|
1814
|
+
h('option', { value: '' }, '全部维度'),
|
|
1815
|
+
groups.map(([id, title]) => h('option', { key: id, value: id }, title))),
|
|
1386
1816
|
),
|
|
1387
|
-
h('
|
|
1817
|
+
h('div', { className: 'dcAgentMappingOptionGroups', role: 'radiogroup', 'aria-label': `${sourceField} 字段映射` },
|
|
1818
|
+
h('label', { className: 'dcAgentMappingClearOption' },
|
|
1819
|
+
h('input', { type: 'radio', name: `mapping:${sourceField}`, value: '', checked: !value, onChange: selectMapping }),
|
|
1820
|
+
h('span', null, '不参与匹配 / 补全')),
|
|
1821
|
+
hiddenSelection ? h('p', { className: 'dcAgentMappingCurrentNotice' }, `当前选择:${label}(不符合筛选,保持不变)`) : null,
|
|
1822
|
+
filteredGroups.map(([id, title, items]) => h('section', { key: id, className: 'dcAgentMappingOptionGroup', 'data-mapping-group': id },
|
|
1823
|
+
h('h4', { className: 'dcAgentMappingOptionGroupTitle' }, title),
|
|
1824
|
+
h('div', { className: 'dcAgentMappingOptionGrid' }, items.map(([key, name]) => h('label', { key, className: 'dcAgentMappingOption' },
|
|
1825
|
+
h('input', { type: 'radio', name: `mapping:${sourceField}`, value: key, checked: value === key, disabled: occupied(key), onChange: selectMapping }),
|
|
1826
|
+
h('span', null, name),
|
|
1827
|
+
occupied(key) ? h('small', null, '已占用') : null,
|
|
1828
|
+
))),
|
|
1829
|
+
)),
|
|
1830
|
+
),
|
|
1831
|
+
h('p', { className: 'dcAgentHint dcAgentMappingMatch', role: 'status' }, filteredFields.length ? `匹配 ${filteredFields.length} 个字段;选择后采用。` : '无匹配字段;当前选择保持不变。'),
|
|
1388
1832
|
),
|
|
1833
|
+
),
|
|
1834
|
+
h('div', { className: 'dcAgentMappingMeta' },
|
|
1389
1835
|
value === 'beneficial_owner_first_name' || value.startsWith('financial_') ? h('p', { className: 'dcAgentHint' }, value === 'beneficial_owner_first_name' ? '仅取返回首条受益所有人,不代表唯一或最大受益人。' : '取返回首个报告期,不跨期补值;报告期保留在结果取值说明中。') : null,
|
|
1390
|
-
h('small', { className: 'dcAgentMappingStatus', 'data-status': value ? 'confirmed' : recommendation.candidates.length ? 'review' : 'unmatched',
|
|
1391
|
-
style: { display: 'block', padding: '6px 0' } },
|
|
1836
|
+
h('small', { className: 'dcAgentMappingStatus', 'data-status': value ? 'confirmed' : recommendation.candidates.length ? 'review' : 'unmatched' },
|
|
1392
1837
|
value ? `${recommendation.automatic && recommendation.candidates[0]?.[0] === value ? '自动通过' : '已确认'}:${label};可手动调整` : recommendation.candidates.length ? `待人工确认:${recommendation.conflict ? '重复列可确认使用同一补全字段;主体标识只选一列' : recommendation.reason}` : '未匹配:保留原列,可手动选择字段'),
|
|
1393
1838
|
!value && recommendation.candidates.length ? h('div', { className: 'dcAgentRow', 'aria-label': `${sourceField} 推荐映射` }, recommendation.candidates.map(([id, name]) =>
|
|
1394
1839
|
h('button', { key: id, type: 'button', className: 'dcAgentButton', disabled: occupied(id), onClick: () => onChange(sourceField, id) }, `推荐:${name}${occupied(id) ? '(已占用)' : ''}`))) : null,
|
|
@@ -1496,8 +1941,20 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1496
1941
|
const time = date && Number.isFinite(date.getTime()) ? date.toLocaleString() : '';
|
|
1497
1942
|
return `${base}|${task.source?.type === 'image' && task.state === 'draft' ? '待识别' : `${task.source?.rowCount ?? 0} 条`}${time ? '|' + time : ''}`;
|
|
1498
1943
|
}
|
|
1944
|
+
function taskBelongsToSession(task, sessionId) {
|
|
1945
|
+
if (!sessionId || task?.originSessionId !== sessionId) return false;
|
|
1946
|
+
const scope = sessionWorkbenchController?.originFor?.(sessionId);
|
|
1947
|
+
return !scope?.originWorkspaceId || task.originWorkspaceId === scope.originWorkspaceId;
|
|
1948
|
+
}
|
|
1949
|
+
function workflowOriginLabel(task) {
|
|
1950
|
+
if (!task?.originSessionId) return '历史版本未保存来源';
|
|
1951
|
+
return `工作区:${task.originWorkspaceName || task.originWorkspaceId || '未取得来源工作区'} · 会话:${task.originSessionName || task.originSessionId}`;
|
|
1952
|
+
}
|
|
1499
1953
|
function cacheWorkflowTask(actions, sessionId, task) {
|
|
1500
1954
|
if (!task) return null;
|
|
1955
|
+
if (!taskBelongsToSession(task, sessionId)) throw new Error('此任务不属于当前会话;请在任务历史中只读查看或打开来源会话。');
|
|
1956
|
+
const previous = workflowTaskBySession.get(String(sessionId));
|
|
1957
|
+
if (previous?.id === task.id && previous.revision > task.revision) return previous;
|
|
1501
1958
|
if (sessionId) workflowTaskBySession.set(String(sessionId), task);
|
|
1502
1959
|
bindTask(sessionId, task.id);
|
|
1503
1960
|
actions.setWorkflowTask(task);
|
|
@@ -1510,10 +1967,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1510
1967
|
}
|
|
1511
1968
|
|
|
1512
1969
|
async function createWorkflowTask(actions, sessionId, draft = {}) {
|
|
1970
|
+
if (!sessionId) throw new Error('请先打开数据清洗会话。');
|
|
1513
1971
|
const key = String(sessionId || 'unassigned');
|
|
1514
1972
|
let pending = workflowTaskCreationBySession.get(key);
|
|
1515
1973
|
if (!pending) {
|
|
1516
1974
|
pending = requestJson('/data-cleaning/api/workflow/tasks', 'POST', {
|
|
1975
|
+
...sessionWorkbenchController?.originFor?.(sessionId),
|
|
1976
|
+
originSessionId: sessionId,
|
|
1517
1977
|
title: draft.title || '企业数据清洗补全任务',
|
|
1518
1978
|
objectives: draft.objectives || DEFAULT_CLEANING_KEYS,
|
|
1519
1979
|
fieldSelection: draft.fieldSelection || DEFAULT_ENRICHMENT_KEYS,
|
|
@@ -1539,9 +1999,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1539
1999
|
const saved = readTaskBindings()[key];
|
|
1540
2000
|
if (ownedSessionId(key) && /^dcw-[a-zA-Z0-9-]+$/.test(saved || '')) {
|
|
1541
2001
|
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(saved)}`);
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
2002
|
+
if (taskBelongsToSession(response.task, sessionId)) {
|
|
2003
|
+
const task = cacheWorkflowTask(actions, sessionId, response.task);
|
|
2004
|
+
if (restoreStage) actions.setStep(task.stage || 'upload');
|
|
2005
|
+
return task;
|
|
2006
|
+
}
|
|
2007
|
+
bindTask(sessionId, null);
|
|
1545
2008
|
}
|
|
1546
2009
|
return createWorkflowTask(actions, sessionId, draft);
|
|
1547
2010
|
}
|
|
@@ -1555,6 +2018,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1555
2018
|
async function ensureEditableWorkflowTask(actions, sessionId, draft = {}, preferredTask) {
|
|
1556
2019
|
const key = String(sessionId || 'unassigned');
|
|
1557
2020
|
const current = workflowTaskBySession.get(key) ?? preferredTask ?? null;
|
|
2021
|
+
if (current && !taskBelongsToSession(current, sessionId)) throw new Error('不能将历史任务绑定到当前会话。请新建清洗任务。');
|
|
1558
2022
|
if (!current) return createWorkflowTask(actions, sessionId, draft);
|
|
1559
2023
|
if (EDITABLE_WORKFLOW_STATES.has(current.state)) return cacheWorkflowTask(actions, sessionId, current);
|
|
1560
2024
|
workflowTaskBySession.delete(key);
|
|
@@ -1578,8 +2042,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1578
2042
|
async function updateWorkflowTask(actions, sessionId, task, input) {
|
|
1579
2043
|
const latest = workflowTaskBySession.get(String(sessionId || 'unassigned')) ?? task;
|
|
1580
2044
|
if (!latest) return ensureWorkflowTask(actions, sessionId, input);
|
|
2045
|
+
if (!taskBelongsToSession(latest, sessionId)) throw new Error('此任务不属于当前会话。');
|
|
1581
2046
|
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(latest.id)}`, 'PATCH', {
|
|
1582
2047
|
...input,
|
|
2048
|
+
originSessionId: sessionId, originWorkspaceId: latest.originWorkspaceId,
|
|
1583
2049
|
expectedRevision: latest.revision,
|
|
1584
2050
|
});
|
|
1585
2051
|
return cacheWorkflowTask(actions, sessionId, response.task);
|
|
@@ -1588,8 +2054,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1588
2054
|
async function workflowAction(actions, sessionId, task, action, input = {}) {
|
|
1589
2055
|
const latest = workflowTaskBySession.get(String(sessionId || 'unassigned')) ?? task;
|
|
1590
2056
|
if (!latest) throw new Error('请先创建数据清洗补全任务。');
|
|
2057
|
+
if (!taskBelongsToSession(latest, sessionId)) throw new Error('此任务不属于当前会话。');
|
|
1591
2058
|
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(latest.id)}/actions/${action}`, 'POST', {
|
|
1592
2059
|
...input,
|
|
2060
|
+
originSessionId: sessionId, originWorkspaceId: latest.originWorkspaceId,
|
|
1593
2061
|
expectedRevision: latest.revision,
|
|
1594
2062
|
});
|
|
1595
2063
|
return cacheWorkflowTask(actions, sessionId, response.task);
|
|
@@ -1603,6 +2071,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1603
2071
|
if (JSON.stringify([...(task.fieldSelection || [])].sort()) !== JSON.stringify([...(expected.enrichmentKeys || [])].sort())) throw new Error('图片任务字段配置尚未保存,请重试。');
|
|
1604
2072
|
const bound = await requestJson(`/data-cleaning/api/images/commands/${encodeURIComponent(expected.imageCommandId)}`, 'PATCH', {
|
|
1605
2073
|
taskId: task.id, expectedRevision: task.revision, executeOnSend: true,
|
|
2074
|
+
originSessionId: sessionId, originWorkspaceId: task.originWorkspaceId,
|
|
1606
2075
|
});
|
|
1607
2076
|
return { ...bound.command, prompt: buildTaskPrompt(expected) };
|
|
1608
2077
|
}
|
|
@@ -1626,6 +2095,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1626
2095
|
});
|
|
1627
2096
|
const response = await requestJson('/data-cleaning/api/g5/commands', 'POST', {
|
|
1628
2097
|
kind: 'enrich', workflowOwned: true, expectedRevision: task.revision, taskId: task.id,
|
|
2098
|
+
originSessionId: sessionId, originWorkspaceId: task.originWorkspaceId,
|
|
1629
2099
|
rows: runtime.rows, headers: runtime.headers, fieldSelection: task.fieldSelection,
|
|
1630
2100
|
});
|
|
1631
2101
|
if (!response.command?.commandId || !response.command?.prompt) throw new Error('Host 未返回执行凭证;未发送任务。');
|
|
@@ -1634,6 +2104,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1634
2104
|
|
|
1635
2105
|
async function refreshHostedTask(actions, sessionId, taskId, run, navigate = true) {
|
|
1636
2106
|
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(taskId)}`);
|
|
2107
|
+
if (!taskBelongsToSession(response.task, sessionId)) {
|
|
2108
|
+
if (readTaskBindings()[sessionId] === taskId) bindTask(sessionId, null);
|
|
2109
|
+
return null;
|
|
2110
|
+
}
|
|
1637
2111
|
const selectedTask = workflowTaskBySession.get(String(sessionId));
|
|
1638
2112
|
if (selectedTask && selectedTask.id !== taskId) return response.task;
|
|
1639
2113
|
if (selectedTask && selectedTask.revision > response.task.revision) return selectedTask;
|
|
@@ -1691,6 +2165,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1691
2165
|
workflowContract: null,
|
|
1692
2166
|
workflowTask: null,
|
|
1693
2167
|
workflowTasks: [],
|
|
2168
|
+
historyTask: null,
|
|
1694
2169
|
taskTitle: '企业数据清洗补全任务',
|
|
1695
2170
|
mappings: [],
|
|
1696
2171
|
objectives: [...DEFAULT_CLEANING_KEYS],
|
|
@@ -1733,6 +2208,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
1733
2208
|
draft.workflowTasks = (Array.isArray(value) ? value : []).map(task =>
|
|
1734
2209
|
(cached.get(task.id)?.revision ?? -1) > (task.revision ?? -1) ? cached.get(task.id) : task);
|
|
1735
2210
|
},
|
|
2211
|
+
setHistoryTask: (draft, value) => { draft.historyTask = value; },
|
|
2212
|
+
refreshHistoryTask: (draft, value) => {
|
|
2213
|
+
if (value?.id === draft.historyTask?.id && value.revision >= draft.historyTask.revision) draft.historyTask = value;
|
|
2214
|
+
},
|
|
1736
2215
|
setTaskTitle: (draft, value) => { draft.taskTitle = String(value ?? ''); },
|
|
1737
2216
|
setMappings: (draft, value) => {
|
|
1738
2217
|
const next = Array.isArray(value) ? value : [];
|
|
@@ -3261,11 +3740,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3261
3740
|
} catch (error) { onError?.(error instanceof Error ? error.message : String(error)); }
|
|
3262
3741
|
};
|
|
3263
3742
|
const complete = expectedCount == null || expectedCount === total;
|
|
3264
|
-
return h('section', { className: 'dcAgentSection', 'aria-label': title },
|
|
3265
|
-
h('
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3743
|
+
return h('section', { className: 'dcAgentSection dcAgentDatasetPreview', 'aria-label': title },
|
|
3744
|
+
h('div', { className: 'dcAgentDatasetHeader' },
|
|
3745
|
+
h('h3', null, title),
|
|
3746
|
+
h('p', { className: 'dcAgentHint', role: 'status' }, complete
|
|
3747
|
+
? `共 ${total} 条,当前显示 ${total ? start + 1 : 0}–${Math.min(start + pageSize, total)} 条;共 ${columns.length} 列,可横向滚动。`
|
|
3748
|
+
: `完整清单尚未就绪:预期 ${expectedCount} 条,当前载入 ${total} 条。请等待同步;刷新后若仍缺失,请重新上传源文件。`),
|
|
3749
|
+
),
|
|
3269
3750
|
h('div', { className: 'dcAgentPreviewTable', tabIndex: 0, role: 'region', 'aria-label': '表格预览,可横向和纵向滚动,表头固定', style: { overflow: 'auto', maxHeight: '420px' } },
|
|
3270
3751
|
h('table', { className: 'dcAgentTable' },
|
|
3271
3752
|
h('thead', null, h('tr', null, h('th', null, '序号'), columns.map((key) => h('th', { key }, resultFieldLabel(key))))),
|
|
@@ -3275,16 +3756,18 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3275
3756
|
))),
|
|
3276
3757
|
),
|
|
3277
3758
|
),
|
|
3278
|
-
h('div', { className: '
|
|
3279
|
-
h('
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
h('
|
|
3285
|
-
|
|
3759
|
+
h('div', { className: 'dcAgentDatasetFooter' },
|
|
3760
|
+
h('div', { className: 'dcAgentDatasetPagination', 'aria-label': '清单分页' },
|
|
3761
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: currentPage === 0, onClick: () => setPage(currentPage - 1) }, '上一页'),
|
|
3762
|
+
h('span', { className: 'dcAgentDatasetPage', 'aria-live': 'polite' }, `第 ${currentPage + 1} / ${Math.max(1, Math.ceil(total / pageSize))} 页`),
|
|
3763
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: start + pageSize >= total, onClick: () => setPage(currentPage + 1) }, '下一页'),
|
|
3764
|
+
),
|
|
3765
|
+
h('div', { className: 'dcAgentDatasetDownloads', 'aria-label': '清单导出' },
|
|
3766
|
+
h('button', { type: 'button', className: 'dcAgentButton', 'aria-label': `下载全部 ${total} 条 CSV`, disabled: !complete || !total, onClick: () => download('csv') }, h(IconDownloadOutline16), h('span', null, `下载全部 ${total} 条 CSV`)),
|
|
3767
|
+
h('button', { type: 'button', className: 'dcAgentButton', 'aria-label': '下载原值 JSON', disabled: !complete || !total, onClick: () => download('json') }, h(IconDownloadOutline16), h('span', null, '下载原值 JSON')),
|
|
3768
|
+
),
|
|
3769
|
+
h('p', { className: 'dcAgentHint dcAgentDatasetFooterNote' }, '下载包含全部行,不受分页影响。CSV 对公式及长编号作文本保护;JSON 保留原值。仅导出当前清单,不触发企查查调用。'),
|
|
3286
3770
|
),
|
|
3287
|
-
h('p', { className: 'dcAgentHint' }, '下载包含全部行,不受分页影响。CSV 对公式及长编号作文本保护;JSON 保留原值。仅导出当前清单,不触发企查查调用。'),
|
|
3288
3771
|
);
|
|
3289
3772
|
}
|
|
3290
3773
|
|
|
@@ -3302,6 +3785,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3302
3785
|
const workflowContract = useStore((state) => state.workflowContract);
|
|
3303
3786
|
const workflowTask = useStore((state) => state.workflowTask);
|
|
3304
3787
|
const workflowTasks = useStore((state) => state.workflowTasks);
|
|
3788
|
+
const historyTask = useStore((state) => state.historyTask);
|
|
3305
3789
|
const taskTitle = useStore((state) => state.taskTitle);
|
|
3306
3790
|
const mappings = useStore((state) => state.mappings);
|
|
3307
3791
|
const objectives = useStore((state) => state.objectives);
|
|
@@ -3319,6 +3803,19 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3319
3803
|
const paidConfirmed = useStore((state) => state.paidConfirmed);
|
|
3320
3804
|
const activeSessionId = useStore((state) => state.activeSessionId);
|
|
3321
3805
|
const [fieldQuery, setFieldQuery] = react.useState('');
|
|
3806
|
+
const [intakeEditorOpen, setIntakeEditorOpen] = react.useState(() => dataset == null);
|
|
3807
|
+
|
|
3808
|
+
react.useEffect(() => {
|
|
3809
|
+
setIntakeEditorOpen(dataset == null);
|
|
3810
|
+
}, [dataset]);
|
|
3811
|
+
|
|
3812
|
+
react.useEffect(() => {
|
|
3813
|
+
if (!open || !visible) return;
|
|
3814
|
+
const owner = [...(document.querySelectorAll?.('.dcAgentWorkbenchContent') || [])]
|
|
3815
|
+
.find((node) => node.dataset.sessionId === String(activeSessionId));
|
|
3816
|
+
const body = owner?.querySelector?.('.dcAgentWbBody');
|
|
3817
|
+
if (body) body.scrollTop = 0;
|
|
3818
|
+
}, [step, activeSessionId, open, visible]);
|
|
3322
3819
|
|
|
3323
3820
|
react.useEffect(() => {
|
|
3324
3821
|
if (!open || !visible) return undefined;
|
|
@@ -3349,6 +3846,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3349
3846
|
try {
|
|
3350
3847
|
const task = await refreshHostedTask(actions, activeSessionId, workflowTask.id, null, false);
|
|
3351
3848
|
if (disposed) return;
|
|
3849
|
+
if (!task) return;
|
|
3352
3850
|
if (['matching', 'enriching'].includes(task.state)) timer = setTimeout(poll, 2000);
|
|
3353
3851
|
else if (step === 'match' || step === 'enrich') actions.setStep(task.stage || step);
|
|
3354
3852
|
} catch (error) { if (!disposed) actions.setError(error.message); }
|
|
@@ -3367,6 +3865,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3367
3865
|
const stagedSource = runtimeFor(`session:${activeSessionId || 'unassigned'}`, false);
|
|
3368
3866
|
const sourceRows = stagedSource?.sourceRows ?? runtime.sourceRows ?? runtime.rows;
|
|
3369
3867
|
const intake = intakeState(dataset, sourceRows, input, runtime.source || stagedSource?.source || cachedTask?.source);
|
|
3868
|
+
const showIntakeEditor = !dataset || intakeEditorOpen;
|
|
3370
3869
|
const lastCsv = runtime.lastCsv;
|
|
3371
3870
|
const fieldByPattern = (pattern) => runtime.headers.find((field) => pattern.test(field)) ?? null;
|
|
3372
3871
|
const phoneField = fieldByPattern(/^(phone|mobile|tel|telephone|联系电话|手机号码|手机号)$/i);
|
|
@@ -3583,8 +4082,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3583
4082
|
throw new Error('当前会话无法提交数据清洗补全企查查任务');
|
|
3584
4083
|
}
|
|
3585
4084
|
const latest = workflowTaskBySession.get(String(activeSessionId)) ?? cachedTask;
|
|
4085
|
+
if (!taskBelongsToSession(latest, activeSessionId)) throw new Error('此任务不属于当前会话。');
|
|
3586
4086
|
const prepared = await api('/data-cleaning/api/g5/commands', {
|
|
3587
4087
|
...payload, workflowOwned: true, expectedRevision: latest.revision,
|
|
4088
|
+
originSessionId: activeSessionId, originWorkspaceId: latest.originWorkspaceId,
|
|
3588
4089
|
...(payload.kind === 'enrich' ? {} : { confirmPaidCalls: true }),
|
|
3589
4090
|
});
|
|
3590
4091
|
const command = prepared?.command;
|
|
@@ -3737,28 +4238,12 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3737
4238
|
};
|
|
3738
4239
|
|
|
3739
4240
|
const resumeWorkflowTask = async (task) => {
|
|
4241
|
+
// History selection has its own state; never hydrate the current task runtime.
|
|
4242
|
+
actions.setHistoryTask(task);
|
|
3740
4243
|
try {
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
if (task.qccRunId) {
|
|
3744
|
-
try {
|
|
3745
|
-
const response = await api(`/data-cleaning/api/g5/run/${encodeURIComponent(task.qccRunId)}`);
|
|
3746
|
-
actions.setQccRun(response);
|
|
3747
|
-
} catch { /* Expired run data does not prevent persisted artifact downloads. */ }
|
|
3748
|
-
}
|
|
4244
|
+
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(task.id)}`);
|
|
4245
|
+
actions.refreshHistoryTask(response.task);
|
|
3749
4246
|
} catch (error) { actions.setError(error.message); return; }
|
|
3750
|
-
workflowTaskBySession.set(String(activeSessionId || 'unassigned'), task);
|
|
3751
|
-
actions.setWorkflowTask(task);
|
|
3752
|
-
actions.setTaskTitle(task.title);
|
|
3753
|
-
actions.setMappings(task.mappings || []);
|
|
3754
|
-
actions.setObjectives(task.objectives || []);
|
|
3755
|
-
actions.setFieldSelection(task.fieldSelection || []);
|
|
3756
|
-
for (const [key, value] of Object.entries(task.matchRules || {})) actions.setMatchRule(key, value);
|
|
3757
|
-
actions.setStep(task.stage || 'upload');
|
|
3758
|
-
if (!runtimeFor(task.id, false)?.rows?.length && task.source?.rowCount && !(task.artifacts || []).length) {
|
|
3759
|
-
actions.setDataset(null);
|
|
3760
|
-
actions.setError('已恢复任务元数据。出于隐私保护,原始企业名单未持久化;继续处理前请重新上传源文件。');
|
|
3761
|
-
}
|
|
3762
4247
|
};
|
|
3763
4248
|
|
|
3764
4249
|
const startNewWorkflow = () => {
|
|
@@ -3788,6 +4273,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3788
4273
|
const rows = exportRows();
|
|
3789
4274
|
if (!rows?.length) throw new Error('当前页面没有可导出的明细。若任务来自历史记录,请重新上传源文件并继续处理。');
|
|
3790
4275
|
const response = await requestJson(`/data-cleaning/api/workflow/tasks/${encodeURIComponent(latest.id)}/artifacts`, 'POST', {
|
|
4276
|
+
originSessionId: activeSessionId, originWorkspaceId: latest.originWorkspaceId,
|
|
3791
4277
|
expectedRevision: latest.revision,
|
|
3792
4278
|
headers: runtime.headers,
|
|
3793
4279
|
rows,
|
|
@@ -3887,7 +4373,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3887
4373
|
let pane;
|
|
3888
4374
|
if (step === 'history') {
|
|
3889
4375
|
pane = h('div', { className: 'dcAgentPane' },
|
|
3890
|
-
h('p', { className: 'dcAgentHint' }, '
|
|
4376
|
+
h('p', { className: 'dcAgentHint' }, '当前 Profile 的任务历史,仅只读查看;不会改变当前会话的任务、名单、规则或执行范围。'),
|
|
3891
4377
|
h('div', { className: 'dcAgentRow' },
|
|
3892
4378
|
h('button', {
|
|
3893
4379
|
type: 'button',
|
|
@@ -3902,9 +4388,29 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3902
4388
|
onClick: startNewWorkflow,
|
|
3903
4389
|
}, '新建清洗任务'),
|
|
3904
4390
|
),
|
|
4391
|
+
historyTask ? h('section', { className: 'dcAgentSection', 'aria-label': '历史任务只读详情' },
|
|
4392
|
+
h('h3', null, workflowDisplayName(historyTask)),
|
|
4393
|
+
h('p', { className: 'dcAgentHint' }, workflowOriginLabel(historyTask)),
|
|
4394
|
+
h('p', null, `只读 · ${WORKFLOW_STATE_LABELS[historyTask.state] || '未知'} · ${historyTask.source?.rowCount ?? 0} 行`),
|
|
4395
|
+
h('p', { className: 'dcAgentHint' }, `任务编号:${historyTask.id}`),
|
|
4396
|
+
sessionWorkbenchController?.canOpenOrigin?.(historyTask)
|
|
4397
|
+
? h('button', { type: 'button', className: 'dcAgentButton', onClick: () => {
|
|
4398
|
+
try { sessionWorkbenchController.openOrigin(historyTask); }
|
|
4399
|
+
catch (error) { actions.setError(error.message); }
|
|
4400
|
+
} }, '打开来源会话')
|
|
4401
|
+
: h('p', { className: 'dcAgentHint' }, '来源会话未知、已不可用或宿主不支持打开;保留只读查看和已有文件下载。'),
|
|
4402
|
+
(historyTask.artifacts || []).filter(a => a.format === 'xlsx').map(artifact =>
|
|
4403
|
+
h('div', { key: artifact.id, className: 'dcAgentRow' },
|
|
4404
|
+
artifact.kind !== 'report' ? h('a', { className: 'dcAgentButton', href: `/data-cleaning/api/workflow/tasks/${encodeURIComponent(historyTask.id)}/artifacts/${encodeURIComponent(artifact.id)}?preview=1`, target: '_blank', rel: 'noopener' }, '预览 / 打开') : null,
|
|
4405
|
+
h('a', { className: artifact.kind === 'report' ? 'dcAgentHint' : 'dcAgentButton',
|
|
4406
|
+
href: `/data-cleaning/api/workflow/tasks/${encodeURIComponent(historyTask.id)}/artifacts/${encodeURIComponent(artifact.id)}`,
|
|
4407
|
+
download: artifact.fileName }, artifact.kind === 'report' ? '下载任务结果报告' : `下载 ${artifact.fileName}`))),
|
|
4408
|
+
!historyTask.artifacts?.length ? h('p', { className: 'dcAgentHint' }, '此任务暂无已保存制品;历史查看不会重新调用企查查。') : null,
|
|
4409
|
+
) : null,
|
|
3905
4410
|
workflowTasks.length ? h('div', { className: 'dcAgentPane', 'aria-label': '任务历史列表' },
|
|
3906
4411
|
workflowTasks.map((task) => h('button', { key: task.id, type: 'button', className: 'dcAgentHistoryTask', onClick: () => resumeWorkflowTask(task) },
|
|
3907
4412
|
h('h3', null, workflowDisplayName(task)),
|
|
4413
|
+
h('p', { className: 'dcAgentHint' }, workflowOriginLabel(task)),
|
|
3908
4414
|
h('div', { className: 'dcAgentRow' },
|
|
3909
4415
|
h('span', { className: 'dcAgentJobsPill', 'data-state': task.state ?? 'idle' }, WORKFLOW_STATE_LABELS[task.state] ?? task.state ?? '未知'),
|
|
3910
4416
|
h('span', { className: 'dcAgentHint' }, `${task.source?.rowCount ?? 0} 行 · ${task.updatedAt ? new Date(task.updatedAt).toLocaleString() : ''}`),
|
|
@@ -3922,16 +4428,31 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3922
4428
|
h('span', null, '任务名称'),
|
|
3923
4429
|
h('input', { className: 'dcAgentField', value: taskTitle, maxLength: 120, onChange: (event) => actions.setTaskTitle(event.target.value) }),
|
|
3924
4430
|
),
|
|
3925
|
-
h('section', { className: 'dcAgentSection' },
|
|
3926
|
-
h('
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
}
|
|
4431
|
+
h('section', { className: 'dcAgentSection dcAgentMappingSection', 'aria-label': '字段映射' },
|
|
4432
|
+
h('div', { className: 'dcAgentMappingHeader' },
|
|
4433
|
+
h('div', null,
|
|
4434
|
+
h('h3', null, '字段映射'),
|
|
4435
|
+
h('p', { className: 'dcAgentHint' }, '至少映射企业名称、统一社会信用代码或注册号其中一项。未映射列会原样保留,但不参与匹配。'),
|
|
4436
|
+
),
|
|
4437
|
+
h('div', { className: 'dcAgentMappingProgress', 'aria-label': `已映射 ${mappings.length} / ${dataset?.headers?.length || 0} 列` },
|
|
4438
|
+
h('b', null, `${mappings.length} / ${dataset?.headers?.length || 0}`), h('span', null, '列已映射')),
|
|
4439
|
+
),
|
|
4440
|
+
h('div', { className: 'dcAgentMappingToolbar' },
|
|
4441
|
+
h('div', { className: 'dcAgentMappingLegend', 'aria-label': '映射状态说明' },
|
|
4442
|
+
h('span', { className: 'dcAgentMappingLegendItem', 'data-status': 'confirmed' }, '通过'),
|
|
4443
|
+
h('span', { className: 'dcAgentMappingLegendItem', 'data-status': 'review' }, '待确认'),
|
|
4444
|
+
h('span', { className: 'dcAgentMappingLegendItem', 'data-status': 'unmatched' }, '未匹配')),
|
|
4445
|
+
h('button', { type: 'button', className: 'dcAgentButton dcAgentMappingAuto', onClick: () => actions.setMappings(mergeRecommendedMappings(dataset?.headers || [], mappings, targetFields)) }, '补充自动映射(保留已有选择)'),
|
|
4446
|
+
),
|
|
4447
|
+
h('p', { className: 'dcAgentHint dcAgentMappingNote' }, '确认映射自动选入补全范围,不调用模型或企查查。多个原列可确认使用同一补全字段,主体匹配标识只选一列。'),
|
|
4448
|
+
h('div', { className: 'dcAgentMappingList' },
|
|
4449
|
+
h('div', { className: 'dcAgentMappingListHead', 'aria-hidden': 'true' }, h('span', null, '原始列'), h('span', null, '目标字段')),
|
|
4450
|
+
mappingHints.map((recommendation, index) => h(MappingPicker, {
|
|
4451
|
+
key: `${index}:${recommendation.sourceField}`, sourceField: recommendation.sourceField,
|
|
4452
|
+
mappings, groups: [...uiFieldGroups, ['input-only', '输入校验字段', inputOnlyMappingFields]],
|
|
4453
|
+
recommendation, onChange: actions.setMapping,
|
|
4454
|
+
})),
|
|
4455
|
+
),
|
|
3935
4456
|
),
|
|
3936
4457
|
h('section', { className: 'dcAgentSection' },
|
|
3937
4458
|
h('h3', null, '任务目标'),
|
|
@@ -3985,56 +4506,83 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
3985
4506
|
),
|
|
3986
4507
|
);
|
|
3987
4508
|
} else if (step === 'profile') {
|
|
3988
|
-
pane = h('div', { className: 'dcAgentPane' },
|
|
3989
|
-
h('
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
stat('列数', profile.columnCount ?? '—'),
|
|
3994
|
-
profile.amountStats ? stat('金额 最小', profile.amountStats.min) : null,
|
|
3995
|
-
profile.amountStats ? stat('金额 最大', profile.amountStats.max) : null,
|
|
3996
|
-
profile.amountStats ? stat('金额 总和', profile.amountStats.sum) : null,
|
|
3997
|
-
profile.amountStats ? stat('金额 均值', typeof profile.amountStats.mean === 'number' ? profile.amountStats.mean.toFixed(2) : profile.amountStats.mean) : null,
|
|
4509
|
+
pane = h('div', { className: 'dcAgentPane dcAgentProfilePane' },
|
|
4510
|
+
h('section', { className: 'dcAgentSection dcAgentProfileSurface', 'aria-label': '质量体检报告' },
|
|
4511
|
+
h('header', { className: 'dcAgentProfileHeader' },
|
|
4512
|
+
h('h3', null, '质量体检报告'),
|
|
4513
|
+
h('p', { className: 'dcAgentHint' }, '基于已解析数据生成本地质量画像(缺失率、去重值、金额分布)。本步骤不发起企查查调用。'),
|
|
3998
4514
|
),
|
|
3999
|
-
|
|
4000
|
-
h('
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
|
|
4009
|
-
h('
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
|
|
4017
|
-
|
|
4018
|
-
|
|
4019
|
-
|
|
4515
|
+
profile ? h('div', { className: 'dcAgentProfileReport' },
|
|
4516
|
+
h('div', { className: 'dcAgentGrid dcAgentProfileMetrics', 'aria-label': '体检摘要' },
|
|
4517
|
+
stat('行数', profile.rowCount ?? '—'),
|
|
4518
|
+
stat('列数', profile.columnCount ?? '—'),
|
|
4519
|
+
profile.amountStats ? stat('金额 最小', profile.amountStats.min) : null,
|
|
4520
|
+
profile.amountStats ? stat('金额 最大', profile.amountStats.max) : null,
|
|
4521
|
+
profile.amountStats ? stat('金额 总和', profile.amountStats.sum) : null,
|
|
4522
|
+
profile.amountStats ? stat('金额 均值', typeof profile.amountStats.mean === 'number' ? profile.amountStats.mean.toFixed(2) : profile.amountStats.mean) : null,
|
|
4523
|
+
),
|
|
4524
|
+
Array.isArray(profile.columns) && profile.columns.length ? h('section', { className: 'dcAgentProfileTableSection', 'aria-label': '字段质量明细' },
|
|
4525
|
+
h('div', { className: 'dcAgentProfileTableHead' },
|
|
4526
|
+
h('h4', null, '字段质量明细'),
|
|
4527
|
+
h('span', { className: 'dcAgentHint' }, `共 ${profile.columns.length} 列`),
|
|
4528
|
+
),
|
|
4529
|
+
h('div', { className: 'dcAgentProfileTableWrap', tabIndex: 0 },
|
|
4530
|
+
h('table', { className: 'dcAgentTable' },
|
|
4531
|
+
h('thead', null, h('tr', null,
|
|
4532
|
+
h('th', null, '字段'),
|
|
4533
|
+
h('th', null, '非空'),
|
|
4534
|
+
h('th', null, '缺失'),
|
|
4535
|
+
h('th', null, '去重值'),
|
|
4536
|
+
)),
|
|
4537
|
+
h('tbody', null, profile.columns.map((col) => h('tr', { key: col.name },
|
|
4538
|
+
h('td', null, col.name),
|
|
4539
|
+
h('td', { className: 'num' }, String(col.present)),
|
|
4540
|
+
h('td', { className: 'num' }, String(col.missing)),
|
|
4541
|
+
h('td', { className: 'num' }, String(col.distinct)),
|
|
4542
|
+
))),
|
|
4543
|
+
),
|
|
4544
|
+
),
|
|
4545
|
+
) : null,
|
|
4546
|
+
h('div', { className: 'dcAgentProfileActions' },
|
|
4547
|
+
h('button', {
|
|
4548
|
+
type: 'button',
|
|
4549
|
+
className: 'dcAgentButton is-primary',
|
|
4550
|
+
disabled: busy,
|
|
4551
|
+
onClick: () => actions.setStep(requiresQcc ? 'match' : 'enrich'),
|
|
4552
|
+
}, requiresQcc ? '下一步:匹配核验' : '下一步:本地清洗补全'),
|
|
4553
|
+
),
|
|
4554
|
+
) : h('div', { className: 'dcAgentProfileEmpty' },
|
|
4555
|
+
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !hasData, 'aria-label': '生成体检报告', onClick: runProfile }, busy ? '体检中…' : '生成体检报告'),
|
|
4020
4556
|
),
|
|
4021
|
-
) : h('div', { className: 'dcAgentRow' },
|
|
4022
|
-
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !hasData, 'aria-label': '生成体检报告', onClick: runProfile }, busy ? '体检中…' : '生成体检报告'),
|
|
4023
4557
|
),
|
|
4024
4558
|
);
|
|
4025
4559
|
} else if (step === 'match') {
|
|
4026
|
-
|
|
4027
|
-
|
|
4028
|
-
h('section', { className: 'dcAgentSection' },
|
|
4029
|
-
h('
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4560
|
+
const identityMappings = mappings.filter((mapping) => ['company_name', 'credit_no', 'reg_no'].includes(mapping.targetField));
|
|
4561
|
+
pane = h('div', { className: 'dcAgentPane dcAgentMatchPane' },
|
|
4562
|
+
h('section', { className: 'dcAgentSection dcAgentMatchSurface', 'aria-label': '主体匹配执行准备' },
|
|
4563
|
+
h('header', { className: 'dcAgentMatchHeader' },
|
|
4564
|
+
h('h3', null, '主体匹配'),
|
|
4565
|
+
h('p', { className: 'dcAgentHint' }, '通过当前用户连接的企查查 MCP 定位企业主体,并按已选维度补全一企一行字段。多候选始终由人工选择;界面不生成虚构置信度。'),
|
|
4566
|
+
),
|
|
4567
|
+
h('div', { className: 'dcAgentMatchContent' },
|
|
4568
|
+
h('section', { className: 'dcAgentMatchBlock', 'aria-label': '匹配依据' },
|
|
4569
|
+
h('div', { className: 'dcAgentMatchBlockHead' },
|
|
4570
|
+
h('h4', null, '匹配依据'),
|
|
4571
|
+
h('span', { className: 'dcAgentMatchScope' }, h('b', null, identityMappings.length), '项'),
|
|
4572
|
+
),
|
|
4573
|
+
h('div', { className: 'dcAgentChips' }, identityMappings.map((mapping) => h('span', { key: mapping.sourceField, className: 'dcAgentChip' }, `${mapping.sourceField} → ${resultFieldLabel(mapping.targetField)}`))),
|
|
4574
|
+
h('p', { className: 'dcAgentHint' }, '统一社会信用代码等强标识优先;名称匹配不明确时进入人工核验队列。'),
|
|
4575
|
+
),
|
|
4576
|
+
h('section', { className: 'dcAgentMatchBlock', 'aria-label': '准备任务说明' },
|
|
4577
|
+
h('div', { className: 'dcAgentMatchBlockHead' },
|
|
4578
|
+
h('h4', null, '准备任务说明'),
|
|
4579
|
+
h('span', { className: 'dcAgentMatchScope' }, h('b', null, dataset?.rowCount ?? runtime.rows.length), '条记录'),
|
|
4580
|
+
),
|
|
4581
|
+
h('p', { className: 'dcAgentHint' }, `已选择 ${fieldSelection.length} 个补全字段。Host 自动检查所需工具并计算去重主体与调用上界。`),
|
|
4582
|
+
h('p', { className: 'dcAgentHint' }, '回填后可修改;点击发送才开始查询,使用你已连接的企查查 MCP 账号及额度。'),
|
|
4583
|
+
),
|
|
4584
|
+
),
|
|
4585
|
+
h('div', { className: 'dcAgentMatchActions' },
|
|
4038
4586
|
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !hasData || !cachedTask?.id, onClick: runQcc }, busy ? '检查并生成中…' : '生成可编辑任务说明'),
|
|
4039
4587
|
),
|
|
4040
4588
|
),
|
|
@@ -4138,44 +4686,59 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4138
4686
|
);
|
|
4139
4687
|
} else {
|
|
4140
4688
|
pane = h('div', { className: 'dcAgentPane' },
|
|
4141
|
-
h('
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4689
|
+
dataset ? h('section', { className: 'dcAgentSection dcAgentIntakeSummary', 'aria-label': '当前导入数据', role: 'status' },
|
|
4690
|
+
h('div', { className: 'dcAgentIntakeSummaryHead' },
|
|
4691
|
+
h('div', null,
|
|
4692
|
+
h('h3', null, intake.available ? `已解析 ${intake.count} 条数据` : '已保存导入摘要'),
|
|
4693
|
+
h('p', { className: 'dcAgentHint', style: { overflowWrap: 'anywhere' } }, `当前来源:${intake.fileName}`),
|
|
4694
|
+
),
|
|
4695
|
+
),
|
|
4145
4696
|
h('p', { className: 'dcAgentHint' }, intake.available
|
|
4146
|
-
? '
|
|
4697
|
+
? '数据已导入。请核对下方完整名单;需要替换来源时点击“重新导入”。'
|
|
4147
4698
|
: '当前页面没有完整原始数据。请重新导入原文件;历史下载制品仍可从任务历史获取。'),
|
|
4148
4699
|
) : null,
|
|
4149
|
-
h('
|
|
4150
|
-
h('
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4700
|
+
showIntakeEditor ? h('section', { id: 'dc-agent-intake-editor', className: 'dcAgentSection dcAgentIntakeEditor', 'aria-label': dataset ? '重新导入数据' : '导入数据' },
|
|
4701
|
+
h('header', { className: 'dcAgentIntakeEditorHeader' },
|
|
4702
|
+
h('h3', null, dataset ? '重新导入数据' : '导入数据'),
|
|
4703
|
+
h('p', { className: 'dcAgentHint' }, '选择表格或 JSON 文件、识别图片,或者粘贴 CSV / JSON 数据。成功解析后此区域会自动收起。'),
|
|
4704
|
+
),
|
|
4705
|
+
h('div', { className: 'dcAgentIntakeSourceActions' },
|
|
4706
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
4707
|
+
onClick: (event) => event.currentTarget.nextElementSibling?.click() }, '选择文件(自动解析)'),
|
|
4708
|
+
h('input', {
|
|
4709
|
+
type: 'file',
|
|
4710
|
+
accept: '.csv,.json,.xlsx,.xls,image/png,image/jpeg,image/webp',
|
|
4711
|
+
className: 'dcAgentField',
|
|
4712
|
+
style: { display: 'none' },
|
|
4713
|
+
disabled: busy,
|
|
4714
|
+
'aria-label': '选择数据文件',
|
|
4715
|
+
onChange: handleFile,
|
|
4716
|
+
}),
|
|
4717
|
+
h('button', { type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
4718
|
+
onClick: () => openImageIntake() }, '图片识别(粘贴 / 选择)'),
|
|
4719
|
+
),
|
|
4720
|
+
h('div', { className: 'dcAgentIntakePaste' },
|
|
4721
|
+
h('textarea', {
|
|
4722
|
+
className: 'dcAgentTextarea',
|
|
4723
|
+
placeholder: '粘贴 CSV 文本,或 JSON 数组(例如 [{"name":"某公司","amount":"100"}])…',
|
|
4724
|
+
'aria-label': '粘贴数据',
|
|
4725
|
+
value: input,
|
|
4726
|
+
disabled: busy,
|
|
4727
|
+
onPaste: (event) => {
|
|
4728
|
+
const files = imageFilesFromTransfer(event.clipboardData);
|
|
4729
|
+
if (files.length && openImageIntake(files[0])) {
|
|
4730
|
+
event.preventDefault();
|
|
4731
|
+
event.stopPropagation?.();
|
|
4732
|
+
}
|
|
4733
|
+
},
|
|
4734
|
+
onInput: (event) => { actions.setInput(event.target.value); actions.setError(null); },
|
|
4735
|
+
}),
|
|
4736
|
+
),
|
|
4737
|
+
h('div', { className: 'dcAgentIntakeEditorActions' },
|
|
4738
|
+
h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !intake.pendingText, 'aria-label': '解析数据', onClick: handleParse }, busy ? '解析中…' : '解析粘贴内容'),
|
|
4739
|
+
intake.pendingText && hasData ? h('p', { className: 'dcAgentHint', role: 'status' }, '有尚未解析的新粘贴内容,请先解析或清空后再继续。') : null,
|
|
4740
|
+
),
|
|
4741
|
+
) : null,
|
|
4179
4742
|
dataset ? h('div', { className: 'dcAgentChips' },
|
|
4180
4743
|
h('span', { className: 'dcAgentChip' }, `格式 ${dataset.fmt}`),
|
|
4181
4744
|
h('span', { className: 'dcAgentChip' }, `${dataset.rowCount} 行`),
|
|
@@ -4189,10 +4752,13 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4189
4752
|
onError: actions.setError,
|
|
4190
4753
|
}) : null,
|
|
4191
4754
|
hasData ? h('p', { className: 'dcAgentHint' }, '请核对完整名单。识别清单不代表已完成企查查匹配。核对后进入「规则与体检」,确认规则生成质量体检;再进入「主体匹配」直接生成可编辑任务说明。Host 自动检查工具和调用范围,回填中央对话框后点击发送才开始查询。') : null,
|
|
4192
|
-
h('div', { className: '
|
|
4193
|
-
|
|
4194
|
-
|
|
4195
|
-
|
|
4755
|
+
h('div', { className: 'dcAgentUploadActions' },
|
|
4756
|
+
hasData && !intakeEditorOpen ? h('button', {
|
|
4757
|
+
type: 'button', className: 'dcAgentButton', disabled: busy,
|
|
4758
|
+
'aria-expanded': false, 'aria-controls': 'dc-agent-intake-editor',
|
|
4759
|
+
onClick: () => { actions.setError(null); setIntakeEditorOpen(true); },
|
|
4760
|
+
}, '重新导入') : null,
|
|
4761
|
+
hasData ? h('button', { type: 'button', className: 'dcAgentButton is-primary', disabled: busy || !intake.available || intake.pendingText, onClick: () => { actions.setError(null); actions.setStep('rules'); } }, '已核对清单,下一步:字段映射与规则') : null,
|
|
4196
4762
|
),
|
|
4197
4763
|
);
|
|
4198
4764
|
}
|
|
@@ -4242,7 +4808,7 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4242
4808
|
h('p', { className: 'dcAgentHint' }, '导入与核验 → 规则与体检 → 主体匹配 → 字段补全 → 结果下载。菜单只切换视图,不启动调用;按页面主按钮逐步确认。'),
|
|
4243
4809
|
h('p', { className: 'dcAgentHint' }, '支持文本、Excel、JSON 和图片名单。原值保留、多候选人工核验;企查查调用使用当前用户自己的连接与额度。'),
|
|
4244
4810
|
) : null,
|
|
4245
|
-
['rules', 'profile'].includes(step) ? h('nav', { className: '
|
|
4811
|
+
['rules', 'profile'].includes(step) ? h('nav', { className: 'dcAgentViewTabs', 'aria-label': '规则与体检视图' },
|
|
4246
4812
|
h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'rules', onClick: () => actions.setStep('rules') }, '字段映射与规则'),
|
|
4247
4813
|
h('button', { type: 'button', className: 'dcAgentButton', 'aria-pressed': step === 'profile', onClick: () => actions.setStep('profile') }, '质量体检报告'),
|
|
4248
4814
|
) : null,
|
|
@@ -4443,6 +5009,27 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4443
5009
|
: null;
|
|
4444
5010
|
const disconnectFixture = typeof ctx.inject !== 'function' ? connectProvider(ctx.betterSidebar) : () => {};
|
|
4445
5011
|
const controller = {
|
|
5012
|
+
originFor(sessionId) {
|
|
5013
|
+
const sessions = typeof ctx.get === 'function' ? ctx.get('sessions') : ctx.sessions;
|
|
5014
|
+
const workspaces = typeof ctx.get === 'function' ? ctx.get('workspaces') : ctx.workspaces;
|
|
5015
|
+
const summary = sessions?.list?.getSnapshot?.()?.byId?.[sessionId];
|
|
5016
|
+
const workspace = workspaces?.list?.getSnapshot?.()?.items?.find(item => item.sessionIds?.includes(sessionId));
|
|
5017
|
+
return { originSessionId: sessionId, originWorkspaceId: workspace?.workspaceId || summary?.workspaceId || null,
|
|
5018
|
+
originSessionName: summary?.title || null, originWorkspaceName: workspace?.name || workspace?.title || null };
|
|
5019
|
+
},
|
|
5020
|
+
canOpenOrigin(task) {
|
|
5021
|
+
const sessions = typeof ctx.get === 'function' ? ctx.get('sessions') : ctx.sessions;
|
|
5022
|
+
if (!task?.originSessionId || !ownedSessionId(task.originSessionId) || typeof sessions?.open !== 'function') return false;
|
|
5023
|
+
const summary = sessions.list?.getSnapshot?.()?.byId?.[task.originSessionId];
|
|
5024
|
+
const scope = controller.originFor(task.originSessionId);
|
|
5025
|
+
return Boolean(summary && (!task.originWorkspaceId || scope.originWorkspaceId === task.originWorkspaceId));
|
|
5026
|
+
},
|
|
5027
|
+
openOrigin(task) {
|
|
5028
|
+
if (!controller.canOpenOrigin(task)) throw new Error('来源会话不可用;请继续只读查看。');
|
|
5029
|
+
const sessions = typeof ctx.get === 'function' ? ctx.get('sessions') : ctx.sessions;
|
|
5030
|
+
sessions.open(task.originSessionId);
|
|
5031
|
+
// Navigation only: no task binding, command preparation, or draft writes.
|
|
5032
|
+
},
|
|
4446
5033
|
storeFor: instanceFor,
|
|
4447
5034
|
actionsFor: sessionId => instanceFor(sessionId).actions,
|
|
4448
5035
|
open(sessionId, step) {
|
|
@@ -4645,6 +5232,10 @@ body:has(.dcAgentPromptBackdrop) { overflow: hidden; }
|
|
|
4645
5232
|
ensureWorkflowTask,
|
|
4646
5233
|
ensureEditableWorkflowTask,
|
|
4647
5234
|
queueWorkflowOperation,
|
|
5235
|
+
taskBelongsToSession,
|
|
5236
|
+
workflowOriginLabel,
|
|
5237
|
+
cacheWorkflowTask,
|
|
5238
|
+
refreshHostedTask,
|
|
4648
5239
|
};
|
|
4649
5240
|
return module.exports;
|
|
4650
5241
|
},
|