浏览代码

develop controls.Ext

main
hulei 3 周前
父节点
当前提交
5942c0a44a
共有 100 个文件被更改,包括 17809 次插入0 次删除
  1. 50
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/ControlEntity/DzyyEntity.cs
  2. 44
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/ControlEntity/PropGuideEntity.cs
  3. 66
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CamPlayer.xaml
  4. 491
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CamPlayer.xaml.cs
  5. 81
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CameraViewer.xaml
  6. 192
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CameraViewer.xaml.cs
  7. 22
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CaptureViewer.xaml
  8. 293
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CaptureViewer.xaml.cs
  9. 152
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckMoney.xaml
  10. 358
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckMoney.xaml.cs
  11. 76
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification.xaml
  12. 199
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification.xaml.cs
  13. 85
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification_ZK.xaml
  14. 566
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification_ZK.xaml.cs
  15. 31
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DataBoxViewer.xaml
  16. 122
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DataBoxViewer.xaml.cs
  17. 20
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateInputControl.xaml
  18. 126
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateInputControl.xaml.cs
  19. 31
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateSpanControl.xaml
  20. 158
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateSpanControl.xaml.cs
  21. 58
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailEdit.xaml
  22. 365
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailEdit.xaml.cs
  23. 57
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailInformation.xaml
  24. 188
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailInformation.xaml.cs
  25. 416
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connection.cs
  26. 254
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connection.ts
  27. 241
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectionAdorner.cs
  28. 162
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectionAdorner.ts
  29. 174
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connector.cs
  30. 192
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connector.ts
  31. 162
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorAdorner.cs
  32. 142
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorAdorner.ts
  33. 10
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorInfo.ts
  34. 699
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvas.cs
  35. 330
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvas.ts
  36. 106
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvasAdorner.cs
  37. 100
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvasAdorner.ts
  38. 258
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerItem.cs
  39. 206
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerItem.ts
  40. 65
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DragThumb.cs
  41. 97
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DragThumb.ts
  42. 8
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ISelectable.cs
  43. 9
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ISelectable.ts
  44. 654
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/PathFinder.cs
  45. 636
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/PathFinder.ts
  46. 82
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RelativePositionPanel.cs
  47. 88
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RelativePositionPanel.ts
  48. 99
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ResizeThumb.cs
  49. 111
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ResizeThumb.ts
  50. 92
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RubberbandAdorner.cs
  51. 133
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RubberbandAdorner.ts
  52. 54
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Entry.cs
  53. 46
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Entry.ts
  54. 125
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Node.cs
  55. 123
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Node.ts
  56. 130
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/Connection.xaml
  57. 187
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/DesignerItem.xaml
  58. 57
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/NodeControlStyles.xaml
  59. 111
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FeeViewer.xaml
  60. 827
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FeeViewer.xaml.cs
  61. 282
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FileViewer.xaml
  62. 1307
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FileViewer.xaml.cs
  63. 121
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/IdCheckViewer.xaml
  64. 589
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/IdCheckViewer.xaml.cs
  65. 61
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ImageManager.xaml
  66. 213
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ImageManager.xaml.cs
  67. 108
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/Imageshow.xaml
  68. 91
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/Imageshow.xaml.cs
  69. 78
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/LeadTradeViewer.xaml
  70. 622
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/LeadTradeViewer.xaml.cs
  71. 275
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridLineDecorator.cs
  72. 250
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridLineDecorator.ts
  73. 20
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridViewColumnHelper.cs
  74. 13
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridViewColumnHelper.ts
  75. 61
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/Listviewpg.xaml
  76. 519
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/Listviewpg.xaml.cs
  77. 52
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/MouseUtilities.cs
  78. 52
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/MouseUtilities.ts
  79. 50
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/VisualService.cs
  80. 43
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/VisualService.ts
  81. 62
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ManageButtonGroup.xaml
  82. 69
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ManageButtonGroup.xaml.cs
  83. 122
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MessageBox/TellerMessageBox.xaml
  84. 335
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MessageBox/TellerMessageBox.xaml.cs
  85. 95
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MobilePhoneCheckViewer.xaml
  86. 148
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MobilePhoneCheckViewer.xaml.cs
  87. 12
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MoneyGrid.xaml
  88. 84
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MoneyGrid.xaml.cs
  89. 110
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MultiSelectComboBox.xaml
  90. 391
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MultiSelectComboBox.xaml.cs
  91. 17
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PairStateSign.xaml
  92. 57
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PairStateSign.xaml.cs
  93. 206
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PersonCardInfoViewer.xaml
  94. 63
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PersonCardInfoViewer.xaml.cs
  95. 24
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PictureCaptureViewer.xaml
  96. 53
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PictureCaptureViewer.xaml.cs
  97. 11
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PropGuide.xaml
  98. 56
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PropGuide.xaml.cs
  99. 70
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ProvinceCityCounty.xaml
  100. 0
    0
      ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ProvinceCityCounty.xaml.cs

+ 50
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/ControlEntity/DzyyEntity.cs 查看文件

@@ -0,0 +1,50 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Controls.Ext.ControlEntity
7
+{
8
+    /// <summary>
9
+    /// 电子验印实体
10
+    /// </summary>
11
+    public class DzyyEntity
12
+    {
13
+        public DzyyEntity()
14
+        {
15
+            AccNo = Amt = Voucher = VoucherNo = VoucherDate = Message = SerialNo = string.Empty;
16
+        }
17
+        /// <summary>
18
+        /// 账号
19
+        /// </summary>
20
+        public string AccNo { get; set; }
21
+        /// <summary>
22
+        /// 金额
23
+        /// </summary>
24
+        public string Amt { get; set; }
25
+        /// <summary>
26
+        /// 凭证类型
27
+        /// </summary>
28
+        public string Voucher { get; set; }
29
+        /// <summary>
30
+        /// 凭证号码
31
+        /// </summary>
32
+        public string VoucherNo { get; set; }
33
+        /// <summary>
34
+        /// 出票日期
35
+        /// </summary>
36
+        public string VoucherDate { get; set; }
37
+        /// <summary>
38
+        /// 处理信息结果
39
+        /// </summary>
40
+        public string Message { get; internal set; }
41
+        /// <summary>
42
+        /// 验印流水号
43
+        /// </summary>
44
+        public string SerialNo { get; internal set; }
45
+        /// <summary>
46
+        /// 验印通过标志
47
+        /// </summary>
48
+        public string YYFlag { get;  set; }
49
+    }
50
+}

+ 44
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/ControlEntity/PropGuideEntity.cs 查看文件

@@ -0,0 +1,44 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using Platform.Common.BasicFunctions;
6
+using System.Collections.ObjectModel;
7
+
8
+namespace TellerSystem.Controls.Ext.ControlEntity
9
+{
10
+    public class PropGuideEntity : ObservableObject
11
+    {
12
+        private string _groupHeader;
13
+
14
+        public string GroupHeader
15
+        {
16
+            get { return _groupHeader; }
17
+            set 
18
+            {
19
+                _groupHeader = value;
20
+                RaisePropertyChanged(() => GroupHeader);
21
+            }
22
+        }
23
+
24
+        private Dictionary<string, string> _children;
25
+
26
+        public Dictionary<string, string> Children
27
+        {
28
+            get
29
+            {
30
+                if (_children == null)
31
+                {
32
+                    _children = new Dictionary<string, string>();
33
+                }
34
+                return _children;
35
+            }
36
+            set
37
+            {
38
+                _children = value;
39
+                RaisePropertyChanged(() => Children);
40
+            }
41
+        }
42
+
43
+    }
44
+}

+ 66
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CamPlayer.xaml 查看文件

@@ -0,0 +1,66 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Controls.Ext.Controls.CamPlayer"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:aforge="clr-namespace:AForge.Controls;assembly=AForge.Controls"
5
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                xmlns:dhcc="http://www.dhcc.com.cn"
7
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                xmlns:wfi="clr-namespace:System.Windows.Forms.Integration;assembly=WindowsFormsIntegration"
9
+                Width="800"
10
+                Height="600"
11
+                d:DesignHeight="300"
12
+                d:DesignWidth="300"
13
+                Loaded="CamPlayer_Loaded"
14
+                mc:Ignorable="d">
15
+
16
+    <Grid>
17
+        <Grid.Resources>
18
+            <Style x:Key="buttonControl" TargetType="{x:Type ItemsControl}">
19
+                <Setter Property="FocusVisualStyle" Value="{x:Null}" />
20
+                <Setter Property="ItemsControl.ItemsPanel">
21
+                    <Setter.Value>
22
+                        <ItemsPanelTemplate>
23
+                            <WrapPanel />
24
+                        </ItemsPanelTemplate>
25
+                    </Setter.Value>
26
+                </Setter>
27
+                <Setter Property="ItemsControl.ItemTemplate">
28
+                    <Setter.Value>
29
+                        <DataTemplate DataType="data:MediaParaEntry">
30
+                            <StackPanel Margin="0,0,0,0" Orientation="Horizontal">
31
+                                <RadioButton Margin="10,0,0,0"
32
+                                             Checked="RadioButton_Checked"
33
+                                             Content="{Binding Text}"
34
+                                             GroupName="device"
35
+                                             IsChecked="{Binding IsRun}"
36
+                                             Tag="{Binding }" />
37
+                            </StackPanel>
38
+                        </DataTemplate>
39
+                    </Setter.Value>
40
+                </Setter>
41
+            </Style>
42
+        </Grid.Resources>
43
+        <Grid.RowDefinitions>
44
+            <RowDefinition Height="auto" />
45
+            <RowDefinition Height="*" />
46
+        </Grid.RowDefinitions>
47
+        <WrapPanel Grid.Row="0"
48
+                   HorizontalAlignment="Center"
49
+                   Orientation="Horizontal">
50
+            <ItemsControl Name="buttons" Style="{StaticResource buttonControl}" />
51
+            <Button x:Name="photoBtn"
52
+                    Margin="40,0,0,0"
53
+                    Click="photoBtn_Click"
54
+                    Content="拍照" />
55
+            <Button x:Name="cancelBtn"
56
+                    Margin="40,0,0,0"
57
+                    Click="cancelBtn_Click"
58
+                    Content="取消" />
59
+        </WrapPanel>
60
+        <wfi:WindowsFormsHost Name="host"
61
+                              Grid.Row="1"
62
+                              Margin="8,0">
63
+            <aforge:VideoSourcePlayer x:Name="vsp" />
64
+        </wfi:WindowsFormsHost>
65
+    </Grid>
66
+</dhcc:TradePage>

+ 491
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CamPlayer.xaml.cs 查看文件

@@ -0,0 +1,491 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using System.ComponentModel;
15
+using System.IO;
16
+using System.Collections.ObjectModel;
17
+using TellerSystem.Library.Ext.Function;
18
+using Platform.Common.RunningParameters;
19
+using AForge.Video.DirectShow;
20
+using System.Drawing;
21
+using AForge.Video;
22
+using System.Drawing.Imaging;
23
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
24
+using AForge.Controls;
25
+
26
+namespace TellerSystem.Controls.Ext.Controls
27
+{
28
+    /// <summary>
29
+    /// CamPlayer.xaml 的交互逻辑
30
+    /// </summary>
31
+    public partial class CamPlayer
32
+    {
33
+        public CamPlayer(string DeviceType)
34
+        {
35
+            InitializeComponent();
36
+            DefaultDevice = DeviceType;
37
+            InitPage();
38
+        }
39
+
40
+        /// <summary>
41
+        /// 依次为标识,VID,PID
42
+        /// </summary>
43
+        private Dictionary<string, Tuple<string, string>> DevicesTagDit = new Dictionary<string, Tuple<string, string>>
44
+        {
45
+           {"PZ",new Tuple<string,string>("0ac8","3370")},
46
+           {"KH",new Tuple<string,string>("0c45","6340")},
47
+           {"GY",new Tuple<string,string>("c456","6341")},
48
+        };
49
+        /// <summary>
50
+        /// 版本控制标志
51
+        /// </summary>
52
+        private string flag = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
53
+        /// <summary>
54
+        /// 是否是拍照产生的图片
55
+        /// </summary>
56
+        bool isPhoto = false;
57
+
58
+        Window win = null;
59
+
60
+        ObservableCollection<MediaParaEntry> collect = new ObservableCollection<MediaParaEntry>();
61
+
62
+        /// <summary>
63
+        /// 
64
+        /// </summary>
65
+        public string DefaultDevice = "KH";
66
+
67
+        /// <summary>
68
+        /// 
69
+        /// </summary>
70
+        public DHCPhoto Photo = new DHCPhoto();
71
+
72
+
73
+        VideoCapabilities getVideoCapabilities(VideoCapabilities[] videos)
74
+        {
75
+            for (int i = 0; i < videos.Length; i++)
76
+            {
77
+                var item = videos[i];
78
+                if (flag == "V2")
79
+                {
80
+                    //鄢陵
81
+                    if (DefaultDevice == "KH" || DefaultDevice == "GY")
82
+                    {
83
+                        if (item.FrameSize.Width == 1280 && item.FrameSize.Height == 960)
84
+                        {
85
+                            return item;
86
+                        }
87
+                    }
88
+                    //凭证和补录
89
+                    else
90
+                    {
91
+                        if (item.FrameSize.Width == 1600 && item.FrameSize.Height == 1200)
92
+                        {
93
+                            return item;
94
+                        }
95
+                    }
96
+                }
97
+                //阳光远程授权
98
+                if (flag == "V8")
99
+                {
100
+                    if (item.FrameSize.Width == 1280 && item.FrameSize.Height == 960)
101
+                    {
102
+                        return item; 
103
+                    }
104
+                    if (item.FrameSize.Width == 1280 && item.FrameSize.Height == 1024)
105
+                    {
106
+                        return item;
107
+                    }
108
+                }
109
+                else if (flag == "V21")
110
+                {
111
+                    if (DefaultDevice == "KH" || DefaultDevice == "GY")
112
+                    {
113
+                        if (item.FrameSize.Width == 1280 && item.FrameSize.Height == 960)
114
+                        {
115
+                            return item;
116
+                        }
117
+                    }
118
+                    //凭证和补录
119
+                    else
120
+                    {
121
+                        if (item.FrameSize.Width == 2592 && item.FrameSize.Height == 1944)
122
+                        {
123
+                            return item;
124
+                        }
125
+                        //if (flag == "V21")
126
+                        //{
127
+                            var item1 = 0;
128
+                            for (int j = 0; j < videos.Length; j++)
129
+                            {
130
+                                if (DefaultDevice != "KH" && DefaultDevice != "GY")
131
+                                {
132
+                                    if (item1 < videos[j].FrameSize.Width)
133
+                                    {
134
+                                        item1 = videos[j].FrameSize.Width;
135
+                                    }
136
+                                }
137
+                            }
138
+                            for (int j = 0; j < videos.Length; j++)
139
+                            {
140
+                                if (DefaultDevice != "KH" && DefaultDevice != "GY")
141
+                                {
142
+                                    if (videos[j].FrameSize.Width == item1)
143
+                                    {
144
+                                        return videos[j];
145
+                                    }
146
+                                }
147
+                            }
148
+                        //}
149
+                    }
150
+                }
151
+                else
152
+                {
153
+                    //客户和柜员 
154
+                    if (DefaultDevice == "KH" || DefaultDevice == "GY")
155
+                    {
156
+                        if (item.FrameSize.Width == 1280 && item.FrameSize.Height == 720)
157
+                        {
158
+                            return item; 
159
+                        }
160
+                    }
161
+                    //凭证和补录
162
+                    else
163
+                    {
164
+                        if (item.FrameSize.Width == 1920 && item.FrameSize.Height == 1080)
165
+                        {
166
+                            return item; 
167
+                        }
168
+                    }
169
+                }
170
+
171
+            }
172
+            return videos[videos.Length - 1];
173
+        }
174
+
175
+        void openCamera(FilterInfo info)
176
+        {
177
+            var videoCapture = new VideoCaptureDevice(info.MonikerString);
178
+            videoCapture.VideoResolution = getVideoCapabilities(videoCapture.VideoCapabilities);
179
+            setHostWH(videoCapture.VideoResolution.FrameSize);
180
+            vsp.VideoSource = videoCapture;
181
+            vsp.NewFrame += new VideoSourcePlayer.NewFrameHandler(this.Vsp_NewFrame);
182
+            vsp.Start();
183
+        }
184
+
185
+        //图像缓存
186
+        private Bitmap bmp;
187
+        private void Vsp_NewFrame(object sender, ref Bitmap image)
188
+        {
189
+            bmp = image;
190
+        }
191
+
192
+        public BitmapImage BitmapToBitmapImage(Bitmap bitmap)
193
+        {
194
+            using (MemoryStream stream = new MemoryStream())
195
+            {
196
+                Bitmap bm2 = new Bitmap(bitmap.Width, bitmap.Height);
197
+                Graphics g = Graphics.FromImage(bm2);
198
+                //重新复制bitmap--解决GDI+
199
+                g.DrawImageUnscaled(bitmap, 0, 0);
200
+                g.Dispose();
201
+                bm2.Save(stream, ImageFormat.Png); // 坑点:格式选Bmp时,不带透明度
202
+
203
+                stream.Position = 0;
204
+                BitmapImage result = new BitmapImage();
205
+                result.BeginInit();
206
+                result.CacheOption = BitmapCacheOption.OnLoad;
207
+                result.StreamSource = stream;
208
+                result.EndInit();
209
+                result.Freeze();
210
+                return result;
211
+            }
212
+        }
213
+
214
+
215
+        public void closeCamera()
216
+        {
217
+            vsp.NewFrame -= Vsp_NewFrame;
218
+            if (vsp.IsRunning)
219
+            {   // 停止视频
220
+                vsp.SignalToStop();
221
+                vsp.WaitForStop();
222
+            }
223
+        }
224
+
225
+
226
+        FilterInfo getDefaultFilter(FilterInfoCollection devices)
227
+        {
228
+            string devTag = DefaultDevice;
229
+            if (devTag == "BL")
230
+            {
231
+                devTag = "PZ";
232
+            }
233
+            FilterInfo result = null;
234
+            String vid = "vid_" + DevicesTagDit[devTag].Item1;
235
+            String pid = "pid_" + DevicesTagDit[devTag].Item2;
236
+            for (int i = 0; i < devices.Count; i++)
237
+            {
238
+                var item = devices[i];
239
+                if (item.MonikerString.Contains(vid) && item.MonikerString.Contains(pid))
240
+                {
241
+                    result = item;
242
+                }
243
+            }
244
+            if (result == null)
245
+            {
246
+                result = devices[0];
247
+            }
248
+            return result;
249
+        }
250
+
251
+
252
+        public bool InitPage()
253
+        {
254
+            if (ConfigManager.GetInstance().GetConfigValue("CameraEnabled", ConfigType.User).ToLower() == "true")
255
+            {
256
+                DevicesTagDit.Clear();
257
+                DevicesTagDit.Add("PZ", new Tuple<string, string>(ConfigManager.GetInstance().GetConfigValue("PZVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("PZPid", ConfigType.User)));
258
+                DevicesTagDit.Add("KH", new Tuple<string, string>(ConfigManager.GetInstance().GetConfigValue("KHVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("KHPid", ConfigType.User)));
259
+                DevicesTagDit.Add("GY", new Tuple<string, string>(ConfigManager.GetInstance().GetConfigValue("GYVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("GYPid", ConfigType.User)));
260
+
261
+            }
262
+            var devices = new FilterInfoCollection(FilterCategory.VideoInputDevice);
263
+            if (devices == null || devices.Count < 1)
264
+            {
265
+                MessageBox.Show("请检查摄像头是否连接");
266
+                win.Close();
267
+                return false;
268
+            }
269
+            FilterInfo dev = getDefaultFilter(devices);
270
+            for (int i = 0; i < devices.Count; i++)
271
+            {
272
+                var item = devices[i];
273
+                collect.Add(new MediaParaEntry() { Text = item.Name, Device = item, IsRun = dev == item });
274
+            }
275
+            buttons.ItemsSource = collect;
276
+            openCamera(dev);
277
+            return true;
278
+        }
279
+
280
+        //modify by hulei   20190409   新增 window 关闭界面时 关掉摄像头,以防被占用 start
281
+        void CamPlayer_Loaded(object sender, RoutedEventArgs e)
282
+        {
283
+            win = this.FindVisualTreeParent(x => x is Window) as Window;
284
+            var buttonGroup = win.FirstVisualTreeChildren(x => x is StackPanel && (x as StackPanel).Name == "buttonsStackPanel") as StackPanel;
285
+            if (buttonGroup.Name == "buttonsStackPanel")
286
+            {
287
+                buttonGroup.Visibility = Visibility.Collapsed;
288
+            }
289
+            var image = win.FirstVisualTreeChildren(x => x is FrameworkElement && (x as FrameworkElement).Name == "image") as FrameworkElement;
290
+            if (image.Name == "image")
291
+            {
292
+                image.Visibility = Visibility.Collapsed;
293
+            }
294
+            win.Closed += new EventHandler(win_Closed);
295
+        }
296
+        void win_Closed(object sender, EventArgs e)
297
+        {
298
+            closeCamera();
299
+        }
300
+        //modify by hulei   20190409   新增 window 关闭界面时 关掉摄像头,以防被占用 end 
301
+
302
+        /// <summary>
303
+        /// 拍照
304
+        /// </summary>
305
+        /// <param name="sender"></param>
306
+        /// <param name="e"></param>
307
+        private void photoBtn_Click(object sender, RoutedEventArgs e)
308
+        {
309
+            isPhoto = true;
310
+            if (bmp == null)
311
+            {
312
+                MessageBox.Show("请重新点击拍照!");
313
+            }
314
+            Photo.Source = BitmapToBitmapImage(bmp);
315
+            closeCamera();
316
+            win.Close();
317
+        }
318
+
319
+        private void RadioButton_Checked(object sender, RoutedEventArgs e)
320
+        {
321
+            RadioButton rd = sender as RadioButton;
322
+            MediaParaEntry entry = rd.Tag as MediaParaEntry;
323
+            closeCamera();
324
+            openCamera(entry.Device);
325
+        }
326
+
327
+        private void cancelBtn_Click(object sender, RoutedEventArgs e)
328
+        {
329
+            isPhoto = false;
330
+            closeCamera();
331
+            win.Close();
332
+        }
333
+
334
+
335
+        void setHostWH(System.Drawing.Size frameSize)
336
+        {
337
+            double rWidth;
338
+            double rHeight;
339
+            double pWidth = 780;
340
+            double pHeight = 540;
341
+            double wRate = (double)frameSize.Width / pWidth;
342
+            double hRate = (double)frameSize.Height / pHeight;
343
+            if (wRate > 1 || hRate > 1)
344
+            {
345
+                if (wRate > hRate)
346
+                {
347
+                    //以宽标准缩放
348
+                    rWidth = pWidth;
349
+                    rHeight = pWidth / frameSize.Width * frameSize.Height;
350
+                }
351
+                else
352
+                {
353
+                    rWidth = pHeight / frameSize.Height * frameSize.Width;
354
+                    rHeight = pHeight;
355
+                }
356
+            }
357
+            else
358
+            {
359
+                rWidth = (double)frameSize.Width;
360
+                rHeight = (double)frameSize.Height;
361
+            }
362
+            host.Width = rWidth;
363
+            host.Height = rHeight;
364
+        }
365
+
366
+    }
367
+
368
+    public class DHCPhoto : INotifyPropertyChanged
369
+    {
370
+        BitmapSource source = null;
371
+        public BitmapSource Source
372
+        {
373
+            get { return source; }
374
+            set
375
+            {
376
+                source = value;
377
+                data = null;
378
+                Notify("Source");
379
+            }
380
+        }
381
+        string devicetype = "KH";
382
+        public string DeviceType
383
+        {
384
+
385
+            get { return devicetype; }
386
+            set
387
+            {
388
+                devicetype = value;
389
+                Notify("DeviceType");
390
+            }
391
+
392
+        }
393
+
394
+
395
+        byte[] data = null;
396
+        int qualityLevel = 100;
397
+        public byte[] Data
398
+        {
399
+            get
400
+            {
401
+
402
+                if (data == null && Source != null)
403
+                {
404
+                    if (DeviceType == "KH")
405
+                    {
406
+                        qualityLevel = 30;
407
+                    }
408
+                    else if (DeviceType == "GY")
409
+                    {
410
+                        qualityLevel = 30;
411
+                    }
412
+                    else
413
+                    {
414
+                        string FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
415
+                        if (FLAG == "V21")
416
+                        {
417
+                            qualityLevel = 30;
418
+                        }
419
+                        else
420
+                        {
421
+                            qualityLevel = 80;
422
+                        }
423
+                    }
424
+                    using (var ms = new MemoryStream())
425
+                    {
426
+                        BitmapEncoder encoder = new JpegBitmapEncoder() { QualityLevel = qualityLevel };
427
+                        encoder.Frames.Add(BitmapFrame.Create(source as BitmapSource));
428
+                        encoder.Save(ms);
429
+                        ms.Flush();
430
+                        data = ms.ToArray();
431
+                        ms.Close();
432
+                    }
433
+                }
434
+                return data;
435
+            }
436
+        }
437
+
438
+        public event PropertyChangedEventHandler PropertyChanged;
439
+
440
+        void Notify(string propName)
441
+        {
442
+            if (this.PropertyChanged != null)
443
+            {
444
+                PropertyChanged(this, new PropertyChangedEventArgs(propName));
445
+            }
446
+        }
447
+    }
448
+
449
+    public class MediaParaEntry : INotifyPropertyChanged
450
+    {
451
+        public string text = string.Empty;
452
+        /// <summary>
453
+        /// 
454
+        /// </summary>
455
+        public string Text
456
+        {
457
+            get { return text; }
458
+            set { text = value; Notify("Text"); }
459
+        }
460
+
461
+        private FilterInfo device;
462
+
463
+        public FilterInfo Device
464
+        {
465
+            get { return device; }
466
+            set { device = value; Notify("Device"); }
467
+        }
468
+
469
+        private bool isRun = false;
470
+        /// <summary>
471
+        /// 
472
+        /// </summary>
473
+        public bool IsRun
474
+        {
475
+            get { return isRun; }
476
+            set { isRun = value; Notify("IsRun"); }
477
+        }
478
+
479
+        public event PropertyChangedEventHandler PropertyChanged;
480
+
481
+        void Notify(string propName)
482
+        {
483
+            if (this.PropertyChanged != null)
484
+            {
485
+                PropertyChanged(this, new PropertyChangedEventArgs(propName));
486
+            }
487
+        }
488
+    }
489
+
490
+
491
+}

+ 81
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CameraViewer.xaml 查看文件

@@ -0,0 +1,81 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Controls.Ext.Controls.CameraViewer"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+                Width="550"
8
+                Height="530"
9
+                dhcc:FocusManager.EnableFocusControl="True"
10
+                Loaded="TradePage_Loaded"
11
+                mc:Ignorable="d">
12
+    <StackPanel Name="TradeCanvasStack">
13
+        <GroupBox Name="grb"
14
+                  Margin="2"
15
+                  Header="采集图像">
16
+            <Grid>
17
+                <Canvas Width="533" Height="400">
18
+                    <WindowsFormsHost Name="Host"
19
+                                      Width="533"
20
+                                      Height="400" />
21
+                </Canvas>
22
+            </Grid>
23
+        </GroupBox>
24
+        <Grid>
25
+            <Grid.RowDefinitions>
26
+                <RowDefinition Height="5" />
27
+                <RowDefinition Height="25" />
28
+                <RowDefinition Height="5" />
29
+                <RowDefinition Height="25" />
30
+                <RowDefinition Height="10" />
31
+                <RowDefinition Height="20" />
32
+                <RowDefinition Height="*" />
33
+            </Grid.RowDefinitions>
34
+            <Grid.ColumnDefinitions>
35
+                <ColumnDefinition Width="10" />
36
+                <ColumnDefinition Width="150" />
37
+                <ColumnDefinition Width="65" />
38
+                <ColumnDefinition Width="10" />
39
+                <ColumnDefinition Width="65" />
40
+                <ColumnDefinition Width="10" />
41
+                <ColumnDefinition Width="65" />
42
+                <ColumnDefinition Width="*" />
43
+            </Grid.ColumnDefinitions>
44
+            <Border Grid.Row="1"
45
+                    Grid.RowSpan="4"
46
+                    Grid.Column="1"
47
+                    Width="80"
48
+                    Height="60"
49
+                    HorizontalAlignment="Left"
50
+                    BorderBrush="Black"
51
+                    BorderThickness="2">
52
+                <Image Name="smallImage" />
53
+            </Border>
54
+            <TextBlock Grid.Row="5"
55
+                       Grid.Column="1"
56
+                       Grid.ColumnSpan="4"
57
+                       Margin="2,0,8,0"
58
+                       HorizontalAlignment="Center"
59
+                       Foreground="Red"
60
+                       Text="提示:可以按住鼠标左键拖出区域进行拍照!" />
61
+            <Button Name="btnOpen"
62
+                    Grid.Row="3"
63
+                    Grid.Column="2"
64
+                    HorizontalAlignment="Center"
65
+                    Click="btnOpen_Click"
66
+                    Content="  采  集  " />
67
+            <Button Name="btnSave"
68
+                    Grid.Row="3"
69
+                    Grid.Column="4"
70
+                    HorizontalAlignment="Center"
71
+                    Click="btnSave_Click"
72
+                    Content="  完  成  " />
73
+            <Button Name="btnClose"
74
+                    Grid.Row="3"
75
+                    Grid.Column="6"
76
+                    HorizontalAlignment="Center"
77
+                    Click="btnClose_Click"
78
+                    Content="  取  消  " />
79
+        </Grid>
80
+    </StackPanel>
81
+</dhcc:TradePage>

+ 192
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CameraViewer.xaml.cs 查看文件

@@ -0,0 +1,192 @@
1
+/*****************************************************************************************
2
+系统名     综合业务系统2.0
3
+程序名     交易2301的源代码
4
+类名       T2301      
5
+概要   	   客户信息维护
6
+作成者     XXX
7
+作成日     
8
+履历       No.        日期          Ver.No       修改人          描述
9
+*****************************************************************************************/
10
+using System;
11
+using System.Collections.Generic;
12
+using System.ComponentModel;
13
+using System.IO;
14
+using System.Windows;
15
+using System.Windows.Controls;
16
+using System.Windows.Media;
17
+using AxDOCCAMERAOCXLib;
18
+using Platform.Library;
19
+using Platform.Presentation.PageFunctions;
20
+using TellerSystem.Library.Ext.Function;
21
+using Application = System.Windows.Application;
22
+using TellerSystem.Library.Ext.TradeExtension;
23
+
24
+namespace TellerSystem.Controls.Ext.Controls
25
+{
26
+    /// <summary>
27
+    /// CameraViewer.xaml 的交互逻辑
28
+    /// </summary>
29
+    [DesignTimeVisible(false)]
30
+    public partial class CameraViewer:TradePage
31
+    {
32
+        private bool _cutBorder = false;
33
+        public CameraViewer(bool cutBorderFlag = false)
34
+        {
35
+            InitializeComponent();
36
+            _cutBorder = cutBorderFlag;
37
+        }
38
+
39
+        //摄像头
40
+        private AxDoccameraOcx myCamera = new AxDoccameraOcx();
41
+        //图像数据
42
+        private byte[] imageData = null;
43
+
44
+        #region  WPF调用OCX
45
+
46
+        /// <summary>
47
+        /// OCX初始化
48
+        /// </summary>
49
+        private void InitOcx()
50
+        {
51
+            myCamera.Width = 533;
52
+            myCamera.Height = 400;
53
+            Host.Child = myCamera;
54
+            myCamera.EndInit();
55
+        }
56
+
57
+        #endregion
58
+
59
+        #region 操作事件
60
+
61
+
62
+        /// <summary>
63
+        /// 打开摄像头
64
+        /// </summary>
65
+        /// <param name="sender"></param>
66
+        /// <param name="e"></param>
67
+        private void btnOpen_Click(object sender, RoutedEventArgs e)
68
+        {
69
+            //清空上一次采集到的图像
70
+            imageData = null;
71
+
72
+            //保存图片
73
+            if (myCamera.bSaveBMP(AppDomain.CurrentDomain.BaseDirectory, "TBMPimage"))
74
+            {
75
+                //this.ShowMessageBox("成功采集图像!");
76
+                FileStream aFileStream = new FileStream(AppDomain.CurrentDomain.BaseDirectory + "TBMPimage.BMP", FileMode.Open);
77
+                imageData = new byte[aFileStream.Length];
78
+                aFileStream.Read(imageData, 0, imageData.Length);
79
+                aFileStream.Close();
80
+            }
81
+            else
82
+            {
83
+                this.ShowMessageBox("采集图像失败!");
84
+            }
85
+
86
+            if (_cutBorder)
87
+            {
88
+                imageData = ImageCutHelper.CutIDCARDBorder(imageData);
89
+            }
90
+            if (imageData != null)
91
+            {
92
+                var imageSourceConverter = new ImageSourceConverter();
93
+                smallImage.Source = imageSourceConverter.ConvertFrom(new MemoryStream(imageData)) as ImageSource;
94
+                smallImage.ToolTip = new System.Windows.Controls.ToolTip()
95
+                                         {
96
+                                             MaxWidth = 533,
97
+                                             MinWidth = 400,
98
+                                             Content = new Image { Source = smallImage.Source, Stretch = Stretch.Uniform }
99
+                                         };
100
+            }
101
+        }
102
+
103
+        /// <summary>
104
+        /// 保存
105
+        /// </summary>
106
+        /// <param name="sender"></param>
107
+        /// <param name="e"></param>
108
+        private void btnSave_Click(object sender, RoutedEventArgs e)
109
+        {
110
+            //关闭
111
+            if (myCamera != null)
112
+            {
113
+                myCamera.bStopPlay();
114
+            }
115
+
116
+            if (imageData == null)
117
+            {
118
+                this.ShowMessageBox("没有采集到数据,请重新拍照!");
119
+                return;
120
+            }
121
+            else
122
+            {
123
+                Dictionary<string, object> dic = new Dictionary<string, object>();
124
+                dic.Add("ImageData", imageData);
125
+                this.SetViewStateData(dic);
126
+                this.OwnerContainer.ClosePage();
127
+            }
128
+        }
129
+
130
+        /// <summary>
131
+        /// 取消操作
132
+        /// </summary>
133
+        /// <param name="sender"></param>
134
+        /// <param name="e"></param>
135
+        private void btnClose_Click(object sender, RoutedEventArgs e)
136
+        {
137
+            //关闭
138
+            if (myCamera != null)
139
+            {
140
+                myCamera.bStopPlay();
141
+            }
142
+
143
+            this.Close();
144
+        }
145
+
146
+        /// <summary>
147
+        /// 浏览选择文件
148
+        /// </summary>
149
+        /// <param name="sender"></param>
150
+        /// <param name="e"></param>
151
+        private void btnBrowse_Click(object sender, RoutedEventArgs e)
152
+        {
153
+            var dialog = new Microsoft.Win32.OpenFileDialog();
154
+            dialog.ShowDialog(Application.Current.MainWindow);
155
+            if (string.IsNullOrEmpty(dialog.FileName)) return;
156
+            imageData = File.ReadAllBytes(dialog.FileName);
157
+        }
158
+
159
+        #endregion
160
+
161
+        /// <summary>
162
+        /// 初始并打开摄像头
163
+        /// </summary>
164
+        /// <param name="sender"></param>
165
+        /// <param name="e"></param>
166
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
167
+        {
168
+            InitOcx();
169
+
170
+            myCamera.vSetDelHBFlag(true);
171
+            //打开摄像头
172
+            if (!myCamera.bStartPlay())
173
+            {
174
+                //TradeLogger.Error("打开摄像头失败!");
175
+                this.Close();
176
+            }
177
+        }
178
+
179
+        /// <summary>
180
+        /// 关闭摄像头
181
+        /// </summary>
182
+        public void CloseCamera()
183
+        {
184
+            //关闭
185
+            if (myCamera != null)
186
+            {
187
+                myCamera.bStopPlay();
188
+            }
189
+        }
190
+
191
+    }
192
+}

+ 22
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CaptureViewer.xaml 查看文件

@@ -0,0 +1,22 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Controls.Ext.Controls.CaptureViewer"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+                d:DesignHeight="1000"
8
+                d:DesignWidth="700"
9
+                dhcc:FocusManager.EnableFocusControl="True"
10
+                mc:Ignorable="d" Name="this">
11
+	<dhcc:TradePage.Resources>
12
+		<DataTemplate x:Key="DataTemplate1">
13
+			<Grid d:DesignWidth="420" d:DesignHeight="79.701" Height="231.94" Width="321.493">
14
+				<Image Source="{Binding Bytes}"/>	
15
+			</Grid>
16
+		</DataTemplate>
17
+	</dhcc:TradePage.Resources>
18
+    <Grid>
19
+        <ListBox Height="297" Margin="12,12,12,0" Name="listBox1" ItemsSource="{Binding ImageCollection, ElementName=this}" VerticalAlignment="Top" ItemTemplate="{DynamicResource DataTemplate1}" />
20
+        <Button Content="浏览图片附件" Height="23" Margin="0,315,12,0" VerticalAlignment="Top" Width="97" Click="Button_Click" />
21
+    </Grid>
22
+</dhcc:TradePage>

+ 293
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CaptureViewer.xaml.cs 查看文件

@@ -0,0 +1,293 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using System.Collections.Specialized;
15
+using Platform.ServiceProxy.ServiceFunction.Entitys;
16
+using System.Collections.ObjectModel;
17
+using System.Windows.Forms;
18
+using System.IO;
19
+
20
+namespace TellerSystem.Controls.Ext.Controls
21
+{
22
+    public partial class CaptureViewer
23
+    {
24
+        private ObservableCollection<attachImage> _ImageCollection = null;
25
+
26
+        public CaptureViewer()
27
+        {
28
+            
29
+        }
30
+
31
+        private void Button_Click(object sender, RoutedEventArgs e)
32
+        {
33
+            OpenFileDialog openFileDialog = new OpenFileDialog();
34
+            //openFileDialog.InitialDirectory = "";
35
+            openFileDialog.Filter = "图片文件|*.jpg";
36
+            openFileDialog.RestoreDirectory = true;
37
+            openFileDialog.FilterIndex = 1;
38
+            if (openFileDialog.ShowDialog() == DialogResult.OK)
39
+            {
40
+                string[] files = openFileDialog.FileNames;
41
+
42
+                for (int i = 0; i < files.Length; i++)
43
+                {
44
+                    attachImage img = new attachImage();
45
+                    FileStream stream = new FileInfo(files[i]).OpenRead();
46
+                    img.Bytes = new Byte[stream.Length];
47
+                    stream.Read(img.Bytes, 0, Convert.ToInt32(stream.Length));
48
+
49
+                    this._ImageCollection.Add(img);
50
+                }
51
+            }
52
+        }
53
+
54
+        internal ObservableCollection<attachImage> ImageCollection
55
+        {
56
+            get
57
+            {
58
+                if (this._ImageCollection == null)
59
+                    this._ImageCollection = new ObservableCollection<attachImage>();
60
+
61
+                return this._ImageCollection;
62
+            }
63
+        }
64
+
65
+        internal class attachImage : DependencyObject
66
+        {
67
+            public byte[] Bytes
68
+            {
69
+                get { return (byte[])GetValue(BytesProperty); }
70
+                set { SetValue(BytesProperty, value); }
71
+            }
72
+
73
+            // Using a DependencyProperty as the backing store for Bytes.  This enables animation, styling, binding, etc...
74
+            public static readonly DependencyProperty BytesProperty =
75
+                DependencyProperty.Register("Bytes", typeof(byte[]), typeof(attachImage), new UIPropertyMetadata(new byte[0]));
76
+        }
77
+    }
78
+}
79
+
80
+////using System;
81
+////using System.Collections.Generic;
82
+////using System.Linq;
83
+////using System.Text;
84
+////using System.Windows;
85
+////using System.Windows.Controls;
86
+////using System.Windows.Data;
87
+////using System.Windows.Documents;
88
+////using System.Windows.Input;
89
+////using System.Windows.Media;
90
+////using System.Windows.Media.Imaging;
91
+////using System.Windows.Navigation;
92
+////using System.Windows.Shapes;
93
+////using System.Collections.Specialized;
94
+////using Platform.ServiceProxy.ServiceFunction.Entitys;
95
+
96
+////namespace TellerSystem.Controls.Ext.Controls
97
+////{
98
+////    /// <summary>
99
+////    /// CaptureViewer.xaml 的交互逻辑
100
+////    /// </summary>
101
+////    public partial class CaptureViewer
102
+////    {
103
+////        #region 交易内部变量
104
+////        public Dictionary<BitmapSource, Dictionary<string, object>> _imagesDict;
105
+
106
+////        /// <summary>
107
+////        /// 捕获的图像数据
108
+////        /// </summary>
109
+////        public List<string> CaptureImageList
110
+////        {
111
+////            get;
112
+////            set;
113
+////        }
114
+
115
+////        private AttchedFiles[] _imageList;
116
+////        public AttchedFiles[] ImageList
117
+////        {
118
+////            get { return _imageList; }
119
+////            set
120
+////            {
121
+////                _imageList = value;
122
+////                this.NotifyPropertyChanged("ImageList");
123
+////            }
124
+////        }
125
+
126
+////        #region 交易变量定义
127
+////        /* 定义变量 */
128
+
129
+////        #endregion
130
+////        #endregion
131
+
132
+////        #region 逻辑代码
133
+////        public CaptureViewer()
134
+////        {
135
+////            CaptureImageList = new List<string>();
136
+////            InitializeComponent();
137
+////            imageCapture.SelectedImages.Clear();
138
+////            imageCapture.SelectedImages.CollectionChanged += new NotifyCollectionChangedEventHandler(SelectedImages_CollectionChanged);
139
+////            imageCapture.ImageClick += new RoutedEventHandler(ImageClick);
140
+////        }
141
+
142
+////        /// <summary>
143
+////        /// 缩略图点击事件
144
+////        /// </summary>
145
+////        /// <param name="sender"></param>
146
+////        /// <param name="e"></param>
147
+////        private void ImageClick(object sender, RoutedEventArgs e)
148
+////        {
149
+////            Comments.Text = string.Empty;
150
+
151
+////            var selectedBi = imageCapture.SelectedBitmapSource;
152
+////            if (_imagesDict.ContainsKey(selectedBi))
153
+////            {
154
+////                object comments;
155
+////                if (_imagesDict[selectedBi].TryGetValue("Comments", out comments))
156
+////                {
157
+////                    Comments.Text = (string)comments;
158
+////                }
159
+////                return;
160
+////            }
161
+
162
+////        }
163
+////        /// <summary>
164
+////        /// 图像集合改变事件
165
+////        /// </summary>
166
+////        /// <param name="sender"></param>
167
+////        /// <param name="e"></param>
168
+////        void SelectedImages_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
169
+////        {
170
+////            Comments.Text = string.Empty;
171
+////            if (e.Action == NotifyCollectionChangedAction.Add)
172
+////            {
173
+////                _imagesDict.Add((BitmapSource)e.NewItems[0], new Dictionary<string, object>() { { "Comments", Comments.Text } });
174
+////            }
175
+////            else if (e.Action == NotifyCollectionChangedAction.Remove)
176
+////            {
177
+////                if (_imagesDict.ContainsKey((BitmapSource)e.OldItems[0]))
178
+////                {
179
+////                    _imagesDict.Remove((BitmapSource)e.OldItems[0]);
180
+////                }
181
+////            }
182
+////        }
183
+
184
+////        /// <summary>
185
+////        /// 图片信息保存按钮
186
+////        /// </summary>
187
+////        /// <param name="sender"></param>
188
+////        /// <param name="e"></param>
189
+////        private void SaveInfoButton_Click(object sender, RoutedEventArgs e)
190
+////        {
191
+////            var selectedBi = imageCapture.SelectedBitmapSource;
192
+////            //更新或添加
193
+////            if (selectedBi != null)
194
+////            {
195
+////                if (_imagesDict.ContainsKey(selectedBi))
196
+////                {
197
+////                    object comments;
198
+////                    if (_imagesDict[selectedBi].TryGetValue("Comments", out comments))
199
+////                    {
200
+////                        if (Comments.Text != (string)comments)
201
+////                        {
202
+////                            _imagesDict[selectedBi]["Comments"] = Comments.Text;
203
+////                        }
204
+////                    }
205
+////                    else
206
+////                    {
207
+////                        _imagesDict[selectedBi].Add("Comments", Comments.Text);
208
+////                    }
209
+////                }
210
+////                else
211
+////                {
212
+////                    _imagesDict.Add(selectedBi, new Dictionary<string, object>() { { "Comments", Comments.Text } });
213
+////                }
214
+////            }
215
+
216
+////        }
217
+
218
+////        /// <summary>
219
+////        /// 初始化逻辑
220
+////        /// </summary>
221
+////        protected override void OnTradePageLoaded()
222
+////        {
223
+////            base.OnTradePageLoaded();
224
+
225
+////            //初始化页面
226
+////            InitPage();
227
+
228
+////        }
229
+
230
+////        /// <summary>
231
+////        /// 初始化页面元素
232
+////        /// </summary>
233
+////        private void InitPage()
234
+////        {
235
+////            _imagesDict = new Dictionary<BitmapSource, Dictionary<string, object>>();
236
+////        }
237
+
238
+
239
+////        #endregion
240
+
241
+////        private void SubmitButton_Click(object sender, RoutedEventArgs e)
242
+////        {
243
+
244
+////            TransDictToImageList(_imagesDict);
245
+////            var ids = PutAttachedFiles(ImageList);
246
+
247
+////            //this.OwnerContainer.CloseTradePage(this, "ImageList");
248
+////            CaptureImageList.AddRange(ids);
249
+////            imageCapture.DisposeImageCap();
250
+////            this.Close();
251
+////        }
252
+
253
+////        private void CancelButton_Click(object sender, RoutedEventArgs e)
254
+////        {
255
+////            this.Close();
256
+
257
+////        }
258
+
259
+////        private void CameraButton_Click(object sender, RoutedEventArgs e)
260
+////        {
261
+////            imageCapture.DisposeImageCap();
262
+////        }
263
+
264
+////        private void TransDictToImageList(Dictionary<BitmapSource, Dictionary<string, object>> imagesDict)
265
+////        {
266
+////            ImageList = new AttchedFiles[imagesDict.Count];
267
+////            int i = 0;
268
+////            int j = 0;
269
+////            foreach (var image in imagesDict)
270
+////            {
271
+////                var propsKv = new MyKV[image.Value.Count];
272
+////                foreach (var prop in image.Value)
273
+////                {
274
+////                    propsKv[j] = new MyKV() { kVal = prop.Key, vVal = prop.Value };
275
+////                    if (j == image.Value.Count - 1) break;
276
+////                    j++;
277
+////                }
278
+////                var img = new AttchedFiles()
279
+////                              {
280
+////                                  filedata = TradePageExtension.BitmapSourceToByte(image.Key),
281
+////                                  fileinfo = propsKv
282
+////                              };Platform.Presentation.PageFunctions.TradePage
283
+////                ImageList[i] = img;
284
+////                i++;
285
+////            }
286
+////        }
287
+
288
+////        private void TradePage_Closed(object sender, Client.Presentation.PageClosedEventArgs e)
289
+////        {
290
+////            imageCapture.DisposeImageCap();
291
+////        }
292
+////    }
293
+////}

+ 152
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckMoney.xaml 查看文件

@@ -0,0 +1,152 @@
1
+<local:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.CheckMoney"
2
+                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                      xmlns:con="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
5
+                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                      xmlns:dhcc="http://www.dhcc.com.cn"
7
+                      xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
8
+                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
+                      xmlns:s="clr-namespace:TellerSystem.Controls.Ext.Controls"
10
+                      d:DesignHeight="255"
11
+                      d:DesignWidth="792"
12
+                      dhcc:FocusManager.EnableFocusControl="True"
13
+                      mc:Ignorable="d">
14
+    <con:TradePanel x:Name="tradepanel"
15
+                    Width="790"
16
+                    Height="246"
17
+                    Header="金额校验">
18
+        <TextBlock Name="current" Text="录入金额:" />
19
+        <StackPanel con:TradePanel.ColumnSpan="3" Orientation="Horizontal">
20
+            <dhcc:CurrencyEditor Name="currentmoney"
21
+                                 Width="150"
22
+                                 IsEnabled="False" />
23
+            <TextBlock Text="元" />
24
+        </StackPanel>
25
+
26
+        <TextBlock Name="t100" Text="100元:" />
27
+        <StackPanel Orientation="Horizontal">
28
+            <dhcc:CurrencyEditor Name="cur_100"
29
+                                 Width="150"
30
+                                 IsEnabled="False" />
31
+            <TextBox Name="num100"
32
+                     Width="48"
33
+                     dhcc:FocusManager.LostFocus="num100_LostFocus"
34
+                     TextChanged="num100_TextChanged" />
35
+            <TextBlock Text="张" />
36
+        </StackPanel>
37
+
38
+        <TextBlock Name="t50" Text="50元:" />
39
+        <StackPanel Orientation="Horizontal">
40
+            <dhcc:CurrencyEditor Name="cur_50"
41
+                                 Width="150"
42
+                                 IsEnabled="False" />
43
+            <TextBox Name="num50"
44
+                     Width="48"
45
+                     dhcc:FocusManager.LostFocus="num50_LostFocus"
46
+                     TextChanged="num50_TextChanged" />
47
+            <TextBlock Text="张" />
48
+        </StackPanel>
49
+        <TextBlock Name="t20" Text="20元:" />
50
+        <StackPanel Orientation="Horizontal">
51
+            <dhcc:CurrencyEditor Name="cur_20"
52
+                                 Width="150"
53
+                                 IsEnabled="False" />
54
+            <TextBox Name="num20"
55
+                     Width="48"
56
+                     dhcc:FocusManager.LostFocus="num20_LostFocus"
57
+                     TextChanged="num20_TextChanged" />
58
+            <TextBlock Text="张" />
59
+        </StackPanel>
60
+
61
+        <TextBlock Name="t10" Text="10元:" />
62
+        <StackPanel Orientation="Horizontal">
63
+            <dhcc:CurrencyEditor Name="cur_10"
64
+                                 Width="150"
65
+                                 IsEnabled="False" />
66
+            <TextBox Name="num10"
67
+                     Width="48"
68
+                     dhcc:FocusManager.LostFocus="num10_LostFocus"
69
+                     TextChanged="num10_TextChanged" />
70
+            <TextBlock Text="张" />
71
+        </StackPanel>
72
+
73
+        <TextBlock Name="t5" Text="5元:" />
74
+        <StackPanel Orientation="Horizontal">
75
+            <dhcc:CurrencyEditor Name="cur_5"
76
+                                 Width="150"
77
+                                 IsEnabled="False" />
78
+            <TextBox Name="num5"
79
+                     Width="48"
80
+                     dhcc:FocusManager.LostFocus="num5_LostFocus"
81
+                     TextChanged="num5_TextChanged" />
82
+            <TextBlock Text="张" />
83
+        </StackPanel>
84
+
85
+        <TextBlock Name="t1" Text="1元:" />
86
+        <StackPanel Orientation="Horizontal">
87
+            <dhcc:CurrencyEditor Name="cur_1"
88
+                                 Width="150"
89
+                                 IsEnabled="False" />
90
+            <TextBox Name="num1"
91
+                     Width="48"
92
+                     dhcc:FocusManager.LostFocus="num1_LostFocus"
93
+                     TextChanged="num1_TextChanged" />
94
+            <TextBlock Text="张" />
95
+        </StackPanel>
96
+
97
+
98
+        <TextBlock Name="t1j" Text="1角:" />
99
+        <StackPanel Orientation="Horizontal">
100
+            <dhcc:CurrencyEditor Name="cur_1j"
101
+                                 Width="150"
102
+                                 IsEnabled="False" />
103
+            <TextBox Name="num1j"
104
+                     Width="48"
105
+                     dhcc:FocusManager.LostFocus="num1j_LostFocus"
106
+                     TextChanged="num1j_TextChanged" />
107
+            <TextBlock Text="张" />
108
+        </StackPanel>
109
+
110
+        <TextBlock Name="t1f" Text="1分:" />
111
+        <StackPanel Orientation="Horizontal">
112
+            <dhcc:CurrencyEditor Name="cur_1f"
113
+                                 Width="150"
114
+                                 IsEnabled="False" />
115
+            <TextBox Name="num1f"
116
+                     Width="48"
117
+                     dhcc:FocusManager.LostFocus="num1f_LostFocus"
118
+                     TextChanged="num1f_TextChanged" />
119
+            <TextBlock Text="张" />
120
+        </StackPanel>
121
+
122
+
123
+        <TextBlock Name="result" Text="统计金额:" />
124
+        <StackPanel Orientation="Horizontal">
125
+            <dhcc:CurrencyEditor Name="cur_result"
126
+                                 Width="150"
127
+                                 IsEnabled="False" />
128
+            <TextBlock Text="元" />
129
+        </StackPanel>
130
+        <TextBlock Name="ChaAmt" Text="差额:" />
131
+        <StackPanel Orientation="Horizontal">
132
+            <TextBox Name="ChaAmtMoney"
133
+                     Width="150"
134
+                     IsEnabled="False" />
135
+            <TextBlock Text="元" />
136
+        </StackPanel>
137
+        <StackPanel con:TradePanel.ColumnSpan="4" Orientation="Horizontal">
138
+            <Button Name="submit"
139
+                    Width="49"
140
+                    Margin="0 0 40 0"
141
+                    Click="submit_Click"
142
+                    Content="确认" />
143
+
144
+            <Button Name="cancel"
145
+                    Width="45"
146
+                    Margin="0 0 40 0"
147
+                    Click="cancel_Click"
148
+                    Content="取消" />
149
+
150
+        </StackPanel>
151
+    </con:TradePanel>
152
+</local:BlankTradePage>

+ 358
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckMoney.xaml.cs 查看文件

@@ -0,0 +1,358 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using Platform.Controls.ControlsHelper;
15
+using Platform.Library;
16
+using TellerSystem.Library.Ext.Function;
17
+using System.Text.RegularExpressions;
18
+
19
+namespace TellerSystem.Controls.Ext.Controls
20
+{
21
+    /// <summary>
22
+    /// CheckMoney.xaml 的交互逻辑
23
+    /// </summary>
24
+    public partial class CheckMoney
25
+    {
26
+        public CheckMoney(string money)
27
+        {
28
+            InitializeComponent();
29
+            currentmoney.Text = money;
30
+        }
31
+
32
+        public bool jieguo = false;
33
+        #region 逻辑代码
34
+        /// <summary>
35
+        /// 界面初始化数据
36
+        /// </summary>
37
+        /// <returns></returns>
38
+        public override bool InitPage()
39
+        {
40
+            /*********************************************
41
+             * 此处需要填充的代码包括:
42
+             * 1.界面初始数据
43
+             * ******************************************/
44
+
45
+            return true;
46
+        }
47
+
48
+        #endregion
49
+
50
+        #region 内部逻辑
51
+
52
+        public bool YanZheng(TextBox element)
53
+        {
54
+            Regex r = new Regex(@"^\s*$|^[0-9]*$");
55
+            if (!r.IsMatch(element.Text))
56
+            {
57
+                this.TradeAPIs.ShowInfoMessageBox("请输入0到9之间的数字!");
58
+                element.Text = "";
59
+                this.TradeAPIs.SetFocus(element);
60
+                return false;
61
+            }
62
+            return true;
63
+        }
64
+
65
+        private void num100_TextChanged(object sender, TextChangedEventArgs e)
66
+        {
67
+            if (YanZheng(num100))
68
+            {
69
+                if (string.IsNullOrWhiteSpace(num100.Text))
70
+                {
71
+                    num100.Text = "0";
72
+                }
73
+                cur_100.Text = (Convert.ToDouble(num100.Text) * 100).ToString();
74
+                total();
75
+                AmtNum();
76
+            }
77
+        }
78
+
79
+        private void num100_LostFocus(object sender, RoutedEventArgs e)
80
+        {
81
+            if (YanZheng(num100))
82
+            {
83
+                if (string.IsNullOrWhiteSpace(num100.Text))
84
+                {
85
+                    num100.Text = "0";
86
+                }
87
+                cur_100.Text = (Convert.ToDouble(num100.Text) * 100).ToString();
88
+                total();
89
+                AmtNum();
90
+            }
91
+        }
92
+
93
+        private void AmtNum()
94
+        {
95
+            decimal d = decimal.Parse(cur_result.Text) - decimal.Parse(currentmoney.Text);
96
+            if (d > 0)
97
+            {
98
+                ChaAmtMoney.Text = "+" + d.ToString();
99
+            }
100
+            else
101
+            {
102
+                ChaAmtMoney.Text = d.ToString();
103
+            }
104
+        }
105
+
106
+        private void total()
107
+        {
108
+            cur_result.Text = (Convert.ToDouble(cur_100.Text) + Convert.ToDouble(cur_50.Text) + Convert.ToDouble(cur_20.Text) + Convert.ToDouble(cur_10.Text) + Convert.ToDouble(cur_5.Text) + Convert.ToDouble(cur_1.Text) + Convert.ToDouble(cur_1j.Text) + Convert.ToDouble(cur_1f.Text)).ToString();
109
+            //当输入金额匹配上时直接跳转至确定按钮
110
+            Decimal chae = currentmoney.Text.ToDecimal() - cur_result.Text.ToDecimal();
111
+            if (chae == 0)
112
+            {
113
+                this.TradeAPIs.SetFocus(submit);
114
+            }
115
+        }
116
+
117
+        private void num50_TextChanged(object sender, TextChangedEventArgs e)
118
+        {
119
+            if (YanZheng(num50))
120
+            {
121
+                if (string.IsNullOrWhiteSpace(num50.Text))
122
+                {
123
+                    num50.Text = "0";
124
+                }
125
+                cur_50.Text = (Convert.ToDouble(num50.Text) * 50).ToString();
126
+                total();
127
+                AmtNum();
128
+            }
129
+        }
130
+
131
+        private void num50_LostFocus(object sender, RoutedEventArgs e)
132
+        {
133
+            if (YanZheng(num50))
134
+            {
135
+                if (string.IsNullOrWhiteSpace(num50.Text))
136
+                {
137
+                    num50.Text = "0";
138
+                }
139
+                cur_50.Text = (Convert.ToDouble(num50.Text) * 50).ToString();
140
+                total();
141
+                AmtNum();
142
+            }
143
+        }
144
+
145
+        private void num20_TextChanged(object sender, TextChangedEventArgs e)
146
+        {
147
+            if (YanZheng(num20))
148
+            {
149
+                if (string.IsNullOrWhiteSpace(num20.Text))
150
+                {
151
+                    num20.Text = "0";
152
+                }
153
+                cur_20.Text = (Convert.ToDouble(num20.Text) * 20).ToString();
154
+                total();
155
+                AmtNum();
156
+            }
157
+        }
158
+
159
+        private void num20_LostFocus(object sender, RoutedEventArgs e)
160
+        {
161
+            if (YanZheng(num20))
162
+            {
163
+                if (string.IsNullOrWhiteSpace(num20.Text))
164
+                {
165
+                    num20.Text = "0";
166
+                }
167
+                cur_20.Text = (Convert.ToDouble(num20.Text) * 20).ToString();
168
+                total();
169
+                AmtNum();
170
+            }
171
+        }
172
+
173
+        private void num10_TextChanged(object sender, TextChangedEventArgs e)
174
+        {
175
+            if (YanZheng(num10))
176
+            {
177
+                if (string.IsNullOrWhiteSpace(num10.Text))
178
+                {
179
+                    num10.Text = "0";
180
+                }
181
+                cur_10.Text = (Convert.ToDouble(num10.Text) * 10).ToString();
182
+                total();
183
+                AmtNum();
184
+            }
185
+        }
186
+
187
+        private void num10_LostFocus(object sender, RoutedEventArgs e)
188
+        {
189
+            if (YanZheng(num10))
190
+            {
191
+                if (string.IsNullOrWhiteSpace(num10.Text))
192
+                {
193
+                    num10.Text = "0";
194
+                }
195
+                cur_10.Text = (Convert.ToDouble(num10.Text) * 10).ToString();
196
+                total();
197
+                AmtNum();
198
+            }
199
+        }
200
+
201
+        private void num5_TextChanged(object sender, TextChangedEventArgs e)
202
+        {
203
+            if (YanZheng(num5))
204
+            {
205
+                if (string.IsNullOrWhiteSpace(num5.Text))
206
+                {
207
+                    num5.Text = "0";
208
+                }
209
+                cur_5.Text = (Convert.ToDouble(num5.Text) * 5).ToString();
210
+                total();
211
+                AmtNum();
212
+            }
213
+        }
214
+
215
+        private void num5_LostFocus(object sender, RoutedEventArgs e)
216
+        {
217
+            if (YanZheng(num5))
218
+            {
219
+                if (string.IsNullOrWhiteSpace(num5.Text))
220
+                {
221
+                    num5.Text = "0";
222
+                }
223
+                cur_5.Text = (Convert.ToDouble(num5.Text) * 5).ToString();
224
+                total();
225
+                AmtNum();
226
+            }
227
+        }
228
+
229
+        private void num1_TextChanged(object sender, TextChangedEventArgs e)
230
+        {
231
+            if (YanZheng(num1))
232
+            {
233
+                if (string.IsNullOrWhiteSpace(num1.Text))
234
+                {
235
+                    num1.Text = "0";
236
+                }
237
+                cur_1.Text = (Convert.ToDouble(num1.Text)).ToString();
238
+                total();
239
+                AmtNum();
240
+            }
241
+        }
242
+
243
+        private void num1_LostFocus(object sender, RoutedEventArgs e)
244
+        {
245
+            if (YanZheng(num1))
246
+            {
247
+                if (string.IsNullOrWhiteSpace(num1.Text))
248
+                {
249
+                    num1.Text = "0";
250
+                }
251
+                cur_1.Text = (Convert.ToDouble(num1.Text)).ToString();
252
+                total();
253
+                AmtNum();
254
+            }
255
+
256
+        }
257
+
258
+        private void submit_Click(object sender, RoutedEventArgs e)
259
+        {
260
+            if (currentmoney.Val != cur_result.Val)
261
+            {
262
+                decimal d = decimal.Parse(cur_result.Text) - decimal.Parse(currentmoney.Text);
263
+
264
+                if (d > 0)
265
+                {
266
+                    this.TradeAPIs.ShowInfoMessageBox("金额校验失败,统计金额比录入金额多出" + d.ToString() + "元");
267
+                }
268
+                else
269
+                {
270
+                    this.TradeAPIs.ShowInfoMessageBox("金额校验失败,统计金额比录入金额相差" + d.ToString().Replace('-', ' ').Trim() + "元");
271
+                }
272
+                cur_100.Text = "0";
273
+                cur_50.Text = "0";
274
+                cur_20.Text = "0";
275
+                cur_10.Text = "0";
276
+                cur_5.Text = "0";
277
+                cur_1.Text = "0";
278
+                //cur_1j.Text = "0";
279
+                //cur_1f.Text = "0";
280
+                cur_result.Text = "0";
281
+                ChaAmtMoney.Text = "";
282
+                this.TradeAPIs.SetFocus(num100);
283
+                return;
284
+            }
285
+            else
286
+            {
287
+                jieguo = true;
288
+                this.Close();
289
+            }
290
+        }
291
+
292
+
293
+
294
+        #endregion
295
+
296
+        private void cancel_Click(object sender, RoutedEventArgs e)
297
+        {
298
+            jieguo = false;
299
+            this.Close();
300
+        }
301
+
302
+        private void num1j_LostFocus(object sender, RoutedEventArgs e)
303
+        {
304
+            if (YanZheng(num1j))
305
+            {
306
+                if (string.IsNullOrWhiteSpace(num1j.Text))
307
+                {
308
+                    num1j.Text = "0";
309
+                }
310
+                cur_1j.Text = (Convert.ToDouble(num1j.Text) * 0.1).ToString();
311
+                total();
312
+                AmtNum();
313
+            }
314
+        }
315
+
316
+        private void num1f_LostFocus(object sender, RoutedEventArgs e)
317
+        {
318
+            if (YanZheng(num1f))
319
+            {
320
+                if (string.IsNullOrWhiteSpace(num1f.Text))
321
+                {
322
+                    num1f.Text = "0";
323
+                }
324
+                cur_1f.Text = (Convert.ToDouble(num1f.Text) * 0.01).ToString();
325
+                total();
326
+                AmtNum();
327
+            }
328
+        }
329
+
330
+        private void num1j_TextChanged(object sender, TextChangedEventArgs e)
331
+        {
332
+            if (YanZheng(num1j))
333
+            {
334
+                if (string.IsNullOrWhiteSpace(num1j.Text))
335
+                {
336
+                    num1j.Text = "0";
337
+                }
338
+                cur_1j.Text = (Convert.ToDouble(num1j.Text) * 0.1).ToString();
339
+                total();
340
+                AmtNum();
341
+            }
342
+        }
343
+
344
+        private void num1f_TextChanged(object sender, TextChangedEventArgs e)
345
+        {
346
+            if (YanZheng(num1f))
347
+            {
348
+                if (string.IsNullOrWhiteSpace(num1f.Text))
349
+                {
350
+                    num1f.Text = "0";
351
+                }
352
+                cur_1f.Text = (Convert.ToDouble(num1f.Text) * 0.01).ToString();
353
+                total();
354
+                AmtNum();
355
+            }
356
+        }
357
+    }
358
+}

+ 76
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification.xaml 查看文件

@@ -0,0 +1,76 @@
1
+<tp:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.CheckSealVerification"
2
+                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                   xmlns:dhcc="http://www.dhcc.com.cn"
6
+                   xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
7
+                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                   xmlns:tp="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
9
+                   dhcc:FocusManager.EnableFocusControl="True"
10
+                   FontFamily="Simsun"
11
+                   Loaded="TradePage_Loaded"
12
+                   mc:Ignorable="d">
13
+    <StackPanel VerticalAlignment="Top">
14
+        <Grid>
15
+            <local:TradePanel Header="验印信息">
16
+                <TextBlock Text="验印流水" />
17
+                <TextBox x:Name="tb_yyls"
18
+                         Width="180"
19
+                         dhcc:FocusManagerExt.AssertNotEmpty="True"
20
+                         dhcc:TextBoxHelper.IsShowLength="True"
21
+                         local:TradePanel.ColumnSpan="3" />
22
+
23
+            </local:TradePanel>
24
+
25
+        </Grid>
26
+        <StackPanel Margin="10"
27
+                    FlowDirection="RightToLeft"
28
+                    Orientation="Horizontal">
29
+            <Button x:Name="btnBack"
30
+                    Width="80"
31
+                    Height="25"
32
+                    Click="btnBack_Click"
33
+                    Content="返  回" />
34
+            <Button x:Name="btnCheck"
35
+                    Width="80"
36
+                    Height="25"
37
+                    Click="btnCheck_Click"
38
+                    Content="验  印" />
39
+        </StackPanel>
40
+
41
+        <local:TradePanel Header="验印结果" IsEnabled="False">
42
+            <TextBlock Text="验印结果" />
43
+            <ComboBox x:Name="cbb_Result"
44
+                      Width="400"
45
+                      local:TradePanel.ColumnSpan="3" />
46
+
47
+            <TextBlock Text="账    号" />
48
+            <TextBox x:Name="tb_ZH" Width="180" />
49
+            <TextBlock Text="金    额" />
50
+            <dhcc:CurrencyEditor x:Name="tb_JE" Width="180" />
51
+            <TextBlock Text="凭证类型" />
52
+            <TextBox x:Name="tb_PZTYPE" Width="180" />
53
+            <TextBlock Text="凭证号码" />
54
+            <TextBox x:Name="tb_PZNO" Width="180" />
55
+            <TextBlock Text="出票日期" />
56
+            <TextBox x:Name="tb_CPRQ" Width="180" />
57
+        </local:TradePanel>
58
+        <Grid>
59
+            <GroupBox Header="验印凭证图像">
60
+                <Image x:Name="imgPhoto"
61
+                       Width="516"
62
+                       Height="234" />
63
+            </GroupBox>
64
+        </Grid>
65
+        <StackPanel Margin="10"
66
+                    FlowDirection="RightToLeft"
67
+                    Orientation="Horizontal">
68
+            <Button x:Name="btnView"
69
+                    Width="80"
70
+                    Height="25"
71
+                    Click="btnView_Click"
72
+                    Content="查  看" />
73
+        </StackPanel>
74
+    </StackPanel>
75
+
76
+</tp:BlankTradePage>

+ 199
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification.xaml.cs 查看文件

@@ -0,0 +1,199 @@
1
+using System;
2
+using System.Windows;
3
+using System.Windows.Media;
4
+using System.Windows.Media.Imaging;
5
+using System.IO;
6
+using Platform.Controls.ControlsHelper;
7
+using Platform.Library;
8
+using TellerSystem.Communication;
9
+using TellerSystem.Library.Ext.Function;
10
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
11
+using System.Collections.Generic;
12
+using Platform.Common.RunningParameters;
13
+
14
+/******************************平台Dll*****************************/
15
+
16
+namespace TellerSystem.Controls.Ext.Controls
17
+{
18
+    /// <summary>
19
+    /// CheckSealVerification.xaml 的交互逻辑
20
+    /// 鑫万佳的验印对接
21
+    /// </summary>
22
+    public partial class CheckSealVerification
23
+    {
24
+        #region Ctor
25
+        public CheckSealVerification()
26
+        {
27
+            InitializeComponent();
28
+            Record = new YYCheckerResult();
29
+            Record.IsOnline = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("Is_CheckYY") == "true";
30
+        }
31
+        string FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
32
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
33
+        {
34
+            cbb_Result.SetItems(new Dictionary<string, string> { { "验印通过", "000" }, { "验印未过", "001" }, { "尚无结果", "999" }, { "验印系统Down机", "301" } });
35
+            tb_yyls.Text = LoginUserInfo.TradeDate;
36
+            this.SetFocus(tb_yyls);
37
+            tb_yyls.Select(tb_yyls.Text.Length, 0);
38
+        }
39
+        #endregion
40
+
41
+        #region Property
42
+
43
+        /// <summary>
44
+        /// 验印结果
45
+        /// </summary>
46
+        public YYCheckerResult Record { get; private set; }
47
+        #endregion
48
+
49
+       
50
+        /// <summary>
51
+        /// 解析图像数据
52
+        /// </summary>
53
+        /// <param name="imageStream"></param>
54
+        private ImageSource CreateImage(String imageStream)
55
+        {
56
+            ImageSource ret = null;
57
+            try
58
+            {
59
+                if (!string.IsNullOrEmpty(imageStream))
60
+                {
61
+                    //把BASE64转码字符串,转成byte数组
62
+                    byte[] arr = Convert.FromBase64String(imageStream);
63
+                    //定义流
64
+                    MemoryStream ms = new MemoryStream(arr);
65
+                    var bitImg = new BitmapImage();
66
+                    bitImg.BeginInit();
67
+                    //ms.Seek(0, SeekOrigin.Begin);
68
+                    bitImg.StreamSource = ms;
69
+                    bitImg.EndInit();
70
+                    ret = bitImg;
71
+                }
72
+            }
73
+            catch (Exception e)
74
+            {
75
+                this.ShowWarnMessageBox("加载图片数据出错!");
76
+            }
77
+            return ret;
78
+        }
79
+
80
+        #region Event
81
+
82
+        /// <summary>
83
+        /// 验印核查
84
+        /// </summary>
85
+        private void btnCheck_Click(object sender, RoutedEventArgs e)
86
+        {
87
+            Message message = new Message(Message.BitMap.Agn);
88
+            this.InitFd(message);
89
+            this.CommSend(message);
90
+            message.Fd16 = "2001";
91
+            message.Fd18 = "DZYY";
92
+            message.Fd37 = tb_yyls.Text;
93
+
94
+            this.TradeAPIs.CallAgn(message);
95
+            if (message.Fd12 != "0000")
96
+            {
97
+                this.TradeAPIs.ShowInfoMessageBox(message.Fd74);
98
+                this.TradeAPIs.SetFocus();
99
+                return;
100
+            }
101
+            cbb_Result.SetSelectedValue(message.Fd47.Trim());
102
+            Record.ZH = tb_ZH.Text = message.Fd38.Trim();
103
+            Record.PZNO = tb_PZNO.Text = message.Fd44.Trim();
104
+            Record.JE = tb_JE.Text = message.Fd39.Trim().ToDecimal().ToString();
105
+            Record.Type = tb_PZTYPE.Text = message.Fd82.Trim();
106
+            Record.CPRQ = tb_CPRQ.Text = message.Fd46.Trim();
107
+            Record.YYLS = tb_yyls.Text.Trim();
108
+            Record.IsComplated = cbb_Result.GetSelectedValue() == "000" ;
109
+            
110
+            string _result = cbb_Result.GetSelectedValue();
111
+            switch(_result)
112
+            {
113
+                case "000":
114
+                case "001":
115
+                    imgPhoto.Source = CreateImage(message.FileData);
116
+                    this.TradeAPIs.SetFocus(btnView);
117
+                    break;
118
+                case "999":
119
+                    this.TradeAPIs.ShowInfoMessageBox("查询尚无结果!");
120
+                    this.TradeAPIs.SetFocus();
121
+                    break;
122
+                case "301":
123
+                    this.TradeAPIs.ShowInfoMessageBox("验印系统Down机!");
124
+                    this.TradeAPIs.SetFocus();
125
+                    break;
126
+            }
127
+        }
128
+
129
+
130
+        private void btnBack_Click(object sender, RoutedEventArgs e)
131
+        {
132
+            this.Close();
133
+        }
134
+        #endregion
135
+
136
+        private void btnView_Click(object sender, RoutedEventArgs e)
137
+        {
138
+            view detail = new view();
139
+            detail.img.Source = imgPhoto.Source;
140
+            if (detail.img.Source != null)
141
+            {
142
+                this.ShowPage(detail, "详细凭证");
143
+            }
144
+            else 
145
+            {
146
+                this.TradeAPIs.ShowInfoMessageBox("暂无图像,无法查看!");
147
+                this.TradeAPIs.SetFocus();
148
+            }
149
+        }
150
+
151
+    }
152
+
153
+    /// <summary>
154
+    /// 核查记录
155
+    /// </summary>
156
+    public class YYCheckerResult
157
+    {
158
+        /// <summary>
159
+        /// 是否验印
160
+        /// </summary>
161
+        public bool IsOnline { get; internal set; }
162
+
163
+        /// <summary>
164
+        /// 是否完成验印 
165
+        /// </summary>
166
+        public bool IsComplated { get; internal set; }
167
+
168
+        /// <summary>
169
+        /// 账号
170
+        /// </summary>
171
+        public string ZH { get; internal set; }
172
+
173
+        /// <summary>
174
+        /// 金额
175
+        /// </summary>
176
+        public string JE { get; internal set; }
177
+
178
+        /// <summary>
179
+        /// 凭证种类
180
+        /// </summary>
181
+        public string Type { get; internal set; }
182
+
183
+        /// <summary>
184
+        /// 凭证号码
185
+        /// </summary>
186
+        public string PZNO { get; internal set; }
187
+
188
+        /// <summary>
189
+        /// 出票日期
190
+        /// </summary>
191
+        public string CPRQ { get; internal set; }
192
+
193
+        /// <summary>
194
+        /// 验印流水
195
+        /// </summary>
196
+        public string YYLS { get; internal set; }
197
+
198
+    }
199
+}

+ 85
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification_ZK.xaml 查看文件

@@ -0,0 +1,85 @@
1
+<tp:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.CheckSealVerification_ZK"
2
+                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                   xmlns:dhcc="http://www.dhcc.com.cn"
6
+                   xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
7
+                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                   xmlns:tp="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
9
+                   dhcc:FocusManager.EnableFocusControl="True"
10
+                   FontFamily="Simsun"
11
+                   Loaded="TradePage_Loaded"
12
+                   mc:Ignorable="d">
13
+    <StackPanel VerticalAlignment="Top">
14
+        <local:TradePanel Header="验印信息">
15
+            <TextBlock Text="账    号" />
16
+            <TextBox x:Name="tb_ZH"
17
+                     Width="180"
18
+                     IsEnabled="False" />
19
+            <TextBlock Text="金    额" />
20
+            <dhcc:CurrencyEditor x:Name="tb_JE"
21
+                                 Width="180"
22
+                                 IsEnabled="False" />
23
+            <TextBlock Text="凭证类型" />
24
+            <TextBox x:Name="tb_PZTYPE"
25
+                     Width="180"
26
+                     IsEnabled="False" />
27
+            <TextBlock Text="凭证号码" />
28
+            <TextBox x:Name="tb_PZNO"
29
+                     Width="180"
30
+                     IsEnabled="False" />
31
+            <TextBlock Text="出票日期" />
32
+            <TextBox x:Name="tb_CPRQ"
33
+                     Width="180"
34
+                     IsEnabled="False" />
35
+            <TextBlock Text="业务类型" />
36
+            <ComboBox x:Name="tb_YWLX"
37
+                      Width="180"
38
+                      dhcc:FocusManager.LostFocus="tb_YWLX_LostFocus" />
39
+            <TextBlock Text="业务校验规则" />
40
+            <ComboBox x:Name="tb_JYGZ" Width="180" />
41
+        </local:TradePanel>
42
+        <Grid>
43
+            <GroupBox Header="验印凭证图像">
44
+                <Image x:Name="imgPhoto"
45
+                       Width="516"
46
+                       Height="234" />
47
+            </GroupBox>
48
+        </Grid>
49
+        <StackPanel Margin="10"
50
+                    FlowDirection="RightToLeft"
51
+                    Orientation="Horizontal">
52
+            <Button x:Name="btnView"
53
+                    Width="80"
54
+                    Height="25"
55
+                    Click="btnView_Click"
56
+                    Content="查  看" />
57
+            <Button x:Name="bt_XZ"
58
+                    Width="90"
59
+                    Height="25"
60
+                    Click="bt_XZ_Click"
61
+                    Content="选择本地图片" />
62
+            <Button x:Name="TakePic"
63
+                    Width="80"
64
+                    Height="25"
65
+                    Click="TakePic_Click"
66
+                    Content="拍  照" />
67
+        </StackPanel>
68
+        <StackPanel Margin="10"
69
+                    FlowDirection="RightToLeft"
70
+                    Orientation="Horizontal">
71
+            <Button x:Name="btnBack"
72
+                    Width="80"
73
+                    Height="25"
74
+                    Click="btnBack_Click"
75
+                    Content="返  回"
76
+                    Visibility="Collapsed" />
77
+            <Button x:Name="btnCheck"
78
+                    Width="80"
79
+                    Height="25"
80
+                    Click="btnCheck_Click"
81
+                    Content="提  交" />
82
+        </StackPanel>
83
+    </StackPanel>
84
+
85
+</tp:BlankTradePage>

+ 566
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/CheckSealVerification_ZK.xaml.cs 查看文件

@@ -0,0 +1,566 @@
1
+using System;
2
+using System.Windows;
3
+using System.Windows.Media;
4
+using System.Windows.Media.Imaging;
5
+using System.IO;
6
+using Platform.Controls.ControlsHelper;
7
+using Platform.Library;
8
+using Platform.Common.BasicFunctions;
9
+using TellerSystem.Communication;
10
+using TellerSystem.Library.Ext.Function;
11
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
12
+using System.Collections.Generic;
13
+using Platform.Common.RunningParameters;
14
+using System.Diagnostics;
15
+using Microsoft.Win32;
16
+using Newtonsoft.Json;
17
+using System.Reflection;
18
+using TellerSystem.Contract.Function;
19
+using TellerSystem.Library.Ext.TradeExtension;
20
+using TellerSystem.PrintTemplate.Extension;
21
+
22
+namespace TellerSystem.Controls.Ext.Controls
23
+{
24
+    /// <summary>
25
+    /// CheckSealVerification_ZK.xaml 的交互逻辑
26
+    /// 中科金财的验印处理
27
+    /// </summary>
28
+    public partial class CheckSealVerification_ZK
29
+    {
30
+        public CheckSealVerification_ZK()
31
+        {
32
+            InitializeComponent();
33
+            Record = new YYCheckerResult();
34
+            Record.IsOnline = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("Is_CheckYY") == "true";
35
+        }
36
+        string flag = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
37
+        string devicesTagStr = null;
38
+        private string imageDir = AppDomain.CurrentDomain.BaseDirectory;
39
+        string outImgPath = string.Empty;
40
+        string saveImgPath = string.Empty;
41
+        public string _zh = string.Empty;
42
+        public string path = string.Empty;
43
+        /// <summary>
44
+        /// 授权柜员编号
45
+        /// </summary>
46
+        private string _sqgybh;
47
+        /// <summary>
48
+        /// 验印结果
49
+        /// </summary>
50
+        public YYCheckerResult Record { get; private set; }
51
+
52
+        private void TakePic_Click(object sender, RoutedEventArgs e)
53
+        {
54
+            var source = openCamPlaye("PZ");
55
+            if (source != null)
56
+            {
57
+                imgPhoto.Source = source;
58
+            }
59
+        }
60
+
61
+        private void btnView_Click(object sender, RoutedEventArgs e)
62
+        {
63
+            view detail = new view();
64
+            detail.img.Source = imgPhoto.Source;
65
+            if (detail.img.Source != null)
66
+            {
67
+                this.ShowPage(detail, "详细凭证");
68
+            }
69
+            else
70
+            {
71
+                this.TradeAPIs.ShowInfoMessageBox("暂无图像,无法查看!");
72
+                this.TradeAPIs.SetFocus();
73
+            }
74
+        }
75
+
76
+        private void btnCheck_Click(object sender, RoutedEventArgs e)
77
+        {
78
+            //检查图片是否为空
79
+            if (imgPhoto.Source == null)
80
+            {
81
+                this.TradeAPIs.ShowInfoMessageBox("选择验印影像信息,选择本地或拍摄");
82
+                return;
83
+            }
84
+            var BILLNO = tb_PZNO.Text == string.Empty ? "0" : tb_PZNO.Text;
85
+            var BILLTYPE = tb_PZTYPE.Text == string.Empty ? "其他" : tb_PZTYPE.Text;
86
+            var AMOUNT = tb_JE.Text == string.Empty ? "0" : (Convert.ToInt64(tb_JE.Text.ToDecimal() * 100).ToString());
87
+            var BILLDATE = tb_CPRQ.Text == string.Empty ? LoginUserInfo.TradeDate : tb_CPRQ.Text;
88
+
89
+            var dicResult = SealVerification(this.TradeInfo.TradeCode, LoginUserInfo.TellerNo + DateTime.Now.ToString("yyyyMMddHHmmsss"), "0", tb_YWLX.GetSelectedValue(), tb_JYGZ.GetSelectedValue(), tb_ZH.Text, BILLNO, BILLTYPE, AMOUNT, BILLDATE, saveImgPath, "200");
90
+
91
+            if (dicResult != null)
92
+            {
93
+                if (dicResult.BILLRESULT == "0")
94
+                {
95
+                    if (flag == "V5" && dicResult.CHECKMODE == "2")
96
+                    {
97
+                        if (AuthAction(new Message() { Fd122_J = "fd122j" }))
98
+                        {
99
+                            if (!string.IsNullOrEmpty(_sqgybh))
100
+                                Record.YYFlag = checkModeMaping(dicResult.CHECKMODE) + billResultMaping(dicResult.BILLRESULT) + " 授权" + _sqgybh + "\n" + "验印流水\n" + dicResult.CHECKID;
101
+                            else
102
+                                Record.YYFlag = checkModeMaping(dicResult.CHECKMODE) + billResultMaping(dicResult.BILLRESULT) + "\n验印流水\n" + dicResult.CHECKID;
103
+                           
104
+                        }
105
+                        else
106
+                            return;
107
+                    }
108
+                    else
109
+                        Record.YYFlag = checkModeMaping(dicResult.CHECKMODE) + billResultMaping(dicResult.BILLRESULT) + "\n验印流水\n" + dicResult.CHECKID;
110
+                    this.TradeAPIs.ShowInfoMessageBox("验印成功,请继续交易");                   
111
+                    Record.IsComplated = true;
112
+                    this.Close();
113
+                }
114
+                else if (dicResult.BILLRESULT == "2")
115
+                {
116
+                    this.TradeAPIs.ShowInfoMessageBox("验印未成功,原因:未验印,请检查!" + dicResult.RETINFO);
117
+                    Record.IsComplated = false;
118
+                    return;
119
+                }
120
+                else
121
+                {
122
+                    if (dicResult.BILLRESULT == "1" && dicResult.BILLRESULT != "0000")
123
+                    {
124
+                        this.TradeAPIs.ShowInfoMessageBox("验印失败:" + checkModeMaping(dicResult.CHECKMODE) +" "+ billResultMaping(dicResult.BILLRESULT) + dicResult.RETINFO + "请检查");
125
+                    
126
+                        Record.IsComplated = false;
127
+                        return;
128
+                    }
129
+                    else
130
+                    {
131
+                        this.TradeAPIs.ShowInfoMessageBox("验印失败,原因:校验未通过,请检查!");
132
+                        Record.IsComplated = false;
133
+                        return;
134
+                    }
135
+
136
+                }
137
+            }
138
+            else
139
+            {
140
+                this.TradeAPIs.ShowInfoMessageBox("返回结果格式不对,或安装目录没找到");
141
+                Record.IsComplated = false;
142
+                return;
143
+            }
144
+        }
145
+        /// <summary>
146
+        /// 授权方法
147
+        /// </summary>
148
+        /// <param name="msg"></param>
149
+        /// <returns></returns>
150
+        private bool AuthAction(Message msg)
151
+        {
152
+            // 组织授权检查要素
153
+            TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData[] page = new TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData[1];
154
+            page[0] = new TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData() { index = 1, datas = this.SaveTradePage((FrameworkElement)this.Content) };
155
+            AuthConditionElement element = new AuthConditionElement();
156
+
157
+            AuthManager c = new AuthManager();
158
+            c.AsksuperResultMessage += new AuthManager.AsksuperResultHandle(AsksuperResultMessage);
159
+            return c.DoAuth(this, element, msg, page, "0", "", "", "", "", "人脸比对", "");
160
+        }
161
+
162
+        private void AsksuperResultMessage(AsksuperResultType result, TradeBusData busData)
163
+        {
164
+            _sqgybh = "";
165
+            switch (result)
166
+            {
167
+                case AsksuperResultType.Success:
168
+                    this.ShowMessageBox("授权已经通过。");
169
+                    if (busData!=null&&busData.ContainsKey("AuthTeller")) 
170
+                    {
171
+                         _sqgybh = busData["AuthTeller"];
172
+                    }
173
+                    break;
174
+                case AsksuperResultType.Failed:
175
+                    this.ShowMessageBox("授权没有通过。");
176
+                    break;
177
+                case AsksuperResultType.Undo:
178
+                    this.ShowMessageBox("授权已撤销。");
179
+                    break;
180
+                default:
181
+                    break;
182
+            }
183
+        }
184
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
185
+        {
186
+            tb_ZH.Text = _zh;
187
+            Record.IsComplated = false;
188
+            tb_YWLX.SetItems(new Dictionary<string, string> { { "支付", "1" }, { "对账", "2" } });
189
+            //删除图像目录  保留当天的图像 by hulei 20210310
190
+
191
+            //因可能客户电脑客户端没有images文件夹,导致下面方法get目录时异常,先创建images文件夹;
192
+            var dirimages = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"images");
193
+            createFolder(dirimages);
194
+            var dirs = getDirectoryInfo(System.IO.Path.Combine(imageDir, @"images"));
195
+            foreach (var item in dirs)
196
+            {
197
+                if (item.Name.ToString() != LoginUserInfo.TradeDate)
198
+                {
199
+                    deleteFolder(System.IO.Path.Combine(imageDir, @"images", item.Name));
200
+                }
201
+            }
202
+        }
203
+
204
+        private void tb_YWLX_LostFocus(object sender, RoutedEventArgs e)
205
+        {
206
+            if (tb_YWLX.GetSelectedValue() == "1")
207
+            {
208
+                tb_JYGZ.SetItems(new Dictionary<string, string> { { "验预留印鉴", "1" }, { "验公章", "2" }, { "验所有章", "3" } });
209
+            }
210
+            else
211
+            {
212
+                tb_JYGZ.SetItems(new Dictionary<string, string> { { "验预留印鉴或公章", "4" } });
213
+            }
214
+        }
215
+
216
+        BitmapSource openCamPlaye(string device)
217
+        {
218
+            Process[] processes = Process.GetProcessesByName("CameraPlayer");
219
+            if (processes.Length > 0)
220
+            {
221
+                foreach (Process process in processes)
222
+                {
223
+                    if (!process.HasExited)
224
+                        process.Kill();
225
+                }
226
+            }
227
+            if (devicesTagStr == null)
228
+            {
229
+                if (ConfigManager.GetInstance().GetConfigValue("CameraEnabled", ConfigType.User).ToLower() == "true")
230
+                {
231
+                    string pz = String.Format("PZ|{0}|{1};", ConfigManager.GetInstance().GetConfigValue("PZVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("PZPid", ConfigType.User));
232
+                    string kh = String.Format("KH|{0}|{1};", ConfigManager.GetInstance().GetConfigValue("KHVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("KHPid", ConfigType.User));
233
+                    string gy = String.Format("GY|{0}|{1};", ConfigManager.GetInstance().GetConfigValue("GYVid", ConfigType.User), ConfigManager.GetInstance().GetConfigValue("GYPid", ConfigType.User));
234
+                    devicesTagStr = pz + kh + gy;
235
+                }
236
+                else
237
+                {
238
+                    devicesTagStr = "null";
239
+                }
240
+            }
241
+
242
+            string saveImgDir = string.Empty;
243
+            string fileName = string.Empty;
244
+
245
+            saveImgDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"images", LoginUserInfo.TradeDate);
246
+            createFolder(saveImgDir);
247
+            fileName = Guid.NewGuid().ToString("N") + ".png";
248
+            //固定路径
249
+            outImgPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "gdview\\tmp\\01.jpg");
250
+
251
+            Process printProcess = new Process();
252
+            printProcess.StartInfo.FileName = System.IO.Path.Combine(@"C:/Windows/twain_32/ggtwain/gdview.exe");
253
+            printProcess.StartInfo.Arguments = flag + " " + device + " " + devicesTagStr + " \"" + outImgPath + "\"";
254
+            printProcess.Start();
255
+            printProcess.WaitForExit();
256
+            printProcess.Close();
257
+          
258
+            saveImgPath = System.IO.Path.Combine(outImgPath);
259
+            if (File.Exists(saveImgPath))
260
+            {
261
+                BitmapImage bitmapImage = new BitmapImage();
262
+                bitmapImage.BeginInit();
263
+                bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
264
+                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
265
+                bitmapImage.UriSource = new Uri(saveImgPath);//szPath为图片的全路径
266
+                bitmapImage.EndInit();
267
+                bitmapImage.Freeze();
268
+                return bitmapImage;
269
+            }
270
+            else
271
+            {
272
+                return null;
273
+            }
274
+        }
275
+        DirectoryInfo createFolder(string filefullpath)
276
+        {
277
+            DirectoryInfo dir = null;
278
+            if (!File.Exists(filefullpath))
279
+            {
280
+                string[] pathes = filefullpath.Split('\\');
281
+                if (pathes.Length > 1)
282
+                {
283
+                    string path = pathes[0];
284
+                    for (int i = 1; i < pathes.Length; i++)
285
+                    {
286
+                        path += "\\" + pathes[i];
287
+                        if (!Directory.Exists(path))
288
+                        {
289
+                            dir = Directory.CreateDirectory(path);
290
+                        }
291
+                    }
292
+                }
293
+            }
294
+            return dir;
295
+        }
296
+        private DirectoryInfo[] getDirectoryInfo(string path)
297
+        {
298
+            DirectoryInfo Dir = new DirectoryInfo(path);
299
+            var dirs = Dir.GetDirectories();
300
+            return dirs;
301
+        }
302
+        void deleteFolder(string file)
303
+        {
304
+            //判断文件夹是否还存在
305
+            if (Directory.Exists(file))
306
+            {
307
+                //去除文件夹和子文件的只读属性
308
+                System.IO.DirectoryInfo fileInfo = new DirectoryInfo(file);
309
+                fileInfo.Attributes = FileAttributes.Normal & FileAttributes.Directory;
310
+                System.IO.File.SetAttributes(file, System.IO.FileAttributes.Normal);
311
+                foreach (string f in Directory.GetFileSystemEntries(file))
312
+                {
313
+                    if (File.Exists(f))
314
+                    {
315
+                        //如果有子文件删除文件
316
+                        File.Delete(f);
317
+                    }
318
+                    else
319
+                    {
320
+                        //循环递归删除子文件夹
321
+                        deleteFolder(f);
322
+                    }
323
+                }
324
+                //删除空文件夹
325
+                Directory.Delete(file);
326
+            }
327
+        }
328
+
329
+        private void btnBack_Click(object sender, RoutedEventArgs e)
330
+        {
331
+            this.Close();
332
+        }
333
+
334
+        private void bt_XZ_Click(object sender, RoutedEventArgs e)
335
+        {
336
+            OpenFileDialog openfiledialog = new OpenFileDialog
337
+            {
338
+                Filter = "图像文件|*.jpg;*.png;*.jpeg;*.bmp;*.gif|所有文件|*.*"
339
+            };
340
+
341
+            if ((bool)openfiledialog.ShowDialog())
342
+            {
343
+                saveImgPath = openfiledialog.FileName;
344
+                imgPhoto.Source = new BitmapImage(new Uri(openfiledialog.FileName));
345
+            }
346
+        }
347
+        /// <summary>
348
+        /// 验印模式
349
+        /// </summary>
350
+        /// <param name="result"></param>
351
+        /// <returns></returns>
352
+        private string checkModeMaping(string checkModeResult)
353
+        {
354
+            string checkMode = string.Empty;
355
+            switch (checkModeResult)
356
+            {
357
+                case "0":
358
+                    checkMode = "自动";
359
+                    break;
360
+                case "1":
361
+                    checkMode = "辅助";
362
+                    break;
363
+                case "2":
364
+                    checkMode = "人工";
365
+                    break;
366
+                default:
367
+                    break;
368
+            }
369
+
370
+
371
+            return checkMode;
372
+        }
373
+
374
+        /// <summary>
375
+        /// 整票结果映射
376
+        /// </summary>
377
+        /// <param name="result"></param>
378
+        /// <returns></returns>
379
+        private string billResultMaping(string result)
380
+        {
381
+            string billResult = string.Empty;
382
+            switch (result)
383
+            {
384
+                case "0":
385
+                    billResult = "通过";
386
+                    break;
387
+                case "1":
388
+                    billResult = "不通过";
389
+                    break;
390
+                case "2":
391
+                    billResult = "未验";
392
+                    break;
393
+                default:
394
+                    break;
395
+            }
396
+
397
+
398
+            return billResult;
399
+        }
400
+        #region 验印相关
401
+        class SealVerificationResult
402
+        {
403
+            /// <summary>
404
+            /// 整票结果 0:通过 1:不通过 2:未验
405
+            /// </summary>
406
+            public string BILLRESULT { get; set; }
407
+            /// <summary>
408
+            /// 验印模式 0:自动 1:辅助 2:人工
409
+            /// </summary>
410
+            public string CHECKMODE { get; set; }
411
+            /// <summary>
412
+            /// 返回代码 0000为成功,其他失败
413
+            /// </summary>
414
+            public string RETCODE { get; set; }
415
+            /// <summary>
416
+            /// 返回信息成功返回空,否则返回错误信息
417
+            /// </summary>
418
+            public string RETINFO { get; set; }
419
+            /// <summary>
420
+            /// 验印结果标识 标识验印记录的唯一流水号
421
+            /// </summary>
422
+            public string CHECKID { get; set; }
423
+        }
424
+
425
+        /// <summary>
426
+        /// 验印接口
427
+        /// </summary>
428
+        /// <param name="helper"></param>
429
+        /// <param name="textbox"></param>
430
+        /// <returns></returns>
431
+        private SealVerificationResult SealVerification(string nodeCode, string TASKID, string TASKTYPE, string XITLX, string CHECKTYPE, string ACCNO, string BILLNO, string BILLTYPE, string AMOUNT, string BILLDATE, string IMAGENAME, string DPI)
432
+        {
433
+            Type _OCXType = null;
434
+            object _ocxObject = null;
435
+            SealVerificationResult SealVerificationResult = null;
436
+            System.Windows.Forms.Control _OCXCtr = null;
437
+            //获取验印配置url 配置在配置文件中  建议 是url+QL+机构号
438
+            string url = ConfigManager.GetInstance().GetConfigValue("SEALAPPURL", ConfigType.Client);
439
+
440
+            //获取动态库配置路径
441
+
442
+            //组json
443
+            Dictionary<string, string> dic = new Dictionary<string, string>() { { "SEALAPPURL", url }, { "SYSCODE", "GMXT" }, { "NODECODE", nodeCode }, { "TASKID", "GMXT" }, { "TASKTYPE", "0" },
444
+            {"XITLX",XITLX},{"CHECKTYPE",CHECKTYPE},{"TELLNO",LoginUserInfo.TellerNo},{"TELLORGNO",LoginUserInfo.KinbrNo},{"ACCNO",ACCNO} ,{"BILLNO",BILLNO},{"BILLTYPE",BILLTYPE},{"AMOUNT",AMOUNT},{"BILLDATE",BILLDATE},{"IMAGENAME",IMAGENAME},{"DPI","200"}};
445
+            var strjson = JsonConvert.SerializeObject(dic);
446
+            //调用接口
447
+            if (_OCXCtr == null || _OCXCtr.IsDisposed)
448
+            {
449
+                //注意这里控件的安装目录不要安装到C:\Program Files (x86)下,否则需要管理员身份运行或者额外进行授权处理。
450
+                //验印控件安装的目录中的SealCheckCom.dll
451
+                Microsoft.Win32.RegistryKey regsvrCloudCmdSign = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey("CLSID\\{9D2CA12E-A504-4574-A9D4-0940B371C0A4}\\InprocServer32\\");
452
+                string ocxDllPath = string.Empty;//Path.Combine(@"D:\software\zhongke", "SealCheckCom.dll");
453
+                if (regsvrCloudCmdSign == null)
454
+                {
455
+                    //this.TradeAPIs.ShowInfoMessageBox("没有找到程序安装目录,请确认是否安装插件");
456
+                    //return null;
457
+                    ocxDllPath = Path.Combine(@"D:\Program Files\Sinodata\ISealCheckSetup", "SealCheckCom.dll");
458
+                }
459
+                else
460
+                {
461
+                    var sealpath = regsvrCloudCmdSign.GetValue("CodeBase", "0");
462
+                    if (sealpath != "0")
463
+                    {
464
+                        ocxDllPath = sealpath.ToString();
465
+                    }
466
+                    else
467
+                    {
468
+                        this.TradeAPIs.ShowInfoMessageBox("没有找到程序安装目录,请确认是否安装插件");
469
+                        return null;
470
+
471
+                    }
472
+                }
473
+
474
+                Assembly ass = Assembly.LoadFrom(ocxDllPath);
475
+                _OCXType = ass.GetType("Sinodata.SealCheckCom.AssitantCheckSeal");
476
+
477
+                _ocxObject = Activator.CreateInstance(_OCXType);
478
+                _OCXCtr = _ocxObject as System.Windows.Forms.Control;
479
+
480
+            }
481
+            try
482
+            {
483
+                //调用Check方法
484
+                Type[] params_type = new Type[1] { typeof(string) };
485
+                MethodInfo check = _OCXType.GetMethod("Check", params_type);
486
+                object[] parameters = new object[] { strjson };
487
+
488
+                object result = check.Invoke(_ocxObject, parameters);
489
+                if (result == null)
490
+                {
491
+
492
+                }
493
+                else
494
+                {
495
+
496
+                    // JsonConvert.DeserializeObject<Dictionary<string, string>>(result.ToString());
497
+                    //解析配置项
498
+                    SealVerificationResult = JsonConvert.DeserializeObject<SealVerificationResult>(result.ToString());// JsonHelper.ParseJson2List(json);
499
+
500
+                    return SealVerificationResult;
501
+                }
502
+                _OCXCtr.Dispose();
503
+                _OCXCtr = null;
504
+            }
505
+            catch (Exception ex)
506
+            {
507
+                string er = "验印异常:" + ex.Message + "," + ex.StackTrace;
508
+                MessageBox.Show(er);
509
+                if (ex.InnerException != null)
510
+                    er = ex.InnerException.Message + "," + ex.InnerException.StackTrace;
511
+                MessageBox.Show(er);
512
+            }
513
+            //处理结果
514
+            return SealVerificationResult;
515
+        }
516
+        #endregion
517
+
518
+
519
+        public class YYCheckerResult
520
+        {
521
+            /// <summary>
522
+            /// 是否验印
523
+            /// </summary>
524
+            public bool IsOnline { get; internal set; }
525
+
526
+            /// <summary>
527
+            /// 是否完成验印 
528
+            /// </summary>
529
+            public bool IsComplated { get; internal set; }
530
+
531
+            /// <summary>
532
+            /// 账号
533
+            /// </summary>
534
+            public string ZH { get; internal set; }
535
+
536
+            /// <summary>
537
+            /// 金额
538
+            /// </summary>
539
+            public string JE { get; internal set; }
540
+
541
+            /// <summary>
542
+            /// 凭证种类
543
+            /// </summary>
544
+            public string Type { get; internal set; }
545
+
546
+            /// <summary>
547
+            /// 凭证号码
548
+            /// </summary>
549
+            public string PZNO { get; internal set; }
550
+
551
+            /// <summary>
552
+            /// 出票日期
553
+            /// </summary>
554
+            public string CPRQ { get; internal set; }
555
+
556
+            /// <summary>
557
+            /// 验印流水
558
+            /// </summary>
559
+            public string YYLS { get; internal set; }
560
+            /// <summary>
561
+            /// 验印结果
562
+            /// </summary>
563
+            public string YYFlag { get; internal set; }
564
+        }
565
+    }
566
+}

+ 31
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DataBoxViewer.xaml 查看文件

@@ -0,0 +1,31 @@
1
+<local:ManagerTradePage x:Class="TellerSystem.Controls.Ext.Controls.DataBoxViewer"
2
+                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                        xmlns:dhcc="http://www.dhcc.com.cn"
6
+                        xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
7
+                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                        Width="700"
9
+                        Height="308"
10
+                        dhcc:FocusManager.EnableFocusControl="True"
11
+                        Loaded="TradePage_Loaded"
12
+                        mc:Ignorable="d">
13
+    <Grid Name="Grid1"
14
+          HorizontalAlignment="Center"
15
+          VerticalAlignment="Center">
16
+        <dhcc:DataBox Name="DataBox1"
17
+                      HorizontalAlignment="Center"
18
+                      VerticalAlignment="Center"
19
+                      dhcc:FocusManager.LostFocus="submit_Click"
20
+                      IsShowExportButton="True"
21
+                      IsShowPageBar="True"
22
+                      IsShowPrintButton="True"
23
+                      KeyDown="DataBox1_KeyDown" />
24
+        <Button Name="submit"
25
+                Grid.Column="1"
26
+                Height="25"
27
+                Margin="0,1111,0,0"
28
+                Click="submit_Click"
29
+                Content="确定" />
30
+    </Grid>
31
+</local:ManagerTradePage>

+ 122
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DataBoxViewer.xaml.cs 查看文件

@@ -0,0 +1,122 @@
1
+using System.Windows;
2
+using System.Windows.Input;
3
+using Platform.Library;
4
+using System.Data;
5
+using Platform.Presentation.Interfaces;
6
+using Platform.Presentation.PageFunctions;
7
+using TellerSystem.Library.Ext.Function;
8
+using TellerSystem.Library.Ext.TradeExtension;
9
+using Platform.Controls.ControlsHelper;
10
+using System.Windows.Controls;
11
+namespace TellerSystem.Controls.Ext.Controls
12
+{
13
+    /// <summary>
14
+    /// DataBoxViewer.xaml 的交互逻辑
15
+    /// </summary>
16
+    public partial class DataBoxViewer
17
+    {
18
+        private double _winWidth;
19
+        private double _winHeight;
20
+        private bool _multiRows = false;
21
+        public DataBoxViewer()
22
+        {
23
+            InitializeComponent();
24
+            _winHeight = this.Height;
25
+            _winWidth = this.Width;
26
+        }
27
+
28
+        public double WinWidth
29
+        {
30
+            get { return _winWidth; }
31
+            set { _winWidth = value; }
32
+        }
33
+
34
+        public double WinHeight
35
+        {
36
+            get { return _winHeight; }
37
+            set { _winHeight = value; }
38
+        }
39
+
40
+        public bool MultiRows
41
+        {
42
+            get { return _multiRows; }
43
+            set { _multiRows = value; }
44
+        }
45
+        public void LoadPageSize(double width, double height)
46
+        {
47
+            if (width > 0 && height > 0)
48
+            {
49
+                this.Width = width;
50
+                this.Height = height;
51
+                this.DataBox1.Width += width - WinWidth;
52
+                this.DataBox1.Height += height - WinHeight;
53
+                this.Grid1.Width += width - WinWidth;
54
+                this.Grid1.Height += height - WinHeight;
55
+            }
56
+        }
57
+
58
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
59
+        {
60
+            this.SetFocus(DataBox1.DataBoxHost);
61
+        }
62
+
63
+        public bool LoadData(string sequence, string[] headerList)
64
+        {
65
+            this.DataBox1.IsMultiSelected = _multiRows;
66
+            this.DataBox1.DataBinding(sequence, headerList);
67
+            return true;
68
+        }
69
+        public bool LoadData(DataTable table)
70
+        {
71
+            this.DataBox1.IsMultiSelected = _multiRows;
72
+            this.DataBox1.DataBinding(table);
73
+            return true;
74
+        }
75
+        /// <summary>
76
+        /// 
77
+        /// </summary>
78
+        /// <param name="sender"></param>
79
+        /// <param name="e"></param>
80
+        private void submit_Click(object sender, RoutedEventArgs e)
81
+        {
82
+            if (!MultiRows)
83
+            {
84
+                var selectedData = this.DataBox1.GetSelectSingleRow();
85
+                if (selectedData == null)
86
+                {
87
+                    this.ShowMessageBox("没有可选信息!", "警告");
88
+                    return;
89
+                }
90
+                this.Tag = selectedData;
91
+                
92
+            }
93
+            else
94
+            {
95
+                var selectedData = this.DataBox1.GetSelectMultiRows();
96
+                if (selectedData == null)
97
+                {
98
+                    this.ShowMessageBox("没有可选信息!", "警告");
99
+                    this.SetFocus(DataBox1.DataBoxHost);
100
+                    return;
101
+                }
102
+                this.Tag = selectedData;
103
+            }
104
+
105
+            this.Close();
106
+        }
107
+
108
+        private void DataBox1_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
109
+        {
110
+            if (e.Key == Key.Escape)
111
+            {
112
+                this.Tag = null;
113
+                this.Close();
114
+            }
115
+
116
+        }
117
+
118
+
119
+
120
+    }
121
+
122
+}

+ 20
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateInputControl.xaml 查看文件

@@ -0,0 +1,20 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.DateInputControl"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
5
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
6
+             xmlns:dhcc="http://www.dhcc.com.cn"
7
+             mc:Ignorable="d" 
8
+             dhcc:FocusManagerExt.IsFocusAdorner="True"
9
+             dhcc:FocusManager.IsInternalKeyboardControlling="True"
10
+             dhcc:FocusManagerExt.ValidationField="DateValue"        
11
+             d:DesignHeight="23" d:DesignWidth="100">
12
+    <dhcc:FocusManagerExt.FieldEmptyPolicies>
13
+        <dhcc:FieldPolicyCollection>
14
+            <dhcc:ShowTipPolicy />
15
+        </dhcc:FieldPolicyCollection>
16
+    </dhcc:FocusManagerExt.FieldEmptyPolicies>
17
+    <Border FocusManager.IsFocusScope="True">
18
+        <DatePicker Name="datePicker" />
19
+    </Border>
20
+</UserControl>

+ 126
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateInputControl.xaml.cs 查看文件

@@ -0,0 +1,126 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using System.Globalization;
15
+using Platform.Presentation.FocusManagers;
16
+
17
+namespace TellerSystem.Controls.Ext.Controls
18
+{
19
+    /// <summary>
20
+    /// DateTextBox.xaml 的交互逻辑
21
+    /// </summary>
22
+    public partial class DateInputControl : UserControl
23
+    {
24
+        private Platform.Presentation.FocusManagers.FocusManager focus;
25
+        public DateInputControl()
26
+        {
27
+            InitializeComponent();
28
+            this.datePicker.DateValidationError += new EventHandler<DatePickerDateValidationErrorEventArgs>(datePicker_DateValidationError);
29
+            this.Loaded += (sender, e) =>
30
+            {
31
+                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;
32
+                focus = Platform.Presentation.FocusManagers.FocusManager.GetManagerInstance((DependencyObject)this) as Platform.Presentation.FocusManagers.FocusManager;
33
+                if (focus == null) throw new ArgumentNullException("无法找到焦点控制模块!");
34
+            };
35
+            Platform.Presentation.FocusManagers.FocusManager.AddPreviewGotFocusHandler(this, PreviewGotFocus);
36
+            Platform.Presentation.FocusManagers.FocusManager.AddPreviewLostFocusHandler(this, PreviewLostFocus);
37
+            this.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(DateInputControl_PreviewKeyDown);
38
+        }
39
+
40
+
41
+        public DateTime? Date
42
+        {
43
+            get { return this.datePicker.SelectedDate; }
44
+            set { this.datePicker.SelectedDate = value; }
45
+        }
46
+
47
+        /// <summary>
48
+        /// 输入日期
49
+        /// </summary>
50
+        public string DateValue
51
+        {
52
+
53
+            get { return Date.HasValue ? Date.Value.ToString("yyyyMMdd") : string.Empty; }
54
+            set
55
+            {
56
+                int year, month, day;
57
+                DateTime date;
58
+                if (value.Length == 8
59
+                    && int.TryParse(value.Substring(0, 4), out year)
60
+                    && int.TryParse(value.Substring(4, 2), out month)
61
+                    && int.TryParse(value.Substring(6, 2), out day)
62
+                    && DateTime.TryParse(string.Format("{0}/{1}/{2}", year, month, day), out date))
63
+                    Date = date;
64
+                else
65
+                    Date = null;
66
+            }
67
+        }
68
+
69
+        void datePicker_DateValidationError(object sender, DatePickerDateValidationErrorEventArgs e)
70
+        {
71
+            var datePicker = sender as DatePicker;
72
+            if (datePicker != null)
73
+            {
74
+                var text = e.Text;
75
+                DateTime dateTime;
76
+                if (DateTime.TryParseExact(text, "yyyyMMdd", CultureInfo.CurrentUICulture, DateTimeStyles.None, out dateTime))
77
+                {
78
+                    datePicker.SelectedDate = dateTime;
79
+                    Date = dateTime;
80
+                }
81
+                else
82
+                {
83
+                    datePicker.SelectedDate = null;
84
+                    Date = null;
85
+                }
86
+            }
87
+        }
88
+
89
+        void DateInputControl_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
90
+        {
91
+
92
+            if (e.Key == Key.Up)
93
+            {
94
+                datePicker.Focus(); 
95
+                focus.MoveFocus(FocusNavigation.Backward);
96
+            }
97
+            else if (e.Key == Key.Down || e.Key == Key.Tab || e.Key == Key.Enter)
98
+            {
99
+                datePicker.Focus(); 
100
+                focus.MoveFocus(FocusNavigation.Forward);
101
+            }
102
+            else if (e.Key == Key.Left)
103
+            {
104
+                datePicker.Focus(); 
105
+                focus.MoveFocus(FocusNavigation.Backward);
106
+            }
107
+            else if (e.Key == Key.Right)
108
+            {
109
+                datePicker.Focus();   
110
+                focus.MoveFocus(FocusNavigation.Forward);
111
+            }
112
+        }
113
+
114
+        private void PreviewGotFocus(object sender, RoutedEventArgs e)
115
+        {
116
+            datePicker.Focus();        
117
+        }
118
+
119
+        private void PreviewLostFocus(object sender, RoutedEventArgs e)
120
+        {
121
+            datePicker.Focus();
122
+        }
123
+
124
+
125
+    }
126
+}

+ 31
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateSpanControl.xaml 查看文件

@@ -0,0 +1,31 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.DateSpanControl"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:dhcc="http://www.dhcc.com.cn"
6
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+             x:Name="uc_DateSpan"
8
+             mc:Ignorable="d">
9
+    <UserControl.Resources>
10
+        <ResourceDictionary Source="/TellerSystem.Controls.Ext;component/ControlsStyle/TradePageElementGeneric.xaml" />
11
+    </UserControl.Resources>
12
+    <StackPanel Orientation="Horizontal">
13
+        <TextBox Name="Beg_date"
14
+                 Width="190"
15
+                 dhcc:FocusManager.LostFocus="Beg_date_LostFocus"
16
+                 Style="{StaticResource StyleDate}"
17
+                 Text="{Binding BeginDate,
18
+                                UpdateSourceTrigger=PropertyChanged,
19
+                                ElementName=uc_DateSpan}" />
20
+        <dhcc:Arrow Name="Larrow"
21
+                    Width="60"
22
+                    Height="20" />
23
+        <TextBox Name="End_date"
24
+                 Width="190"
25
+                 dhcc:FocusManager.LostFocus="End_date_LostFocus"
26
+                 Style="{StaticResource StyleDate}"
27
+                 Text="{Binding EndDate,
28
+                                UpdateSourceTrigger=PropertyChanged,
29
+                                ElementName=uc_DateSpan}" />
30
+    </StackPanel>
31
+</UserControl>

+ 158
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DateSpanControl.xaml.cs 查看文件

@@ -0,0 +1,158 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using Platform.Presentation.FocusManagers;
15
+using Platform.Controls.ControlsHelper;
16
+using Platform.Presentation.Interfaces;
17
+
18
+namespace TellerSystem.Controls.Ext.Controls
19
+{
20
+    /// <summary>
21
+    /// DateSpanControl.xaml 的交互逻辑
22
+    /// </summary>
23
+    public partial class DateSpanControl : UserControl
24
+    {
25
+
26
+        #region 事件
27
+        public delegate void DateLostFocusHandle(TextBox beginBox,TextBox endBox);
28
+        public event DateLostFocusHandle BeginDateLostFocus;
29
+        public event DateLostFocusHandle EndDateLostFocus;
30
+        //public static readonly RoutedEvent BeginDateLostFocusEvent = EventManager.RegisterRoutedEvent("BeginDateLostFocus", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(DateSpanControl));
31
+
32
+        //public event RoutedEventHandler BeginDateLostFocus
33
+        //{
34
+        //    add { this.AddHandler(BeginDateLostFocusEvent,value);}
35
+        //    remove { this.RemoveHandler(BeginDateLostFocusEvent, value); }
36
+        //}
37
+
38
+        //public static readonly RoutedEvent EndDateLostFocusEvent = EventManager.RegisterRoutedEvent("EndDateLostFocus", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(DateSpanControl));
39
+
40
+        //public event RoutedEventHandler EndDateLostFocus
41
+        //{
42
+        //    add { this.AddHandler(EndDateLostFocusEvent, value); }
43
+        //    remove { this.RemoveHandler(EndDateLostFocusEvent, value); }
44
+        //}
45
+        #endregion
46
+
47
+        #region 属性
48
+        /// <summary>
49
+        /// 设置或获取时间值的必输性,true为必输
50
+        /// </summary>
51
+        public bool IsNotEmpty
52
+        {
53
+            get { return (bool)GetValue(IsNotEmptyProperty); }
54
+            set { SetValue(IsNotEmptyProperty, value); }
55
+        }
56
+
57
+        public static readonly DependencyProperty IsNotEmptyProperty =
58
+            DependencyProperty.Register("IsNotEmpty", typeof(bool), typeof(DateSpanControl), new UIPropertyMetadata(false, new PropertyChangedCallback(IsNotEmptyChangedCallback)));
59
+
60
+
61
+
62
+        public string BeginDate
63
+        {
64
+            get { return (string)GetValue(BeginDateProperty); }
65
+            set { SetValue(BeginDateProperty, value); }
66
+        }
67
+
68
+
69
+        public static readonly DependencyProperty BeginDateProperty =
70
+            DependencyProperty.Register("BeginDate", typeof(string), typeof(DateSpanControl), new UIPropertyMetadata(""));
71
+
72
+
73
+
74
+        public string EndDate
75
+        {
76
+            get { return (string)GetValue(EndDateProperty); }
77
+            set { SetValue(EndDateProperty, value); }
78
+        }
79
+
80
+        public static readonly DependencyProperty EndDateProperty =
81
+            DependencyProperty.Register("EndDate", typeof(string), typeof(DateSpanControl), new UIPropertyMetadata(""));
82
+
83
+
84
+
85
+        public bool IsVerifiy
86
+        {
87
+            get { return (bool)GetValue(IsVerifiyProperty); }
88
+            set { SetValue(IsVerifiyProperty, value); }
89
+        }
90
+
91
+        // Using a DependencyProperty as the backing store for IsVerifiy.  This enables animation, styling, binding, etc...
92
+        public static readonly DependencyProperty IsVerifiyProperty =
93
+            DependencyProperty.Register("IsVerifiy", typeof(bool), typeof(DateSpanControl), new UIPropertyMetadata(true));
94
+
95
+
96
+        
97
+        #endregion
98
+
99
+        #region 方法
100
+        public DateSpanControl()
101
+        {
102
+            InitializeComponent();
103
+        }
104
+
105
+        static void IsNotEmptyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
106
+        {
107
+            DateSpanControl ds = d as DateSpanControl;
108
+            if (ds != null)
109
+            {
110
+                StackPanel sp_Content = ds.Content as StackPanel;
111
+                if (sp_Content != null)
112
+                {
113
+                    TextBox tb_Begin = sp_Content.Children[0] as TextBox;
114
+                    TextBox tb_End = sp_Content.Children[2] as TextBox;
115
+                    if ((bool)e.NewValue)
116
+                    {
117
+                        FocusManagerExt.SetAssertNotEmpty(tb_Begin, true);
118
+                        FocusManagerExt.SetAssertNotEmpty(tb_End, true);
119
+                    }
120
+                    else
121
+                    {
122
+                        FocusManagerExt.SetAssertNotEmpty(tb_Begin, false);
123
+                        FocusManagerExt.SetAssertNotEmpty(tb_End, false);
124
+                    }
125
+
126
+                }
127
+            }
128
+
129
+        }
130
+        #endregion
131
+
132
+        private void End_date_LostFocus(object sender, RoutedEventArgs e)
133
+        {
134
+            if (this.IsVerifiy )
135
+            {
136
+                if(string.IsNullOrEmpty(this.Beg_date.Text)||string.IsNullOrEmpty(this.End_date.Text))
137
+                    return;
138
+
139
+                if (long.Parse(this.End_date.Text) < long.Parse(this.Beg_date.Text))
140
+                {
141
+                    this.End_date.ShowTip("结束日期不能小于开始日期");
142
+                    IPage page = Platform.Common.BasicFunctions.DependencyObjectExtensions.FindVisualTreeAncestor(this, x => { return (x is IPage); }) as IPage;
143
+                    page.SetFocus();
144
+                    return;
145
+                }
146
+            }
147
+
148
+            if (this.EndDateLostFocus != null)
149
+                this.EndDateLostFocus(this.Beg_date,this.End_date);
150
+        }
151
+
152
+        private void Beg_date_LostFocus(object sender, RoutedEventArgs e)
153
+        {
154
+            if (this.BeginDateLostFocus != null)
155
+                this.BeginDateLostFocus(this.Beg_date, this.End_date);
156
+        }
157
+    }
158
+}

+ 58
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailEdit.xaml 查看文件

@@ -0,0 +1,58 @@
1
+<local:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.DetailEdit"
2
+                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                      xmlns:control="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
5
+                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                      xmlns:dhcc="http://www.dhcc.com.cn"
7
+                      xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
8
+                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
+                      xmlns:s="clr-namespace:TellerSystem.Controls.Ext.Controls"
10
+                      d:DesignHeight="410"
11
+                      d:DesignWidth="800"
12
+                      dhcc:FocusManager.EnableFocusControl="True"
13
+                      mc:Ignorable="d">
14
+    <Grid Height="400">
15
+        <Grid.RowDefinitions>
16
+            <RowDefinition Height="330" />
17
+            <RowDefinition Height="70" />
18
+        </Grid.RowDefinitions>
19
+        <control:TradePanel Height="325" Header="明细详情">
20
+            <control:TradePanel.Resources>
21
+                <ResourceDictionary Source="/TellerSystem.Controls.Ext;component/ControlsStyle/TradePageElementGeneric.xaml" />
22
+            </control:TradePanel.Resources>
23
+            <dhcc:DataBox x:Name="Detail_DataBox"
24
+                          Width="780"
25
+                          Height="295"
26
+                          Margin="2,2,2,2"
27
+                          control:TradePanel.ColumnSpan="4" />
28
+        </control:TradePanel>
29
+        <control:TradePanel Grid.Row="1"
30
+                            Height="60"
31
+                            Header="明细详情">
32
+            <control:TradePanel.Resources>
33
+                <ResourceDictionary Source="/TellerSystem.Controls.Ext;component/ControlsStyle/TradePageElementGeneric.xaml" />
34
+            </control:TradePanel.Resources>
35
+            <Canvas Width="780"
36
+                    Height="23"
37
+                    Margin="2,2,2,2"
38
+                    control:TradePanel.ColumnSpan="4">
39
+                <Button Name="AddDetail"
40
+                        Canvas.Left="20"
41
+                        Click="AddDetail_OnClick"
42
+                        Content="增  加" />
43
+                <Button Name="ModifyDetail"
44
+                        Canvas.Left="120"
45
+                        Click="ModifyDetail_OnClick"
46
+                        Content="修  改" />
47
+                <Button Name="DeleteDetail"
48
+                        Canvas.Left="220"
49
+                        Click="DeleteDetail_OnClick"
50
+                        Content="删  除" />
51
+                <Button Name="Quit"
52
+                        Canvas.Left="320"
53
+                        Click="Quit_OnClick"
54
+                        Content="保存并退出" />
55
+            </Canvas>
56
+        </control:TradePanel>
57
+    </Grid>
58
+</local:BlankTradePage>

+ 365
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailEdit.xaml.cs 查看文件

@@ -0,0 +1,365 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Data;
4
+using System.Linq;
5
+using System.Text;
6
+using System.Windows;
7
+using System.Windows.Controls;
8
+using System.Windows.Data;
9
+using System.Windows.Documents;
10
+using System.Windows.Input;
11
+using System.Windows.Media;
12
+using System.Windows.Media.Imaging;
13
+using System.Windows.Navigation;
14
+using System.Windows.Shapes;
15
+using Platform.Controls.ControlsHelper;
16
+using Platform.Library;
17
+using TellerSystem.Library.Ext.Function;
18
+using System.Text.RegularExpressions;
19
+using Platform.Controls.ComponentContainer;
20
+using TellerSystem.Library.Ext.TradeExtension;
21
+
22
+namespace TellerSystem.Controls.Ext.Controls
23
+{
24
+    /// <summary>
25
+    /// CheckMoney.xaml 的交互逻辑
26
+    /// </summary>
27
+    public partial class DetailEdit
28
+    {
29
+        #region 构造函数
30
+
31
+        public DetailEdit()
32
+        {
33
+            InitializeComponent();
34
+        }
35
+
36
+        #endregion
37
+
38
+        #region 变量
39
+
40
+        #region 传输数据所用的字典
41
+
42
+        /// <summary>
43
+        /// 传输数据所用的字典
44
+        /// </summary>
45
+        private Dictionary<string, string> DetailInfoDic = new Dictionary<string, string>()
46
+        {
47
+            {"ProjectCode", ""},
48
+            {"ProjectName", ""},
49
+            {"StandardCode", ""},
50
+            {"StandardName", ""},
51
+            {"UnitOfMeasurement", ""},
52
+            {"ChargingCount", ""},
53
+            {"Amount", ""},
54
+            {"ParmKPRQ", ""},
55
+            {"ParmDWBM", ""},
56
+            {"ParmSFJM", ""},
57
+            {"ParmJKFS", ""},
58
+            {"ParmIsOperate", ""}
59
+        };
60
+
61
+        #endregion
62
+
63
+        #region 列名到打控件名的映射字典
64
+
65
+        /// <summary>
66
+        /// 列名到打控件名的映射字典
67
+        /// </summary>
68
+        private Dictionary<string, string> ColumnName = new Dictionary<string, string>()
69
+        {
70
+            {"项目编码", "ProjectCode"},
71
+            {"项目名称", "ProjectName"},
72
+            {"标准编码", "StandardCode"},
73
+            {"标准名称", "StandardName"},
74
+            {"计量单位", "UnitOfMeasurement"},
75
+            {"计费数量", "ChargingCount"},
76
+            {"金额", "Amount"}
77
+        };
78
+
79
+        #endregion
80
+
81
+        /// <summary>
82
+        /// 输入参数类
83
+        /// </summary>
84
+        public DetailEditEntity DetailEditEntity { internal get; set; }
85
+
86
+        /// <summary>
87
+        /// 输出参数类
88
+        /// </summary>
89
+        public DetailEditResult DetailEditResult { get; internal set; }
90
+
91
+        #endregion
92
+
93
+        #region 逻辑代码
94
+
95
+        /// <summary>
96
+        /// 界面初始化数据
97
+        /// </summary>
98
+        /// <returns></returns>
99
+        public override bool InitPage()
100
+        {
101
+            /*********************************************
102
+             * 此处需要填充的代码包括:
103
+             * 1.界面初始数据
104
+             * ******************************************/
105
+            //如果数据源不为null用数据源,为null加载默认列名
106
+            //做数据恢复用,方便重新编辑。
107
+            if (DetailEditEntity.DetailEditResult.SourceDT != null)
108
+                this.Detail_DataBox.DataBinding(DetailEditEntity.DetailEditResult.SourceDT);
109
+            else
110
+                this.Detail_DataBox.DataBinding("", new string[] { "项目编码", "项目名称", "标准编码", "标准名称", "计量单位", "计费数量", "金额" });
111
+            //实例化结果类
112
+            DetailEditResult = new DetailEditResult();
113
+            //如果没有数据,焦点停留在新增按钮上
114
+            if (!this.Detail_DataBox.DataBoxHost.Rows().Any())
115
+                this.SetFocus(AddDetail);
116
+            else
117
+                this.SetFocus(Detail_DataBox);
118
+            return true;
119
+        }
120
+
121
+        #endregion
122
+
123
+        #region 内部逻辑
124
+
125
+        /// <summary>
126
+        /// 新增一条明细
127
+        /// </summary>
128
+        /// <param name="sender"></param>
129
+        /// <param name="e"></param>
130
+        private void AddDetail_OnClick(object sender, RoutedEventArgs e)
131
+        {
132
+            if (Detail_DataBox.DataBoxHost.Rows().Count() == 5)
133
+            {
134
+                this.ShowWarnMessageBox("只能添加五条明细!");
135
+                return;
136
+            }
137
+            //设置字典的值
138
+            SetDicValue(null);
139
+            //明细详情窗口
140
+            DetailInformation df = new DetailInformation()
141
+            {
142
+                DetailInfoDic = this.DetailInfoDic
143
+            };
144
+            this.ShowPage(df);
145
+            DetailInfoDic = df.DetailInfoDic;
146
+            //没有操作,不添加
147
+            if (String.CompareOrdinal(DetailInfoDic["ParmIsOperate"], "true") != 0) return;
148
+            //查找重复项
149
+            if (CheckDetailExist()) return;
150
+            //添加一项
151
+            this.Detail_DataBox.AddRow(GetDicRowData());
152
+            //清除字典的值
153
+            ClearDicValue();
154
+        }
155
+
156
+        /// <summary>
157
+        /// 修改一条明细
158
+        /// </summary>
159
+        /// <param name="sender"></param>
160
+        /// <param name="e"></param>
161
+        private void ModifyDetail_OnClick(object sender, RoutedEventArgs e)
162
+        {
163
+            var selectedRow = this.Detail_DataBox.GetSelectSingleRow();
164
+            if(selectedRow == null) return;
165
+            SetDicValue(selectedRow);
166
+
167
+            //明细详情窗口
168
+            var df = new DetailInformation()
169
+            {
170
+                DetailInfoDic = this.DetailInfoDic
171
+            };
172
+            this.ShowPage(df);
173
+            DetailInfoDic = df.DetailInfoDic;
174
+
175
+            //没有操作,不修改
176
+            if (String.CompareOrdinal(DetailInfoDic["ParmIsOperate"], "true") != 0) return;
177
+
178
+            //如果修改了项目编码和标准编码的组合,需要验证是否重复。
179
+            if (!(Equals(selectedRow["项目编码"], DetailInfoDic["ProjectCode"]) ||
180
+                Equals(selectedRow["标准编码"], DetailInfoDic["StandardCode"]))
181
+                && CheckDetailExist())
182
+            {
183
+                return;
184
+            }
185
+
186
+            //修改选中列
187
+            Detail_DataBox.UpdateRow(GetDicRowData() );
188
+            //清除字典数据
189
+            ClearDicValue();
190
+        }
191
+
192
+        /// <summary>
193
+        /// 删除一条明细
194
+        /// </summary>
195
+        /// <param name="sender"></param>
196
+        /// <param name="e"></param>
197
+        private void DeleteDetail_OnClick(object sender, RoutedEventArgs e)
198
+        {
199
+            this.Detail_DataBox.DeleteSelectRows();
200
+        }
201
+
202
+        /// <summary>
203
+        /// 退出系统
204
+        /// </summary>
205
+        /// <param name="sender"></param>
206
+        /// <param name="e"></param>
207
+        private void Quit_OnClick(object sender, RoutedEventArgs e)
208
+        {
209
+            if (this.ShowMessageBox("确定保存并退出吗?", "系统提示", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
210
+            {
211
+                return;
212
+            }
213
+            //传出数据源
214
+            DetailEditResult.SourceDT = Detail_DataBox.GetDataForDataTable();
215
+            //传出数据
216
+            GetDataForString();
217
+            DetailEditResult.TotalMoney =
218
+                this.Detail_DataBox.DataBoxHost.Items.Cast<DataRowView>()
219
+                    .Sum(view => decimal.Parse(view.Row["金额"].ToString()));
220
+            this.Close();
221
+        }
222
+
223
+        /// <summary>
224
+        /// 检查明细是否存在
225
+        /// </summary>
226
+        /// <param name="projectCode">项目编码</param>
227
+        /// <param name="StandardCode">标准编码</param>
228
+        /// <returns>true存在,false不存在</returns>
229
+        private bool CheckDetailExist()
230
+        {
231
+            var correctRow = Detail_DataBox.DataBoxHost.Items.Cast<DataRowView>()
232
+                 .ToList()
233
+                 .Find(x => Equals(x.Row["项目编码"], DetailInfoDic["ProjectCode"]) && Equals(x.Row["标准编码"],  DetailInfoDic["StandardCode"]));
234
+            if (correctRow != null)
235
+            {
236
+                this.ShowErrorMessageBox("该条明细已存在!");
237
+                return true;
238
+            }
239
+            return false;
240
+        }
241
+
242
+        /// <summary>
243
+        /// 得到表格数据
244
+        /// 兼容老系统,每行前面加上"||"
245
+        /// </summary>
246
+        private void GetDataForString()
247
+        {
248
+            var dataTable = Detail_DataBox.GetDataForDataTable();
249
+            if (dataTable == null) return;
250
+
251
+            StringBuilder fileData = new StringBuilder();
252
+
253
+            //构造数据
254
+            for (var i = 0; i < dataTable.Rows.Count; i++)
255
+            {
256
+                for (var j = 0; j < dataTable.Columns.Count; j++)
257
+                {
258
+                    if (j == 0)
259
+                    {
260
+                        fileData.Append("||");
261
+                    }
262
+                    fileData.Append(dataTable.Rows[i][j].ToString() + "|");
263
+                }
264
+
265
+                fileData.Append("\n");
266
+            }
267
+            DetailEditResult.DetailData = fileData.ToString();
268
+
269
+        }
270
+
271
+        /// <summary>
272
+        /// 清除字典的值
273
+        /// </summary>
274
+        private void ClearDicValue()
275
+        {
276
+            var colName = DetailInfoDic.Keys.ToArray().Where(x => !x.StartsWith("Parm"));
277
+            foreach (string val in colName)
278
+            {
279
+                DetailInfoDic[val] = "";
280
+            }
281
+        }
282
+
283
+        /// <summary>
284
+        /// 设置字典的值
285
+        /// </summary>
286
+        /// <param name="row"></param>
287
+        private void SetDicValue(DataRow row)
288
+        {
289
+            if (row != null)
290
+            {
291
+                foreach (KeyValuePair<string, string> keyValuePair in ColumnName)
292
+                    this.DetailInfoDic[keyValuePair.Value] = row[keyValuePair.Key].ToString().Trim();
293
+            }
294
+            this.DetailInfoDic["ParmKPRQ"] = this.DetailEditEntity.KPRQParm;
295
+            this.DetailInfoDic["ParmDWBM"] = this.DetailEditEntity.DWBMParm;
296
+            this.DetailInfoDic["ParmSFJM"] = this.DetailEditEntity.SFJMParm;
297
+            this.DetailInfoDic["ParmJKFS"] = this.DetailEditEntity.JKFSParm;
298
+        }
299
+
300
+        /// <summary>
301
+        /// 得到字典中列数据的值
302
+        /// </summary>
303
+        /// <returns></returns>
304
+        private string[] GetDicRowData()
305
+        {
306
+            return new string[]
307
+            {
308
+                DetailInfoDic["ProjectCode"],
309
+                DetailInfoDic["ProjectName"],
310
+                DetailInfoDic["StandardCode"],
311
+                DetailInfoDic["StandardName"],
312
+                DetailInfoDic["UnitOfMeasurement"],
313
+                DetailInfoDic["ChargingCount"],
314
+                DetailInfoDic["Amount"]
315
+            };
316
+        }
317
+
318
+        #endregion
319
+    }
320
+
321
+    #region 参数类
322
+
323
+    /// <summary>
324
+    /// 明细详情参数类
325
+    /// </summary>
326
+    public class DetailEditEntity
327
+    {
328
+
329
+        /// <summary>
330
+        /// 开票日期,交易中传过来
331
+        /// </summary>
332
+        public string KPRQParm { internal get; set; }
333
+
334
+        /// <summary>
335
+        /// 单位编码,交易中传过来
336
+        /// </summary>
337
+        public string DWBMParm { internal get; set; }
338
+
339
+        /// <summary>
340
+        /// 是否减免,交易中传过来
341
+        /// </summary>
342
+        public string SFJMParm { internal get; set; }
343
+
344
+        /// <summary>
345
+        /// 缴库方式,交易中传过来
346
+        /// </summary>
347
+        public string JKFSParm { internal get; set; }
348
+
349
+        public DetailEditResult DetailEditResult { internal get; set; }
350
+    }
351
+
352
+    /// <summary>
353
+    /// 明细详情结果类
354
+    /// </summary>
355
+    public class DetailEditResult
356
+    {
357
+        public string DetailData { get; internal set; }
358
+
359
+        public DataTable SourceDT { get; internal set; }
360
+
361
+        public decimal TotalMoney { get; internal set; }
362
+    }
363
+
364
+    #endregion
365
+}

+ 57
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailInformation.xaml 查看文件

@@ -0,0 +1,57 @@
1
+<local:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.DetailInformation"
2
+                      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                      xmlns:con="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
5
+                      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                      xmlns:dhcc="http://www.dhcc.com.cn"
7
+                      xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
8
+                      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
+                      xmlns:s="clr-namespace:TellerSystem.Controls.Ext.Controls"
10
+                      d:DesignHeight="285"
11
+                      d:DesignWidth="792"
12
+                      dhcc:FocusManager.EnableFocusControl="True"
13
+                      mc:Ignorable="d">
14
+    <con:TradePanel Header="明细详情">
15
+        <TextBlock Text="项目编码" />
16
+        <TextBox Name="ProjectCode"
17
+                 con:TradePanel.ColumnSpan="3"
18
+                 dhcc:FocusManager.LostFocus="ProjectCode_OnLostFocus"
19
+                 dhcc:FocusManagerExt.AssertNotEmpty="True" />
20
+        <TextBlock Text="项目名称" />
21
+        <TextBox Name="ProjectName"
22
+                 Width="300"
23
+                 con:TradePanel.ColumnSpan="3"
24
+                 IsEnabled="False"
25
+                 MaxLength="120" />
26
+        <TextBlock Text="标准编码" />
27
+        <TextBox Name="StandardCode"
28
+                 con:TradePanel.ColumnSpan="3"
29
+                 dhcc:FocusManager.LostFocus="StandardCode_OnLostFocus"
30
+                 dhcc:FocusManagerExt.AssertNotEmpty="True" />
31
+        <TextBlock Text="标准名称" />
32
+        <TextBox Name="StandardName"
33
+                 Width="300"
34
+                 con:TradePanel.ColumnSpan="3"
35
+                 IsEnabled="False" />
36
+        <TextBlock Text="计量单位" />
37
+        <TextBox Name="UnitOfMeasurement"
38
+                 Width="120"
39
+                 con:TradePanel.ColumnSpan="3"
40
+                 IsEnabled="False" />
41
+        <TextBlock Text="计费数量" />
42
+        <TextBox Name="ChargingCount"
43
+                 con:TradePanel.ColumnSpan="3"
44
+                 dhcc:FocusManagerExt.AssertNotEmpty="True"
45
+                 dhcc:RegexRuleExtension.InputType="NumberStr" />
46
+        <TextBlock Text="金    额" />
47
+        <dhcc:CurrencyEditor Name="Amount"
48
+                             con:TradePanel.ColumnSpan="3"
49
+                             dhcc:FocusManagerExt.AssertNotEmpty="True" />
50
+        <Button Click="Button_Click"
51
+                con:TradePanel.ColumnSpan="4"
52
+                Content="确  定" />
53
+
54
+
55
+    </con:TradePanel>
56
+
57
+</local:BlankTradePage>

+ 188
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DetailInformation.xaml.cs 查看文件

@@ -0,0 +1,188 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Data;
4
+using System.Linq;
5
+using System.Text;
6
+using System.Windows;
7
+using System.Windows.Controls;
8
+using System.Windows.Data;
9
+using System.Windows.Documents;
10
+using System.Windows.Input;
11
+using System.Windows.Media;
12
+using System.Windows.Media.Imaging;
13
+using System.Windows.Navigation;
14
+using System.Windows.Shapes;
15
+using Platform.Controls.ControlsHelper;
16
+using Platform.Library;
17
+using TellerSystem.Library.Ext.Function;
18
+using System.Text.RegularExpressions;
19
+using System.Windows.Forms.VisualStyles;
20
+using Platform.Controls.NumericContainer;
21
+using TellerSystem.Communication;
22
+
23
+namespace TellerSystem.Controls.Ext.Controls
24
+{
25
+    /// <summary>
26
+    /// CheckMoney.xaml 的交互逻辑
27
+    /// </summary>
28
+    public partial class DetailInformation
29
+    {
30
+        #region 构造函数
31
+
32
+        public DetailInformation()
33
+        {
34
+            InitializeComponent();
35
+        }
36
+
37
+        #endregion
38
+
39
+        #region 变量
40
+
41
+        public Dictionary<string,string> DetailInfoDic = new Dictionary<string, string>(); 
42
+
43
+        #endregion
44
+
45
+        #region 逻辑代码
46
+
47
+        /// <summary>
48
+        /// 界面初始化数据
49
+        /// </summary>
50
+        /// <returns></returns>
51
+        public override bool InitPage()
52
+        {
53
+            /*********************************************
54
+             * 此处需要填充的代码包括:
55
+             * 1.界面初始数据
56
+             * ******************************************/
57
+
58
+            if (DetailInfoDic.ContainsKey("ProjectCode") &&
59
+                !string.IsNullOrWhiteSpace(DetailInfoDic["ProjectCode"]))
60
+            {
61
+                foreach (
62
+                    KeyValuePair<string, string> keyValuePair in DetailInfoDic.Where(x => !x.Value.StartsWith("Parm")))
63
+                {
64
+                    TextBox textbox = this.FindName(keyValuePair.Key) as TextBox;
65
+                    if (textbox != null) textbox.Text = keyValuePair.Value;
66
+                }
67
+            }
68
+            DetailInfoDic["ParmIsOperate"] = "false";
69
+            return true;
70
+        }
71
+
72
+        #endregion
73
+
74
+        #region 内部逻辑
75
+
76
+        /// <summary>
77
+        /// 项目编码焦点事件
78
+        /// 获取项目名称
79
+        /// </summary>
80
+        /// <param name="sender"></param>
81
+        /// <param name="e"></param>
82
+        private void ProjectCode_OnLostFocus(object sender, RoutedEventArgs e)
83
+        {
84
+            Message _msg = new Message(Message.BitMap.Agn);
85
+            this.TradeAPIs.InitFd(_msg);
86
+            this.TradeAPIs.CommSend(_msg);
87
+            _msg.Fd16 = "6998";
88
+            _msg.Fd60 = "FSSR";
89
+            _msg.Fd22 = "06";
90
+            _msg.Fd123 = string.Format("select fxmmc from fssr_hbxmxx where fxmbm = '{0}'", this.ProjectCode.Text.Trim());
91
+            this.CallAgnTips(_msg);
92
+            if (_msg.Fd12 != "0000")
93
+            {
94
+                this.TradeAPIs.ShowErrorMessageBox(this.TradeAPIs.GetError(_msg));
95
+                return;
96
+            }
97
+            if (_msg.FileData == "")
98
+            {
99
+                this.TradeAPIs.ShowTip("请输入有效项目编码!");
100
+                this.SetFocus();
101
+                return;
102
+            }
103
+            this.ProjectName.Text = _msg.FileData.Split('|')[0];
104
+        }
105
+
106
+        /// <summary>
107
+        /// 标准编码焦点事件
108
+        /// 获取标准名称,计量单位
109
+        /// </summary>
110
+        /// <param name="sender"></param>
111
+        /// <param name="e"></param>
112
+        private void StandardCode_OnLostFocus(object sender, RoutedEventArgs e)
113
+        {
114
+            Message _msg = new Message(Message.BitMap.Agn);
115
+            this.TradeAPIs.InitFd(_msg);
116
+            this.TradeAPIs.CommSend(_msg);
117
+            _msg.Fd16 = "6998";
118
+            _msg.Fd60 = "FSSR";
119
+            _msg.Fd22 = "06";
120
+            _msg.Fd123 = string.Format("select fbzmc,fjldw from fssr_xmbzxx where fxmbm = '{0}' and fbzbm = '{1}'",
121
+                this.ProjectCode.Text.Trim(), this.StandardCode.Text.Trim());
122
+            this.CallAgnTips(_msg);
123
+            if (_msg.Fd12 != "0000")
124
+            {
125
+                this.TradeAPIs.ShowErrorMessageBox(this.TradeAPIs.GetError(_msg));
126
+                return;
127
+            }
128
+            if (_msg.FileData == "")
129
+            {
130
+                this.TradeAPIs.ShowTip("请输入有效标准编码!");
131
+                this.SetFocus();
132
+                return;
133
+            }
134
+            this.StandardName.Text = _msg.FileData.Split('|')[0];
135
+            this.UnitOfMeasurement.Text = _msg.FileData.Split('|')[1];
136
+        }
137
+
138
+        /// <summary>
139
+        /// 确定点击事件
140
+        /// </summary>
141
+        /// <param name="sender"></param>
142
+        /// <param name="e"></param>
143
+        private void Button_Click(object sender, RoutedEventArgs e)
144
+        {
145
+            Message _msg = new Message(Message.BitMap.Agn);
146
+            this.TradeAPIs.InitFd(_msg);
147
+            this.TradeAPIs.CommSend(_msg);
148
+            _msg.Fd16 = "6949";
149
+            _msg.Fd22 = "06";
150
+            _msg.Fd60 = "FSSR";
151
+            _msg.Fd44 = DetailInfoDic["ParmKPRQ"];
152
+            _msg.Fd30 = DetailInfoDic["ParmDWBM"];
153
+            _msg.Fd31 = this.ProjectCode.Text;
154
+            _msg.Fd32 = this.StandardCode.Text;
155
+            _msg.Fd67 = DetailInfoDic["ParmSFJM"];
156
+            _msg.Fd23 = DetailInfoDic["ParmJKFS"];
157
+            _msg.Fd40 = this.TradeAPIs.Itoa(decimal.Parse(this.ChargingCount.Text), "%016.0f");
158
+            _msg.Fd41 = this.TradeAPIs.Itoa(decimal.Parse(this.Amount.Text), "%016.0f");
159
+            this.TradeAPIs.CallAgnTips(_msg);
160
+            if (_msg.Fd12 != "0000")
161
+            {
162
+                if (this.ShowMessageBox("此条明细存在问题:" + this.TradeAPIs.GetError(_msg) + "。点击确定继续添加,取消重新编辑。"
163
+                    , "系统提示", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
164
+                {
165
+                    this.SetFocus(ProjectCode);
166
+                    return;
167
+                }
168
+            }
169
+            DetailInfoDic["ParmIsOperate"] = "true";
170
+            var colName =  DetailInfoDic.Keys.ToArray().Where(x => !x.StartsWith("Parm"));
171
+            foreach (string key in colName)
172
+            {
173
+                var textBox = this.FindName(key) as TextBox;
174
+                if (textBox != null)
175
+                    DetailInfoDic[key] = textBox.Text.Trim();
176
+            }
177
+            var currencyEditor = this.FindName("Amount") as CurrencyEditor;
178
+            DetailInfoDic["Amount"] = currencyEditor.Val;
179
+
180
+            this.Close();
181
+        }
182
+
183
+        #endregion
184
+
185
+    }
186
+
187
+
188
+}

+ 416
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connection.cs 查看文件

@@ -0,0 +1,416 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.ComponentModel;
4
+using System.Windows;
5
+using System.Windows.Controls;
6
+using System.Windows.Documents;
7
+using System.Windows.Input;
8
+using System.Windows.Media;
9
+
10
+namespace TellerSystem.Controls.Ext.Controls
11
+{
12
+    public class Connection : Control, INotifyPropertyChanged
13
+    {
14
+        private Adorner connectionAdorner;
15
+
16
+        #region Properties
17
+
18
+        // source connector
19
+        private Connector source;
20
+        public Connector Source
21
+        {
22
+            get
23
+            {
24
+                return source;
25
+            }
26
+            set
27
+            {
28
+                if (source != value)
29
+                {
30
+                    if (source != null)
31
+                    {
32
+                        source.PropertyChanged -= new PropertyChangedEventHandler(OnConnectorPositionChanged);
33
+                        source.Connections.Remove(this);
34
+                    }
35
+
36
+                    source = value;
37
+
38
+                    if (source != null)
39
+                    {
40
+                        source.Connections.Add(this);
41
+                        source.PropertyChanged += new PropertyChangedEventHandler(OnConnectorPositionChanged);
42
+                    }
43
+
44
+                    UpdatePathGeometry();
45
+                }
46
+            }
47
+        }
48
+
49
+        // sink connector
50
+        private Connector sink;
51
+        public Connector Sink
52
+        {
53
+            get { return sink; }
54
+            set
55
+            {
56
+                if (sink != value)
57
+                {
58
+                    if (sink != null)
59
+                    {
60
+                        sink.PropertyChanged -= new PropertyChangedEventHandler(OnConnectorPositionChanged);
61
+                        sink.Connections.Remove(this);
62
+                    }
63
+
64
+                    sink = value;
65
+
66
+                    if (sink != null)
67
+                    {
68
+                        sink.Connections.Add(this);
69
+                        sink.PropertyChanged += new PropertyChangedEventHandler(OnConnectorPositionChanged);
70
+                    }
71
+                    UpdatePathGeometry();
72
+                }
73
+            }
74
+        }
75
+
76
+        // connection path geometry
77
+        private PathGeometry pathGeometry;
78
+        public PathGeometry PathGeometry
79
+        {
80
+            get { return pathGeometry; }
81
+            set
82
+            {
83
+                if (pathGeometry != value)
84
+                {
85
+                    pathGeometry = value;
86
+                    UpdateAnchorPosition();
87
+                    OnPropertyChanged("PathGeometry");
88
+                }
89
+            }
90
+        }
91
+
92
+        // between source connector position and the beginning 
93
+        // of the path geometry we leave some space for visual reasons; 
94
+        // so the anchor position source really marks the beginning 
95
+        // of the path geometry on the source side
96
+        private Point anchorPositionSource;
97
+        public Point AnchorPositionSource
98
+        {
99
+            get { return anchorPositionSource; }
100
+            set
101
+            {
102
+                if (anchorPositionSource != value)
103
+                {
104
+                    anchorPositionSource = value;
105
+                    OnPropertyChanged("AnchorPositionSource");
106
+                }
107
+            }
108
+        }
109
+
110
+        // slope of the path at the anchor position
111
+        // needed for the rotation angle of the arrow
112
+        private double anchorAngleSource = 0;
113
+        public double AnchorAngleSource
114
+        {
115
+            get { return anchorAngleSource; }
116
+            set
117
+            {
118
+                if (anchorAngleSource != value)
119
+                {
120
+                    anchorAngleSource = value;
121
+                    OnPropertyChanged("AnchorAngleSource");
122
+                }
123
+            }
124
+        }
125
+
126
+        // analogue to source side
127
+        private Point anchorPositionSink;
128
+        public Point AnchorPositionSink
129
+        {
130
+            get { return anchorPositionSink; }
131
+            set
132
+            {
133
+                if (anchorPositionSink != value)
134
+                {
135
+                    anchorPositionSink = value;
136
+                    OnPropertyChanged("AnchorPositionSink");
137
+                }
138
+            }
139
+        }
140
+        // analogue to source side
141
+        private double anchorAngleSink = 0;
142
+        public double AnchorAngleSink
143
+        {
144
+            get { return anchorAngleSink; }
145
+            set
146
+            {
147
+                if (anchorAngleSink != value)
148
+                {
149
+                    anchorAngleSink = value;
150
+                    OnPropertyChanged("AnchorAngleSink");
151
+                }
152
+            }
153
+        }
154
+
155
+        private ArrowSymbol sourceArrowSymbol = ArrowSymbol.None;
156
+        public ArrowSymbol SourceArrowSymbol
157
+        {
158
+            get { return sourceArrowSymbol; }
159
+            set
160
+            {
161
+                if (sourceArrowSymbol != value)
162
+                {
163
+                    sourceArrowSymbol = value;
164
+                    OnPropertyChanged("SourceArrowSymbol");
165
+                }
166
+            }
167
+        }
168
+
169
+        public ArrowSymbol sinkArrowSymbol = ArrowSymbol.Arrow;
170
+        public ArrowSymbol SinkArrowSymbol
171
+        {
172
+            get { return sinkArrowSymbol; }
173
+            set
174
+            {
175
+                if (sinkArrowSymbol != value)
176
+                {
177
+                    sinkArrowSymbol = value;
178
+                    OnPropertyChanged("SinkArrowSymbol");
179
+                }
180
+            }
181
+        }
182
+
183
+        // specifies a point at half path length
184
+        private Point labelPosition;
185
+        public Point LabelPosition
186
+        {
187
+            get { return labelPosition; }
188
+            set
189
+            {
190
+                if (labelPosition != value)
191
+                {
192
+                    labelPosition = value;
193
+                    OnPropertyChanged("LabelPosition");
194
+                }
195
+            }
196
+        }
197
+
198
+        // pattern of dashes and gaps that is used to outline the connection path
199
+        private DoubleCollection strokeDashArray;
200
+        public DoubleCollection StrokeDashArray
201
+        {
202
+            get
203
+            {
204
+                return strokeDashArray;
205
+            }
206
+            set
207
+            {
208
+                if (strokeDashArray != value)
209
+                {
210
+                    strokeDashArray = value;
211
+                    OnPropertyChanged("StrokeDashArray");
212
+                }
213
+            }
214
+        }
215
+
216
+        private string _brach = "";
217
+        /// <summary>
218
+        /// 分支的值
219
+        /// </summary>
220
+        public string Brach
221
+        {
222
+            get
223
+            {
224
+                return _brach;
225
+            }
226
+            set
227
+            {
228
+                if (_brach != value)
229
+                {
230
+                    _brach = value;
231
+                    OnPropertyChanged("Brach");
232
+                }
233
+            }
234
+        }
235
+        // if connected, the ConnectionAdorner becomes visible
236
+        private bool isSelected;
237
+        public bool IsSelected
238
+        {
239
+            get { return isSelected; }
240
+            set
241
+            {
242
+                if (isSelected != value)
243
+                {
244
+                    isSelected = value;
245
+                    OnPropertyChanged("IsSelected");
246
+                    if (isSelected)
247
+                        ShowAdorner();
248
+                    else
249
+                        HideAdorner();
250
+                }
251
+            }
252
+        }
253
+
254
+        #endregion
255
+
256
+        public Connection(Connector source, Connector sink,string strContent = "")
257
+        {
258
+            this.Source = source;
259
+            this.Sink = sink;
260
+            Brach = strContent;
261
+            base.Unloaded += new RoutedEventHandler(Connection_Unloaded);
262
+        }
263
+
264
+        protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
265
+        {
266
+            base.OnMouseDown(e);
267
+
268
+            // usual selection business
269
+            DesignerCanvas designer = VisualTreeHelper.GetParent(this) as DesignerCanvas;
270
+            if (designer != null)
271
+                if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None)
272
+                    if (this.IsSelected)
273
+                    {
274
+                        this.IsSelected = false;
275
+                       // designer.SelectedItems.Remove(this);
276
+                    }
277
+                    else
278
+                    {
279
+                        this.IsSelected = true;
280
+                       // designer.SelectedItems.Add(this);
281
+                    }
282
+                else if (!this.IsSelected)
283
+                {
284
+                    foreach (ISelectable item in designer.SelectedItems)
285
+                        item.IsSelected = false;
286
+
287
+                    designer.SelectedItems.Clear();
288
+                    this.IsSelected = true;
289
+                    //designer.SelectedItems.Add(this);
290
+                }
291
+            e.Handled = false;
292
+        }
293
+
294
+        void OnConnectorPositionChanged(object sender, PropertyChangedEventArgs e)
295
+        {
296
+            // whenever the 'Position' property of the source or sink Connector 
297
+            // changes we must update the connection path geometry
298
+            if (e.PropertyName.Equals("Position"))
299
+            {
300
+                UpdatePathGeometry();
301
+            }
302
+        }
303
+
304
+        private void UpdatePathGeometry()
305
+        {
306
+            if (Source != null && Sink != null)
307
+            {
308
+                PathGeometry geometry = new PathGeometry();
309
+                List<Point> linePoints = PathFinder.GetConnectionLine(Source.GetInfo(), Sink.GetInfo(), true);
310
+                if (linePoints.Count > 0)
311
+                {
312
+                    PathFigure figure = new PathFigure();
313
+                    figure.StartPoint = linePoints[0];
314
+                    linePoints.Remove(linePoints[0]);
315
+                    figure.Segments.Add(new PolyLineSegment(linePoints, true));
316
+                    geometry.Figures.Add(figure);
317
+
318
+                    this.PathGeometry = geometry;
319
+                }
320
+            }
321
+        }
322
+
323
+        private void UpdateAnchorPosition()
324
+        {
325
+            Point pathStartPoint, pathTangentAtStartPoint;
326
+            Point pathEndPoint, pathTangentAtEndPoint;
327
+            Point pathMidPoint, pathTangentAtMidPoint;
328
+
329
+            // the PathGeometry.GetPointAtFractionLength method gets the point and a tangent vector 
330
+            // on PathGeometry at the specified fraction of its length
331
+            this.PathGeometry.GetPointAtFractionLength(0, out pathStartPoint, out pathTangentAtStartPoint);
332
+            this.PathGeometry.GetPointAtFractionLength(1, out pathEndPoint, out pathTangentAtEndPoint);
333
+            this.PathGeometry.GetPointAtFractionLength(0.5, out pathMidPoint, out pathTangentAtMidPoint);
334
+
335
+            // get angle from tangent vector
336
+            this.AnchorAngleSource = Math.Atan2(-pathTangentAtStartPoint.Y, -pathTangentAtStartPoint.X) * (180 / Math.PI);
337
+            this.AnchorAngleSink = Math.Atan2(pathTangentAtEndPoint.Y, pathTangentAtEndPoint.X) * (180 / Math.PI);
338
+
339
+            // add some margin on source and sink side for visual reasons only
340
+            pathStartPoint.Offset(-pathTangentAtStartPoint.X * 5, -pathTangentAtStartPoint.Y * 5);
341
+            pathEndPoint.Offset(pathTangentAtEndPoint.X * 5, pathTangentAtEndPoint.Y * 5);
342
+
343
+            this.AnchorPositionSource = pathStartPoint;
344
+            this.AnchorPositionSink = pathEndPoint;
345
+            this.LabelPosition = pathMidPoint;
346
+        }
347
+
348
+        private void ShowAdorner()
349
+        {
350
+            // the ConnectionAdorner is created once for each Connection
351
+            if (this.connectionAdorner == null)
352
+            {
353
+                DesignerCanvas designer = VisualTreeHelper.GetParent(this) as DesignerCanvas;
354
+
355
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(designer);
356
+                if (adornerLayer != null)
357
+                {
358
+                    this.connectionAdorner = new ConnectionAdorner(designer, this);
359
+                    adornerLayer.Add(this.connectionAdorner);
360
+                }
361
+            }
362
+            this.connectionAdorner.Visibility = Visibility.Visible;
363
+        }
364
+
365
+        internal void HideAdorner()
366
+        {
367
+            if (this.connectionAdorner != null)
368
+                this.connectionAdorner.Visibility = Visibility.Collapsed;
369
+        }
370
+
371
+        void Connection_Unloaded(object sender, RoutedEventArgs e)
372
+        {
373
+            // do some housekeeping when Connection is unloaded
374
+
375
+            // remove event handler
376
+            source.PropertyChanged -= new PropertyChangedEventHandler(OnConnectorPositionChanged);
377
+            sink.PropertyChanged -= new PropertyChangedEventHandler(OnConnectorPositionChanged);
378
+
379
+            // remove adorner
380
+            if (this.connectionAdorner != null)
381
+            {
382
+                DesignerCanvas designer = VisualTreeHelper.GetParent(this) as DesignerCanvas;
383
+
384
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(designer);
385
+                if (adornerLayer != null)
386
+                {
387
+                    adornerLayer.Remove(this.connectionAdorner);
388
+                    this.connectionAdorner = null;
389
+                }
390
+            }
391
+        }
392
+
393
+        #region INotifyPropertyChanged Members
394
+
395
+        // we could use DependencyProperties as well to inform others of property changes
396
+        public event PropertyChangedEventHandler PropertyChanged;
397
+
398
+        protected void OnPropertyChanged(string name)
399
+        {
400
+            PropertyChangedEventHandler handler = PropertyChanged;
401
+            if (handler != null)
402
+            {
403
+                handler(this, new PropertyChangedEventArgs(name));
404
+            }
405
+        }
406
+
407
+        #endregion
408
+    }
409
+
410
+    public enum ArrowSymbol
411
+    {
412
+        None,
413
+        Arrow,
414
+        Diamond
415
+    }
416
+}

+ 254
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connection.ts 查看文件

@@ -0,0 +1,254 @@
1
+import { reactive, ref, computed } from 'vue'
2
+import type { Connector } from './Connector'
3
+import { PathFinder } from './PathFinder'
4
+
5
+export enum ArrowSymbol {
6
+    None = 0,
7
+    Arrow = 1,
8
+    Diamond = 2
9
+}
10
+
11
+export class Connection {
12
+    private _source: Connector | null = null
13
+    private _sink: Connector | null = null
14
+    private _pathGeometry: any = null
15
+    private _anchorPositionSource = { x: 0, y: 0 }
16
+    private _anchorAngleSource = 0
17
+    private _anchorPositionSink = { x: 0, y: 0 }
18
+    private _anchorAngleSink = 0
19
+    private _sourceArrowSymbol = ArrowSymbol.None
20
+    private _sinkArrowSymbol = ArrowSymbol.Arrow
21
+    private _labelPosition = { x: 0, y: 0 }
22
+    private _strokeDashArray: number[] = []
23
+    private _brach = ""
24
+    private _isSelected = false
25
+    private _connectionAdorner: any = null
26
+
27
+    get source(): Connector | null {
28
+        return this._source
29
+    }
30
+    set source(value: Connector | null) {
31
+        if (this._source !== value) {
32
+            if (this._source) {
33
+                this._source.onPositionChanged.unsubscribe(this.onConnectorPositionChanged)
34
+                this._source.connections.delete(this)
35
+            }
36
+
37
+            this._source = value
38
+
39
+            if (this._source) {
40
+                this._source.connections.add(this)
41
+                this._source.onPositionChanged.subscribe(this.onConnectorPositionChanged)
42
+            }
43
+
44
+            this.updatePathGeometry()
45
+        }
46
+    }
47
+
48
+    get sink(): Connector | null {
49
+        return this._sink
50
+    }
51
+    set sink(value: Connector | null) {
52
+        if (this._sink !== value) {
53
+            if (this._sink) {
54
+                this._sink.onPositionChanged.unsubscribe(this.onConnectorPositionChanged)
55
+                this._sink.connections.delete(this)
56
+            }
57
+
58
+            this._sink = value
59
+
60
+            if (this._sink) {
61
+                this._sink.connections.add(this)
62
+                this._sink.onPositionChanged.subscribe(this.onConnectorPositionChanged)
63
+            }
64
+
65
+            this.updatePathGeometry()
66
+        }
67
+    }
68
+
69
+    get pathGeometry(): any {
70
+        return this._pathGeometry
71
+    }
72
+    set pathGeometry(value: any) {
73
+        if (this._pathGeometry !== value) {
74
+            this._pathGeometry = value
75
+            this.updateAnchorPosition()
76
+        }
77
+    }
78
+
79
+    get anchorPositionSource(): { x: number, y: number } {
80
+        return this._anchorPositionSource
81
+    }
82
+    set anchorPositionSource(value: { x: number, y: number }) {
83
+        if (this._anchorPositionSource.x !== value.x || this._anchorPositionSource.y !== value.y) {
84
+            this._anchorPositionSource = value
85
+        }
86
+    }
87
+
88
+    get anchorAngleSource(): number {
89
+        return this._anchorAngleSource
90
+    }
91
+    set anchorAngleSource(value: number) {
92
+        if (this._anchorAngleSource !== value) {
93
+            this._anchorAngleSource = value
94
+        }
95
+    }
96
+
97
+    get anchorPositionSink(): { x: number, y: number } {
98
+        return this._anchorPositionSink
99
+    }
100
+    set anchorPositionSink(value: { x: number, y: number }) {
101
+        if (this._anchorPositionSink.x !== value.x || this._anchorPositionSink.y !== value.y) {
102
+            this._anchorPositionSink = value
103
+        }
104
+    }
105
+
106
+    get anchorAngleSink(): number {
107
+        return this._anchorAngleSink
108
+    }
109
+    set anchorAngleSink(value: number) {
110
+        if (this._anchorAngleSink !== value) {
111
+            this._anchorAngleSink = value
112
+        }
113
+    }
114
+
115
+    get sourceArrowSymbol(): ArrowSymbol {
116
+        return this._sourceArrowSymbol
117
+    }
118
+    set sourceArrowSymbol(value: ArrowSymbol) {
119
+        if (this._sourceArrowSymbol !== value) {
120
+            this._sourceArrowSymbol = value
121
+        }
122
+    }
123
+
124
+    get sinkArrowSymbol(): ArrowSymbol {
125
+        return this._sinkArrowSymbol
126
+    }
127
+    set sinkArrowSymbol(value: ArrowSymbol) {
128
+        if (this._sinkArrowSymbol !== value) {
129
+            this._sinkArrowSymbol = value
130
+        }
131
+    }
132
+
133
+    get labelPosition(): { x: number, y: number } {
134
+        return this._labelPosition
135
+    }
136
+    set labelPosition(value: { x: number, y: number }) {
137
+        if (this._labelPosition.x !== value.x || this._labelPosition.y !== value.y) {
138
+            this._labelPosition = value
139
+        }
140
+    }
141
+
142
+    get strokeDashArray(): number[] {
143
+        return this._strokeDashArray
144
+    }
145
+    set strokeDashArray(value: number[]) {
146
+        if (JSON.stringify(this._strokeDashArray) !== JSON.stringify(value)) {
147
+            this._strokeDashArray = value
148
+        }
149
+    }
150
+
151
+    get brach(): string {
152
+        return this._brach
153
+    }
154
+    set brach(value: string) {
155
+        if (this._brach !== value) {
156
+            this._brach = value
157
+        }
158
+    }
159
+
160
+    get isSelected(): boolean {
161
+        return this._isSelected
162
+    }
163
+    set isSelected(value: boolean) {
164
+        if (this._isSelected !== value) {
165
+            this._isSelected = value
166
+            if (this._isSelected) {
167
+                this.showAdorner()
168
+            } else {
169
+                this.hideAdorner()
170
+            }
171
+        }
172
+    }
173
+
174
+    constructor(source: Connector | null, sink: Connector | null, strContent = "") {
175
+        this.source = source
176
+        this.sink = sink
177
+        this.brach = strContent
178
+    }
179
+
180
+    private onConnectorPositionChanged = () => {
181
+        this.updatePathGeometry()
182
+    }
183
+
184
+    private updatePathGeometry(): void {
185
+        if (this.source && this.sink) {
186
+            const linePoints = PathFinder.getConnectionLine(this.source.getInfo(), this.sink.getInfo(), true)
187
+            if (linePoints.length > 0) {
188
+                // 创建路径几何图形
189
+                this.pathGeometry = {
190
+                    startPoint: linePoints[0],
191
+                    segments: linePoints.slice(1)
192
+                }
193
+            }
194
+        }
195
+    }
196
+
197
+    private updateAnchorPosition(): void {
198
+        if (!this.pathGeometry) return
199
+
200
+        // 计算路径起点、中点和终点的位置和切线
201
+        const pathStartPoint = this.pathGeometry.startPoint
202
+        const pathEndPoint = this.pathGeometry.segments[this.pathGeometry.segments.length - 1]
203
+        const pathMidPoint = this.pathGeometry.segments[Math.floor(this.pathGeometry.segments.length / 2)]
204
+
205
+        // 计算角度
206
+        this.anchorAngleSource = Math.atan2(-pathStartPoint.y, -pathStartPoint.x) * (180 / Math.PI)
207
+        this.anchorAngleSink = Math.atan2(pathEndPoint.y, pathEndPoint.x) * (180 / Math.PI)
208
+
209
+        // 添加边距
210
+        pathStartPoint.x -= pathStartPoint.x * 0.1
211
+        pathStartPoint.y -= pathStartPoint.y * 0.1
212
+        pathEndPoint.x += pathEndPoint.x * 0.1
213
+        pathEndPoint.y += pathEndPoint.y * 0.1
214
+
215
+        this.anchorPositionSource = pathStartPoint
216
+        this.anchorPositionSink = pathEndPoint
217
+        this.labelPosition = pathMidPoint
218
+    }
219
+
220
+    private showAdorner(): void {
221
+        if (!this._connectionAdorner) {
222
+            // 创建装饰器
223
+            this._connectionAdorner = {
224
+                visible: true
225
+            }
226
+        }
227
+        this._connectionAdorner.visible = true
228
+    }
229
+
230
+    private hideAdorner(): void {
231
+        if (this._connectionAdorner) {
232
+            this._connectionAdorner.visible = false
233
+        }
234
+    }
235
+
236
+    public dispose(): void {
237
+        if (this.source) {
238
+            this.source.onPositionChanged.unsubscribe(this.onConnectorPositionChanged)
239
+        }
240
+        if (this.sink) {
241
+            this.sink.onPositionChanged.unsubscribe(this.onConnectorPositionChanged)
242
+        }
243
+        this.hideAdorner()
244
+    }
245
+}
246
+
247
+// Vue组合式API封装
248
+export const useConnection = (source: Connector | null, sink: Connector | null, strContent = "") => {
249
+    const connection = reactive(new Connection(source, sink, strContent))
250
+    return {
251
+        connection,
252
+        ArrowSymbol
253
+    }
254
+}

+ 241
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectionAdorner.cs 查看文件

@@ -0,0 +1,241 @@
1
+using System.Collections.Generic;
2
+using System.ComponentModel;
3
+using System.Windows;
4
+using System.Windows.Controls;
5
+using System.Windows.Controls.Primitives;
6
+using System.Windows.Documents;
7
+using System.Windows.Input;
8
+using System.Windows.Media;
9
+
10
+namespace TellerSystem.Controls.Ext.Controls
11
+{
12
+    public class ConnectionAdorner : Adorner
13
+    {
14
+        private DesignerCanvas designerCanvas;
15
+        private Canvas adornerCanvas;
16
+        private Connection connection;
17
+        private PathGeometry pathGeometry;
18
+        private Connector fixConnector, dragConnector;
19
+        private Thumb sourceDragThumb, sinkDragThumb;
20
+        private Pen drawingPen;
21
+
22
+        private DesignerItem hitDesignerItem;
23
+        private DesignerItem HitDesignerItem
24
+        {
25
+            get { return hitDesignerItem; }
26
+            set
27
+            {
28
+                if (hitDesignerItem != value)
29
+                {
30
+                    if (hitDesignerItem != null)
31
+                        hitDesignerItem.IsDragConnectionOver = false;
32
+
33
+                    hitDesignerItem = value;
34
+
35
+                    if (hitDesignerItem != null)
36
+                        hitDesignerItem.IsDragConnectionOver = true;
37
+                }
38
+            }
39
+        }
40
+
41
+        private Connector hitConnector;
42
+        private Connector HitConnector
43
+        {
44
+            get { return hitConnector; }
45
+            set
46
+            {
47
+                if (hitConnector != value)
48
+                {
49
+                    hitConnector = value;
50
+                }
51
+            }
52
+        }
53
+
54
+        private VisualCollection visualChildren;
55
+        protected override int VisualChildrenCount
56
+        {
57
+            get
58
+            {
59
+                return this.visualChildren.Count;
60
+            }
61
+        }
62
+
63
+        protected override Visual GetVisualChild(int index)
64
+        {
65
+            return this.visualChildren[index];
66
+        }
67
+
68
+        public ConnectionAdorner(DesignerCanvas designer, Connection connection)
69
+            : base(designer)
70
+        {
71
+            this.designerCanvas = designer;
72
+            adornerCanvas = new Canvas();
73
+            this.visualChildren = new VisualCollection(this);
74
+            this.visualChildren.Add(adornerCanvas);
75
+
76
+            this.connection = connection;
77
+            this.connection.PropertyChanged += new PropertyChangedEventHandler(AnchorPositionChanged);
78
+
79
+            InitializeDragThumbs();
80
+
81
+            drawingPen = new Pen(Brushes.LightSlateGray, 1);
82
+            drawingPen.LineJoin = PenLineJoin.Round;
83
+        }
84
+
85
+        private void InitializeDragThumbs()
86
+        {
87
+            Style dragThumbStyle = connection.FindResource("ConnectionAdornerThumbStyle") as Style;
88
+
89
+            //source drag thumb
90
+            sourceDragThumb = new Thumb();
91
+            Canvas.SetLeft(sourceDragThumb, connection.AnchorPositionSource.X);
92
+            Canvas.SetTop(sourceDragThumb, connection.AnchorPositionSource.Y);
93
+            this.adornerCanvas.Children.Add(sourceDragThumb);
94
+            if (dragThumbStyle != null)
95
+                sourceDragThumb.Style = dragThumbStyle;
96
+
97
+            sourceDragThumb.DragDelta += new DragDeltaEventHandler(thumbDragThumb_DragDelta);
98
+            sourceDragThumb.DragStarted += new DragStartedEventHandler(thumbDragThumb_DragStarted);
99
+            sourceDragThumb.DragCompleted += new DragCompletedEventHandler(thumbDragThumb_DragCompleted);
100
+
101
+            // sink drag thumb
102
+            sinkDragThumb = new Thumb();
103
+            Canvas.SetLeft(sinkDragThumb, connection.AnchorPositionSink.X);
104
+            Canvas.SetTop(sinkDragThumb, connection.AnchorPositionSink.Y);
105
+            this.adornerCanvas.Children.Add(sinkDragThumb);
106
+            if (dragThumbStyle != null)
107
+                sinkDragThumb.Style = dragThumbStyle;
108
+
109
+            sinkDragThumb.DragDelta += new DragDeltaEventHandler(thumbDragThumb_DragDelta);
110
+            sinkDragThumb.DragStarted += new DragStartedEventHandler(thumbDragThumb_DragStarted);
111
+            sinkDragThumb.DragCompleted += new DragCompletedEventHandler(thumbDragThumb_DragCompleted);
112
+        }
113
+        void AnchorPositionChanged(object sender, PropertyChangedEventArgs e)
114
+        {
115
+            if (e.PropertyName.Equals("AnchorPositionSource"))
116
+            {
117
+                Canvas.SetLeft(sourceDragThumb, connection.AnchorPositionSource.X);
118
+                Canvas.SetTop(sourceDragThumb, connection.AnchorPositionSource.Y);
119
+            }
120
+
121
+            if (e.PropertyName.Equals("AnchorPositionSink"))
122
+            {
123
+                Canvas.SetLeft(sinkDragThumb, connection.AnchorPositionSink.X);
124
+                Canvas.SetTop(sinkDragThumb, connection.AnchorPositionSink.Y);
125
+            }
126
+        }
127
+
128
+        void thumbDragThumb_DragCompleted(object sender, DragCompletedEventArgs e)
129
+        {
130
+            if (HitConnector != null)
131
+            {
132
+                if (connection != null)
133
+                {
134
+                    if (connection.Source == fixConnector)
135
+                        connection.Sink = this.HitConnector;
136
+                    else
137
+                        connection.Source = this.HitConnector;
138
+                }
139
+            }
140
+
141
+            this.HitDesignerItem = null;
142
+            this.HitConnector = null;
143
+            this.pathGeometry = null;
144
+            this.connection.StrokeDashArray = null;
145
+            this.InvalidateVisual();
146
+        }
147
+
148
+        void thumbDragThumb_DragStarted(object sender, DragStartedEventArgs e)
149
+        {
150
+            this.HitDesignerItem = null;
151
+            this.HitConnector = null;
152
+            this.pathGeometry = null;
153
+            this.Cursor = Cursors.Cross;
154
+            this.connection.StrokeDashArray = new DoubleCollection(new double[] { 1, 2 });
155
+
156
+            if (sender == sourceDragThumb)
157
+            {
158
+                fixConnector = connection.Sink;
159
+                dragConnector = connection.Source;
160
+            }
161
+            else if (sender == sinkDragThumb)
162
+            {
163
+                dragConnector = connection.Sink;
164
+                fixConnector = connection.Source;
165
+            }
166
+        }
167
+
168
+        void thumbDragThumb_DragDelta(object sender, DragDeltaEventArgs e)
169
+        {
170
+            Point currentPosition = Mouse.GetPosition(this);
171
+            this.HitTesting(currentPosition);
172
+            this.pathGeometry = UpdatePathGeometry(currentPosition);
173
+            this.InvalidateVisual();
174
+        }
175
+
176
+        protected override void OnRender(DrawingContext dc)
177
+        {
178
+            base.OnRender(dc);
179
+            dc.DrawGeometry(null, drawingPen, this.pathGeometry);
180
+        }
181
+
182
+        protected override Size ArrangeOverride(Size finalSize)
183
+        {
184
+            adornerCanvas.Arrange(new Rect(0, 0, this.designerCanvas.ActualWidth, this.designerCanvas.ActualHeight));
185
+            return finalSize;
186
+        }
187
+
188
+        private PathGeometry UpdatePathGeometry(Point position)
189
+        {
190
+            PathGeometry geometry = new PathGeometry();
191
+
192
+            ConnectorOrientation targetOrientation;
193
+            if (HitConnector != null)
194
+                targetOrientation = HitConnector.Orientation;
195
+            else
196
+                targetOrientation = dragConnector.Orientation;
197
+
198
+            List<Point> linePoints = PathFinder.GetConnectionLine(fixConnector.GetInfo(), position, targetOrientation);
199
+
200
+            if (linePoints.Count > 0)
201
+            {
202
+                PathFigure figure = new PathFigure();
203
+                figure.StartPoint = linePoints[0];
204
+                linePoints.Remove(linePoints[0]);
205
+                figure.Segments.Add(new PolyLineSegment(linePoints, true));
206
+                geometry.Figures.Add(figure);
207
+            }
208
+
209
+            return geometry;
210
+        }
211
+
212
+        private void HitTesting(Point hitPoint)
213
+        {
214
+            bool hitConnectorFlag = false;
215
+
216
+            DependencyObject hitObject = designerCanvas.InputHitTest(hitPoint) as DependencyObject;
217
+            while (hitObject != null &&
218
+                   hitObject != fixConnector.ParentDesignerItem &&
219
+                   hitObject.GetType() != typeof(DesignerCanvas))
220
+            {
221
+                if (hitObject is Connector)
222
+                {
223
+                    HitConnector = hitObject as Connector;
224
+                    hitConnectorFlag = true;
225
+                }
226
+
227
+                if (hitObject is DesignerItem)
228
+                {
229
+                    HitDesignerItem = hitObject as DesignerItem;
230
+                    if (!hitConnectorFlag)
231
+                        HitConnector = null;
232
+                    return;
233
+                }
234
+                hitObject = VisualTreeHelper.GetParent(hitObject);
235
+            }
236
+
237
+            HitConnector = null;
238
+            HitDesignerItem = null;
239
+        }
240
+    }
241
+}

+ 162
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectionAdorner.ts 查看文件

@@ -0,0 +1,162 @@
1
+import { reactive, ref, onMounted, onUnmounted } from 'vue'
2
+import type { Connection } from './Connection'
3
+import type { DesignerCanvas } from './DesignerCanvas'
4
+import type { Connector } from './Connector'
5
+import type { DesignerItem } from './DesignerItem'
6
+import { PathFinder } from './PathFinder'
7
+
8
+export class ConnectionAdorner {
9
+    private designerCanvas: DesignerCanvas
10
+    private connection: Connection
11
+    private pathGeometry: any = null
12
+    private fixConnector: Connector | null = null
13
+    private dragConnector: Connector | null = null
14
+    private hitDesignerItem: DesignerItem | null = null
15
+    private hitConnector: Connector | null = null
16
+    private isVisible = false
17
+
18
+    constructor(designerCanvas: DesignerCanvas, connection: Connection) {
19
+        this.designerCanvas = designerCanvas
20
+        this.connection = connection
21
+        this.connection.onAnchorPositionChanged(this.onAnchorPositionChanged)
22
+        this.initDragHandlers()
23
+    }
24
+
25
+    private onAnchorPositionChanged = (propertyName: string) => {
26
+        if (!this.isVisible) return
27
+        
28
+        if (propertyName === 'AnchorPositionSource') {
29
+            this.updateSourceThumbPosition()
30
+        } else if (propertyName === 'AnchorPositionSink') {
31
+            this.updateSinkThumbPosition()
32
+        }
33
+    }
34
+
35
+    private initDragHandlers() {
36
+        // 初始化拖拽处理逻辑
37
+        this.designerCanvas.onDragStart(this.onDragStart)
38
+        this.designerCanvas.onDrag(this.onDrag)
39
+        this.designerCanvas.onDragEnd(this.onDragEnd)
40
+    }
41
+
42
+    private onDragStart = (event: MouseEvent, thumbType: 'source' | 'sink') => {
43
+        this.isVisible = true
44
+        this.hitDesignerItem = null
45
+        this.hitConnector = null
46
+        this.pathGeometry = null
47
+        this.connection.strokeDashArray = [1, 2]
48
+
49
+        if (thumbType === 'source') {
50
+            this.fixConnector = this.connection.sink
51
+            this.dragConnector = this.connection.source
52
+        } else {
53
+            this.dragConnector = this.connection.sink
54
+            this.fixConnector = this.connection.source
55
+        }
56
+    }
57
+
58
+    private onDrag = (event: MouseEvent) => {
59
+        if (!this.isVisible) return
60
+        
61
+        const position = { x: event.clientX, y: event.clientY }
62
+        this.hitTesting(position)
63
+        this.pathGeometry = this.updatePathGeometry(position)
64
+    }
65
+
66
+    private onDragEnd = (event: MouseEvent) => {
67
+        if (!this.isVisible) return
68
+        
69
+        if (this.hitConnector) {
70
+            if (this.connection.source === this.fixConnector) {
71
+                this.connection.sink = this.hitConnector
72
+            } else {
73
+                this.connection.source = this.hitConnector
74
+            }
75
+        }
76
+
77
+        this.hitDesignerItem = null
78
+        this.hitConnector = null
79
+        this.pathGeometry = null
80
+        this.connection.strokeDashArray = []
81
+        this.isVisible = false
82
+    }
83
+
84
+    private hitTesting(position: { x: number, y: number }) {
85
+        let hitConnectorFlag = false
86
+        const hitElement = this.designerCanvas.getElementFromPoint(position)
87
+
88
+        // 模拟WPF的视觉树遍历
89
+        let current = hitElement
90
+        while (current) {
91
+            if (current.isConnector) {
92
+                this.hitConnector = current as Connector
93
+                hitConnectorFlag = true
94
+            }
95
+
96
+            if (current.isDesignerItem) {
97
+                this.hitDesignerItem = current as DesignerItem
98
+                if (!hitConnectorFlag) {
99
+                    this.hitConnector = null
100
+                }
101
+                return
102
+            }
103
+
104
+            current = current.parentElement
105
+        }
106
+
107
+        this.hitConnector = null
108
+        this.hitDesignerItem = null
109
+    }
110
+
111
+    private updatePathGeometry(position: { x: number, y: number }): any {
112
+        if (!this.fixConnector) return null
113
+
114
+        const targetOrientation = this.hitConnector 
115
+            ? this.hitConnector.orientation 
116
+            : (this.dragConnector?.orientation || 'Right')
117
+
118
+        const linePoints = PathFinder.getConnectionLine(
119
+            this.fixConnector.getInfo(),
120
+            position,
121
+            targetOrientation
122
+        )
123
+
124
+        if (linePoints.length > 0) {
125
+            return {
126
+                startPoint: linePoints[0],
127
+                segments: linePoints.slice(1)
128
+            }
129
+        }
130
+        return null
131
+    }
132
+
133
+    private updateSourceThumbPosition() {
134
+        if (!this.isVisible) return
135
+        // 更新源点拖拽thumb位置
136
+    }
137
+
138
+    private updateSinkThumbPosition() {
139
+        if (!this.isVisible) return
140
+        // 更新目标点拖拽thumb位置
141
+    }
142
+
143
+    public dispose() {
144
+        this.designerCanvas.offDragStart(this.onDragStart)
145
+        this.designerCanvas.offDrag(this.onDrag)
146
+        this.designerCanvas.offDragEnd(this.onDragEnd)
147
+        this.connection.offAnchorPositionChanged(this.onAnchorPositionChanged)
148
+    }
149
+}
150
+
151
+// Vue组合式API封装
152
+export const useConnectionAdorner = (designerCanvas: DesignerCanvas, connection: Connection) => {
153
+    const adorner = reactive(new ConnectionAdorner(designerCanvas, connection))
154
+    
155
+    onUnmounted(() => {
156
+        adorner.dispose()
157
+    })
158
+
159
+    return {
160
+        adorner
161
+    }
162
+}

+ 174
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connector.cs 查看文件

@@ -0,0 +1,174 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.ComponentModel;
4
+using System.Windows;
5
+using System.Windows.Controls;
6
+using System.Windows.Documents;
7
+using System.Windows.Input;
8
+using System.Windows.Media;
9
+
10
+namespace TellerSystem.Controls.Ext.Controls
11
+{
12
+    public class Connector : Control, INotifyPropertyChanged
13
+    {
14
+        // drag start point, relative to the DesignerCanvas
15
+        private Point? dragStartPoint = null;
16
+
17
+        public ConnectorOrientation Orientation { get; set; }
18
+
19
+        // center position of this Connector relative to the DesignerCanvas
20
+        private Point position;
21
+        public Point Position
22
+        {
23
+            get { return position; }
24
+            set
25
+            {
26
+                if (position != value)
27
+                {
28
+                    position = value;
29
+                    OnPropertyChanged("Position");
30
+                }
31
+            }
32
+        }
33
+
34
+        // the DesignerItem this Connector belongs to;
35
+        // retrieved from DataContext, which is set in the
36
+        // DesignerItem template
37
+        private DesignerItem parentDesignerItem;
38
+        public DesignerItem ParentDesignerItem
39
+        {
40
+            get
41
+            {
42
+                if (parentDesignerItem == null)
43
+                    parentDesignerItem = this.DataContext as DesignerItem;
44
+
45
+                return parentDesignerItem;
46
+            }
47
+        }
48
+
49
+        // keep track of connections that link to this connector
50
+        private List<Connection> connections;
51
+        public List<Connection> Connections
52
+        {
53
+            get
54
+            {
55
+                if (connections == null)
56
+                    connections = new List<Connection>();
57
+                return connections;
58
+            }
59
+        }
60
+
61
+        public Connector()
62
+        {
63
+            // fired when layout changes
64
+            base.LayoutUpdated += new EventHandler(Connector_LayoutUpdated);
65
+        }
66
+
67
+        // when the layout changes we update the position property
68
+        void Connector_LayoutUpdated(object sender, EventArgs e)
69
+        {
70
+            DesignerCanvas designer = GetDesignerCanvas(this);
71
+            if (designer != null)
72
+            {
73
+                //get centre position of this Connector relative to the DesignerCanvas
74
+                this.Position = this.TransformToAncestor(designer).Transform(new Point(this.Width / 2, this.Height / 2));
75
+            }
76
+        }
77
+
78
+        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
79
+        {
80
+            base.OnMouseLeftButtonDown(e);
81
+            DesignerCanvas canvas = GetDesignerCanvas(this);
82
+            if (canvas != null)
83
+            {
84
+                // position relative to DesignerCanvas
85
+                this.dragStartPoint = new Point?(e.GetPosition(canvas));
86
+                e.Handled = true;
87
+            }
88
+        }
89
+
90
+        protected override void OnMouseMove(MouseEventArgs e)
91
+        {
92
+            base.OnMouseMove(e);
93
+
94
+            // if mouse button is not pressed we have no drag operation, ...
95
+            if (e.LeftButton != MouseButtonState.Pressed)
96
+                this.dragStartPoint = null;
97
+
98
+            // but if mouse button is pressed and start point value is set we do have one
99
+            if (this.dragStartPoint.HasValue)
100
+            {
101
+                // create connection adorner 
102
+                DesignerCanvas canvas = GetDesignerCanvas(this);
103
+                if (canvas != null)
104
+                {
105
+                    AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(canvas);
106
+                    if (adornerLayer != null)
107
+                    {
108
+                        ConnectorAdorner adorner = new ConnectorAdorner(canvas, this);
109
+                        if (adorner != null)
110
+                        {
111
+                            adornerLayer.Add(adorner);
112
+                            e.Handled = true;
113
+                        }
114
+                    }
115
+                }
116
+            }
117
+        }
118
+
119
+        internal ConnectorInfo GetInfo()
120
+        {
121
+            ConnectorInfo info = new ConnectorInfo();
122
+            info.DesignerItemLeft = DesignerCanvas.GetLeft(this.ParentDesignerItem);
123
+            info.DesignerItemTop = DesignerCanvas.GetTop(this.ParentDesignerItem);
124
+            info.DesignerItemSize = new Size(this.ParentDesignerItem.ActualWidth, this.ParentDesignerItem.ActualHeight);
125
+            info.Orientation = this.Orientation;
126
+            info.Position = this.Position;
127
+            return info;
128
+        }
129
+
130
+        // iterate through visual tree to get parent DesignerCanvas
131
+        private DesignerCanvas GetDesignerCanvas(DependencyObject element)
132
+        {
133
+            while (element != null && !(element is DesignerCanvas))
134
+                element = VisualTreeHelper.GetParent(element);
135
+
136
+            return element as DesignerCanvas;
137
+        }
138
+
139
+        #region INotifyPropertyChanged Members
140
+
141
+        // we could use DependencyProperties as well to inform others of property changes
142
+        public event PropertyChangedEventHandler PropertyChanged;
143
+        protected void OnPropertyChanged(string name)
144
+        {
145
+            PropertyChangedEventHandler handler = PropertyChanged;
146
+            if (handler != null)
147
+            {
148
+                handler(this, new PropertyChangedEventArgs(name));
149
+            }
150
+        }
151
+
152
+        #endregion
153
+    }
154
+
155
+    // provides compact info about a connector; used for the 
156
+    // routing algorithm, instead of hand over a full fledged Connector
157
+    internal struct ConnectorInfo
158
+    {
159
+        public double DesignerItemLeft { get; set; }
160
+        public double DesignerItemTop { get; set; }
161
+        public Size DesignerItemSize { get; set; }
162
+        public Point Position { get; set; }
163
+        public ConnectorOrientation Orientation { get; set; }
164
+    }
165
+
166
+    public enum ConnectorOrientation
167
+    {
168
+        None,
169
+        Left,
170
+        Top,
171
+        Right,
172
+        Bottom
173
+    }
174
+}

+ 192
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Connector.ts 查看文件

@@ -0,0 +1,192 @@
1
+import { reactive, ref, onMounted, onUnmounted } from 'vue'
2
+import type { DesignerCanvas } from './DesignerCanvas'
3
+import type { DesignerItem } from './DesignerItem'
4
+import type { Connection } from './Connection'
5
+
6
+export enum ConnectorOrientation {
7
+    None = 'None',
8
+    Left = 'Left',
9
+    Top = 'Top',
10
+    Right = 'Right',
11
+    Bottom = 'Bottom'
12
+}
13
+
14
+export interface ConnectorInfo {
15
+    designerItemLeft: number
16
+    designerItemTop: number
17
+    designerItemSize: { width: number, height: number }
18
+    position: { x: number, y: number }
19
+    orientation: ConnectorOrientation
20
+}
21
+
22
+export class Connector {
23
+    private _dragStartPoint: { x: number, y: number } | null = null
24
+    private _orientation: ConnectorOrientation = ConnectorOrientation.None
25
+    private _position = { x: 0, y: 0 }
26
+    private _parentDesignerItem: DesignerItem | null = null
27
+    private _connections: Set<Connection> = new Set()
28
+    private _isActive = false
29
+
30
+    get orientation(): ConnectorOrientation {
31
+        return this._orientation
32
+    }
33
+    set orientation(value: ConnectorOrientation) {
34
+        if (this._orientation !== value) {
35
+            this._orientation = value
36
+            this.onPropertyChanged('Orientation')
37
+        }
38
+    }
39
+
40
+    get position(): { x: number, y: number } {
41
+        return this._position
42
+    }
43
+    set position(value: { x: number, y: number }) {
44
+        if (this._position.x !== value.x || this._position.y !== value.y) {
45
+            this._position = value
46
+            this.onPropertyChanged('Position')
47
+        }
48
+    }
49
+
50
+    get parentDesignerItem(): DesignerItem | null {
51
+        if (!this._parentDesignerItem) {
52
+            // 从Vue上下文获取父设计器项
53
+            this._parentDesignerItem = this.getParentDesignerItem()
54
+        }
55
+        return this._parentDesignerItem
56
+    }
57
+
58
+    get connections(): Connection[] {
59
+        return Array.from(this._connections)
60
+    }
61
+
62
+    constructor(orientation: ConnectorOrientation = ConnectorOrientation.None) {
63
+        this._orientation = orientation
64
+    }
65
+
66
+    // 布局更新时重新计算位置
67
+    public updatePosition() {
68
+        const designer = this.getDesignerCanvas()
69
+        if (designer && this.parentDesignerItem) {
70
+            // 计算相对于设计器画布的中心位置
71
+            const itemPos = designer.getItemPosition(this.parentDesignerItem)
72
+            const itemSize = this.parentDesignerItem.size
73
+            
74
+            let x = itemPos.x
75
+            let y = itemPos.y
76
+            
77
+            // 根据方向计算连接点位置
78
+            switch (this._orientation) {
79
+                case ConnectorOrientation.Left:
80
+                    x = itemPos.x
81
+                    y = itemPos.y + itemSize.height / 2
82
+                    break
83
+                case ConnectorOrientation.Top:
84
+                    x = itemPos.x + itemSize.width / 2
85
+                    y = itemPos.y
86
+                    break
87
+                case ConnectorOrientation.Right:
88
+                    x = itemPos.x + itemSize.width
89
+                    y = itemPos.y + itemSize.height / 2
90
+                    break
91
+                case ConnectorOrientation.Bottom:
92
+                    x = itemPos.x + itemSize.width / 2
93
+                    y = itemPos.y + itemSize.height
94
+                    break
95
+                default: // Center
96
+                    x = itemPos.x + itemSize.width / 2
97
+                    y = itemPos.y + itemSize.height / 2
98
+            }
99
+            
100
+            this.position = { x, y }
101
+        }
102
+    }
103
+
104
+    // 鼠标按下事件处理
105
+    public onMouseDown(event: MouseEvent) {
106
+        const canvas = this.getDesignerCanvas()
107
+        if (canvas) {
108
+            this._dragStartPoint = {
109
+                x: event.clientX - canvas.position.x,
110
+                y: event.clientY - canvas.position.y
111
+            }
112
+            this._isActive = true
113
+        }
114
+    }
115
+
116
+    // 鼠标移动事件处理
117
+    public onMouseMove(event: MouseEvent) {
118
+        if (!this._isActive || !this._dragStartPoint) return
119
+
120
+        const canvas = this.getDesignerCanvas()
121
+        if (canvas) {
122
+            // 创建连接装饰器
123
+            canvas.showConnectorAdorner(this)
124
+        }
125
+    }
126
+
127
+    // 鼠标释放事件处理
128
+    public onMouseUp() {
129
+        this._isActive = false
130
+        this._dragStartPoint = null
131
+    }
132
+
133
+    // 添加连接
134
+    public addConnection(connection: Connection) {
135
+        this._connections.add(connection)
136
+    }
137
+
138
+    // 移除连接
139
+    public removeConnection(connection: Connection) {
140
+        this._connections.delete(connection)
141
+    }
142
+
143
+    // 获取连接点信息
144
+    public getInfo(): ConnectorInfo {
145
+        if (!this.parentDesignerItem) {
146
+            throw new Error('Parent designer item not found')
147
+        }
148
+
149
+        return {
150
+            designerItemLeft: this.parentDesignerItem.position.x,
151
+            designerItemTop: this.parentDesignerItem.position.y,
152
+            designerItemSize: {
153
+                width: this.parentDesignerItem.size.width,
154
+                height: this.parentDesignerItem.size.height
155
+            },
156
+            position: this.position,
157
+            orientation: this.orientation
158
+        }
159
+    }
160
+
161
+    // 获取父设计器画布
162
+    private getDesignerCanvas(): DesignerCanvas | null {
163
+        // 在实际实现中需要遍历DOM树查找
164
+        return null
165
+    }
166
+
167
+    // 获取父设计器项
168
+    private getParentDesignerItem(): DesignerItem | null {
169
+        // 在实际实现中需要从Vue上下文中获取
170
+        return null
171
+    }
172
+
173
+    // 属性变更通知
174
+    private onPropertyChanged(propertyName: string) {
175
+        // 通知Vue响应式系统
176
+        // 在实际实现中需要触发事件或调用回调
177
+    }
178
+}
179
+
180
+// Vue组合式API封装
181
+export const useConnector = (orientation: ConnectorOrientation = ConnectorOrientation.None) => {
182
+    const connector = reactive(new Connector(orientation))
183
+    
184
+    onMounted(() => {
185
+        connector.updatePosition()
186
+    })
187
+
188
+    return {
189
+        connector,
190
+        ConnectorOrientation
191
+    }
192
+}

+ 162
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorAdorner.cs 查看文件

@@ -0,0 +1,162 @@
1
+using System.Collections.Generic;
2
+using System.Windows;
3
+using System.Windows.Documents;
4
+using System.Windows.Input;
5
+using System.Windows.Media;
6
+
7
+namespace TellerSystem.Controls.Ext.Controls
8
+{
9
+    public class ConnectorAdorner : Adorner
10
+    {
11
+        private PathGeometry pathGeometry;
12
+        private DesignerCanvas designerCanvas;
13
+        private Connector sourceConnector;
14
+        private Pen drawingPen;
15
+
16
+        private DesignerItem hitDesignerItem;
17
+        private DesignerItem HitDesignerItem
18
+        {
19
+            get { return hitDesignerItem; }
20
+            set
21
+            {
22
+                if (hitDesignerItem != value)
23
+                {
24
+                    if (hitDesignerItem != null)
25
+                        hitDesignerItem.IsDragConnectionOver = false;
26
+
27
+                    hitDesignerItem = value;
28
+
29
+                    if (hitDesignerItem != null)
30
+                        hitDesignerItem.IsDragConnectionOver = true;
31
+                }
32
+            }
33
+        }
34
+
35
+        private Connector hitConnector;
36
+        private Connector HitConnector
37
+        {
38
+            get { return hitConnector; }
39
+            set
40
+            {
41
+                if (hitConnector != value)
42
+                {
43
+                    hitConnector = value;
44
+                }
45
+            }
46
+        }
47
+
48
+        public ConnectorAdorner(DesignerCanvas designer, Connector sourceConnector)
49
+            : base(designer)
50
+        {
51
+            this.designerCanvas = designer;
52
+            this.sourceConnector = sourceConnector;
53
+            drawingPen = new Pen(Brushes.LightSlateGray, 1);
54
+            drawingPen.LineJoin = PenLineJoin.Round;
55
+            this.Cursor = Cursors.Cross;
56
+        }
57
+
58
+        protected override void OnMouseUp(MouseButtonEventArgs e)
59
+        {
60
+            if (HitConnector != null)
61
+            {
62
+                Connector sourceConnector = this.sourceConnector;
63
+                Connector sinkConnector = this.HitConnector;
64
+                Connection newConnection = new Connection(sourceConnector, sinkConnector);
65
+
66
+                // connections are added with z-index of zero
67
+                this.designerCanvas.Children.Insert(0, newConnection);
68
+            }
69
+            if (HitDesignerItem != null)
70
+            {
71
+                this.HitDesignerItem.IsDragConnectionOver = false;
72
+            }
73
+
74
+            if (this.IsMouseCaptured) this.ReleaseMouseCapture();
75
+
76
+            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.designerCanvas);
77
+            if (adornerLayer != null)
78
+            {
79
+                adornerLayer.Remove(this);
80
+            }
81
+        }
82
+
83
+        protected override void OnMouseMove(MouseEventArgs e)
84
+        {
85
+            if (e.LeftButton == MouseButtonState.Pressed)
86
+            {
87
+                if (!this.IsMouseCaptured) this.CaptureMouse();
88
+                HitTesting(e.GetPosition(this));
89
+                this.pathGeometry = GetPathGeometry(e.GetPosition(this));
90
+                this.InvalidateVisual();
91
+            }
92
+            else
93
+            {
94
+                if (this.IsMouseCaptured) this.ReleaseMouseCapture();
95
+            }
96
+        }
97
+
98
+        protected override void OnRender(DrawingContext dc)
99
+        {
100
+            base.OnRender(dc);
101
+            dc.DrawGeometry(null, drawingPen, this.pathGeometry);
102
+
103
+            // without a background the OnMouseMove event would not be fired
104
+            // Alternative: implement a Canvas as a child of this adorner, like
105
+            // the ConnectionAdorner does.
106
+            dc.DrawRectangle(Brushes.Transparent, null, new Rect(RenderSize));
107
+        }
108
+
109
+        private PathGeometry GetPathGeometry(Point position)
110
+        {
111
+            PathGeometry geometry = new PathGeometry();
112
+
113
+            ConnectorOrientation targetOrientation;
114
+            if (HitConnector != null)
115
+                targetOrientation = HitConnector.Orientation;
116
+            else
117
+                targetOrientation = ConnectorOrientation.None;
118
+
119
+            List<Point> pathPoints = PathFinder.GetConnectionLine(sourceConnector.GetInfo(), position, targetOrientation);
120
+
121
+            if (pathPoints.Count > 0)
122
+            {
123
+                PathFigure figure = new PathFigure();
124
+                figure.StartPoint = pathPoints[0];
125
+                pathPoints.Remove(pathPoints[0]);
126
+                figure.Segments.Add(new PolyLineSegment(pathPoints, true));
127
+                geometry.Figures.Add(figure);
128
+            }
129
+
130
+            return geometry;
131
+        }
132
+
133
+        private void HitTesting(Point hitPoint)
134
+        {
135
+            bool hitConnectorFlag = false;
136
+
137
+            DependencyObject hitObject = designerCanvas.InputHitTest(hitPoint) as DependencyObject;
138
+            while (hitObject != null &&
139
+                   hitObject != sourceConnector.ParentDesignerItem &&
140
+                   hitObject.GetType() != typeof(DesignerCanvas))
141
+            {
142
+                if (hitObject is Connector)
143
+                {
144
+                    HitConnector = hitObject as Connector;
145
+                    hitConnectorFlag = true;
146
+                }
147
+
148
+                if (hitObject is DesignerItem)
149
+                {
150
+                    HitDesignerItem = hitObject as DesignerItem;
151
+                    if (!hitConnectorFlag)
152
+                        HitConnector = null;
153
+                    return;
154
+                }
155
+                hitObject = VisualTreeHelper.GetParent(hitObject);
156
+            }
157
+
158
+            HitConnector = null;
159
+            HitDesignerItem = null;
160
+        }
161
+    }
162
+}

+ 142
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorAdorner.ts 查看文件

@@ -0,0 +1,142 @@
1
+import { reactive, onMounted, onUnmounted } from 'vue'
2
+import type { DesignerCanvas } from './DesignerCanvas'
3
+import type { Connector } from './Connector'
4
+import type { DesignerItem } from './DesignerItem'
5
+import type { Connection } from './Connection'
6
+import { PathFinder } from './PathFinder'
7
+
8
+export class ConnectorAdorner {
9
+    private pathGeometry: any = null
10
+    private designerCanvas: DesignerCanvas
11
+    private sourceConnector: Connector
12
+    private hitDesignerItem: DesignerItem | null = null
13
+    private hitConnector: Connector | null = null
14
+    private isActive = false
15
+
16
+    constructor(designerCanvas: DesignerCanvas, sourceConnector: Connector) {
17
+        this.designerCanvas = designerCanvas
18
+        this.sourceConnector = sourceConnector
19
+        this.init()
20
+    }
21
+
22
+    private init() {
23
+        this.designerCanvas.onMouseMove(this.onMouseMove)
24
+        this.designerCanvas.onMouseUp(this.onMouseUp)
25
+    }
26
+
27
+    private onMouseMove = (event: MouseEvent) => {
28
+        if (!this.isActive) return
29
+
30
+        const position = {
31
+            x: event.clientX - this.designerCanvas.position.x,
32
+            y: event.clientY - this.designerCanvas.position.y
33
+        }
34
+
35
+        this.hitTesting(position)
36
+        this.pathGeometry = this.getPathGeometry(position)
37
+        this.designerCanvas.requestRender()
38
+    }
39
+
40
+    private onMouseUp = (event: MouseEvent) => {
41
+        if (!this.isActive) return
42
+
43
+        if (this.hitConnector) {
44
+            const newConnection = new Connection(
45
+                this.sourceConnector,
46
+                this.hitConnector
47
+            )
48
+            this.designerCanvas.addConnection(newConnection)
49
+        }
50
+
51
+        if (this.hitDesignerItem) {
52
+            this.hitDesignerItem.isDragConnectionOver = false
53
+        }
54
+
55
+        this.isActive = false
56
+        this.designerCanvas.hideConnectorAdorner()
57
+    }
58
+
59
+    public activate() {
60
+        this.isActive = true
61
+    }
62
+
63
+    private hitTesting(position: { x: number, y: number }) {
64
+        let hitConnectorFlag = false
65
+        const hitElement = this.designerCanvas.getElementFromPoint(position)
66
+
67
+        let current = hitElement
68
+        while (current) {
69
+            if (current.isConnector) {
70
+                this.hitConnector = current as Connector
71
+                hitConnectorFlag = true
72
+            }
73
+
74
+            if (current.isDesignerItem) {
75
+                this.hitDesignerItem = current as DesignerItem
76
+                if (!hitConnectorFlag) {
77
+                    this.hitConnector = null
78
+                }
79
+                return
80
+            }
81
+
82
+            current = current.parentElement
83
+        }
84
+
85
+        this.hitConnector = null
86
+        this.hitDesignerItem = null
87
+    }
88
+
89
+    private getPathGeometry(position: { x: number, y: number }): any {
90
+        const targetOrientation = this.hitConnector 
91
+            ? this.hitConnector.orientation 
92
+            : 'None'
93
+
94
+        const pathPoints = PathFinder.getConnectionLine(
95
+            this.sourceConnector.getInfo(),
96
+            position,
97
+            targetOrientation
98
+        )
99
+
100
+        if (pathPoints.length > 0) {
101
+            return {
102
+                startPoint: pathPoints[0],
103
+                segments: pathPoints.slice(1)
104
+            }
105
+        }
106
+        return null
107
+    }
108
+
109
+    public render(ctx: CanvasRenderingContext2D) {
110
+        if (!this.pathGeometry) return
111
+
112
+        ctx.beginPath()
113
+        ctx.moveTo(this.pathGeometry.startPoint.x, this.pathGeometry.startPoint.y)
114
+        
115
+        this.pathGeometry.segments.forEach((point: {x: number, y: number}) => {
116
+            ctx.lineTo(point.x, point.y)
117
+        })
118
+
119
+        ctx.strokeStyle = '#778899'
120
+        ctx.lineWidth = 1
121
+        ctx.lineJoin = 'round'
122
+        ctx.stroke()
123
+    }
124
+
125
+    public dispose() {
126
+        this.designerCanvas.offMouseMove(this.onMouseMove)
127
+        this.designerCanvas.offMouseUp(this.onMouseUp)
128
+    }
129
+}
130
+
131
+// Vue组合式API封装
132
+export const useConnectorAdorner = (designerCanvas: DesignerCanvas, sourceConnector: Connector) => {
133
+    const adorner = reactive(new ConnectorAdorner(designerCanvas, sourceConnector))
134
+    
135
+    onUnmounted(() => {
136
+        adorner.dispose()
137
+    })
138
+
139
+    return {
140
+        adorner
141
+    }
142
+}

+ 10
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ConnectorInfo.ts 查看文件

@@ -0,0 +1,10 @@
1
+import { Point } from './GeometryTypes'
2
+import { ConnectorOrientation } from './PathFinder'
3
+
4
+export interface ConnectorInfo {
5
+    designerItemLeft: number
6
+    designerItemTop: number
7
+    designerItemSize: { width: number; height: number }
8
+    position: Point
9
+    orientation: ConnectorOrientation
10
+}

+ 699
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvas.cs 查看文件

@@ -0,0 +1,699 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.IO;
4
+using System.Windows;
5
+using System.Windows.Controls;
6
+using System.Windows.Documents;
7
+using System.Windows.Input;
8
+using System.Windows.Markup;
9
+using System.Xml;
10
+using System.Windows.Media;
11
+using System.Globalization;
12
+using System.Linq;
13
+using Platform.Presentation.FocusCheck;
14
+
15
+namespace TellerSystem.Controls.Ext.Controls
16
+{
17
+    public class DesignerCanvas : Canvas
18
+    {
19
+        //拖拽起始点
20
+        private Point? rubberbandSelectionStartPoint = null;
21
+
22
+        Adorner _preAdorder;
23
+        AdornerLayer _focusAdornerLayer;
24
+        //选中的节点集合
25
+        private List<ISelectable> selectedItems;
26
+        public List<ISelectable> SelectedItems
27
+        {
28
+            get
29
+            {
30
+                if (selectedItems == null)
31
+                    selectedItems = new List<ISelectable>();
32
+                return selectedItems;
33
+            }
34
+            set
35
+            {
36
+                selectedItems = value;
37
+            }
38
+        }
39
+        /// <summary>
40
+        /// 界面元素排序层数
41
+        /// </summary>
42
+        private int m_LayOutCount = 0;
43
+        /// <summary>
44
+        /// 开始节点和结束节点X轴偏移位置
45
+        /// </summary>
46
+        private const float mc_START_X = 20f;
47
+        /// <summary>
48
+        /// 开始节点和结束节点Y轴偏移位置
49
+        /// </summary>
50
+        private const float mc_START_Y = 10f;
51
+        /// <summary>
52
+        /// 相邻元素之间的偏移量
53
+        /// </summary>
54
+        private const float mc_OFFSET_X = 220f;
55
+        /// <summary>
56
+        /// 相邻元素之间的偏移量
57
+        /// </summary>
58
+        private const float mc_OFFSET_Y = 120f;
59
+        /// <summary>
60
+        /// 在界面最左边的节点图形的X坐标
61
+        /// </summary>
62
+        private float m_Leftest_X = float.Epsilon;
63
+        /// <summary>
64
+        /// 开始节点编码
65
+        /// </summary>
66
+        private string startNode = "0";
67
+        /// <summary>
68
+        /// 结束节点编码
69
+        /// </summary>
70
+        private string endNode = "0";
71
+        /// <summary>
72
+        /// 确定位置后的交易节点集合
73
+        /// </summary>
74
+        private List<Tx_Node> m_LstNodes;
75
+        /// <summary>
76
+        /// 交易流程中的结点
77
+        /// </summary>
78
+        private List<Tx_Node> m_Nodes;
79
+        /// <summary>
80
+        /// 交易流程中的所有头结点
81
+        /// </summary>
82
+        private List<Tx_Node> m_LstHeadNode;
83
+        /// <summary>
84
+        /// 交易流程中的线条集合
85
+        /// </summary>
86
+        private List<Tx_Entry> m_LstEntrys;
87
+        /// <summary>
88
+        /// 节点
89
+        /// </summary>
90
+        private object nodeStyle = null;
91
+
92
+        public DesignerCanvas()
93
+        {
94
+            this.AllowDrop = true;
95
+            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this) == true) return;
96
+            ResourceDictionary anmationResource = new ResourceDictionary();
97
+            anmationResource.Source = new Uri("/TellerSystem.Controls.Ext;component/Controls/DiagramDesigner/Resources/NodeControlStyles.xaml", UriKind.RelativeOrAbsolute);
98
+            Application.Current.Resources.MergedDictionaries.Add(anmationResource);
99
+            nodeStyle = Application.Current.Resources["NodeStyle"] as Style;
100
+        }
101
+        /// <summary>
102
+        /// 初始化流程图
103
+        /// </summary>
104
+        /// <param name="flowList"></param>
105
+        public void LoadFlowChat(List<Tx_Node> flowList)
106
+        {
107
+            m_LstNodes = new List<Tx_Node>();
108
+            m_Nodes = new List<Tx_Node>();//交易流程节点集合
109
+            m_LstEntrys = new List<Tx_Entry>();//确定线条集合
110
+            if (flowList == null || flowList.Count() < 1) return;
111
+            int m_MaxFlowCode = flowList.Count() + 1;
112
+            startNode = flowList.Select(x => x.Sub_Code).Min();
113
+            endNode = m_MaxFlowCode.ToString();
114
+            m_Nodes.Add(new Tx_Node(startNode, "", "开始"));
115
+            m_Nodes.Add(new Tx_Node(endNode, "", "结束"));
116
+            LayOut(flowList);//确定布局,初始化数据
117
+            if (m_LstNodes == null) return;
118
+            #region 构造流程节点
119
+            foreach (var node in m_LstNodes)
120
+            {
121
+                Label lbl = new Label { Width = 150, Height = 45, Content = node.Name, Tag = node.Code };
122
+                lbl.Style = nodeStyle as Style;
123
+                DesignerItem item = new DesignerItem(node.Code);
124
+                item.Remark = node.Content;//备注
125
+                item.ErrorInfo = node.ErrInfo;//错误信息  
126
+                switch (node.Stat.ToUpper())
127
+                {
128
+                    case "Z":
129
+                        item.SourceTipSymbol = DesignerItemTip.Error; //失败
130
+                        item.ToolTip = "结账失败";
131
+                        break;
132
+                    case "Y":
133
+                        item.SourceTipSymbol = DesignerItemTip.Success;//成功
134
+                        item.ToolTip = "结账成功";
135
+                        break;
136
+                    case "N":
137
+                        item.SourceTipSymbol = DesignerItemTip.UnHandled;//未处理
138
+                        item.ToolTip = "未处理";
139
+                        break;
140
+                    case "S":
141
+                        item.SourceTipSymbol = DesignerItemTip.None;//正在执行(初始化报错)
142
+                        //if (_focusAdornerLayer == null)
143
+                        //{
144
+                        //    _focusAdornerLayer = AdornerLayer.GetAdornerLayer(item);
145
+                        //}
146
+                        //_preAdorder = new FocusAdorner(item);
147
+                        //_preAdorder.IsClipEnabled = true;
148
+                        //_focusAdornerLayer.Add(_preAdorder);
149
+                        item.ToolTip = "正在执行";
150
+                        break;
151
+                    default:
152
+                        item.SourceTipSymbol = DesignerItemTip.None;
153
+                        break;
154
+                }
155
+                Canvas.SetLeft(item, Double.Parse("10", CultureInfo.InvariantCulture) + node.X);
156
+                Canvas.SetTop(item, Double.Parse("5", CultureInfo.InvariantCulture) + node.Y);
157
+                Canvas.SetZIndex(item, Int32.Parse("0"));
158
+                item.Content = lbl;
159
+                item.ToolTip = node.Content;
160
+                if (!string.IsNullOrEmpty(node.Sub_Code.Trim()))
161
+                    item.IsDragConnectionOver = true;
162
+                this.Children.Add(item);
163
+                ControlTemplate template = DesignerItem.GetConnectorDecoratorTemplate(item) as ControlTemplate;
164
+                DesignerItem.SetConnectorDecoratorTemplate(item, template);
165
+            }
166
+            #endregion
167
+
168
+            #region  构造流程线条
169
+            this.InvalidateVisual();//使元素的呈现无效,并强制执行完整的新布局处理过程。布局循环完成后              
170
+            if (m_LstEntrys == null) return;
171
+            foreach (Tx_Entry entry in m_LstEntrys)
172
+            {
173
+                string sourceID = entry.StartNode;
174
+                string sinkID = entry.EndNode;
175
+                string sourceConnectorName = "ConnectorBottomName";
176
+                string sinkConnectorName = "ConnectorTopName";
177
+                if (!string.IsNullOrEmpty(sinkID) && !string.IsNullOrEmpty(sourceID))
178
+                {
179
+                    String strContent = entry.Condition;
180
+                    Connector sourceConnector = GetConnector(sourceID, sourceConnectorName);
181
+                    Connector sinkConnector = GetConnector(sinkID, sinkConnectorName);
182
+                    Connection connection = new Connection(sourceConnector, sinkConnector, strContent);
183
+                    Canvas.SetZIndex(connection, 5);
184
+                    this.Children.Add(connection);
185
+                }
186
+            }
187
+            #endregion
188
+        }
189
+        /// <summary>
190
+        /// 初始化流程图
191
+        /// </summary>
192
+        /// <param name="flowxml">xml文本</param>
193
+        public void LoadFlowChat(string flowxml)
194
+        {
195
+            var nodeList = new List<Tx_Node>();
196
+            XmlDocument doc = new XmlDocument();
197
+            doc.LoadXml(flowxml);
198
+            var allNodes = doc.SelectSingleNode("Nodes");
199
+            //获取到Nodes所有子节点    
200
+            XmlNodeList childNodeList = allNodes.ChildNodes;
201
+            //遍历所有子节点    
202
+            foreach (XmlNode xmlNode in childNodeList)
203
+            {
204
+                var code = xmlNode.Attributes["batcode"].Value;
205
+                var name = xmlNode.Attributes["batname"].Value;
206
+                var parentcode = xmlNode.Attributes["parentcode"].Value;
207
+                var batdesc = xmlNode.Attributes["batdesc"].Value;
208
+                var batstat = xmlNode.Attributes["batstat"].Value;
209
+                var errinfo = xmlNode.Attributes["errinfo"].Value;
210
+                var batremark = xmlNode.Attributes["batremark"].Value;
211
+                nodeList.Add(new Tx_Node(code, parentcode, name, "", batdesc, batremark, batstat, errinfo));
212
+            }
213
+            this.LoadFlowChat(nodeList);
214
+        }
215
+        /// <summary>
216
+        /// 设置流程节点状态
217
+        /// </summary>
218
+        /// <param name="flowxml">xml文本</param>
219
+        public void SetNodeStat(string flowxml)
220
+        {
221
+            var lstDesigner = this.Children.OfType<ISelectable>();
222
+            XmlDocument doc = new XmlDocument();
223
+            doc.LoadXml(flowxml);
224
+            var allNodes = doc.SelectSingleNode("Nodes");
225
+            //获取到Nodes所有子节点    
226
+            XmlNodeList childNodeList = allNodes.ChildNodes;
227
+            //遍历所有子节点    
228
+            foreach (XmlNode xmlNode in childNodeList)
229
+            {
230
+                var code = xmlNode.Attributes["batcode"].Value;
231
+                var batstat = xmlNode.Attributes["batstat"].Value; //Y-结账成功 Z-正在执行 E-结账失败
232
+
233
+                var errinfo = xmlNode.Attributes["errinfo"].Value;
234
+                var batremark = xmlNode.Attributes["batremark"].Value;
235
+                foreach (DesignerItem item in lstDesigner)
236
+                {
237
+                    if (item.CurrentSerialNumber == code)
238
+                    {
239
+                        item.Remark = batremark;
240
+                        item.ErrorInfo = errinfo;
241
+                        switch (batstat.ToUpper())
242
+                        {
243
+                            case "Z":
244
+                                item.SourceTipSymbol = DesignerItemTip.Error; //失败
245
+                                item.ToolTip = "结账失败";
246
+                                break;
247
+                            case "Y":
248
+                                item.SourceTipSymbol = DesignerItemTip.Success;//成功
249
+                                item.ToolTip = "结账成功";
250
+                                break;
251
+                            case "N":
252
+                                item.SourceTipSymbol = DesignerItemTip.UnHandled;//未处理
253
+                                item.ToolTip = "未处理";
254
+                                break;
255
+                            case "S":
256
+                                item.SourceTipSymbol = DesignerItemTip.None;//正在执行
257
+                                //if (_focusAdornerLayer == null)
258
+                                //{
259
+                                //    _focusAdornerLayer = AdornerLayer.GetAdornerLayer(item);
260
+                                //}
261
+                                //_preAdorder = new FocusAdorner(item);
262
+                                //_preAdorder.IsClipEnabled = true;
263
+                                //_focusAdornerLayer.Add(_preAdorder);
264
+                                item.ToolTip = "正在执行";
265
+                                break;
266
+                            default:
267
+                                item.SourceTipSymbol = DesignerItemTip.None;
268
+                                break;
269
+                        }
270
+                    }
271
+                }
272
+            }
273
+        }
274
+        /// <summary>
275
+        /// 初始化数据 
276
+        /// 确定交易流程节点集合
277
+        /// 确定线条集合
278
+        /// 确定节点位置
279
+        /// </summary>
280
+        internal void LayOut(List<Tx_Node> flowList)
281
+        {
282
+            this.m_LayOutCount = 0; //初始化界面层级数
283
+            foreach (var item in flowList)
284
+            {
285
+                var _s = item.Sub_Code.Split(',');
286
+                _s.ToList().ForEach(k =>
287
+                {
288
+                    Tx_Entry entry = new Tx_Entry(k, item.Code, item.Conditions);
289
+                    m_LstEntrys.Add(entry);
290
+                });
291
+                m_Nodes.Add(item);
292
+            }
293
+            Tx_Node lstNode = FindLstNode(flowList);//查找最后一个节点和结束节点串联
294
+            if (lstNode != null)
295
+                m_LstEntrys.Add(new Tx_Entry(lstNode.Code, endNode, ""));//添加虚拟结束节点
296
+            if (m_Nodes.Count < 1) return;
297
+            var nodes = from n in m_Nodes
298
+                        orderby int.Parse(n.Code) ascending
299
+                        select n;
300
+            Tx_Node firstNode = this.FindFirstNode(startNode.Trim());
301
+            firstNode.X = mc_START_X;
302
+            firstNode.Y = mc_START_Y;
303
+            this.m_LayOutCount++;
304
+            m_LstNodes.Add(firstNode);
305
+            this.LayOut_NextNodes(firstNode);
306
+            m_LstHeadNode = GetHeadNodes();   //查找非起始交易的头节点        
307
+            foreach (Tx_Node nextLayNode in nodes)
308
+            {
309
+                if (m_LstHeadNode != null && m_LstHeadNode.Count() > 0)
310
+                {
311
+                    //非起始子交易的头结点树的分布控制
312
+                    foreach (Tx_Node txNodeHaad in m_LstHeadNode)
313
+                    {
314
+                        if (txNodeHaad.Code == nextLayNode.Code)
315
+                        {
316
+                            txNodeHaad.X = mc_START_X + 100;
317
+                            txNodeHaad.Y = mc_START_Y;
318
+                            this.m_LayOutCount++;
319
+                            m_LstNodes.Add(txNodeHaad);
320
+                            this.LayOut_NextNodes(txNodeHaad);
321
+                        }
322
+                    }
323
+                }
324
+                this.LayOut_NextNodes(nextLayNode);
325
+            }
326
+        }
327
+        /// <summary>
328
+        /// 找出交易流程的所有头结点
329
+        /// </summary>
330
+        /// <returns></returns>
331
+        private List<Tx_Node> GetHeadNodes()
332
+        {
333
+            List<Tx_Node> headNodes = new List<Tx_Node>();
334
+            foreach (Tx_Node node in m_Nodes)
335
+            {
336
+                bool found = false;
337
+                if (node.Code == startNode || node.Code == endNode)
338
+                {
339
+                    continue;
340
+                }
341
+                foreach (Tx_Entry entry in this.m_LstEntrys)
342
+                {
343
+                    if (entry.EndNode == node.Code)
344
+                    {
345
+                        found = true;
346
+                        break;
347
+                    }
348
+                }
349
+                if (!found)
350
+                {
351
+                    headNodes.Add(node);
352
+                }
353
+            }
354
+            return headNodes;
355
+        }
356
+        /// <summary>
357
+        /// 计算一个节点后续节点的位置算法
358
+        /// </summary>
359
+        /// <param name="nodeIndex"></param>
360
+        private void LayOut_NextNodes(Tx_Node node)
361
+        {
362
+            //获取后续节点串
363
+            List<Tx_Node> lstNextNodes = this.FindNextNodes(node);
364
+            //若后续节点串为空或者已布局节点数等于全部节点数,则退出布局
365
+            if (lstNextNodes == null || lstNextNodes.Count == 0)
366
+            {
367
+                return;
368
+            }
369
+            float half = 0f;
370
+            //偶数个节点
371
+            if (lstNextNodes.Count % 2 == 0)
372
+            {
373
+                half = lstNextNodes.Count / 2 - 1f;
374
+            }
375
+            else
376
+            {
377
+                half = lstNextNodes.Count / 2;
378
+            }
379
+            for (int i = 0; i < lstNextNodes.Count; i++)
380
+            {
381
+                //只对还没有定位的,进行定位;并对其后续节点定位
382
+                if (lstNextNodes[i].X == 0 && lstNextNodes[i].Y == 0)
383
+                {
384
+                    lstNextNodes[i].Y = node.Y + mc_OFFSET_Y;
385
+
386
+                    if (lstNextNodes[i].Code != endNode)
387
+                    {
388
+                        lstNextNodes[i].X = node.X + (i - half) * mc_OFFSET_X;
389
+                        if (!string.IsNullOrEmpty(node.Sub_Code))
390
+                        {
391
+                            string[] sub_node = node.Sub_Code.Split(',');
392
+                            for (int y = 0; y < sub_node.Count(); y++)
393
+                            {
394
+                                if (sub_node.Count() <= 1)
395
+                                {
396
+                                    break;
397
+                                }
398
+                                //else
399
+                                //{
400
+                                //    float offset = i - half == 0 ? 1 : i - half;
401
+                                //    lstNextNodes[i].X = node.X + offset * mc_OFFSET_X;
402
+                                //}
403
+                            }
404
+                        }
405
+                    }
406
+                    else
407
+                    {
408
+                        lstNextNodes[i].X = mc_START_X;
409
+                        float MaxY = 0.0f;
410
+                        foreach (var maxNodeY in m_LstNodes)
411
+                        {
412
+                            if (maxNodeY.Y >= MaxY)
413
+                            {
414
+                                MaxY = maxNodeY.Y;
415
+                            }
416
+                        }
417
+                        lstNextNodes[i].Y = MaxY + mc_OFFSET_Y;
418
+                    }
419
+                    m_LstNodes.Add(lstNextNodes[i]);
420
+                    //保存界面最左的图形节点的X坐标值
421
+                    if (lstNextNodes[i].X < m_Leftest_X)
422
+                    {
423
+                        m_Leftest_X = lstNextNodes[i].X;
424
+                    }
425
+                    if (lstNextNodes.Count() == 1)
426
+                    {
427
+                        this.m_LayOutCount++;
428
+                        //递归对后续节点进行布局
429
+                        this.LayOut_NextNodes(lstNextNodes[i]);
430
+                    }
431
+                }
432
+            }
433
+            //递归对后续节点进行布局
434
+            if (lstNextNodes.Count() > 1)
435
+            {
436
+                this.m_LayOutCount++;
437
+            }
438
+        }
439
+        /// <summary>
440
+        /// 找到第一个没有前导节点的节点
441
+        /// </summary>
442
+        /// <returns></returns>
443
+        private Tx_Node FindFirstNode(string code)
444
+        {
445
+            if (string.IsNullOrEmpty(code))
446
+                return null;
447
+            foreach (Tx_Node node in this.m_Nodes)
448
+            {
449
+                if (node.Code == code.Trim())
450
+                    return node;
451
+            }
452
+            return null;
453
+        }
454
+        /// <summary>
455
+        /// 找到节点序列中最后一个节点
456
+        /// </summary>
457
+        /// <param name="flowList"></param>
458
+        /// <returns></returns>
459
+        private Tx_Node FindLstNode(List<Tx_Node> flowList)
460
+        {
461
+            if (flowList == null)
462
+                return null;
463
+            foreach (Tx_Node node in flowList)
464
+            {
465
+                bool isExist = false;
466
+                foreach (Tx_Node subnode in flowList)
467
+                {
468
+                    var _s = subnode.Sub_Code.Split(',');
469
+                    if (_s.Contains(node.Code))
470
+                    {
471
+                        isExist = true;
472
+                        break;
473
+                    }
474
+                }
475
+                if (!isExist)
476
+                {
477
+                    return node;
478
+                }
479
+            }
480
+            return null;
481
+        }
482
+        /// <summary>
483
+        /// 查找指定节点的后续节点
484
+        /// </summary>
485
+        /// <param name="nodeIndex"></param>
486
+        /// <returns></returns>
487
+        private List<Tx_Node> FindNextNodes(Tx_Node node)
488
+        {
489
+            List<Tx_Node> lstNextNodes = new List<Tx_Node>();
490
+            //根据线条查找后续节点串
491
+            foreach (Tx_Entry entry in this.m_LstEntrys)
492
+            {
493
+                if (entry.StartNode == node.Code)
494
+                {
495
+                    foreach (var nodes in m_Nodes)
496
+                    {
497
+                        if (nodes.Code == entry.EndNode)
498
+                        {
499
+                            lstNextNodes.Add(nodes);
500
+                        }
501
+                    }
502
+                }
503
+            }
504
+            return lstNextNodes;
505
+        }
506
+        /// <summary>
507
+        /// 查找指定节点的前导节点
508
+        /// </summary>
509
+        /// <param name="node"></param>
510
+        /// <returns></returns>
511
+        private List<Tx_Node> FindPreNodes(Tx_Node node)
512
+        {
513
+            string subtxCode = "";
514
+            List<Tx_Node> lstPreNodes = new List<Tx_Node>();
515
+            //根据线条查找后续节点串
516
+            foreach (Tx_Node entry in this.m_Nodes)
517
+            {
518
+                if (entry.Code == node.Code)
519
+                {
520
+                    subtxCode = node.Code;
521
+                    foreach (Tx_Node lstentry in this.m_LstNodes)
522
+                    {
523
+                        if (lstentry.Sub_Code == subtxCode)
524
+                        {
525
+                            lstPreNodes.Add(lstentry);
526
+                        }
527
+                    }
528
+                }
529
+            }
530
+            return lstPreNodes;
531
+        }
532
+
533
+        private void GetConnectors(DependencyObject parent, List<Connector> connectors)
534
+        {
535
+            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
536
+            for (int i = 0; i < childrenCount; i++)
537
+            {
538
+                DependencyObject child = VisualTreeHelper.GetChild(parent, i);
539
+                if (child is Connector)
540
+                {
541
+                    connectors.Add(child as Connector);
542
+                }
543
+                else
544
+                    GetConnectors(child, connectors);
545
+            }
546
+        }
547
+        private Connector GetConnector(string itemID, String connectorName)
548
+        {
549
+            DesignerItem designerItem = (from item in this.Children.OfType<DesignerItem>()
550
+                                         where item.CurrentSerialNumber == itemID
551
+                                         select item).FirstOrDefault();
552
+            if (designerItem != null)
553
+                designerItem.ApplyTemplate();
554
+            Control connectorDecorator = designerItem.Template.FindName("PART_ConnectorDecorator", designerItem) as Control;
555
+            if (connectorDecorator != null)
556
+                connectorDecorator.ApplyTemplate();
557
+            return connectorDecorator.Template.FindName(connectorName, connectorDecorator) as Connector;
558
+        }
559
+        /// <summary>
560
+        /// 更新设计面板中集合
561
+        /// </summary>
562
+        private void UpdateZIndex()
563
+        {
564
+            List<UIElement> ordered = (from UIElement item in this.Children
565
+                                       orderby Canvas.GetZIndex(item as UIElement)
566
+                                       select item as UIElement).ToList();
567
+
568
+            for (int i = 0; i < ordered.Count; i++)
569
+            {
570
+                Canvas.SetZIndex(ordered[i], i);
571
+            }
572
+        }
573
+        /// <summary>
574
+        /// 判断奇数和偶数
575
+        /// </summary>
576
+        /// <param name="n"></param>
577
+        /// <returns>True-奇数,False-偶数</returns>
578
+        static bool IsOdd(int n)
579
+        {
580
+            return Convert.ToBoolean(n % 2);
581
+        }
582
+
583
+        protected override void OnMouseDown(MouseButtonEventArgs e)
584
+        {
585
+            base.OnMouseDown(e);
586
+            if (e.Source == this)
587
+            {
588
+                // in case that this click is the start for a 
589
+                // drag operation we cache the start point
590
+                this.rubberbandSelectionStartPoint = new Point?(e.GetPosition(this));
591
+
592
+                // if you click directly on the canvas all 
593
+                // selected items are 'de-selected'
594
+                foreach (ISelectable item in SelectedItems)
595
+                    item.IsSelected = false;
596
+                selectedItems.Clear();
597
+
598
+                e.Handled = true;
599
+            }
600
+        }
601
+
602
+        protected override void OnMouseMove(MouseEventArgs e)
603
+        {
604
+            base.OnMouseMove(e);
605
+
606
+            // if mouse button is not pressed we have no drag operation, ...
607
+            if (e.LeftButton != MouseButtonState.Pressed)
608
+                this.rubberbandSelectionStartPoint = null;
609
+
610
+            // ... but if mouse button is pressed and start
611
+            // point value is set we do have one
612
+            if (this.rubberbandSelectionStartPoint.HasValue)
613
+            {
614
+                // create rubberband adorner
615
+                AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this);
616
+                if (adornerLayer != null)
617
+                {
618
+                    RubberbandAdorner adorner = new RubberbandAdorner(this, rubberbandSelectionStartPoint);
619
+                    if (adorner != null)
620
+                    {
621
+                        adornerLayer.Add(adorner);
622
+                    }
623
+                }
624
+            }
625
+            e.Handled = true;
626
+        }
627
+
628
+        protected override void OnDrop(DragEventArgs e)
629
+        {
630
+            base.OnDrop(e);
631
+            DragObject dragObject = e.Data.GetData(typeof(DragObject)) as DragObject;
632
+            if (dragObject != null && !String.IsNullOrEmpty(dragObject.Xaml))
633
+            {
634
+                DesignerItem newItem = null;
635
+                Object content = XamlReader.Load(XmlReader.Create(new StringReader(dragObject.Xaml)));
636
+
637
+                if (content != null)
638
+                {
639
+                    newItem = new DesignerItem("");
640
+                    newItem.Content = content;
641
+
642
+                    Point position = e.GetPosition(this);
643
+
644
+                    if (dragObject.DesiredSize.HasValue)
645
+                    {
646
+                        Size desiredSize = dragObject.DesiredSize.Value;
647
+                        newItem.Width = desiredSize.Width;
648
+                        newItem.Height = desiredSize.Height;
649
+
650
+                        DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X - newItem.Width / 2));
651
+                        DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y - newItem.Height / 2));
652
+                    }
653
+                    else
654
+                    {
655
+                        DesignerCanvas.SetLeft(newItem, Math.Max(0, position.X));
656
+                        DesignerCanvas.SetTop(newItem, Math.Max(0, position.Y));
657
+                    }
658
+
659
+                    this.Children.Add(newItem);
660
+
661
+                    //update selection
662
+                    foreach (ISelectable item in this.SelectedItems)
663
+                        item.IsSelected = false;
664
+                    SelectedItems.Clear();
665
+                    newItem.IsSelected = true;
666
+                    this.SelectedItems.Add(newItem);
667
+                }
668
+
669
+                e.Handled = true;
670
+            }
671
+        }
672
+
673
+        protected override Size MeasureOverride(Size constraint)
674
+        {
675
+            Size size = new Size();
676
+            foreach (UIElement element in base.Children)
677
+            {
678
+                double left = Canvas.GetLeft(element);
679
+                double top = Canvas.GetTop(element);
680
+                left = double.IsNaN(left) ? 0 : left;
681
+                top = double.IsNaN(top) ? 0 : top;
682
+
683
+                //measure desired size for each child
684
+                element.Measure(constraint);
685
+
686
+                Size desiredSize = element.DesiredSize;
687
+                if (!double.IsNaN(desiredSize.Width) && !double.IsNaN(desiredSize.Height))
688
+                {
689
+                    size.Width = Math.Max(size.Width, left + desiredSize.Width);
690
+                    size.Height = Math.Max(size.Height, top + desiredSize.Height);
691
+                }
692
+            }
693
+            // add margin 
694
+            size.Width += 10;
695
+            size.Height += 10;
696
+            return size;
697
+        }
698
+    }
699
+}

+ 330
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvas.ts 查看文件

@@ -0,0 +1,330 @@
1
+import { reactive, ref, onMounted, nextTick } from 'vue'
2
+import type { DesignerItem } from './DesignerItem'
3
+import type { Connection } from './Connection'
4
+import type { Connector } from './Connector'
5
+import { DesignerItemTip } from './DesignerItemTip'
6
+
7
+interface TxNode {
8
+    code: string
9
+    parentCode: string
10
+    name: string
11
+    content: string
12
+    remark: string
13
+    stat: string
14
+    errInfo: string
15
+    x: number
16
+    y: number
17
+    subCode: string
18
+    conditions: string
19
+}
20
+
21
+interface TxEntry {
22
+    startNode: string
23
+    endNode: string
24
+    condition: string
25
+}
26
+
27
+export class DesignerCanvas {
28
+    private rubberbandSelectionStartPoint: {x: number, y: number} | null = null
29
+    private selectedItems: DesignerItem[] = []
30
+    private layoutCount = 0
31
+    private readonly START_X = 20
32
+    private readonly START_Y = 10
33
+    private readonly OFFSET_X = 220
34
+    private readonly OFFSET_Y = 120
35
+    private leftestX = Number.MAX_VALUE
36
+    private startNode = "0"
37
+    private endNode = "0"
38
+    private lstNodes: TxNode[] = []
39
+    private nodes: TxNode[] = []
40
+    private lstHeadNodes: TxNode[] = []
41
+    private lstEntrys: TxEntry[] = []
42
+    private canvasRef: HTMLElement | null = null
43
+
44
+    constructor(canvasElement: HTMLElement) {
45
+        this.canvasRef = canvasElement
46
+    }
47
+
48
+    getSelectedItems(): DesignerItem[] {
49
+        return this.selectedItems
50
+    }
51
+
52
+    clearSelection() {
53
+        this.selectedItems.forEach(item => item.isSelected = false)
54
+        this.selectedItems = []
55
+    }
56
+
57
+    async loadFlowChat(flowList: TxNode[]) {
58
+        this.lstNodes = []
59
+        this.nodes = []
60
+        this.lstEntrys = []
61
+        
62
+        if (!flowList || flowList.length < 1) return
63
+        
64
+        this.startNode = flowList.reduce((min, item) => 
65
+            item.code < min ? item.code : min, flowList[0].code)
66
+        this.endNode = (flowList.length + 1).toString()
67
+        
68
+        this.nodes.push({
69
+            code: this.startNode,
70
+            parentCode: "",
71
+            name: "开始",
72
+            content: "",
73
+            remark: "",
74
+            stat: "",
75
+            errInfo: "",
76
+            x: 0,
77
+            y: 0,
78
+            subCode: "",
79
+            conditions: ""
80
+        })
81
+        
82
+        this.nodes.push({
83
+            code: this.endNode,
84
+            parentCode: "",
85
+            name: "结束", 
86
+            content: "",
87
+            remark: "",
88
+            stat: "",
89
+            errInfo: "",
90
+            x: 0,
91
+            y: 0,
92
+            subCode: "",
93
+            conditions: ""
94
+        })
95
+        
96
+        this.layout(flowList)
97
+        await this.renderNodes()
98
+        await this.renderConnections()
99
+    }
100
+
101
+    private async renderNodes() {
102
+        if (!this.canvasRef) return
103
+        
104
+        for (const node of this.lstNodes) {
105
+            const item = new DesignerItem(node.code)
106
+            item.name = node.name
107
+            item.remark = node.remark
108
+            item.errorInfo = node.errInfo
109
+            
110
+            switch(node.stat.toUpperCase()) {
111
+                case "Z":
112
+                    item.tipSymbol = DesignerItemTip.Error
113
+                    item.tooltip = "结账失败"
114
+                    break
115
+                case "Y":
116
+                    item.tipSymbol = DesignerItemTip.Success
117
+                    item.tooltip = "结账成功"
118
+                    break
119
+                case "N":
120
+                    item.tipSymbol = DesignerItemTip.UnHandled
121
+                    item.tooltip = "未处理"
122
+                    break
123
+                case "S":
124
+                    item.tipSymbol = DesignerItemTip.None
125
+                    item.tooltip = "正在执行"
126
+                    break
127
+                default:
128
+                    item.tipSymbol = DesignerItemTip.None
129
+            }
130
+            
131
+            item.position = {
132
+                x: this.START_X + node.x,
133
+                y: this.START_Y + node.y
134
+            }
135
+            
136
+            this.canvasRef.appendChild(item.element)
137
+            await nextTick()
138
+        }
139
+    }
140
+
141
+    private async renderConnections() {
142
+        if (!this.canvasRef) return
143
+        
144
+        for (const entry of this.lstEntrys) {
145
+            const sourceConnector = this.getConnector(entry.startNode, "bottom")
146
+            const sinkConnector = this.getConnector(entry.endNode, "top")
147
+            
148
+            if (sourceConnector && sinkConnector) {
149
+                const connection = new Connection(
150
+                    sourceConnector, 
151
+                    sinkConnector,
152
+                    entry.condition
153
+                )
154
+                this.canvasRef.appendChild(connection.element)
155
+                await nextTick()
156
+            }
157
+        }
158
+    }
159
+
160
+    private layout(flowList: TxNode[]) {
161
+        this.layoutCount = 0
162
+        
163
+        // 构建节点和连接关系
164
+        flowList.forEach(item => {
165
+            const subCodes = item.subCode.split(',')
166
+            subCodes.forEach(k => {
167
+                this.lstEntrys.push({
168
+                    startNode: k,
169
+                    endNode: item.code,
170
+                    condition: item.conditions
171
+                })
172
+            })
173
+            this.nodes.push(item)
174
+        })
175
+        
176
+        // 查找结束节点并添加虚拟连接
177
+        const lastNode = this.findLastNode(flowList)
178
+        if (lastNode) {
179
+            this.lstEntrys.push({
180
+                startNode: lastNode.code,
181
+                endNode: this.endNode,
182
+                condition: ""
183
+            })
184
+        }
185
+        
186
+        // 排序节点
187
+        this.nodes.sort((a, b) => parseInt(a.code) - parseInt(b.code))
188
+        
189
+        // 布局起始节点
190
+        const firstNode = this.findFirstNode(this.startNode)
191
+        if (firstNode) {
192
+            firstNode.x = this.START_X
193
+            firstNode.y = this.START_Y
194
+            this.layoutCount++
195
+            this.lstNodes.push(firstNode)
196
+            this.layoutNextNodes(firstNode)
197
+        }
198
+        
199
+        // 布局其他节点
200
+        this.lstHeadNodes = this.getHeadNodes()
201
+        this.nodes.forEach(node => {
202
+            if (this.lstHeadNodes.some(n => n.code === node.code)) {
203
+                node.x = this.START_X + 100
204
+                node.y = this.START_Y
205
+                this.layoutCount++
206
+                this.lstNodes.push(node)
207
+                this.layoutNextNodes(node)
208
+            }
209
+            this.layoutNextNodes(node)
210
+        })
211
+    }
212
+
213
+    private layoutNextNodes(node: TxNode) {
214
+        const nextNodes = this.findNextNodes(node)
215
+        if (!nextNodes || nextNodes.length === 0) return
216
+        
217
+        const half = nextNodes.length % 2 === 0 
218
+            ? nextNodes.length / 2 - 1 
219
+            : Math.floor(nextNodes.length / 2)
220
+            
221
+        for (let i = 0; i < nextNodes.length; i++) {
222
+            if (nextNodes[i].x === 0 && nextNodes[i].y === 0) {
223
+                nextNodes[i].y = node.y + this.OFFSET_Y
224
+                
225
+                if (nextNodes[i].code !== this.endNode) {
226
+                    nextNodes[i].x = node.x + (i - half) * this.OFFSET_X
227
+                    
228
+                    if (node.subCode) {
229
+                        const subNodes = node.subCode.split(',')
230
+                        if (subNodes.length > 1) {
231
+                            // 处理多分支情况
232
+                        }
233
+                    }
234
+                } else {
235
+                    nextNodes[i].x = this.START_X
236
+                    const maxY = this.lstNodes.reduce((max, n) => 
237
+                        n.y > max ? n.y : max, 0)
238
+                    nextNodes[i].y = maxY + this.OFFSET_Y
239
+                }
240
+                
241
+                this.lstNodes.push(nextNodes[i])
242
+                this.leftestX = Math.min(this.leftestX, nextNodes[i].x)
243
+                
244
+                if (nextNodes.length === 1) {
245
+                    this.layoutCount++
246
+                    this.layoutNextNodes(nextNodes[i])
247
+                }
248
+            }
249
+        }
250
+        
251
+        if (nextNodes.length > 1) {
252
+            this.layoutCount++
253
+        }
254
+    }
255
+
256
+    private findFirstNode(code: string): TxNode | undefined {
257
+        return this.nodes.find(n => n.code === code)
258
+    }
259
+
260
+    private findLastNode(flowList: TxNode[]): TxNode | undefined {
261
+        for (const node of flowList) {
262
+            const isLast = !flowList.some(n => 
263
+                n.subCode.split(',').includes(node.code))
264
+            if (isLast) return node
265
+        }
266
+    }
267
+
268
+    private findNextNodes(node: TxNode): TxNode[] {
269
+        return this.lstEntrys
270
+            .filter(e => e.startNode === node.code)
271
+            .map(e => this.nodes.find(n => n.code === e.endNode))
272
+            .filter(Boolean) as TxNode[]
273
+    }
274
+
275
+    private getHeadNodes(): TxNode[] {
276
+        return this.nodes.filter(n => {
277
+            if (n.code === this.startNode || n.code === this.endNode) {
278
+                return false
279
+            }
280
+            return !this.lstEntrys.some(e => e.endNode === n.code)
281
+        })
282
+    }
283
+
284
+    private getConnector(itemId: string, position: string): Connector | null {
285
+        // 实际实现中需要查找DOM中的连接点元素
286
+        return null
287
+    }
288
+
289
+    handleMouseDown(e: MouseEvent) {
290
+        if (e.target === this.canvasRef) {
291
+            this.rubberbandSelectionStartPoint = {
292
+                x: e.clientX,
293
+                y: e.clientY
294
+            }
295
+            this.clearSelection()
296
+        }
297
+    }
298
+
299
+    handleMouseMove(e: MouseEvent) {
300
+        if (!this.rubberbandSelectionStartPoint) return
301
+        
302
+        // 实现框选逻辑
303
+        // ...
304
+    }
305
+
306
+    handleMouseUp() {
307
+        this.rubberbandSelectionStartPoint = null
308
+    }
309
+}
310
+
311
+// Vue组合式API封装
312
+export const useDesignerCanvas = (canvasElement: HTMLElement) => {
313
+    const canvas = reactive(new DesignerCanvas(canvasElement))
314
+    
315
+    onMounted(() => {
316
+        canvasElement.addEventListener('mousedown', canvas.handleMouseDown)
317
+        canvasElement.addEventListener('mousemove', canvas.handleMouseMove)
318
+        canvasElement.addEventListener('mouseup', canvas.handleMouseUp)
319
+    })
320
+    
321
+    onUnmounted(() => {
322
+        canvasElement.removeEventListener('mousedown', canvas.handleMouseDown)
323
+        canvasElement.removeEventListener('mousemove', canvas.handleMouseMove)
324
+        canvasElement.removeEventListener('mouseup', canvas.handleMouseUp)
325
+    })
326
+    
327
+    return {
328
+        canvas
329
+    }
330
+}

+ 106
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvasAdorner.cs 查看文件

@@ -0,0 +1,106 @@
1
+using System.Collections.Generic;
2
+using System.Windows;
3
+using System.Windows.Controls;
4
+using System.Windows.Documents;
5
+using System.Windows.Input;
6
+using System.Windows.Media;
7
+using System.Windows.Shapes;
8
+
9
+namespace TellerSystem.Controls.Ext.Controls
10
+{
11
+    public class DesignerCanvasAdorner : Adorner
12
+    {
13
+        public DesignerCanvasAdorner(UIElement adornedElement)
14
+            : base(adornedElement)
15
+        {
16
+            if (adornedElement is FrameworkElement)
17
+            {
18
+                _adornedElement = adornedElement as FrameworkElement;
19
+                CreateGrip();
20
+            }
21
+        }
22
+        private void CreateGrip()
23
+        {
24
+            // Scaling grip
25
+            Rectangle rect = new Rectangle();
26
+            rect.Stroke = Brushes.Blue;
27
+            rect.Fill = Brushes.Red;
28
+            rect.Cursor = Cursors.SizeNWSE;
29
+
30
+            rect.MouseDown += OnGripMouseDown;
31
+            rect.MouseUp += OnGripMouseUp;
32
+            rect.MouseMove += OnGripMouseMove;
33
+            AddVisualChild(rect);
34
+            _scalingGrip = rect;
35
+        }
36
+
37
+        protected override int VisualChildrenCount
38
+        {
39
+            get
40
+            {
41
+                return _adornedElement != null ? 1 : 0;
42
+            }
43
+        }
44
+
45
+        protected override Visual GetVisualChild(int index)
46
+        {
47
+            if (_adornedElement != null)
48
+                return _scalingGrip;
49
+            return base.GetVisualChild(index);
50
+        }
51
+
52
+        protected override Size ArrangeOverride(Size finalSize)
53
+        {
54
+            Size size = base.ArrangeOverride(finalSize);
55
+            if (_scalingGrip != null)
56
+                _scalingGrip.Arrange(new Rect(finalSize.Width - 5, finalSize.Height - 5, 10, 10));
57
+            return size;
58
+        }
59
+
60
+        protected override void OnRender(DrawingContext drawingContext)
61
+        {
62
+            SolidColorBrush renderBrush = new SolidColorBrush(Colors.Green);
63
+            Pen renderPen = new Pen(new SolidColorBrush(Colors.Navy), 1);
64
+            renderPen.DashStyle = new DashStyle(new double[] { 2.5, 2.5 }, 0);
65
+
66
+            Rect rect = new Rect(0, 0, _adornedElement.ActualWidth, _adornedElement.ActualHeight);
67
+            drawingContext.DrawRectangle(Brushes.Transparent, renderPen, rect);
68
+
69
+            base.OnRender(drawingContext);
70
+        }
71
+
72
+        private void OnGripMouseDown(object sender, MouseEventArgs args)
73
+        {
74
+            if (args.LeftButton != MouseButtonState.Pressed)
75
+                return;
76
+
77
+            Rectangle rect = sender as Rectangle;
78
+            if (rect != null)
79
+                Mouse.Capture(rect);
80
+        }
81
+
82
+        private void OnGripMouseUp(object sender, MouseEventArgs args)
83
+        {
84
+            Rectangle rect = sender as Rectangle;
85
+            if (rect != null)
86
+                Mouse.Capture(null);
87
+        }
88
+
89
+        private void OnGripMouseMove(object sender, MouseEventArgs args)
90
+        {
91
+            if (args.LeftButton != MouseButtonState.Pressed)
92
+                return;
93
+
94
+            Rectangle rect = sender as Rectangle;
95
+            if (rect == null || _adornedElement == null)
96
+                return;
97
+
98
+            Point point = args.GetPosition(_adornedElement);
99
+            _adornedElement.Width = point.X > 0 ? point.X : 0;
100
+            _adornedElement.Height = point.Y > 0 ? point.Y : 0;
101
+        }
102
+
103
+        Rectangle _scalingGrip = null;
104
+        FrameworkElement _adornedElement = null;
105
+    }
106
+}

+ 100
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerCanvasAdorner.ts 查看文件

@@ -0,0 +1,100 @@
1
+import { reactive, onMounted, onUnmounted } from 'vue'
2
+
3
+export class DesignerCanvasAdorner {
4
+    private adornedElement: HTMLElement | null = null
5
+    private scalingGrip: HTMLElement | null = null
6
+    private isDragging = false
7
+    private startX = 0
8
+    private startY = 0
9
+    private startWidth = 0
10
+    private startHeight = 0
11
+
12
+    constructor(element: HTMLElement) {
13
+        this.adornedElement = element
14
+        this.createGrip()
15
+    }
16
+
17
+    private createGrip() {
18
+        if (!this.adornedElement) return
19
+
20
+        // 创建缩放控制柄
21
+        const grip = document.createElement('div')
22
+        grip.style.position = 'absolute'
23
+        grip.style.width = '10px'
24
+        grip.style.height = '10px'
25
+        grip.style.right = '0'
26
+        grip.style.bottom = '0'
27
+        grip.style.backgroundColor = 'red'
28
+        grip.style.border = '1px solid blue'
29
+        grip.style.cursor = 'nwse-resize'
30
+        
31
+        grip.addEventListener('mousedown', this.onGripMouseDown)
32
+        this.adornedElement.appendChild(grip)
33
+        this.scalingGrip = grip
34
+
35
+        // 添加选中边框
36
+        this.adornedElement.style.border = '1px dashed navy'
37
+    }
38
+
39
+    private onGripMouseDown = (e: MouseEvent) => {
40
+        if (!this.adornedElement) return
41
+
42
+        this.isDragging = true
43
+        this.startX = e.clientX
44
+        this.startY = e.clientY
45
+        this.startWidth = parseInt(document.defaultView?.getComputedStyle(this.adornedElement).width || '0', 10)
46
+        this.startHeight = parseInt(document.defaultView?.getComputedStyle(this.adornedElement).height || '0', 10)
47
+        
48
+        document.addEventListener('mousemove', this.onGripMouseMove)
49
+        document.addEventListener('mouseup', this.onGripMouseUp)
50
+    }
51
+
52
+    private onGripMouseMove = (e: MouseEvent) => {
53
+        if (!this.isDragging || !this.adornedElement) return
54
+
55
+        const dx = e.clientX - this.startX
56
+        const dy = e.clientY - this.startY
57
+        
58
+        this.adornedElement.style.width = `${Math.max(0, this.startWidth + dx)}px`
59
+        this.adornedElement.style.height = `${Math.max(0, this.startHeight + dy)}px`
60
+    }
61
+
62
+    private onGripMouseUp = () => {
63
+        this.isDragging = false
64
+        document.removeEventListener('mousemove', this.onGripMouseMove)
65
+        document.removeEventListener('mouseup', this.onGripMouseUp)
66
+    }
67
+
68
+    public dispose() {
69
+        if (this.scalingGrip) {
70
+            this.scalingGrip.removeEventListener('mousedown', this.onGripMouseDown)
71
+            this.scalingGrip.remove()
72
+        }
73
+        
74
+        if (this.adornedElement) {
75
+            this.adornedElement.style.border = 'none'
76
+        }
77
+        
78
+        document.removeEventListener('mousemove', this.onGripMouseMove)
79
+        document.removeEventListener('mouseup', this.onGripMouseUp)
80
+    }
81
+}
82
+
83
+// Vue组合式API封装
84
+export const useDesignerCanvasAdorner = (elementRef: Ref<HTMLElement | null>) => {
85
+    const adorner = reactive<DesignerCanvasAdorner | null>(null)
86
+
87
+    onMounted(() => {
88
+        if (elementRef.value) {
89
+            adorner = new DesignerCanvasAdorner(elementRef.value)
90
+        }
91
+    })
92
+
93
+    onUnmounted(() => {
94
+        adorner?.dispose()
95
+    })
96
+
97
+    return {
98
+        adorner
99
+    }
100
+}

+ 258
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerItem.cs 查看文件

@@ -0,0 +1,258 @@
1
+using System.Windows;
2
+using System.Windows.Controls;
3
+using System.Windows.Input;
4
+using System.Windows.Media;
5
+using Platform.Presentation.Interfaces;
6
+using Platform.Common.BasicFunctions;
7
+using Platform.Library;
8
+using Platform.Presentation.FocusManagers;
9
+using System.Windows.Documents;
10
+using Platform.Presentation.FocusCheck;
11
+using System.Windows.Controls.Primitives;
12
+using System.ComponentModel;
13
+namespace TellerSystem.Controls.Ext.Controls
14
+{
15
+    [TemplatePart(Name = "PART_DragThumb", Type = typeof(DragThumb))]
16
+    [TemplatePart(Name = "PART_ResizeDecorator", Type = typeof(Control))]
17
+    [TemplatePart(Name = "PART_ConnectorDecorator", Type = typeof(Control))]
18
+    [TemplatePart(Name = "PART_ContentPresenter", Type = typeof(ContentPresenter))]
19
+    public class DesignerItem : ContentControl, ISelectable, INotifyPropertyChanged
20
+    {        
21
+        #region IsSelected Property
22
+        public bool IsSelected
23
+        {
24
+            get { return (bool)GetValue(IsSelectedProperty); }
25
+            set { SetValue(IsSelectedProperty, value); }
26
+        }
27
+        public static readonly DependencyProperty IsSelectedProperty =
28
+          DependencyProperty.Register("IsSelected",
29
+                                       typeof(bool),
30
+                                       typeof(DesignerItem),
31
+                                       new FrameworkPropertyMetadata(false));
32
+
33
+        #endregion
34
+
35
+        #region DragThumbTemplate Property
36
+
37
+        // can be used to replace the default template for the DragThumb
38
+        public static readonly DependencyProperty DragThumbTemplateProperty =
39
+            DependencyProperty.RegisterAttached("DragThumbTemplate", typeof(ControlTemplate), typeof(DesignerItem));
40
+
41
+        public static ControlTemplate GetDragThumbTemplate(UIElement element)
42
+        {
43
+            return (ControlTemplate)element.GetValue(DragThumbTemplateProperty);
44
+        }
45
+
46
+        public static void SetDragThumbTemplate(UIElement element, ControlTemplate value)
47
+        {
48
+            element.SetValue(DragThumbTemplateProperty, value);
49
+        }
50
+
51
+        #endregion
52
+
53
+        #region ConnectorDecoratorTemplate Property
54
+
55
+        // can be used to replace the default template for the ConnectorDecorator
56
+        public static readonly DependencyProperty ConnectorDecoratorTemplateProperty =
57
+            DependencyProperty.RegisterAttached("ConnectorDecoratorTemplate", typeof(ControlTemplate), typeof(DesignerItem));
58
+
59
+        public static ControlTemplate GetConnectorDecoratorTemplate(UIElement element)
60
+        {
61
+            return (ControlTemplate)element.GetValue(ConnectorDecoratorTemplateProperty);
62
+        }
63
+
64
+        public static void SetConnectorDecoratorTemplate(UIElement element, ControlTemplate value)
65
+        {
66
+            element.SetValue(ConnectorDecoratorTemplateProperty, value);
67
+        }
68
+
69
+        #endregion
70
+
71
+        #region IsDragConnectionOver
72
+
73
+        // while drag connection procedure is ongoing and the mouse moves over 
74
+        // this item this value is true; if true the ConnectorDecorator is triggered
75
+        // to be visible, see template
76
+        public bool IsDragConnectionOver
77
+        {
78
+            get { return (bool)GetValue(IsDragConnectionOverProperty); }
79
+            set { SetValue(IsDragConnectionOverProperty, value); }
80
+        }
81
+        public static readonly DependencyProperty IsDragConnectionOverProperty =
82
+            DependencyProperty.Register("IsDragConnectionOver",
83
+                                         typeof(bool),
84
+                                         typeof(DesignerItem),
85
+                                         new FrameworkPropertyMetadata(false));
86
+
87
+        #endregion
88
+
89
+        private DesignerItemTip sourceTipSymbol = DesignerItemTip.None;
90
+        public DesignerItemTip SourceTipSymbol
91
+        {
92
+            get { return sourceTipSymbol; }
93
+            set
94
+            {
95
+                if (sourceTipSymbol != value)
96
+                {
97
+                    sourceTipSymbol = value;
98
+                    OnPropertyChanged("SourceTipSymbol");
99
+                }
100
+            }
101
+        }
102
+
103
+        
104
+        static DesignerItem()
105
+        {
106
+            // set the key to reference the style for this control
107
+            FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
108
+                typeof(DesignerItem), new FrameworkPropertyMetadata(typeof(DesignerItem)));
109
+        }
110
+        /// <summary>
111
+        /// 当前序号
112
+        /// </summary>
113
+        public string CurrentSerialNumber{get;set;}
114
+        /// <summary>
115
+        /// 备注信息
116
+        /// </summary>
117
+        public string Remark { get; set; }
118
+        /// <summary>
119
+        /// 错误信息
120
+        /// </summary>
121
+        public string ErrorInfo { get; set; }
122
+        
123
+        public DesignerItem(string key)
124
+        {
125
+            CurrentSerialNumber = key;
126
+            this.Loaded += new RoutedEventHandler(DesignerItem_Loaded);
127
+        }
128
+
129
+        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
130
+        {
131
+            base.OnPreviewMouseDown(e);
132
+            DesignerCanvas designer = VisualTreeHelper.GetParent(this) as DesignerCanvas;
133
+            // update selection
134
+            if (designer != null)
135
+                if ((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None)
136
+                    if (this.IsSelected)
137
+                    {
138
+                        this.IsSelected = false;
139
+                        designer.SelectedItems.Remove(this);
140
+                    }
141
+                    else
142
+                    {
143
+                        this.IsSelected = true;
144
+                        designer.SelectedItems.Add(this);
145
+                    }
146
+                else if (!this.IsSelected)
147
+                {
148
+                    foreach (ISelectable item in designer.SelectedItems)
149
+                        item.IsSelected = false;
150
+                    designer.SelectedItems.Clear();
151
+                    this.IsSelected = true;
152
+                    designer.SelectedItems.Add(this);
153
+                }
154
+            e.Handled = false;
155
+        }
156
+        void DesignerItem_Loaded(object sender, RoutedEventArgs e)
157
+        {
158
+            if (base.Template != null)
159
+            {
160
+                ContentPresenter contentPresenter =
161
+                    this.Template.FindName("PART_ContentPresenter", this) as ContentPresenter;
162
+                if (contentPresenter != null)
163
+                {
164
+                    if (VisualTreeHelper.GetChildrenCount(contentPresenter) > 0)
165
+                    {
166
+                        UIElement contentVisual = VisualTreeHelper.GetChild(contentPresenter, 0) as UIElement;                                     
167
+                        if (contentVisual != null)
168
+                        {
169
+                            DragThumb thumb = this.Template.FindName("PART_DragThumb", this) as DragThumb;
170
+                            Control connectorDecorator = this.Template.FindName("PART_ConnectorDecorator", this) as Control;
171
+                            if (thumb != null)
172
+                            {
173
+                                ControlTemplate template =
174
+                                    DesignerItem.GetDragThumbTemplate(contentVisual) as ControlTemplate;
175
+                                if (template != null)
176
+                                    thumb.Template = template;
177
+                            }
178
+                            if (connectorDecorator != null)
179
+                            {
180
+                                ControlTemplate template =
181
+                                    DesignerItem.GetConnectorDecoratorTemplate(contentVisual) as ControlTemplate;
182
+                                if (template != null)
183
+                                    connectorDecorator.Template = template;
184
+                            }
185
+                        }
186
+                    }
187
+
188
+                }
189
+            }
190
+        }      
191
+        protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
192
+        {
193
+            Popup pop = new Popup();
194
+            TextBlock txbKeyword = new TextBlock();
195
+            txbKeyword.Width = 360;          
196
+            txbKeyword.FontSize = 15;
197
+            txbKeyword.TextWrapping = TextWrapping.Wrap;
198
+            txbKeyword.Text = this.Remark;
199
+            var border = new Border()
200
+            {
201
+                BorderBrush = new SolidColorBrush(Colors.DarkGreen),
202
+                BorderThickness = new Thickness(5),
203
+                Width = 400,    
204
+                Background = Brushes.White,
205
+                CornerRadius = new CornerRadius(5)
206
+            };           
207
+             border.Child = txbKeyword;
208
+            pop.Child = border;
209
+            pop.PlacementTarget = this;
210
+            pop.Placement = PlacementMode.Mouse ;           
211
+            pop.IsOpen = true;
212
+            pop.StaysOpen = false;
213
+            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(txbKeyword);
214
+            adornerLayer.Add(new DesignerCanvasAdorner(txbKeyword));            
215
+            base.OnMouseDoubleClick(e);
216
+        }
217
+        #region INotifyPropertyChanged Members
218
+
219
+        // we could use DependencyProperties as well to inform others of property changes
220
+        public event PropertyChangedEventHandler PropertyChanged;
221
+
222
+        protected void OnPropertyChanged(string name)
223
+        {
224
+            PropertyChangedEventHandler handler = PropertyChanged;
225
+            if (handler != null)
226
+            {
227
+                handler(this, new PropertyChangedEventArgs(name));
228
+            }
229
+        }
230
+
231
+        #endregion
232
+        public static T FindVisualChild<T>(DependencyObject obj)
233
+         where T : DependencyObject
234
+        {
235
+            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
236
+            {
237
+                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
238
+                if (child != null && child is T)
239
+                    return (T)child;
240
+                else
241
+                {
242
+                    T childOfChild = FindVisualChild<T>(child);
243
+                    if (childOfChild != null)
244
+                        return childOfChild;
245
+                }
246
+            }
247
+            return null;
248
+        }
249
+    }
250
+    public enum DesignerItemTip
251
+    {
252
+        None,
253
+        Error,
254
+        UnHandled,
255
+        Execute,
256
+        Success
257
+    }
258
+}

+ 206
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DesignerItem.ts 查看文件

@@ -0,0 +1,206 @@
1
+import { reactive, ref, computed, onMounted } from 'vue'
2
+import type { DesignerCanvas } from './DesignerCanvas'
3
+
4
+export enum DesignerItemTip {
5
+    None = 'None',
6
+    Error = 'Error',
7
+    UnHandled = 'UnHandled',
8
+    Execute = 'Execute',
9
+    Success = 'Success'
10
+}
11
+
12
+export class DesignerItem {
13
+    private _isSelected = false
14
+    private _isDragConnectionOver = false
15
+    private _sourceTipSymbol = DesignerItemTip.None
16
+    private _currentSerialNumber: string
17
+    private _remark = ''
18
+    private _errorInfo = ''
19
+    private _element: HTMLElement | null = null
20
+    private _parentCanvas: DesignerCanvas | null = null
21
+
22
+    constructor(key: string) {
23
+        this._currentSerialNumber = key
24
+    }
25
+
26
+    get isSelected(): boolean {
27
+        return this._isSelected
28
+    }
29
+    set isSelected(value: boolean) {
30
+        if (this._isSelected !== value) {
31
+            this._isSelected = value
32
+            this.updateSelectionStyle()
33
+        }
34
+    }
35
+
36
+    get isDragConnectionOver(): boolean {
37
+        return this._isDragConnectionOver
38
+    }
39
+    set isDragConnectionOver(value: boolean) {
40
+        if (this._isDragConnectionOver !== value) {
41
+            this._isDragConnectionOver = value
42
+            this.updateConnectorVisibility()
43
+        }
44
+    }
45
+
46
+    get sourceTipSymbol(): DesignerItemTip {
47
+        return this._sourceTipSymbol
48
+    }
49
+    set sourceTipSymbol(value: DesignerItemTip) {
50
+        if (this._sourceTipSymbol !== value) {
51
+            this._sourceTipSymbol = value
52
+            this.updateTipSymbol()
53
+        }
54
+    }
55
+
56
+    get currentSerialNumber(): string {
57
+        return this._currentSerialNumber
58
+    }
59
+
60
+    get remark(): string {
61
+        return this._remark
62
+    }
63
+    set remark(value: string) {
64
+        this._remark = value
65
+    }
66
+
67
+    get errorInfo(): string {
68
+        return this._errorInfo
69
+    }
70
+    set errorInfo(value: string) {
71
+        this._errorInfo = value
72
+    }
73
+
74
+    public initialize(element: HTMLElement, parentCanvas: DesignerCanvas) {
75
+        this._element = element
76
+        this._parentCanvas = parentCanvas
77
+        this.setupEventListeners()
78
+        this.render()
79
+    }
80
+
81
+    private setupEventListeners() {
82
+        if (!this._element) return
83
+
84
+        this._element.addEventListener('mousedown', this.onMouseDown)
85
+        this._element.addEventListener('dblclick', this.onDoubleClick)
86
+    }
87
+
88
+    private onMouseDown = (e: MouseEvent) => {
89
+        if (!this._parentCanvas) return
90
+
91
+        const isCtrlPressed = e.ctrlKey || e.metaKey
92
+        const isShiftPressed = e.shiftKey
93
+
94
+        if (isCtrlPressed || isShiftPressed) {
95
+            if (this._isSelected) {
96
+                this._isSelected = false
97
+                this._parentCanvas.removeSelectedItem(this)
98
+            } else {
99
+                this._isSelected = true
100
+                this._parentCanvas.addSelectedItem(this)
101
+            }
102
+        } else if (!this._isSelected) {
103
+            this._parentCanvas.clearSelection()
104
+            this._isSelected = true
105
+            this._parentCanvas.addSelectedItem(this)
106
+        }
107
+
108
+        e.stopPropagation()
109
+    }
110
+
111
+    private onDoubleClick = () => {
112
+        this.showRemarkPopup()
113
+    }
114
+
115
+    private showRemarkPopup() {
116
+        if (!this._element) return
117
+
118
+        const popup = document.createElement('div')
119
+        popup.style.position = 'absolute'
120
+        popup.style.zIndex = '1000'
121
+        popup.style.border = '5px solid darkgreen'
122
+        popup.style.borderRadius = '5px'
123
+        popup.style.backgroundColor = 'white'
124
+        popup.style.width = '400px'
125
+        popup.style.padding = '10px'
126
+
127
+        const content = document.createElement('div')
128
+        content.style.width = '360px'
129
+        content.style.fontSize = '15px'
130
+        content.style.wordWrap = 'break-word'
131
+        content.textContent = this._remark
132
+
133
+        popup.appendChild(content)
134
+        document.body.appendChild(popup)
135
+
136
+        const rect = this._element.getBoundingClientRect()
137
+        popup.style.left = `${rect.left}px`
138
+        popup.style.top = `${rect.top}px`
139
+
140
+        const closePopup = () => {
141
+            document.body.removeChild(popup)
142
+            document.removeEventListener('mousedown', closePopup)
143
+        }
144
+
145
+        document.addEventListener('mousedown', closePopup)
146
+    }
147
+
148
+    private updateSelectionStyle() {
149
+        if (!this._element) return
150
+
151
+        if (this._isSelected) {
152
+            this._element.style.boxShadow = '0 0 5px 2px rgba(0, 0, 255, 0.5)'
153
+        } else {
154
+            this._element.style.boxShadow = 'none'
155
+        }
156
+    }
157
+
158
+    private updateConnectorVisibility() {
159
+        // 在实际实现中更新连接器可见性
160
+    }
161
+
162
+    private updateTipSymbol() {
163
+        if (!this._element) return
164
+
165
+        const tipElement = this._element.querySelector('.tip-symbol')
166
+        if (tipElement) {
167
+            tipElement.className = `tip-symbol ${this._sourceTipSymbol.toLowerCase()}`
168
+        }
169
+    }
170
+
171
+    private render() {
172
+        if (!this._element) return
173
+
174
+        this._element.innerHTML = `
175
+            <div class="designer-item">
176
+                <div class="header">
177
+                    <span class="serial">${this._currentSerialNumber}</span>
178
+                    <span class="tip-symbol ${this._sourceTipSymbol.toLowerCase()}"></span>
179
+                </div>
180
+                <div class="content">
181
+                    <!-- 内容区域 -->
182
+                </div>
183
+                <div class="connectors">
184
+                    <!-- 连接点区域 -->
185
+                </div>
186
+            </div>
187
+        `
188
+    }
189
+}
190
+
191
+// Vue组合式API封装
192
+export const useDesignerItem = (key: string) => {
193
+    const item = reactive(new DesignerItem(key))
194
+    
195
+    onMounted(() => {
196
+        const element = document.getElementById(`designer-item-${key}`)
197
+        if (element) {
198
+            item.initialize(element, /* 传入父画布实例 */)
199
+        }
200
+    })
201
+
202
+    return {
203
+        item,
204
+        DesignerItemTip
205
+    }
206
+}

+ 65
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DragThumb.cs 查看文件

@@ -0,0 +1,65 @@
1
+using System;
2
+using System.Linq;
3
+using System.Windows.Controls;
4
+using System.Windows.Controls.Primitives;
5
+using System.Windows.Media;
6
+using System.Windows;
7
+
8
+namespace TellerSystem.Controls.Ext.Controls
9
+{
10
+    public class DragThumb : Thumb
11
+    {
12
+        public DragThumb()
13
+        {
14
+            base.DragDelta += new DragDeltaEventHandler(DragThumb_DragDelta);
15
+        }
16
+
17
+        void DragThumb_DragDelta(object sender, DragDeltaEventArgs e)
18
+        {
19
+            DesignerItem designerItem = this.DataContext as DesignerItem;
20
+            DesignerCanvas designer = VisualTreeHelper.GetParent(designerItem) as DesignerCanvas;
21
+            if (designerItem != null && designer != null && designerItem.IsSelected)
22
+            {
23
+                double minLeft = double.MaxValue;
24
+                double minTop = double.MaxValue;
25
+
26
+                // we only move DesignerItems
27
+                var designerItems = from item in designer.SelectedItems
28
+                                    where item is DesignerItem
29
+                                    select item;
30
+
31
+                foreach (DesignerItem item in designerItems)
32
+                {
33
+                    double left = Canvas.GetLeft(item);
34
+                    double top = Canvas.GetTop(item);
35
+
36
+                    minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
37
+                    minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
38
+                }
39
+
40
+                double deltaHorizontal = Math.Max(-minLeft, e.HorizontalChange);
41
+                double deltaVertical = Math.Max(-minTop, e.VerticalChange);
42
+
43
+                foreach (DesignerItem item in designerItems)
44
+                {
45
+                    double left = Canvas.GetLeft(item);
46
+                    double top = Canvas.GetTop(item);
47
+
48
+                    if (double.IsNaN(left)) left = 0;
49
+                    if (double.IsNaN(top)) top = 0;
50
+
51
+                    Canvas.SetLeft(item, left + deltaHorizontal);
52
+                    Canvas.SetTop(item, top + deltaVertical);
53
+                }
54
+
55
+                designer.InvalidateMeasure();
56
+                e.Handled = true;
57
+            }
58
+        }
59
+    }
60
+    public class DragObject
61
+    {
62
+        public String Xaml { get; set; }       
63
+        public Size? DesiredSize { get; set; }
64
+    }
65
+}

+ 97
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/DragThumb.ts 查看文件

@@ -0,0 +1,97 @@
1
+import { reactive, onMounted, onUnmounted } from 'vue'
2
+import type { DesignerCanvas } from './DesignerCanvas'
3
+import type { DesignerItem } from './DesignerItem'
4
+
5
+export class DragThumb {
6
+    private element: HTMLElement | null = null
7
+    private startX = 0
8
+    private startY = 0
9
+    private isDragging = false
10
+    private designerCanvas: DesignerCanvas | null = null
11
+
12
+    constructor(element: HTMLElement, canvas: DesignerCanvas) {
13
+        this.element = element
14
+        this.designerCanvas = canvas
15
+        this.setupDragHandlers()
16
+    }
17
+
18
+    private setupDragHandlers() {
19
+        if (!this.element) return
20
+
21
+        this.element.addEventListener('mousedown', this.onMouseDown)
22
+        document.addEventListener('mousemove', this.onMouseMove)
23
+        document.addEventListener('mouseup', this.onMouseUp)
24
+    }
25
+
26
+    private onMouseDown = (e: MouseEvent) => {
27
+        if (!this.designerCanvas) return
28
+
29
+        this.isDragging = true
30
+        this.startX = e.clientX
31
+        this.startY = e.clientY
32
+        e.preventDefault()
33
+    }
34
+
35
+    private onMouseMove = (e: MouseEvent) => {
36
+        if (!this.isDragging || !this.designerCanvas) return
37
+
38
+        const deltaX = e.clientX - this.startX
39
+        const deltaY = e.clientY - this.startY
40
+
41
+        const selectedItems = this.designerCanvas.getSelectedItems()
42
+        if (selectedItems.length === 0) return
43
+
44
+        // 计算最小偏移量防止移出画布
45
+        let minLeft = Infinity
46
+        let minTop = Infinity
47
+        
48
+        selectedItems.forEach(item => {
49
+            minLeft = Math.min(minLeft, item.position.x)
50
+            minTop = Math.min(minTop, item.position.y)
51
+        })
52
+
53
+        const actualDeltaX = Math.max(-minLeft, deltaX)
54
+        const actualDeltaY = Math.max(-minTop, deltaY)
55
+
56
+        // 更新所有选中项位置
57
+        selectedItems.forEach(item => {
58
+            item.position = {
59
+                x: item.position.x + actualDeltaX,
60
+                y: item.position.y + actualDeltaY
61
+            }
62
+        })
63
+
64
+        this.startX = e.clientX
65
+        this.startY = e.clientY
66
+    }
67
+
68
+    private onMouseUp = () => {
69
+        this.isDragging = false
70
+    }
71
+
72
+    public dispose() {
73
+        if (!this.element) return
74
+
75
+        this.element.removeEventListener('mousedown', this.onMouseDown)
76
+        document.removeEventListener('mousemove', this.onMouseMove)
77
+        document.removeEventListener('mouseup', this.onMouseUp)
78
+    }
79
+}
80
+
81
+// Vue组合式API封装
82
+export const useDragThumb = (elementRef: HTMLElement, canvas: DesignerCanvas) => {
83
+    const dragThumb = reactive(new DragThumb(elementRef, canvas))
84
+    
85
+    onUnmounted(() => {
86
+        dragThumb.dispose()
87
+    })
88
+
89
+    return {
90
+        dragThumb
91
+    }
92
+}
93
+
94
+export interface DragObject {
95
+    xaml: string
96
+    desiredSize?: { width: number; height: number }
97
+}

+ 8
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ISelectable.cs 查看文件

@@ -0,0 +1,8 @@
1
+
2
+namespace TellerSystem.Controls.Ext.Controls
3
+{
4
+    public interface ISelectable
5
+    {
6
+        bool IsSelected { get; set; }
7
+    }
8
+}

+ 9
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ISelectable.ts 查看文件

@@ -0,0 +1,9 @@
1
+/**
2
+ * 可选中对象接口
3
+ */
4
+export interface ISelectable {
5
+    /**
6
+     * 获取或设置是否选中
7
+     */
8
+    isSelected: boolean;
9
+}

+ 654
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/PathFinder.cs 查看文件

@@ -0,0 +1,654 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Windows;
4
+using System.Windows.Controls;
5
+
6
+namespace TellerSystem.Controls.Ext.Controls
7
+{   
8
+    internal class PathFinder
9
+    {
10
+        private const int margin = 20;
11
+
12
+        internal static List<Point> GetConnectionLine(ConnectorInfo source, ConnectorInfo sink, bool showLastLine)
13
+        {
14
+            List<Point> linePoints = new List<Point>();
15
+
16
+            Rect rectSource = GetRectWithMargin(source, margin);
17
+            Rect rectSink = GetRectWithMargin(sink, margin);
18
+
19
+            Point startPoint = GetOffsetPoint(source, rectSource);
20
+            Point endPoint = GetOffsetPoint(sink, rectSink);
21
+
22
+            linePoints.Add(startPoint);
23
+            Point currentPoint = startPoint;
24
+
25
+            if (!rectSink.Contains(currentPoint) && !rectSource.Contains(endPoint))
26
+            {
27
+                while (true)
28
+                {
29
+                    #region source node
30
+
31
+                    if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource, rectSink }))
32
+                    {
33
+                        linePoints.Add(endPoint);
34
+                        currentPoint = endPoint;
35
+                        break;
36
+                    }
37
+
38
+                    Point neighbour = GetNearestVisibleNeighborSink(currentPoint, endPoint, sink, rectSource, rectSink);
39
+                    if (!double.IsNaN(neighbour.X))
40
+                    {
41
+                        linePoints.Add(neighbour);
42
+                        linePoints.Add(endPoint);
43
+                        currentPoint = endPoint;
44
+                        break;
45
+                    }
46
+
47
+                    if (currentPoint == startPoint)
48
+                    {
49
+                        bool flag;
50
+                        Point n = GetNearestNeighborSource(source, endPoint, rectSource, rectSink, out flag);
51
+                        linePoints.Add(n);
52
+                        currentPoint = n;
53
+
54
+                        if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource }))
55
+                        {
56
+                            Point n1, n2;
57
+                            GetOppositeCorners(source.Orientation, rectSource, out n1, out n2);
58
+                            if (flag)
59
+                            {
60
+                                linePoints.Add(n1);
61
+                                currentPoint = n1;
62
+                            }
63
+                            else
64
+                            {
65
+                                linePoints.Add(n2);
66
+                                currentPoint = n2;
67
+                            }
68
+                            if (!IsRectVisible(currentPoint, rectSink, new Rect[] { rectSource }))
69
+                            {
70
+                                if (flag)
71
+                                {
72
+                                    linePoints.Add(n2);
73
+                                    currentPoint = n2;
74
+                                }
75
+                                else
76
+                                {
77
+                                    linePoints.Add(n1);
78
+                                    currentPoint = n1;
79
+                                }
80
+                            }
81
+                        }
82
+                    }
83
+                    #endregion
84
+
85
+                    #region sink node
86
+
87
+                    else // from here on we jump to the sink node
88
+                    {
89
+                        Point n1, n2; // neighbour corner
90
+                        Point s1, s2; // opposite corner
91
+                        GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2);
92
+                        GetOppositeCorners(sink.Orientation, rectSink, out n1, out n2);
93
+
94
+                        bool n1Visible = IsPointVisible(currentPoint, n1, new Rect[] { rectSource, rectSink });
95
+                        bool n2Visible = IsPointVisible(currentPoint, n2, new Rect[] { rectSource, rectSink });
96
+
97
+                        if (n1Visible && n2Visible)
98
+                        {
99
+                            if (rectSource.Contains(n1))
100
+                            {
101
+                                linePoints.Add(n2);
102
+                                if (rectSource.Contains(s2))
103
+                                {
104
+                                    linePoints.Add(n1);
105
+                                    linePoints.Add(s1);
106
+                                }
107
+                                else
108
+                                    linePoints.Add(s2);
109
+
110
+                                linePoints.Add(endPoint);
111
+                                currentPoint = endPoint;
112
+                                break;
113
+                            }
114
+
115
+                            if (rectSource.Contains(n2))
116
+                            {
117
+                                linePoints.Add(n1);
118
+                                if (rectSource.Contains(s1))
119
+                                {
120
+                                    linePoints.Add(n2);
121
+                                    linePoints.Add(s2);
122
+                                }
123
+                                else
124
+                                    linePoints.Add(s1);
125
+
126
+                                linePoints.Add(endPoint);
127
+                                currentPoint = endPoint;
128
+                                break;
129
+                            }
130
+
131
+                            if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
132
+                            {
133
+                                linePoints.Add(n1);
134
+                                if (rectSource.Contains(s1))
135
+                                {
136
+                                    linePoints.Add(n2);
137
+                                    linePoints.Add(s2);
138
+                                }
139
+                                else
140
+                                    linePoints.Add(s1);
141
+                                linePoints.Add(endPoint);
142
+                                currentPoint = endPoint;
143
+                                break;
144
+                            }
145
+                            else
146
+                            {
147
+                                linePoints.Add(n2);
148
+                                if (rectSource.Contains(s2))
149
+                                {
150
+                                    linePoints.Add(n1);
151
+                                    linePoints.Add(s1);
152
+                                }
153
+                                else
154
+                                    linePoints.Add(s2);
155
+                                linePoints.Add(endPoint);
156
+                                currentPoint = endPoint;
157
+                                break;
158
+                            }
159
+                        }
160
+                        else if (n1Visible)
161
+                        {
162
+                            linePoints.Add(n1);
163
+                            if (rectSource.Contains(s1))
164
+                            {
165
+                                linePoints.Add(n2);
166
+                                linePoints.Add(s2);
167
+                            }
168
+                            else
169
+                                linePoints.Add(s1);
170
+                            linePoints.Add(endPoint);
171
+                            currentPoint = endPoint;
172
+                            break;
173
+                        }
174
+                        else
175
+                        {
176
+                            linePoints.Add(n2);
177
+                            if (rectSource.Contains(s2))
178
+                            {
179
+                                linePoints.Add(n1);
180
+                                linePoints.Add(s1);
181
+                            }
182
+                            else
183
+                                linePoints.Add(s2);
184
+                            linePoints.Add(endPoint);
185
+                            currentPoint = endPoint;
186
+                            break;
187
+                        }
188
+                    }
189
+                    #endregion
190
+                }
191
+            }
192
+            else
193
+            {
194
+                linePoints.Add(endPoint);
195
+            }
196
+
197
+            linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource, rectSink }, source.Orientation, sink.Orientation);
198
+
199
+            CheckPathEnd(source, sink, showLastLine, linePoints);
200
+            return linePoints;
201
+        }        
202
+
203
+        internal static List<Point> GetConnectionLine(ConnectorInfo source, Point sinkPoint, ConnectorOrientation preferredOrientation)
204
+        {
205
+            List<Point> linePoints = new List<Point>();
206
+            Rect rectSource = GetRectWithMargin(source, 10);
207
+            Point startPoint = GetOffsetPoint(source, rectSource);
208
+            Point endPoint = sinkPoint;
209
+
210
+            linePoints.Add(startPoint);
211
+            Point currentPoint = startPoint;
212
+
213
+            if (!rectSource.Contains(endPoint))
214
+            {
215
+                while (true)
216
+                {
217
+                    if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource }))
218
+                    {
219
+                        linePoints.Add(endPoint);
220
+                        break;
221
+                    }
222
+
223
+                    bool sideFlag;
224
+                    Point n = GetNearestNeighborSource(source, endPoint, rectSource, out sideFlag);
225
+                    linePoints.Add(n);
226
+                    currentPoint = n;
227
+
228
+                    if (IsPointVisible(currentPoint, endPoint, new Rect[] { rectSource }))
229
+                    {
230
+                        linePoints.Add(endPoint);
231
+                        break;
232
+                    }
233
+                    else
234
+                    {
235
+                        Point n1, n2;
236
+                        GetOppositeCorners(source.Orientation, rectSource, out n1, out n2);
237
+                        if (sideFlag)
238
+                            linePoints.Add(n1);
239
+                        else
240
+                            linePoints.Add(n2);
241
+
242
+                        linePoints.Add(endPoint);
243
+                        break;
244
+                    }
245
+                }
246
+            }
247
+            else
248
+            {
249
+                linePoints.Add(endPoint);
250
+            }
251
+
252
+            if (preferredOrientation != ConnectorOrientation.None)
253
+                linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, preferredOrientation);
254
+            else
255
+                linePoints = OptimizeLinePoints(linePoints, new Rect[] { rectSource }, source.Orientation, GetOpositeOrientation(source.Orientation));
256
+
257
+            return linePoints;
258
+        }
259
+
260
+        private static List<Point> OptimizeLinePoints(List<Point> linePoints, Rect[] rectangles, ConnectorOrientation sourceOrientation, ConnectorOrientation sinkOrientation)
261
+        {
262
+            List<Point> points = new List<Point>();
263
+            int cut = 0;
264
+
265
+            for (int i = 0; i < linePoints.Count; i++)
266
+            {
267
+                if (i >= cut)
268
+                {
269
+                    for (int k = linePoints.Count - 1; k > i; k--)
270
+                    {
271
+                        if (IsPointVisible(linePoints[i], linePoints[k], rectangles))
272
+                        {
273
+                            cut = k;
274
+                            break;
275
+                        }
276
+                    }
277
+                    points.Add(linePoints[i]);
278
+                }
279
+            }
280
+
281
+            #region Line
282
+            for (int j = 0; j < points.Count - 1; j++)
283
+            {
284
+                if (points[j].X != points[j + 1].X && points[j].Y != points[j + 1].Y)
285
+                {
286
+                    ConnectorOrientation orientationFrom;
287
+                    ConnectorOrientation orientationTo;
288
+
289
+                    // orientation from point
290
+                    if (j == 0)
291
+                        orientationFrom = sourceOrientation;
292
+                    else
293
+                        orientationFrom = GetOrientation(points[j], points[j - 1]);
294
+
295
+                    // orientation to pint 
296
+                    if (j == points.Count - 2)
297
+                        orientationTo = sinkOrientation;
298
+                    else
299
+                        orientationTo = GetOrientation(points[j + 1], points[j + 2]);
300
+
301
+
302
+                    if ((orientationFrom == ConnectorOrientation.Left || orientationFrom == ConnectorOrientation.Right) &&
303
+                        (orientationTo == ConnectorOrientation.Left || orientationTo == ConnectorOrientation.Right))
304
+                    {
305
+                        double centerX = Math.Min(points[j].X, points[j + 1].X) + Math.Abs(points[j].X - points[j + 1].X) / 2;
306
+                        points.Insert(j + 1, new Point(centerX, points[j].Y));
307
+                        points.Insert(j + 2, new Point(centerX, points[j + 2].Y));
308
+                        if (points.Count - 1 > j + 3)
309
+                            points.RemoveAt(j + 3);
310
+                        return points;
311
+                    }
312
+
313
+                    if ((orientationFrom == ConnectorOrientation.Top || orientationFrom == ConnectorOrientation.Bottom) &&
314
+                        (orientationTo == ConnectorOrientation.Top || orientationTo == ConnectorOrientation.Bottom))
315
+                    {
316
+                        double centerY = Math.Min(points[j].Y, points[j + 1].Y) + Math.Abs(points[j].Y - points[j + 1].Y) / 2;
317
+                        points.Insert(j + 1, new Point(points[j].X, centerY));
318
+                        points.Insert(j + 2, new Point(points[j + 2].X, centerY));
319
+                        if (points.Count - 1 > j + 3)
320
+                            points.RemoveAt(j + 3);
321
+                        return points;
322
+                    }
323
+
324
+                    if ((orientationFrom == ConnectorOrientation.Left || orientationFrom == ConnectorOrientation.Right) &&
325
+                        (orientationTo == ConnectorOrientation.Top || orientationTo == ConnectorOrientation.Bottom))
326
+                    {
327
+                        points.Insert(j + 1, new Point(points[j + 1].X, points[j].Y));
328
+                        return points;
329
+                    }
330
+
331
+                    if ((orientationFrom == ConnectorOrientation.Top || orientationFrom == ConnectorOrientation.Bottom) &&
332
+                        (orientationTo == ConnectorOrientation.Left || orientationTo == ConnectorOrientation.Right))
333
+                    {
334
+                        points.Insert(j + 1, new Point(points[j].X, points[j + 1].Y));
335
+                        return points;
336
+                    }
337
+                }
338
+            }
339
+            #endregion
340
+
341
+            return points;
342
+        }
343
+
344
+        private static ConnectorOrientation GetOrientation(Point p1, Point p2)
345
+        {
346
+            if (p1.X == p2.X)
347
+            {
348
+                if (p1.Y >= p2.Y)
349
+                    return ConnectorOrientation.Bottom;
350
+                else
351
+                    return ConnectorOrientation.Top;
352
+            }
353
+            else if (p1.Y == p2.Y)
354
+            {
355
+                if (p1.X >= p2.X)
356
+                    return ConnectorOrientation.Right;
357
+                else
358
+                    return ConnectorOrientation.Left;
359
+            }
360
+            throw new Exception("Failed to retrieve orientation");
361
+        }
362
+
363
+        private static Orientation GetOrientation(ConnectorOrientation sourceOrientation)
364
+        {
365
+            switch (sourceOrientation)
366
+            {
367
+                case ConnectorOrientation.Left:
368
+                    return Orientation.Horizontal;
369
+                case ConnectorOrientation.Top:
370
+                    return Orientation.Vertical;
371
+                case ConnectorOrientation.Right:
372
+                    return Orientation.Horizontal;
373
+                case ConnectorOrientation.Bottom:
374
+                    return Orientation.Vertical;
375
+                default:
376
+                    throw new Exception("Unknown ConnectorOrientation");
377
+            }
378
+        }
379
+
380
+        private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, Rect rectSink, out bool flag)
381
+        {
382
+            Point n1, n2; // neighbors
383
+            GetNeighborCorners(source.Orientation, rectSource, out n1, out n2);
384
+
385
+            if (rectSink.Contains(n1))
386
+            {
387
+                flag = false;
388
+                return n2;
389
+            }
390
+
391
+            if (rectSink.Contains(n2))
392
+            {
393
+                flag = true;
394
+                return n1;
395
+            }
396
+
397
+            if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
398
+            {
399
+                flag = true;
400
+                return n1;
401
+            }
402
+            else
403
+            {
404
+                flag = false;
405
+                return n2;
406
+            }
407
+        }
408
+
409
+        private static Point GetNearestNeighborSource(ConnectorInfo source, Point endPoint, Rect rectSource, out bool flag)
410
+        {
411
+            Point n1, n2; // neighbors
412
+            GetNeighborCorners(source.Orientation, rectSource, out n1, out n2);
413
+
414
+            if ((Distance(n1, endPoint) <= Distance(n2, endPoint)))
415
+            {
416
+                flag = true;
417
+                return n1;
418
+            }
419
+            else
420
+            {
421
+                flag = false;
422
+                return n2;
423
+            }
424
+        }
425
+
426
+        private static Point GetNearestVisibleNeighborSink(Point currentPoint, Point endPoint, ConnectorInfo sink, Rect rectSource, Rect rectSink)
427
+        {
428
+            Point s1, s2; // neighbors on sink side
429
+            GetNeighborCorners(sink.Orientation, rectSink, out s1, out s2);
430
+
431
+            bool flag1 = IsPointVisible(currentPoint, s1, new Rect[] { rectSource, rectSink });
432
+            bool flag2 = IsPointVisible(currentPoint, s2, new Rect[] { rectSource, rectSink });
433
+
434
+            if (flag1) // s1 visible
435
+            {
436
+                if (flag2) // s1 and s2 visible
437
+                {
438
+                    if (rectSink.Contains(s1))
439
+                        return s2;
440
+
441
+                    if (rectSink.Contains(s2))
442
+                        return s1;
443
+
444
+                    if ((Distance(s1, endPoint) <= Distance(s2, endPoint)))
445
+                        return s1;
446
+                    else
447
+                        return s2;
448
+
449
+                }
450
+                else
451
+                {
452
+                    return s1;
453
+                }
454
+            }
455
+            else // s1 not visible
456
+            {
457
+                if (flag2) // only s2 visible
458
+                {
459
+                    return s2;
460
+                }
461
+                else // s1 and s2 not visible
462
+                {
463
+                    return new Point(double.NaN, double.NaN);
464
+                }
465
+            }
466
+        }
467
+
468
+        private static bool IsPointVisible(Point fromPoint, Point targetPoint, Rect[] rectangles)
469
+        {
470
+            foreach (Rect rect in rectangles)
471
+            {
472
+                if (RectangleIntersectsLine(rect, fromPoint, targetPoint))
473
+                    return false;
474
+            }
475
+            return true;
476
+        }
477
+
478
+        private static bool IsRectVisible(Point fromPoint, Rect targetRect, Rect[] rectangles)
479
+        {
480
+            if (IsPointVisible(fromPoint, targetRect.TopLeft, rectangles))
481
+                return true;
482
+
483
+            if (IsPointVisible(fromPoint, targetRect.TopRight, rectangles))
484
+                return true;
485
+
486
+            if (IsPointVisible(fromPoint, targetRect.BottomLeft, rectangles))
487
+                return true;
488
+
489
+            if (IsPointVisible(fromPoint, targetRect.BottomRight, rectangles))
490
+                return true;
491
+
492
+            return false;
493
+        }
494
+
495
+        private static bool RectangleIntersectsLine(Rect rect, Point startPoint, Point endPoint)
496
+        {
497
+            rect.Inflate(-1, -1);
498
+            return rect.IntersectsWith(new Rect(startPoint, endPoint));
499
+        }
500
+
501
+        private static void GetOppositeCorners(ConnectorOrientation orientation, Rect rect, out Point n1, out Point n2)
502
+        {
503
+            switch (orientation)
504
+            {
505
+                case ConnectorOrientation.Left:
506
+                    n1 = rect.TopRight; n2 = rect.BottomRight;
507
+                    break;
508
+                case ConnectorOrientation.Top:
509
+                    n1 = rect.BottomLeft; n2 = rect.BottomRight;
510
+                    break;
511
+                case ConnectorOrientation.Right:
512
+                    n1 = rect.TopLeft; n2 = rect.BottomLeft;
513
+                    break;
514
+                case ConnectorOrientation.Bottom:
515
+                    n1 = rect.TopLeft; n2 = rect.TopRight;
516
+                    break;
517
+                default:
518
+                    throw new Exception("No opposite corners found!");
519
+            }
520
+        }
521
+
522
+        private static void GetNeighborCorners(ConnectorOrientation orientation, Rect rect, out Point n1, out Point n2)
523
+        {
524
+            switch (orientation)
525
+            {
526
+                case ConnectorOrientation.Left:
527
+                    n1 = rect.TopLeft; n2 = rect.BottomLeft;
528
+                    break;
529
+                case ConnectorOrientation.Top:
530
+                    n1 = rect.TopLeft; n2 = rect.TopRight;
531
+                    break;
532
+                case ConnectorOrientation.Right:
533
+                    n1 = rect.TopRight; n2 = rect.BottomRight;
534
+                    break;
535
+                case ConnectorOrientation.Bottom:
536
+                    n1 = rect.BottomLeft; n2 = rect.BottomRight;
537
+                    break;
538
+                default:
539
+                    throw new Exception("No neighour corners found!");
540
+            }
541
+        }
542
+
543
+        private static double Distance(Point p1, Point p2)
544
+        {
545
+            return Point.Subtract(p1, p2).Length;
546
+        }
547
+
548
+        private static Rect GetRectWithMargin(ConnectorInfo connectorThumb, double margin)
549
+        {
550
+            Rect rect = new Rect(connectorThumb.DesignerItemLeft,
551
+                                 connectorThumb.DesignerItemTop,
552
+                                 connectorThumb.DesignerItemSize.Width,
553
+                                 connectorThumb.DesignerItemSize.Height);
554
+
555
+            rect.Inflate(margin, margin);
556
+
557
+            return rect;
558
+        }
559
+
560
+        private static Point GetOffsetPoint(ConnectorInfo connector, Rect rect)
561
+        {
562
+            Point offsetPoint = new Point();
563
+
564
+            switch (connector.Orientation)
565
+            {
566
+                case ConnectorOrientation.Left:
567
+                    offsetPoint = new Point(rect.Left, connector.Position.Y);
568
+                    break;
569
+                case ConnectorOrientation.Top:
570
+                    offsetPoint = new Point(connector.Position.X, rect.Top);
571
+                    break;
572
+                case ConnectorOrientation.Right:
573
+                    offsetPoint = new Point(rect.Right, connector.Position.Y);
574
+                    break;
575
+                case ConnectorOrientation.Bottom:
576
+                    offsetPoint = new Point(connector.Position.X, rect.Bottom);
577
+                    break;
578
+                default:
579
+                    break;
580
+            }
581
+
582
+            return offsetPoint;
583
+        }
584
+
585
+        private static void CheckPathEnd(ConnectorInfo source, ConnectorInfo sink, bool showLastLine, List<Point> linePoints)
586
+        {
587
+            if (showLastLine)
588
+            {
589
+                Point startPoint = new Point(0, 0);
590
+                Point endPoint = new Point(0, 0);
591
+                double marginPath = 15;
592
+                switch (source.Orientation)
593
+                {
594
+                    case ConnectorOrientation.Left:
595
+                        startPoint = new Point(source.Position.X - marginPath, source.Position.Y);
596
+                        break;
597
+                    case ConnectorOrientation.Top:
598
+                        startPoint = new Point(source.Position.X, source.Position.Y - marginPath);
599
+                        break;
600
+                    case ConnectorOrientation.Right:
601
+                        startPoint = new Point(source.Position.X + marginPath, source.Position.Y);
602
+                        break;
603
+                    case ConnectorOrientation.Bottom:
604
+                        startPoint = new Point(source.Position.X, source.Position.Y + marginPath);
605
+                        break;
606
+                    default:
607
+                        break;
608
+                }
609
+
610
+                switch (sink.Orientation)
611
+                {
612
+                    case ConnectorOrientation.Left:
613
+                        endPoint = new Point(sink.Position.X - marginPath, sink.Position.Y);
614
+                        break;
615
+                    case ConnectorOrientation.Top:
616
+                        endPoint = new Point(sink.Position.X, sink.Position.Y - marginPath);
617
+                        break;
618
+                    case ConnectorOrientation.Right:
619
+                        endPoint = new Point(sink.Position.X + marginPath, sink.Position.Y);
620
+                        break;
621
+                    case ConnectorOrientation.Bottom:
622
+                        endPoint = new Point(sink.Position.X, sink.Position.Y + marginPath);
623
+                        break;
624
+                    default:
625
+                        break;
626
+                }
627
+                linePoints.Insert(0, startPoint);
628
+                linePoints.Add(endPoint);
629
+            }
630
+            else
631
+            {
632
+                linePoints.Insert(0, source.Position);
633
+                linePoints.Add(sink.Position);
634
+            }
635
+        }
636
+
637
+        private static ConnectorOrientation GetOpositeOrientation(ConnectorOrientation connectorOrientation)
638
+        {
639
+            switch (connectorOrientation)
640
+            {
641
+                case ConnectorOrientation.Left:
642
+                    return ConnectorOrientation.Right;
643
+                case ConnectorOrientation.Top:
644
+                    return ConnectorOrientation.Bottom;
645
+                case ConnectorOrientation.Right:
646
+                    return ConnectorOrientation.Left;
647
+                case ConnectorOrientation.Bottom:
648
+                    return ConnectorOrientation.Top;
649
+                default:
650
+                    return ConnectorOrientation.Top;
651
+            }
652
+        }
653
+    }
654
+}

+ 636
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/PathFinder.ts 查看文件

@@ -0,0 +1,636 @@
1
+// 定义枚举类型
2
+enum ConnectorOrientation {
3
+  Left,
4
+  Top,
5
+  Right,
6
+  Bottom,
7
+  None
8
+}
9
+
10
+// 定义ConnectorInfo接口
11
+interface ConnectorInfo {
12
+  DesignerItemLeft: number;
13
+  DesignerItemTop: number;
14
+  DesignerItemSize: { Width: number; Height: number };
15
+  Orientation: ConnectorOrientation;
16
+  Position: { X: number; Y: number };
17
+}
18
+
19
+// 定义PathFinder类
20
+class PathFinder {
21
+  private static readonly margin = 20;
22
+
23
+  // 获取连接线路径
24
+  public static GetConnectionLine(source: ConnectorInfo, sink: ConnectorInfo, showLastLine: boolean): { X: number; Y: number }[] {
25
+    let linePoints: { X: number; Y: number }[] = [];
26
+
27
+    const rectSource = this.GetRectWithMargin(source, this.margin);
28
+    const rectSink = this.GetRectWithMargin(sink, this.margin);
29
+
30
+    const startPoint = this.GetOffsetPoint(source, rectSource);
31
+    const endPoint = this.GetOffsetPoint(sink, rectSink);
32
+
33
+    linePoints.push(startPoint);
34
+    let currentPoint = startPoint;
35
+
36
+    if (!this.isPointInRect(currentPoint, rectSink) && !this.isPointInRect(endPoint, rectSource)) {
37
+      while (true) {
38
+        // 源节点处理
39
+        if (this.IsPointVisible(currentPoint, endPoint, [rectSource, rectSink])) {
40
+          linePoints.push(endPoint);
41
+          currentPoint = endPoint;
42
+          break;
43
+        }
44
+
45
+        const neighbour = this.GetNearestVisibleNeighborSink(currentPoint, endPoint, sink, rectSource, rectSink);
46
+        if (!isNaN(neighbour.X)) {
47
+          linePoints.push(neighbour);
48
+          linePoints.push(endPoint);
49
+          currentPoint = endPoint;
50
+          break;
51
+        }
52
+
53
+        if (this.isSamePoint(currentPoint, startPoint)) {
54
+          let flag: boolean;
55
+          const n = this.GetNearestNeighborSource(source, endPoint, rectSource, rectSink, flag);
56
+          linePoints.push(n);
57
+          currentPoint = n;
58
+
59
+          if (!this.IsRectVisible(currentPoint, rectSink, [rectSource])) {
60
+            let n1: { X: number; Y: number };
61
+            let n2: { X: number; Y: number };
62
+            this.GetOppositeCorners(source.Orientation, rectSource, n1, n2);
63
+            if (flag) {
64
+              linePoints.push(n1);
65
+              currentPoint = n1;
66
+            } else {
67
+              linePoints.push(n2);
68
+              currentPoint = n2;
69
+            }
70
+            if (!this.IsRectVisible(currentPoint, rectSink, [rectSource])) {
71
+              if (flag) {
72
+                linePoints.push(n2);
73
+                currentPoint = n2;
74
+              } else {
75
+                linePoints.push(n1);
76
+                currentPoint = n1;
77
+              }
78
+            }
79
+          }
80
+        }
81
+
82
+        // 目标节点处理
83
+        else {
84
+          let n1: { X: number; Y: number };
85
+          let n2: { X: number; Y: number }; // 邻居角点
86
+          let s1: { X: number; Y: number };
87
+          let s2: { X: number; Y: number }; // 对角点
88
+          this.GetNeighborCorners(sink.Orientation, rectSink, n1, n2);
89
+          this.GetOppositeCorners(sink.Orientation, rectSink, s1, s2);
90
+
91
+          const n1Visible = this.IsPointVisible(currentPoint, n1, [rectSource, rectSink]);
92
+          const n2Visible = this.IsPointVisible(currentPoint, n2, [rectSource, rectSink]);
93
+
94
+          if (n1Visible && n2Visible) {
95
+            if (this.isPointInRect(n1, rectSource)) {
96
+              linePoints.push(n2);
97
+              if (this.isPointInRect(s2, rectSource)) {
98
+                linePoints.push(n1);
99
+                linePoints.push(s1);
100
+              } else {
101
+                linePoints.push(s2);
102
+              }
103
+              linePoints.push(endPoint);
104
+              currentPoint = endPoint;
105
+              break;
106
+            }
107
+
108
+            if (this.isPointInRect(n2, rectSource)) {
109
+              linePoints.push(n1);
110
+              if (this.isPointInRect(s1, rectSource)) {
111
+                linePoints.push(n2);
112
+                linePoints.push(s2);
113
+              } else {
114
+                linePoints.push(s1);
115
+              }
116
+              linePoints.push(endPoint);
117
+              currentPoint = endPoint;
118
+              break;
119
+            }
120
+
121
+            if (this.Distance(n1, endPoint) <= this.Distance(n2, endPoint)) {
122
+              linePoints.push(n1);
123
+              if (this.isPointInRect(s1, rectSource)) {
124
+                linePoints.push(n2);
125
+                linePoints.push(s2);
126
+              } else {
127
+                linePoints.push(s1);
128
+              }
129
+              linePoints.push(endPoint);
130
+              currentPoint = endPoint;
131
+              break;
132
+            } else {
133
+              linePoints.push(n2);
134
+              if (this.isPointInRect(s2, rectSource)) {
135
+                linePoints.push(n1);
136
+                linePoints.push(s1);
137
+              } else {
138
+                linePoints.push(s2);
139
+              }
140
+              linePoints.push(endPoint);
141
+              currentPoint = endPoint;
142
+              break;
143
+            }
144
+          } else if (n1Visible) {
145
+            linePoints.push(n1);
146
+            if (this.isPointInRect(s1, rectSource)) {
147
+              linePoints.push(n2);
148
+              linePoints.push(s2);
149
+            } else {
150
+              linePoints.push(s1);
151
+            }
152
+            linePoints.push(endPoint);
153
+            currentPoint = endPoint;
154
+            break;
155
+          } else {
156
+            linePoints.push(n2);
157
+            if (this.isPointInRect(s2, rectSource)) {
158
+              linePoints.push(n1);
159
+              linePoints.push(s1);
160
+            } else {
161
+              linePoints.push(s2);
162
+            }
163
+            linePoints.push(endPoint);
164
+            currentPoint = endPoint;
165
+            break;
166
+          }
167
+        }
168
+      }
169
+    } else {
170
+      linePoints.push(endPoint);
171
+    }
172
+
173
+    linePoints = this.OptimizeLinePoints(linePoints, [rectSource, rectSink], source.Orientation, sink.Orientation);
174
+
175
+    this.CheckPathEnd(source, sink, showLastLine, linePoints);
176
+    return linePoints;
177
+  }
178
+
179
+  // 获取连接线路径(另一个重载方法)
180
+  public static GetConnectionLine2(source: ConnectorInfo, sinkPoint: { X: number; Y: number }, preferredOrientation: ConnectorOrientation): { X: number; Y: number }[] {
181
+    let linePoints: { X: number; Y: number }[] = [];
182
+    const rectSource = this.GetRectWithMargin(source, 10);
183
+    const startPoint = this.GetOffsetPoint(source, rectSource);
184
+    const endPoint = sinkPoint;
185
+
186
+    linePoints.push(startPoint);
187
+    let currentPoint = startPoint;
188
+
189
+    if (!this.isPointInRect(endPoint, rectSource)) {
190
+      while (true) {
191
+        if (this.IsPointVisible(currentPoint, endPoint, [rectSource])) {
192
+          linePoints.push(endPoint);
193
+          break;
194
+        }
195
+
196
+        let sideFlag: boolean;
197
+        const n = this.GetNearestNeighborSource(source, endPoint, rectSource, sideFlag);
198
+        linePoints.push(n);
199
+        currentPoint = n;
200
+
201
+        if (this.IsPointVisible(currentPoint, endPoint, [rectSource])) {
202
+          linePoints.push(endPoint);
203
+          break;
204
+        } else {
205
+          let n1: { X: number; Y: number };
206
+          let n2: { X: number; Y: number };
207
+          this.GetOppositeCorners(source.Orientation, rectSource, n1, n2);
208
+          if (sideFlag) {
209
+            linePoints.push(n1);
210
+          } else {
211
+            linePoints.push(n2);
212
+          }
213
+          linePoints.push(endPoint);
214
+          break;
215
+        }
216
+      }
217
+    } else {
218
+      linePoints.push(endPoint);
219
+    }
220
+
221
+    if (preferredOrientation !== ConnectorOrientation.None) {
222
+      linePoints = this.OptimizeLinePoints(linePoints, [rectSource], source.Orientation, preferredOrientation);
223
+    } else {
224
+      linePoints = this.OptimizeLinePoints(linePoints, [rectSource], source.Orientation, this.GetOpositeOrientation(source.Orientation));
225
+    }
226
+
227
+    return linePoints;
228
+  }
229
+
230
+  // 优化线路点
231
+  private static OptimizeLinePoints(linePoints: { X: number; Y: number }[], rectangles: { Left: number; Top: number; Width: number; Height: number }[], sourceOrientation: ConnectorOrientation, sinkOrientation: ConnectorOrientation): { X: number; Y: number }[] {
232
+    let points: { X: number; Y: number }[] = [];
233
+    let cut = 0;
234
+
235
+    for (let i = 0; i < linePoints.length; i++) {
236
+      if (i >= cut) {
237
+        for (let k = linePoints.length - 1; k > i; k--) {
238
+          if (this.IsPointVisible(linePoints[i], linePoints[k], rectangles)) {
239
+            cut = k;
240
+            break;
241
+          }
242
+        }
243
+        points.push(linePoints[i]);
244
+      }
245
+    }
246
+
247
+    for (let j = 0; j < points.length - 1; j++) {
248
+      if (points[j].X !== points[j + 1].X && points[j].Y !== points[j + 1].Y) {
249
+        let orientationFrom: ConnectorOrientation;
250
+        let orientationTo: ConnectorOrientation;
251
+
252
+        // 起始点方向
253
+        if (j === 0) {
254
+          orientationFrom = sourceOrientation;
255
+        } else {
256
+          orientationFrom = this.GetOrientation(points[j], points[j - 1]);
257
+        }
258
+
259
+        // 目标点方向
260
+        if (j === points.length - 2) {
261
+          orientationTo = sinkOrientation;
262
+        } else {
263
+          orientationTo = this.GetOrientation(points[j + 1], points[j + 2]);
264
+        }
265
+
266
+        if ((orientationFrom === ConnectorOrientation.Left || orientationFrom === ConnectorOrientation.Right) &&
267
+          (orientationTo === ConnectorOrientation.Left || orientationTo === ConnectorOrientation.Right)) {
268
+          const centerX = Math.min(points[j].X, points[j + 1].X) + Math.abs(points[j].X - points[j + 1].X) / 2;
269
+          points.splice(j + 1, 0, { X: centerX, Y: points[j].Y });
270
+          points.splice(j + 2, 0, { X: centerX, Y: points[j + 2].Y });
271
+          if (points.length - 1 > j + 3) {
272
+            points.splice(j + 3, 1);
273
+          }
274
+          return points;
275
+        }
276
+
277
+        if ((orientationFrom === ConnectorOrientation.Top || orientationFrom === ConnectorOrientation.Bottom) &&
278
+          (orientationTo === ConnectorOrientation.Top || orientationTo === ConnectorOrientation.Bottom)) {
279
+          const centerY = Math.min(points[j].Y, points[j + 1].Y) + Math.abs(points[j].Y - points[j + 1].Y) / 2;
280
+          points.splice(j + 1, 0, { X: points[j].X, Y: centerY });
281
+          points.splice(j + 2, 0, { X: points[j + 2].X, Y: centerY });
282
+          if (points.length - 1 > j + 3) {
283
+            points.splice(j + 3, 1);
284
+          }
285
+          return points;
286
+        }
287
+
288
+        if ((orientationFrom === ConnectorOrientation.Left || orientationFrom === ConnectorOrientation.Right) &&
289
+          (orientationTo === ConnectorOrientation.Top || orientationTo === ConnectorOrientation.Bottom)) {
290
+          points.splice(j + 1, 0, { X: points[j + 1].X, Y: points[j].Y });
291
+          return points;
292
+        }
293
+
294
+        if ((orientationFrom === ConnectorOrientation.Top || orientationFrom === ConnectorOrientation.Bottom) &&
295
+          (orientationTo === ConnectorOrientation.Left || orientationTo === ConnectorOrientation.Right)) {
296
+          points.splice(j + 1, 0, { X: points[j].X, Y: points[j + 1].Y });
297
+          return points;
298
+        }
299
+      }
300
+    }
301
+
302
+    return points;
303
+  }
304
+
305
+  // 获取方向
306
+  private static GetOrientation(p1: { X: number; Y: number }, p2: { X: number; Y: number }): ConnectorOrientation {
307
+    if (p1.X === p2.X) {
308
+      if (p1.Y >= p2.Y) {
309
+        return ConnectorOrientation.Bottom;
310
+      } else {
311
+        return ConnectorOrientation.Top;
312
+      }
313
+    } else if (p1.Y === p2.Y) {
314
+      if (p1.X >= p2.X) {
315
+        return ConnectorOrientation.Right;
316
+      } else {
317
+        return ConnectorOrientation.Left;
318
+      }
319
+    }
320
+    throw new Error('Failed to retrieve orientation');
321
+  }
322
+
323
+  // 获取方向(另一个重载方法)
324
+  private static GetOrientation2(sourceOrientation: ConnectorOrientation): 'horizontal' | 'vertical' {
325
+    switch (sourceOrientation) {
326
+      case ConnectorOrientation.Left:
327
+        return 'horizontal';
328
+      case ConnectorOrientation.Top:
329
+        return 'vertical';
330
+      case ConnectorOrientation.Right:
331
+        return 'horizontal';
332
+      case ConnectorOrientation.Bottom:
333
+        return 'vertical';
334
+      default:
335
+        throw new Error('Unknown ConnectorOrientation');
336
+    }
337
+  }
338
+
339
+  // 获取最近的源邻居点
340
+  private static GetNearestNeighborSource(source: ConnectorInfo, endPoint: { X: number; Y: number }, rectSource: { Left: number; Top: number; Width: number; Height: number }, rectSink: { Left: number; Top: number; Width: number; Height: number }, flag: boolean): { X: number; Y: number } {
341
+    let n1: { X: number; Y: number };
342
+    let n2: { X: number; Y: number }; // 邻居点
343
+    this.GetNeighborCorners(source.Orientation, rectSource, n1, n2);
344
+
345
+    if (this.isPointInRect(n1, rectSink)) {
346
+      flag = false;
347
+      return n2;
348
+    }
349
+
350
+    if (this.isPointInRect(n2, rectSink)) {
351
+      flag = true;
352
+      return n1;
353
+    }
354
+
355
+    if (this.Distance(n1, endPoint) <= this.Distance(n2, endPoint)) {
356
+      flag = true;
357
+      return n1;
358
+    } else {
359
+      flag = false;
360
+      return n2;
361
+    }
362
+  }
363
+
364
+  // 获取最近的源邻居点(另一个重载方法)
365
+  private static GetNearestNeighborSource2(source: ConnectorInfo, endPoint: { X: number; Y: number }, rectSource: { Left: number; Top: number; Width: number; Height: number }, flag: boolean): { X: number; Y: number } {
366
+    let n1: { X: number; Y: number };
367
+    let n2: { X: number; Y: number }; // 邻居点
368
+    this.GetNeighborCorners(source.Orientation, rectSource, n1, n2);
369
+
370
+    if (this.Distance(n1, endPoint) <= this.Distance(n2, endPoint)) {
371
+      flag = true;
372
+      return n1;
373
+    } else {
374
+      flag = false;
375
+      return n2;
376
+    }
377
+  }
378
+
379
+  // 获取最近的可见目标邻居点
380
+  private static GetNearestVisibleNeighborSink(currentPoint: { X: number; Y: number }, endPoint: { X: number; Y: number }, sink: ConnectorInfo, rectSource: { Left: number; Top: number; Width: number; Height: number }, rectSink: { Left: number; Top: number; Width: number; Height: number }): { X: number; Y: number } {
381
+    let s1: { X: number; Y: number };
382
+    let s2: { X: number; Y: number }; // 目标侧邻居点
383
+    this.GetNeighborCorners(sink.Orientation, rectSink, s1, s2);
384
+
385
+    const flag1 = this.IsPointVisible(currentPoint, s1, [rectSource, rectSink]);
386
+    const flag2 = this.IsPointVisible(currentPoint, s2, [rectSource, rectSink]);
387
+
388
+    if (flag1) { // s1可见
389
+      if (flag2) { // s1和s2都可见
390
+        if (this.isPointInRect(s1, rectSink)) {
391
+          return s2;
392
+        }
393
+
394
+        if (this.isPointInRect(s2, rectSink)) {
395
+          return s1;
396
+        }
397
+
398
+        if (this.Distance(s1, endPoint) <= this.Distance(s2, endPoint)) {
399
+          return s1;
400
+        } else {
401
+          return s2;
402
+        }
403
+      } else {
404
+        return s1;
405
+      }
406
+    } else { // s1不可见
407
+      if (flag2) { // 只有s2可见
408
+        return s2;
409
+      } else { // s1和s2都不可见
410
+        return { X: NaN, Y: NaN };
411
+      }
412
+    }
413
+  }
414
+
415
+  // 判断点是否可见
416
+  private static IsPointVisible(fromPoint: { X: number; Y: number }, targetPoint: { X: number; Y: number }, rectangles: { Left: number; Top: number; Width: number; Height: number }[]): boolean {
417
+    for (const rect of rectangles) {
418
+      if (this.RectangleIntersectsLine(rect, fromPoint, targetPoint)) {
419
+        return false;
420
+      }
421
+    }
422
+    return true;
423
+  }
424
+
425
+  // 判断矩形是否可见
426
+  private static IsRectVisible(fromPoint: { X: number; Y: number }, targetRect: { Left: number; Top: number; Width: number; Height: number }, rectangles: { Left: number; Top: number; Width: number; Height: number }[]): boolean {
427
+    if (this.IsPointVisible(fromPoint, { X: targetRect.Left, Y: targetRect.Top }, rectangles)) {
428
+      return true;
429
+    }
430
+
431
+    if (this.IsPointVisible(fromPoint, { X: targetRect.Left + targetRect.Width, Y: targetRect.Top }, rectangles)) {
432
+      return true;
433
+    }
434
+
435
+    if (this.IsPointVisible(fromPoint, { X: targetRect.Left, Y: targetRect.Top + targetRect.Height }, rectangles)) {
436
+      return true;
437
+    }
438
+
439
+    if (this.IsPointVisible(fromPoint, { X: targetRect.Left + targetRect.Width, Y: targetRect.Top + targetRect.Height }, rectangles)) {
440
+      return true;
441
+    }
442
+
443
+    return false;
444
+  }
445
+
446
+  // 判断矩形是否与线段相交
447
+  private static RectangleIntersectsLine(rect: { Left: number; Top: number; Width: number; Height: number }, startPoint: { X: number; Y: number }, endPoint: { X: number; Y: number }): boolean {
448
+    const newRect = { ...rect };
449
+    newRect.Left -= 1;
450
+    newRect.Top -= 1;
451
+    newRect.Width += 2;
452
+    newRect.Height += 2;
453
+    const lineRect = {
454
+      Left: Math.min(startPoint.X, endPoint.X),
455
+      Top: Math.min(startPoint.Y, endPoint.Y),
456
+      Width: Math.abs(startPoint.X - endPoint.X),
457
+      Height: Math.abs(startPoint.Y - endPoint.Y)
458
+    };
459
+    return this.isRectIntersect(newRect, lineRect);
460
+  }
461
+
462
+  // 获取对角点
463
+  private static GetOppositeCorners(orientation: ConnectorOrientation, rect: { Left: number; Top: number; Width: number; Height: number }, n1: { X: number; Y: number }, n2: { X: number; Y: number }): void {
464
+    switch (orientation) {
465
+      case ConnectorOrientation.Left:
466
+        n1 = { X: rect.Left + rect.Width, Y: rect.Top };
467
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top + rect.Height };
468
+        break;
469
+      case ConnectorOrientation.Top:
470
+        n1 = { X: rect.Left, Y: rect.Top + rect.Height };
471
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top + rect.Height };
472
+        break;
473
+      case ConnectorOrientation.Right:
474
+        n1 = { X: rect.Left, Y: rect.Top };
475
+        n2 = { X: rect.Left, Y: rect.Top + rect.Height };
476
+        break;
477
+      case ConnectorOrientation.Bottom:
478
+        n1 = { X: rect.Left, Y: rect.Top };
479
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top };
480
+        break;
481
+      default:
482
+        throw new Error('No opposite corners found!');
483
+    }
484
+  }
485
+
486
+  // 获取邻居角点
487
+  private static GetNeighborCorners(orientation: ConnectorOrientation, rect: { Left: number; Top: number; Width: number; Height: number }, n1: { X: number; Y: number }, n2: { X: number; Y: number }): void {
488
+    switch (orientation) {
489
+      case ConnectorOrientation.Left:
490
+        n1 = { X: rect.Left, Y: rect.Top };
491
+        n2 = { X: rect.Left, Y: rect.Top + rect.Height };
492
+        break;
493
+      case ConnectorOrientation.Top:
494
+        n1 = { X: rect.Left, Y: rect.Top };
495
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top };
496
+        break;
497
+      case ConnectorOrientation.Right:
498
+        n1 = { X: rect.Left + rect.Width, Y: rect.Top };
499
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top + rect.Height };
500
+        break;
501
+      case ConnectorOrientation.Bottom:
502
+        n1 = { X: rect.Left, Y: rect.Top + rect.Height };
503
+        n2 = { X: rect.Left + rect.Width, Y: rect.Top + rect.Height };
504
+        break;
505
+      default:
506
+        throw new Error('No neighour corners found!');
507
+    }
508
+  }
509
+
510
+  // 计算两点之间的距离
511
+  private static Distance(p1: { X: number; Y: number }, p2: { X: number; Y: number }): number {
512
+    const dx = p1.X - p2.X;
513
+    const dy = p1.Y - p2.Y;
514
+    return Math.sqrt(dx * dx + dy * dy);
515
+  }
516
+
517
+  // 获取带有边距的矩形
518
+  private static GetRectWithMargin(connectorThumb: ConnectorInfo, margin: number): { Left: number; Top: number; Width: number; Height: number } {
519
+    const rect = {
520
+      Left: connectorThumb.DesignerItemLeft,
521
+      Top: connectorThumb.DesignerItemTop,
522
+      Width: connectorThumb.DesignerItemSize.Width,
523
+      Height: connectorThumb.DesignerItemSize.Height
524
+    };
525
+    rect.Left -= margin;
526
+    rect.Top -= margin;
527
+    rect.Width += 2 * margin;
528
+    rect.Height += 2 * margin;
529
+    return rect;
530
+  }
531
+
532
+  // 获取偏移点
533
+  private static GetOffsetPoint(connector: ConnectorInfo, rect: { Left: number; Top: number; Width: number; Height: number }): { X: number; Y: number } {
534
+    let offsetPoint: { X: number; Y: number };
535
+    switch (connector.Orientation) {
536
+      case ConnectorOrientation.Left:
537
+        offsetPoint = { X: rect.Left, Y: connector.Position.Y };
538
+        break;
539
+      case ConnectorOrientation.Top:
540
+        offsetPoint = { X: connector.Position.X, Y: rect.Top };
541
+        break;
542
+      case ConnectorOrientation.Right:
543
+        offsetPoint = { X: rect.Left + rect.Width, Y: connector.Position.Y };
544
+        break;
545
+      case ConnectorOrientation.Bottom:
546
+        offsetPoint = { X: connector.Position.X, Y: rect.Top + rect.Height };
547
+        break;
548
+      default:
549
+        offsetPoint = { X: 0, Y: 0 };
550
+        break;
551
+    }
552
+    return offsetPoint;
553
+  }
554
+
555
+  // 检查路径终点
556
+  private static CheckPathEnd(source: ConnectorInfo, sink: ConnectorInfo, showLastLine: boolean, linePoints: { X: number; Y: number }[]): void {
557
+    if (showLastLine) {
558
+      let startPoint: { X: number; Y: number };
559
+      let endPoint: { X: number; Y: number };
560
+      const marginPath = 15;
561
+      switch (source.Orientation) {
562
+        case ConnectorOrientation.Left:
563
+          startPoint = { X: source.Position.X - marginPath, Y: source.Position.Y };
564
+          break;
565
+        case ConnectorOrientation.Top:
566
+          startPoint = { X: source.Position.X, Y: source.Position.Y - marginPath };
567
+          break;
568
+        case ConnectorOrientation.Right:
569
+          startPoint = { X: source.Position.X + marginPath, Y: source.Position.Y };
570
+          break;
571
+        case ConnectorOrientation.Bottom:
572
+          startPoint = { X: source.Position.X, Y: source.Position.Y + marginPath };
573
+          break;
574
+        default:
575
+          startPoint = { X: 0, Y: 0 };
576
+          break;
577
+      }
578
+
579
+      switch (sink.Orientation) {
580
+        case ConnectorOrientation.Left:
581
+          endPoint = { X: sink.Position.X - marginPath, Y: sink.Position.Y };
582
+          break;
583
+        case ConnectorOrientation.Top:
584
+          endPoint = { X: sink.Position.X, Y: sink.Position.Y - marginPath };
585
+          break;
586
+        case ConnectorOrientation.Right:
587
+          endPoint = { X: sink.Position.X + marginPath, Y: sink.Position.Y };
588
+          break;
589
+        case ConnectorOrientation.Bottom:
590
+          endPoint = { X: sink.Position.X, Y: sink.Position.Y + marginPath };
591
+          break;
592
+        default:
593
+          endPoint = { X: 0, Y: 0 };
594
+          break;
595
+      }
596
+      linePoints.unshift(startPoint);
597
+      linePoints.push(endPoint);
598
+    } else {
599
+      linePoints.unshift(source.Position);
600
+      linePoints.push(sink.Position);
601
+    }
602
+  }
603
+
604
+  // 获取相反方向
605
+  private static GetOpositeOrientation(connectorOrientation: ConnectorOrientation): ConnectorOrientation {
606
+    switch (connectorOrientation) {
607
+      case ConnectorOrientation.Left:
608
+        return ConnectorOrientation.Right;
609
+      case ConnectorOrientation.Top:
610
+        return ConnectorOrientation.Bottom;
611
+      case ConnectorOrientation.Right:
612
+        return ConnectorOrientation.Left;
613
+      case ConnectorOrientation.Bottom:
614
+        return ConnectorOrientation.Top;
615
+      default:
616
+        return ConnectorOrientation.Top;
617
+    }
618
+  }
619
+
620
+  // 判断点是否在矩形内
621
+  private static isPointInRect(point: { X: number; Y: number }, rect: { Left: number; Top: number; Width: number; Height: number }): boolean {
622
+    return point.X >= rect.Left && point.X <= rect.Left + rect.Width && point.Y >= rect.Top && point.Y <= rect.Top + rect.Height;
623
+  }
624
+
625
+  // 判断两个点是否相同
626
+  private static isSamePoint(p1: { X: number; Y: number }, p2: { X: number; Y: number }): boolean {
627
+    return p1.X === p2.X && p1.Y === p2.Y;
628
+  }
629
+
630
+  // 判断两个矩形是否相交
631
+  private static isRectIntersect(rect1: { Left: number; Top: number; Width: number; Height: number }, rect2: { Left: number; Top: number; Width: number; Height: number }): boolean {
632
+    return !(rect1.Left + rect1.Width < rect2.Left || rect2.Left + rect2.Width < rect1.Left || rect1.Top + rect1.Height < rect2.Top || rect2.Top + rect2.Height < rect1.Top);
633
+  }
634
+}
635
+
636
+export { PathFinder, ConnectorOrientation, ConnectorInfo };

+ 82
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RelativePositionPanel.cs 查看文件

@@ -0,0 +1,82 @@
1
+using System;
2
+using System.Windows;
3
+using System.Windows.Controls;
4
+using System.Windows.Media;
5
+
6
+namespace TellerSystem.Controls.Ext.Controls
7
+{
8
+    public class RelativePositionPanel : Panel
9
+    {
10
+        public static readonly DependencyProperty RelativePositionProperty =
11
+            DependencyProperty.RegisterAttached("RelativePosition", typeof(Point), typeof(RelativePositionPanel),
12
+            new FrameworkPropertyMetadata(new Point(0, 0),
13
+                                          new PropertyChangedCallback(RelativePositionPanel.OnRelativePositionChanged)));
14
+
15
+        public static Point GetRelativePosition(UIElement element)
16
+        {
17
+            if (element == null)
18
+            {
19
+                throw new ArgumentNullException("element");
20
+            }
21
+            return (Point)element.GetValue(RelativePositionProperty);
22
+        }
23
+
24
+        public static void SetRelativePosition(UIElement element, Point value)
25
+        {
26
+            if (element == null)
27
+            {
28
+                throw new ArgumentNullException("element");
29
+            }
30
+            element.SetValue(RelativePositionProperty, value);
31
+        }
32
+
33
+        private static void OnRelativePositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
34
+        {
35
+            UIElement reference = d as UIElement;
36
+            if (reference != null)
37
+            {
38
+                RelativePositionPanel parent = VisualTreeHelper.GetParent(reference) as RelativePositionPanel;
39
+                if (parent != null)
40
+                {
41
+                    parent.InvalidateArrange();
42
+                }
43
+            }
44
+        }
45
+
46
+        protected override Size ArrangeOverride(Size arrangeSize)
47
+        {
48
+            foreach (UIElement element in base.InternalChildren)
49
+            {
50
+                if (element != null)
51
+                {
52
+                    Point relPosition = GetRelativePosition(element);
53
+                    double x = (arrangeSize.Width - element.DesiredSize.Width) * relPosition.X;
54
+                    double y = (arrangeSize.Height - element.DesiredSize.Height) * relPosition.Y;
55
+
56
+                    if (double.IsNaN(x)) x = 0;
57
+                    if (double.IsNaN(y)) y = 0;
58
+
59
+                    element.Arrange(new Rect(new Point(x, y), element.DesiredSize));
60
+                }
61
+            }
62
+            return arrangeSize;
63
+        }
64
+
65
+        protected override Size MeasureOverride(Size availableSize)
66
+        {
67
+            Size size = new Size(double.PositiveInfinity, double.PositiveInfinity);
68
+
69
+            // SDK docu says about InternalChildren Property: 'Classes that are derived from Panel 
70
+            // should use this property, instead of the Children property, for internal overrides 
71
+            // such as MeasureCore and ArrangeCore.
72
+
73
+            foreach (UIElement element in this.InternalChildren)
74
+            {
75
+                if (element != null)
76
+                    element.Measure(size);
77
+            }
78
+
79
+            return base.MeasureOverride(availableSize);
80
+        }
81
+    }
82
+}

+ 88
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RelativePositionPanel.ts 查看文件

@@ -0,0 +1,88 @@
1
+import { ref, onBeforeUpdate, watchEffect } from 'vue';
2
+
3
+// 定义附加属性的存储对象
4
+const relativePositions = new WeakMap<HTMLElement, { x: number; y: number }>();
5
+
6
+// 获取相对位置
7
+export function getRelativePosition(element: HTMLElement): { x: number; y: number } {
8
+  if (!element) {
9
+    throw new Error('element is null');
10
+  }
11
+  return relativePositions.get(element) || { x: 0, y: 0 };
12
+}
13
+
14
+// 设置相对位置
15
+export function setRelativePosition(element: HTMLElement, value: { x: number; y: number }): void {
16
+  if (!element) {
17
+    throw new Error('element is null');
18
+  }
19
+  relativePositions.set(element, value);
20
+  // 触发重新布局
21
+  const parent = element.parentElement;
22
+  if (parent) {
23
+    const parentComponent = (parent as any).__vueParentComponent;
24
+    if (parentComponent) {
25
+      parentComponent.forceUpdate();
26
+    }
27
+  }
28
+}
29
+
30
+// 自定义相对位置面板组件
31
+export default {
32
+  name: 'RelativePositionPanel',
33
+  setup() {
34
+    const containerRef = ref<HTMLElement | null>(null);
35
+
36
+    // 测量子元素大小
37
+    const measureChildren = () => {
38
+      if (containerRef.value) {
39
+        const children = containerRef.value.children;
40
+        for (let i = 0; i < children.length; i++) {
41
+          const child = children[i] as HTMLElement;
42
+          // 这里模拟 Measure 操作,实际中可能需要更复杂的逻辑
43
+          child.style.width = 'auto';
44
+          child.style.height = 'auto';
45
+        }
46
+      }
47
+    };
48
+
49
+    // 布局子元素
50
+    const arrangeChildren = () => {
51
+      if (containerRef.value) {
52
+        const containerWidth = containerRef.value.offsetWidth;
53
+        const containerHeight = containerRef.value.offsetHeight;
54
+        const children = containerRef.value.children;
55
+        for (let i = 0; i < children.length; i++) {
56
+          const child = children[i] as HTMLElement;
57
+          const { x, y } = getRelativePosition(child);
58
+          const childWidth = child.offsetWidth;
59
+          const childHeight = child.offsetHeight;
60
+          const left = (containerWidth - childWidth) * x;
61
+          const top = (containerHeight - childHeight) * y;
62
+          child.style.position = 'absolute';
63
+          child.style.left = isNaN(left) ? '0px' : `${left}px`;
64
+          child.style.top = isNaN(top) ? '0px' : `${top}px`;
65
+        }
66
+      }
67
+    };
68
+
69
+    // 在更新前测量子元素
70
+    onBeforeUpdate(() => {
71
+      measureChildren();
72
+    });
73
+
74
+    // 监听容器大小变化并重新布局
75
+    watchEffect(() => {
76
+      arrangeChildren();
77
+    });
78
+
79
+    return {
80
+      containerRef,
81
+    };
82
+  },
83
+  template: `
84
+    <div ref="containerRef">
85
+      <slot></slot>
86
+    </div>
87
+  `,
88
+};

+ 99
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ResizeThumb.cs 查看文件

@@ -0,0 +1,99 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Windows;
5
+using System.Windows.Controls;
6
+using System.Windows.Controls.Primitives;
7
+using System.Windows.Media;
8
+
9
+namespace TellerSystem.Controls.Ext.Controls
10
+{
11
+    public class ResizeThumb : Thumb
12
+    {
13
+        public ResizeThumb()
14
+        {
15
+            base.DragDelta += new DragDeltaEventHandler(ResizeThumb_DragDelta);
16
+        }
17
+
18
+        void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e)
19
+        {
20
+            DesignerItem designerItem = this.DataContext as DesignerItem;
21
+            DesignerCanvas designer = VisualTreeHelper.GetParent(designerItem) as DesignerCanvas;
22
+            
23
+            if (designerItem != null && designer != null && designerItem.IsSelected)
24
+            {
25
+                double minLeft, minTop, minDeltaHorizontal, minDeltaVertical;
26
+                double dragDeltaVertical, dragDeltaHorizontal;
27
+
28
+                // only resize DesignerItems
29
+                var selectedDesignerItems = from item in designer.SelectedItems
30
+                                            where item is DesignerItem
31
+                                            select item;
32
+
33
+                CalculateDragLimits(selectedDesignerItems, out minLeft, out minTop, 
34
+                                    out minDeltaHorizontal, out minDeltaVertical);               
35
+
36
+                foreach (DesignerItem item in selectedDesignerItems)
37
+                {
38
+                    if (item != null)
39
+                    {
40
+                        switch (base.VerticalAlignment)
41
+                        {
42
+                            case VerticalAlignment.Bottom:
43
+                                dragDeltaVertical = Math.Min(-e.VerticalChange, minDeltaVertical);
44
+                                item.Height = item.ActualHeight - dragDeltaVertical;
45
+                                break;
46
+                            case VerticalAlignment.Top:
47
+                                double top = Canvas.GetTop(item);
48
+                                dragDeltaVertical = Math.Min(Math.Max(-minTop, e.VerticalChange), minDeltaVertical);
49
+                                Canvas.SetTop(item, top + dragDeltaVertical);
50
+                                item.Height = item.ActualHeight - dragDeltaVertical;
51
+                                break;
52
+                            default:
53
+                                break;
54
+                        }
55
+
56
+                        switch (base.HorizontalAlignment)
57
+                        {
58
+                            case HorizontalAlignment.Left:
59
+                                double left = Canvas.GetLeft(item);
60
+                                dragDeltaHorizontal = Math.Min(Math.Max(-minLeft, e.HorizontalChange), minDeltaHorizontal);
61
+                                Canvas.SetLeft(item, left + dragDeltaHorizontal);
62
+                                item.Width = item.ActualWidth - dragDeltaHorizontal;
63
+                                break;
64
+                            case HorizontalAlignment.Right:
65
+                                dragDeltaHorizontal = Math.Min(-e.HorizontalChange, minDeltaHorizontal);
66
+                                item.Width = item.ActualWidth - dragDeltaHorizontal;
67
+                                break;
68
+                            default:
69
+                                break;
70
+                        }
71
+                    }
72
+                }
73
+                e.Handled = true;
74
+            }
75
+        }
76
+        
77
+        private static void CalculateDragLimits(IEnumerable<ISelectable> selectedDesignerItems, out double minLeft, out double minTop, out double minDeltaHorizontal, out double minDeltaVertical)
78
+        {
79
+            minLeft = double.MaxValue;
80
+            minTop = double.MaxValue;
81
+            minDeltaHorizontal = double.MaxValue;
82
+            minDeltaVertical = double.MaxValue;
83
+
84
+            // drag limits are set by these parameters: canvas top, canvas left, minHeight, minWidth
85
+            // calculate min value for each parameter for each item
86
+            foreach (DesignerItem item in selectedDesignerItems)
87
+            {
88
+                double left = Canvas.GetLeft(item);
89
+                double top = Canvas.GetTop(item);
90
+
91
+                minLeft = double.IsNaN(left) ? 0 : Math.Min(left, minLeft);
92
+                minTop = double.IsNaN(top) ? 0 : Math.Min(top, minTop);
93
+
94
+                minDeltaVertical = Math.Min(minDeltaVertical, item.ActualHeight - item.MinHeight);
95
+                minDeltaHorizontal = Math.Min(minDeltaHorizontal, item.ActualWidth - item.MinWidth);
96
+            }
97
+        }
98
+    }
99
+}

+ 111
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/ResizeThumb.ts 查看文件

@@ -0,0 +1,111 @@
1
+import { ref, onMounted } from 'vue';
2
+
3
+// 假设这些类型已经在其他文件中定义
4
+interface DesignerItem {
5
+    IsSelected: boolean;
6
+    ActualHeight: number;
7
+    ActualWidth: number;
8
+    Height: number;
9
+    Width: number;
10
+    MinHeight: number;
11
+    MinWidth: number;
12
+}
13
+
14
+interface DesignerCanvas {
15
+    SelectedItems: DesignerItem[];
16
+}
17
+
18
+interface ISelectable {
19
+    // 这里可以根据实际情况补充 ISelectable 接口的属性和方法
20
+}
21
+
22
+// 模拟 Thumb 组件的功能
23
+class ResizeThumb {
24
+    private verticalAlignment: string;
25
+    private horizontalAlignment: string;
26
+    private dragDeltaHandler: (e: { VerticalChange: number; HorizontalChange: number }) => void;
27
+
28
+    constructor(verticalAlignment: string, horizontalAlignment: string, dragDeltaHandler: (e: { VerticalChange: number; HorizontalChange: number }) => void) {
29
+        this.verticalAlignment = verticalAlignment;
30
+        this.horizontalAlignment = horizontalAlignment;
31
+        this.dragDeltaHandler = dragDeltaHandler;
32
+        // 模拟订阅 DragDelta 事件
33
+        onMounted(() => {
34
+            // 这里可以添加实际的拖拽事件监听逻辑
35
+            // 例如:document.addEventListener('mousemove', this.handleDragDelta);
36
+        });
37
+    }
38
+
39
+    private handleDragDelta = (e: { VerticalChange: number; HorizontalChange: number }) => {
40
+        this.dragDeltaHandler(e);
41
+    }
42
+}
43
+
44
+// 实现 ResizeThumb 的主要逻辑
45
+const useResizeThumb = (verticalAlignment: string, horizontalAlignment: string, designerCanvas: DesignerCanvas) => {
46
+    const resizeThumb = new ResizeThumb(verticalAlignment, horizontalAlignment, (e) => {
47
+        const selectedDesignerItems = designerCanvas.SelectedItems.filter(item => item.IsSelected);
48
+        let minLeft: number, minTop: number, minDeltaHorizontal: number, minDeltaVertical: number;
49
+        CalculateDragLimits(selectedDesignerItems, out minLeft, out minTop, out minDeltaHorizontal, out minDeltaVertical);
50
+
51
+        selectedDesignerItems.forEach(item => {
52
+            if (item) {
53
+                let dragDeltaVertical: number, dragDeltaHorizontal: number;
54
+
55
+                switch (verticalAlignment) {
56
+                    case 'Bottom':
57
+                        dragDeltaVertical = Math.min(-e.VerticalChange, minDeltaVertical);
58
+                        item.Height = item.ActualHeight - dragDeltaVertical;
59
+                        break;
60
+                    case 'Top':
61
+                        const top = item.Top;
62
+                        dragDeltaVertical = Math.min(Math.max(-minTop, e.VerticalChange), minDeltaVertical);
63
+                        item.Top = top + dragDeltaVertical;
64
+                        item.Height = item.ActualHeight - dragDeltaVertical;
65
+                        break;
66
+                    default:
67
+                        break;
68
+                }
69
+
70
+                switch (horizontalAlignment) {
71
+                    case 'Left':
72
+                        const left = item.Left;
73
+                        dragDeltaHorizontal = Math.min(Math.max(-minLeft, e.HorizontalChange), minDeltaHorizontal);
74
+                        item.Left = left + dragDeltaHorizontal;
75
+                        item.Width = item.ActualWidth - dragDeltaHorizontal;
76
+                        break;
77
+                    case 'Right':
78
+                        dragDeltaHorizontal = Math.min(-e.HorizontalChange, minDeltaHorizontal);
79
+                        item.Width = item.ActualWidth - dragDeltaHorizontal;
80
+                        break;
81
+                    default:
82
+                        break;
83
+                }
84
+            }
85
+        });
86
+    });
87
+
88
+    return resizeThumb;
89
+};
90
+
91
+// 计算拖拽限制的方法
92
+const CalculateDragLimits = (selectedDesignerItems: ISelectable[], out minLeft: number, out minTop: number, out minDeltaHorizontal: number, out minDeltaVertical: number) => {
93
+    minLeft = Number.MAX_VALUE;
94
+    minTop = Number.MAX_VALUE;
95
+    minDeltaHorizontal = Number.MAX_VALUE;
96
+    minDeltaVertical = Number.MAX_VALUE;
97
+
98
+    selectedDesignerItems.forEach(item => {
99
+        const designerItem = item as DesignerItem;
100
+        const left = designerItem.Left;
101
+        const top = designerItem.Top;
102
+
103
+        minLeft = isNaN(left) ? 0 : Math.min(left, minLeft);
104
+        minTop = isNaN(top) ? 0 : Math.min(top, minTop);
105
+
106
+        minDeltaVertical = Math.min(minDeltaVertical, designerItem.ActualHeight - designerItem.MinHeight);
107
+        minDeltaHorizontal = Math.min(minDeltaHorizontal, designerItem.ActualWidth - designerItem.MinWidth);
108
+    });
109
+};
110
+
111
+export { useResizeThumb };

+ 92
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RubberbandAdorner.cs 查看文件

@@ -0,0 +1,92 @@
1
+using System.Windows;
2
+using System.Windows.Controls;
3
+using System.Windows.Documents;
4
+using System.Windows.Input;
5
+using System.Windows.Media;
6
+
7
+namespace TellerSystem.Controls.Ext.Controls
8
+{
9
+    public class RubberbandAdorner : Adorner
10
+    {
11
+        private Point? startPoint;
12
+        private Point? endPoint;
13
+        private Pen rubberbandPen;
14
+
15
+        private DesignerCanvas designerCanvas;
16
+
17
+        public RubberbandAdorner(DesignerCanvas designerCanvas, Point? dragStartPoint)
18
+            : base(designerCanvas)
19
+        {
20
+            this.designerCanvas = designerCanvas;
21
+            this.startPoint = dragStartPoint;
22
+            rubberbandPen = new Pen(Brushes.LightSlateGray, 1);
23
+            rubberbandPen.DashStyle = new DashStyle(new double[] { 2 }, 1);
24
+        }
25
+
26
+        protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
27
+        {
28
+            if (e.LeftButton == MouseButtonState.Pressed)
29
+            {
30
+                if (!this.IsMouseCaptured)
31
+                    this.CaptureMouse();
32
+
33
+                endPoint = e.GetPosition(this);
34
+                UpdateSelection();
35
+                this.InvalidateVisual();
36
+            }
37
+            else
38
+            {
39
+                if (this.IsMouseCaptured) this.ReleaseMouseCapture();
40
+            }
41
+
42
+            e.Handled = true;
43
+        }
44
+
45
+        protected override void OnMouseUp(System.Windows.Input.MouseButtonEventArgs e)
46
+        {
47
+            // release mouse capture
48
+            if (this.IsMouseCaptured) this.ReleaseMouseCapture();
49
+
50
+            // remove this adorner from adorner layer
51
+            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(this.designerCanvas);
52
+            if (adornerLayer != null)
53
+                adornerLayer.Remove(this);
54
+
55
+            e.Handled = true;
56
+        }
57
+
58
+        protected override void OnRender(DrawingContext dc)
59
+        {
60
+            base.OnRender(dc);
61
+
62
+            // without a background the OnMouseMove event would not be fired !
63
+            // Alternative: implement a Canvas as a child of this adorner, like
64
+            // the ConnectionAdorner does.
65
+            dc.DrawRectangle(Brushes.Transparent, null, new Rect(RenderSize));
66
+
67
+            if (this.startPoint.HasValue && this.endPoint.HasValue)
68
+                dc.DrawRectangle(Brushes.Transparent, rubberbandPen, new Rect(this.startPoint.Value, this.endPoint.Value));
69
+        }
70
+
71
+        private void UpdateSelection()
72
+        {
73
+            foreach (ISelectable item in designerCanvas.SelectedItems)
74
+                item.IsSelected = false;
75
+            designerCanvas.SelectedItems.Clear();
76
+
77
+            Rect rubberBand = new Rect(startPoint.Value, endPoint.Value);
78
+            foreach (Control item in designerCanvas.Children)
79
+            {
80
+                Rect itemRect = VisualTreeHelper.GetDescendantBounds(item);
81
+                Rect itemBounds = item.TransformToAncestor(designerCanvas).TransformBounds(itemRect);
82
+
83
+                if (rubberBand.Contains(itemBounds) && item is ISelectable)
84
+                {
85
+                    ISelectable selectableItem = item as ISelectable;
86
+                    selectableItem.IsSelected = true;
87
+                    designerCanvas.SelectedItems.Add(selectableItem);
88
+                }
89
+            }
90
+        }
91
+    }
92
+}

+ 133
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/RubberbandAdorner.ts 查看文件

@@ -0,0 +1,133 @@
1
+import { ref, onMounted, onUnmounted, Ref } from 'vue';
2
+
3
+// 假设 ISelectable 接口定义如下
4
+interface ISelectable {
5
+  IsSelected: boolean;
6
+}
7
+
8
+// 假设 DesignerCanvas 类定义如下
9
+class DesignerCanvas {
10
+  Children: HTMLElement[] = [];
11
+  SelectedItems: ISelectable[] = [];
12
+}
13
+
14
+export default {
15
+  props: {
16
+    designerCanvas: {
17
+      type: Object as () => DesignerCanvas,
18
+      required: true
19
+    },
20
+    dragStartPoint: {
21
+      type: Object as () => { x: number; y: number } | null,
22
+      default: null
23
+    }
24
+  },
25
+  setup(props) {
26
+    const startPoint = ref<{ x: number; y: number } | null>(props.dragStartPoint);
27
+    const endPoint = ref<{ x: number; y: number } | null>(null);
28
+    const rubberbandPen = {
29
+      color: 'LightSlateGray',
30
+      width: 1,
31
+      dashStyle: [2, 2]
32
+    };
33
+    const designerCanvas = props.designerCanvas;
34
+    const containerRef = ref<HTMLElement | null>(null);
35
+
36
+    const onMouseMove = (e: MouseEvent) => {
37
+      if (e.buttons === 1) {
38
+        if (!containerRef.value?.hasPointerCapture(e.pointerId)) {
39
+          containerRef.value?.setPointerCapture(e.pointerId);
40
+        }
41
+        endPoint.value = { x: e.offsetX, y: e.offsetY };
42
+        updateSelection();
43
+      } else {
44
+        if (containerRef.value?.hasPointerCapture(e.pointerId)) {
45
+          containerRef.value?.releasePointerCapture(e.pointerId);
46
+        }
47
+      }
48
+      e.preventDefault();
49
+    };
50
+
51
+    const onMouseUp = (e: MouseEvent) => {
52
+      if (containerRef.value?.hasPointerCapture(e.pointerId)) {
53
+        containerRef.value?.releasePointerCapture(e.pointerId);
54
+      }
55
+      // 移除这个“装饰器”逻辑,在 Vue 中可以通过 v-if 等方式移除元素
56
+      endPoint.value = null;
57
+      e.preventDefault();
58
+    };
59
+
60
+    const updateSelection = () => {
61
+      designerCanvas.SelectedItems.forEach((item) => {
62
+        item.IsSelected = false;
63
+      });
64
+      designerCanvas.SelectedItems = [];
65
+
66
+      if (startPoint.value && endPoint.value) {
67
+        const rubberBand = {
68
+          left: Math.min(startPoint.value.x, endPoint.value.x),
69
+          top: Math.min(startPoint.value.y, endPoint.value.y),
70
+          width: Math.abs(startPoint.value.x - endPoint.value.x),
71
+          height: Math.abs(startPoint.value.y - endPoint.value.y)
72
+        };
73
+
74
+        designerCanvas.Children.forEach((item) => {
75
+          const rect = item.getBoundingClientRect();
76
+          const itemBounds = {
77
+            left: rect.left,
78
+            top: rect.top,
79
+            width: rect.width,
80
+            height: rect.height
81
+          };
82
+
83
+          if (
84
+            rubberBand.left <= itemBounds.left &&
85
+            rubberBand.top <= itemBounds.top &&
86
+            rubberBand.left + rubberBand.width >= itemBounds.left + itemBounds.width &&
87
+            rubberBand.top + rubberBand.height >= itemBounds.top + itemBounds.height &&
88
+            'IsSelected' in item
89
+          ) {
90
+            (item as unknown as ISelectable).IsSelected = true;
91
+            designerCanvas.SelectedItems.push(item as unknown as ISelectable);
92
+          }
93
+        });
94
+      }
95
+    };
96
+
97
+    onMounted(() => {
98
+      if (containerRef.value) {
99
+        containerRef.value.addEventListener('mousemove', onMouseMove);
100
+        containerRef.value.addEventListener('mouseup', onMouseUp);
101
+      }
102
+    });
103
+
104
+    onUnmounted(() => {
105
+      if (containerRef.value) {
106
+        containerRef.value.removeEventListener('mousemove', onMouseMove);
107
+        containerRef.value.removeEventListener('mouseup', onMouseUp);
108
+      }
109
+    });
110
+
111
+    return {
112
+      startPoint,
113
+      endPoint,
114
+      rubberbandPen,
115
+      containerRef
116
+    };
117
+  },
118
+  template: `
119
+    <div ref="containerRef" style="position: relative; width: 100%; height: 100%;">
120
+      <div
121
+        v-if="startPoint && endPoint"
122
+        :style="{
123
+          position: 'absolute',
124
+          left: Math.min(startPoint.x, endPoint.x) + 'px',
125
+          top: Math.min(startPoint.y, endPoint.y) + 'px',
126
+          width: Math.abs(startPoint.x - endPoint.x) + 'px',
127
+          height: Math.abs(startPoint.y - endPoint.y) + 'px',
128
+          border: \`\${rubberbandPen.width}px dashed \${rubberbandPen.color}\`
129
+        }"
130
+      ></div>
131
+    </div>
132
+  `
133
+};

+ 54
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Entry.cs 查看文件

@@ -0,0 +1,54 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Controls.Ext.Controls
7
+{
8
+    internal class Tx_Entry
9
+    {
10
+        #region 字段
11
+        private string m_StartNode;
12
+        private string m_EndNode;
13
+        private string m_Condition;
14
+        #endregion 字段
15
+
16
+        #region 属性
17
+
18
+        /// <summary>
19
+        /// 开始节点
20
+        /// </summary>
21
+        internal string StartNode
22
+        {
23
+            get { return m_StartNode; }
24
+            set { m_StartNode = value; }
25
+        }
26
+
27
+        /// <summary>
28
+        /// 结束节点
29
+        /// </summary>
30
+        internal string EndNode
31
+        {
32
+            get { return m_EndNode; }
33
+            set { m_EndNode = value; }
34
+        }
35
+
36
+        /// <summary>
37
+        /// 条件
38
+        /// </summary>
39
+        public string Condition
40
+        {
41
+            get { return m_Condition; }
42
+            set { m_Condition = value; }
43
+        }
44
+
45
+        #endregion 属性
46
+
47
+        public Tx_Entry(string start, string end, string condition)
48
+        {
49
+            this.m_StartNode = start;
50
+            this.m_EndNode = end;
51
+            this.m_Condition = condition;
52
+        }
53
+    }
54
+}

+ 46
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Entry.ts 查看文件

@@ -0,0 +1,46 @@
1
+// 定义 Tx_Entry 类,用于表示流程图中的连接信息
2
+export class Tx_Entry {
3
+    // 开始节点
4
+    private m_StartNode: string;
5
+    // 结束节点
6
+    private m_EndNode: string;
7
+    // 条件
8
+    private m_Condition: string;
9
+
10
+    // 获取开始节点
11
+    get StartNode(): string {
12
+        return this.m_StartNode;
13
+    }
14
+
15
+    // 设置开始节点
16
+    set StartNode(value: string) {
17
+        this.m_StartNode = value;
18
+    }
19
+
20
+    // 获取结束节点
21
+    get EndNode(): string {
22
+        return this.m_EndNode;
23
+    }
24
+
25
+    // 设置结束节点
26
+    set EndNode(value: string) {
27
+        this.m_EndNode = value;
28
+    }
29
+
30
+    // 获取条件
31
+    get Condition(): string {
32
+        return this.m_Condition;
33
+    }
34
+
35
+    // 设置条件
36
+    set Condition(value: string) {
37
+        this.m_Condition = value;
38
+    }
39
+
40
+    // 构造函数,用于初始化开始节点、结束节点和条件
41
+    constructor(start: string, end: string, condition: string) {
42
+        this.m_StartNode = start;
43
+        this.m_EndNode = end;
44
+        this.m_Condition = condition;
45
+    }
46
+}

+ 125
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Node.cs 查看文件

@@ -0,0 +1,125 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+
6
+namespace TellerSystem.Controls.Ext.Controls
7
+{
8
+    public class Tx_Node
9
+    {
10
+        #region 字段
11
+        private string m_Code;
12
+        private string m_Sub_Code;
13
+        private string m_Name;
14
+        private string m_Condition=string.Empty;
15
+        private string m_Content=null;
16
+        private string m_stat;
17
+        private string m_errinfo;
18
+        private string m_desc;
19
+        private float m_X = 0.0f;
20
+        private float m_Y = 0.0f;
21
+        #endregion 字段
22
+
23
+        #region 属性
24
+        /// <summary>
25
+        /// 流程节点编号  
26
+        /// 0-流程开始节点
27
+        /// 1-流程结束节点
28
+        /// </summary>
29
+        public string Code
30
+        {
31
+            get { return m_Code; }
32
+            set { m_Code = value; }
33
+        }
34
+
35
+        /// <summary>
36
+        /// 子节点编号,逗号分割
37
+        /// </summary>
38
+        public string Sub_Code
39
+        {
40
+            get { return m_Sub_Code; }
41
+            set { m_Sub_Code = value; }
42
+        }
43
+        /// <summary>
44
+        /// 节点名称
45
+        /// </summary>
46
+        public string Name
47
+        {
48
+            get { return m_Name; }
49
+            set { m_Name = value; }
50
+        }
51
+        /// <summary>
52
+        /// 条件
53
+        /// </summary>
54
+        public string Conditions
55
+        {
56
+            get { return m_Condition; }
57
+            set { m_Condition = value; }
58
+        }
59
+        /// <summary>
60
+        /// 节点说明
61
+        /// </summary>
62
+        public string Desc
63
+        {
64
+            get { return m_desc; }
65
+            set { m_desc = value; }
66
+        }
67
+        /// <summary>
68
+        /// 备注说明
69
+        /// </summary>
70
+        public string Content
71
+        {
72
+            get { return m_Content; }
73
+            set { m_Content = value; }
74
+        }
75
+        /// <summary>
76
+        /// 状态
77
+        /// </summary>
78
+        public string Stat
79
+        {
80
+            get { return m_stat; }
81
+            set { m_stat = value; }
82
+        }
83
+        /// <summary>
84
+        /// 错误信息
85
+        /// </summary>
86
+        public string ErrInfo
87
+        {
88
+            get { return m_errinfo; }
89
+            set { m_errinfo = value; }
90
+        }
91
+        /// <summary>
92
+        /// X坐标
93
+        /// </summary>
94
+        public float X
95
+        {
96
+            get { return m_X; }
97
+            set { m_X = value; }
98
+        }
99
+
100
+        /// <summary>
101
+        /// Y坐标
102
+        /// </summary>
103
+        public float Y
104
+        {
105
+            get { return m_Y; }
106
+            set { m_Y = value; }
107
+        }
108
+
109
+        #endregion 属性
110
+
111
+        public Tx_Node()
112
+        { }
113
+        public Tx_Node(string code, string subtxCode, string name,string condition="",string desc="",string content="",string stat="",string errinfo="")
114
+        {
115
+            this.m_Code = code;
116
+            this.m_Sub_Code= subtxCode;
117
+            this.m_Name = name;
118
+            this.m_Condition = condition;
119
+            this.m_Content = content;
120
+            this.m_stat = stat;
121
+            this.m_errinfo = errinfo;
122
+            this.m_desc = desc;
123
+        }
124
+    }
125
+}

+ 123
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/FlowChat/Tx_Node.ts 查看文件

@@ -0,0 +1,123 @@
1
+// 定义 Tx_Node 类,代表流程节点
2
+export class Tx_Node {
3
+    // 定义私有字段,用于存储节点的各种属性
4
+    private m_Code: string;
5
+    private m_Sub_Code: string;
6
+    private m_Name: string;
7
+    private m_Condition: string;
8
+    private m_Content: string | null;
9
+    private m_stat: string;
10
+    private m_errinfo: string;
11
+    private m_desc: string;
12
+    private m_X: number;
13
+    private m_Y: number;
14
+
15
+    // 定义属性,提供对私有字段的访问和修改
16
+    public get Code(): string {
17
+        return this.m_Code;
18
+    }
19
+
20
+    public set Code(value: string) {
21
+        this.m_Code = value;
22
+    }
23
+
24
+    public get Sub_Code(): string {
25
+        return this.m_Sub_Code;
26
+    }
27
+
28
+    public set Sub_Code(value: string) {
29
+        this.m_Sub_Code = value;
30
+    }
31
+
32
+    public get Name(): string {
33
+        return this.m_Name;
34
+    }
35
+
36
+    public set Name(value: string) {
37
+        this.m_Name = value;
38
+    }
39
+
40
+    public get Conditions(): string {
41
+        return this.m_Condition;
42
+    }
43
+
44
+    public set Conditions(value: string) {
45
+        this.m_Condition = value;
46
+    }
47
+
48
+    public get Desc(): string {
49
+        return this.m_desc;
50
+    }
51
+
52
+    public set Desc(value: string) {
53
+        this.m_desc = value;
54
+    }
55
+
56
+    public get Content(): string | null {
57
+        return this.m_Content;
58
+    }
59
+
60
+    public set Content(value: string | null) {
61
+        this.m_Content = value;
62
+    }
63
+
64
+    public get Stat(): string {
65
+        return this.m_stat;
66
+    }
67
+
68
+    public set Stat(value: string) {
69
+        this.m_stat = value;
70
+    }
71
+
72
+    public get ErrInfo(): string {
73
+        return this.m_errinfo;
74
+    }
75
+
76
+    public set ErrInfo(value: string) {
77
+        this.m_errinfo = value;
78
+    }
79
+
80
+    public get X(): number {
81
+        return this.m_X;
82
+    }
83
+
84
+    public set X(value: number) {
85
+        this.m_X = value;
86
+    }
87
+
88
+    public get Y(): number {
89
+        return this.m_Y;
90
+    }
91
+
92
+    public set Y(value: number) {
93
+        this.m_Y = value;
94
+    }
95
+
96
+    // 无参构造函数
97
+    constructor() {
98
+        this.m_Code = '';
99
+        this.m_Sub_Code = '';
100
+        this.m_Name = '';
101
+        this.m_Condition = '';
102
+        this.m_Content = null;
103
+        this.m_stat = '';
104
+        this.m_errinfo = '';
105
+        this.m_desc = '';
106
+        this.m_X = 0;
107
+        this.m_Y = 0;
108
+    }
109
+
110
+    // 有参构造函数,用于初始化节点对象
111
+    constructor(code: string, subtxCode: string, name: string, condition: string = '', desc: string = '', content: string = '', stat: string = '', errinfo: string = '') {
112
+        this.m_Code = code;
113
+        this.m_Sub_Code = subtxCode;
114
+        this.m_Name = name;
115
+        this.m_Condition = condition;
116
+        this.m_Content = content;
117
+        this.m_stat = stat;
118
+        this.m_errinfo = errinfo;
119
+        this.m_desc = desc;
120
+        this.m_X = 0;
121
+        this.m_Y = 0;
122
+    }
123
+}

+ 130
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/Connection.xaml 查看文件

@@ -0,0 +1,130 @@
1
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3
+                    xmlns:s="clr-namespace:TellerSystem.Controls.Ext.Controls">
4
+    <Style TargetType="{x:Type s:Connection}">
5
+        <Style.Resources>
6
+            <!--  Style for the ConnectorAdorner thumbs  -->
7
+            <Style x:Key="ConnectionAdornerThumbStyle" TargetType="{x:Type Thumb}">
8
+                <Setter Property="Width" Value="12" />
9
+                <Setter Property="Height" Value="12" />
10
+                <Setter Property="SnapsToDevicePixels" Value="true" />
11
+                <Setter Property="RenderTransform">
12
+                    <Setter.Value>
13
+                        <TranslateTransform X="-6" Y="-6" />
14
+                    </Setter.Value>
15
+                </Setter>
16
+                <Setter Property="Template">
17
+                    <Setter.Value>
18
+                        <ControlTemplate TargetType="{x:Type Thumb}">
19
+                            <Rectangle Fill="#AADCDCDC"
20
+                                       RadiusX="0"
21
+                                       RadiusY="0"
22
+                                       Stroke="DodgerBlue"
23
+                                       StrokeThickness="1" />
24
+                        </ControlTemplate>
25
+                    </Setter.Value>
26
+                </Setter>
27
+            </Style>
28
+            <!--  Arrow Grid Style  -->
29
+            <Style x:Key="ArrowGridStyle" TargetType="Grid">
30
+                <Setter Property="Width" Value="10" />
31
+                <Setter Property="Height" Value="10" />
32
+                <Setter Property="RenderTransform">
33
+                    <Setter.Value>
34
+                        <TranslateTransform X="-5" Y="-5" />
35
+                    </Setter.Value>
36
+                </Setter>
37
+            </Style>
38
+            <!--  base style for all arrow shapes  -->
39
+            <Style x:Key="ArrowSymbolBaseStyle" TargetType="Path">
40
+                <Setter Property="Fill" Value="#FF4387D7" />
41
+                <Setter Property="Stretch" Value="Fill" />
42
+            </Style>
43
+            <!--  Arrow  -->
44
+            <Style x:Key="Arrow"
45
+                   BasedOn="{StaticResource ArrowSymbolBaseStyle}"
46
+                   TargetType="Path">
47
+                <Setter Property="Data" Value="M0,0 8,4 0,8 Z" />
48
+
49
+            </Style>
50
+            <!--  Diamond  -->
51
+            <Style x:Key="Diamond"
52
+                   BasedOn="{StaticResource ArrowSymbolBaseStyle}"
53
+                   TargetType="Path">
54
+                <Setter Property="Data" Value="M-5,0 0,-5 5,0 0,5 Z" />
55
+            </Style>
56
+        </Style.Resources>
57
+        <Setter Property="SnapsToDevicePixels" Value="True" />
58
+        <Setter Property="Template">
59
+            <Setter.Value>
60
+                <ControlTemplate TargetType="{x:Type s:Connection}">
61
+                    <Canvas DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
62
+                        <Path Name="PART_ConnectionPath"
63
+                              Data="{Binding PathGeometry}"
64
+                              SnapsToDevicePixels="True"
65
+                              Stroke="#FF4387D7"
66
+                              StrokeDashArray="{Binding StrokeDashArray}"
67
+                              StrokeEndLineCap="Round"
68
+                              StrokeLineJoin="Round"
69
+                              StrokeStartLineCap="Round"
70
+                              StrokeThickness="2" />
71
+                        <Grid Canvas.Left="{Binding AnchorPositionSource.X}"
72
+                              Canvas.Top="{Binding AnchorPositionSource.Y}"
73
+                              Style="{StaticResource ArrowGridStyle}">
74
+                            <Path Name="PART_SourceAnchorPath" />
75
+                            <Grid.LayoutTransform>
76
+                                <RotateTransform Angle="{Binding AnchorAngleSource}" />
77
+                            </Grid.LayoutTransform>
78
+                        </Grid>
79
+                        <Grid Canvas.Left="{Binding AnchorPositionSink.X}"
80
+                              Canvas.Top="{Binding AnchorPositionSink.Y}"
81
+                              Style="{StaticResource ArrowGridStyle}">
82
+                            <Path Name="PART_SinkAnchorPath" />
83
+                            <Grid.LayoutTransform>
84
+                                <RotateTransform Angle="{Binding AnchorAngleSink}" />
85
+                            </Grid.LayoutTransform>
86
+                        </Grid>
87
+
88
+                        <Label x:Name="editBrach"
89
+                               Canvas.Left="{Binding LabelPosition.X}"
90
+                               Canvas.Top="{Binding LabelPosition.Y}"
91
+                               Width="50"
92
+                               Height="28"
93
+                               Content="{Binding Path=Brach,
94
+                                                 Mode=TwoWay}"
95
+                               Cursor="Hand"
96
+                               FontSize="12">
97
+                            <Label.RenderTransform>
98
+                                <TranslateTransform X="-15" Y="-20" />
99
+                            </Label.RenderTransform>
100
+                        </Label>
101
+                        <!--
102
+                            线条投影
103
+                            <Canvas.BitmapEffect>
104
+                            <DropShadowBitmapEffect Direction="315"
105
+                            Opacity="0.1"
106
+                            ShadowDepth="10"
107
+                            Softness="0"
108
+                            Color="Gray" />
109
+                            </Canvas.BitmapEffect>
110
+                        -->
111
+                    </Canvas>
112
+                    <ControlTemplate.Triggers>
113
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SourceArrowSymbol}" Value="Arrow">
114
+                            <Setter TargetName="PART_SourceAnchorPath" Property="Style" Value="{StaticResource Arrow}" />
115
+                        </DataTrigger>
116
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SourceArrowSymbol}" Value="Diamond">
117
+                            <Setter TargetName="PART_SourceAnchorPath" Property="Style" Value="{StaticResource Diamond}" />
118
+                        </DataTrigger>
119
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SinkArrowSymbol}" Value="Arrow">
120
+                            <Setter TargetName="PART_SinkAnchorPath" Property="Style" Value="{StaticResource Arrow}" />
121
+                        </DataTrigger>
122
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SinkArrowSymbol}" Value="Diamond">
123
+                            <Setter TargetName="PART_SinkAnchorPath" Property="Style" Value="{StaticResource Diamond}" />
124
+                        </DataTrigger>
125
+                    </ControlTemplate.Triggers>
126
+                </ControlTemplate>
127
+            </Setter.Value>
128
+        </Setter>
129
+    </Style>
130
+</ResourceDictionary>

+ 187
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/DesignerItem.xaml 查看文件

@@ -0,0 +1,187 @@
1
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
2
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3
+                    xmlns:dhcc="http://www.dhcc.com.cn"
4
+                    xmlns:s="clr-namespace:TellerSystem.Controls.Ext.Controls">
5
+    <!--  Connector Style  -->
6
+    <Style TargetType="{x:Type s:Connector}">
7
+        <Setter Property="Width" Value="8" />
8
+        <Setter Property="Height" Value="8" />
9
+        <Setter Property="Cursor" Value="Cross" />
10
+        <Setter Property="SnapsToDevicePixels" Value="true" />
11
+        <Setter Property="Template">
12
+            <Setter.Value>
13
+                <ControlTemplate TargetType="{x:Type s:Connector}">
14
+                    <Grid>
15
+                        <Rectangle Margin="-2" Fill="Transparent" />
16
+                        <Rectangle Fill="Lavender"
17
+                                   Stroke="#AA000080"
18
+                                   StrokeThickness="1" />
19
+                    </Grid>
20
+                </ControlTemplate>
21
+            </Setter.Value>
22
+        </Setter>
23
+    </Style>
24
+
25
+    <!--  ConnectorDecoratorTemplate Default Template  -->
26
+    <ControlTemplate x:Key="ConnectorDecoratorTemplate" TargetType="{x:Type Control}">
27
+        <Grid Margin="-5">
28
+            <s:Connector x:Name="ConnectorLeftName"
29
+                         HorizontalAlignment="Left"
30
+                         VerticalAlignment="Center"
31
+                         Orientation="Left" />
32
+            <s:Connector x:Name="ConnectorTopLeftName"
33
+                         HorizontalAlignment="Left"
34
+                         VerticalAlignment="Top"
35
+                         Orientation="Top" />
36
+            <s:Connector x:Name="ConnectorTopName"
37
+                         HorizontalAlignment="Center"
38
+                         VerticalAlignment="Top"
39
+                         Orientation="Top" />
40
+            <s:Connector x:Name="ConnectorTopRightName"
41
+                         HorizontalAlignment="Right"
42
+                         VerticalAlignment="Top"
43
+                         Orientation="Top" />
44
+            <s:Connector x:Name="ConnectorRightName"
45
+                         HorizontalAlignment="Right"
46
+                         VerticalAlignment="Center"
47
+                         Orientation="Right" />
48
+            <s:Connector x:Name="ConnectorBottomLeftName"
49
+                         HorizontalAlignment="Left"
50
+                         VerticalAlignment="Bottom"
51
+                         Orientation="Bottom" />
52
+            <s:Connector x:Name="ConnectorBottomName"
53
+                         HorizontalAlignment="Center"
54
+                         VerticalAlignment="Bottom"
55
+                         Orientation="Bottom" />
56
+            <s:Connector x:Name="ConnectorBottomRightName"
57
+                         HorizontalAlignment="Right"
58
+                         VerticalAlignment="Bottom"
59
+                         Orientation="Bottom" />
60
+        </Grid>
61
+    </ControlTemplate>
62
+
63
+    <!--  ResizeDecorator Default Template  -->
64
+    <ControlTemplate x:Key="ResizeDecoratorTemplate" TargetType="{x:Type Control}">
65
+        <Grid Opacity="0.7" SnapsToDevicePixels="true">
66
+            <s:ResizeThumb Height="3"
67
+                           Margin="0 -4 0 0"
68
+                           HorizontalAlignment="Stretch"
69
+                           VerticalAlignment="Top"
70
+                           Cursor="SizeNS" />
71
+            <s:ResizeThumb Width="3"
72
+                           Margin="-4 0 0 0"
73
+                           HorizontalAlignment="Left"
74
+                           VerticalAlignment="Stretch"
75
+                           Cursor="SizeWE" />
76
+            <s:ResizeThumb Width="3"
77
+                           Margin="0 0 -4 0"
78
+                           HorizontalAlignment="Right"
79
+                           VerticalAlignment="Stretch"
80
+                           Cursor="SizeWE" />
81
+            <s:ResizeThumb Height="3"
82
+                           Margin="0 0 0 -4"
83
+                           HorizontalAlignment="Stretch"
84
+                           VerticalAlignment="Bottom"
85
+                           Cursor="SizeNS" />
86
+            <s:ResizeThumb Width="7"
87
+                           Height="7"
88
+                           Margin="-6 -6 0 0"
89
+                           HorizontalAlignment="Left"
90
+                           VerticalAlignment="Top"
91
+                           Cursor="SizeNWSE" />
92
+            <s:ResizeThumb Width="7"
93
+                           Height="7"
94
+                           Margin="0 -6 -6 0"
95
+                           HorizontalAlignment="Right"
96
+                           VerticalAlignment="Top"
97
+                           Cursor="SizeNESW" />
98
+            <s:ResizeThumb Width="7"
99
+                           Height="7"
100
+                           Margin="-6 0 0 -6"
101
+                           HorizontalAlignment="Left"
102
+                           VerticalAlignment="Bottom"
103
+                           Cursor="SizeNESW" />
104
+            <s:ResizeThumb Width="7"
105
+                           Height="7"
106
+                           Margin="0 0 -6 -6"
107
+                           HorizontalAlignment="Right"
108
+                           VerticalAlignment="Bottom"
109
+                           Cursor="SizeNWSE" />
110
+        </Grid>
111
+    </ControlTemplate>
112
+
113
+    <!--  DragThumb Default Template  -->
114
+    <Style TargetType="{x:Type s:DragThumb}">
115
+        <Setter Property="Template">
116
+            <Setter.Value>
117
+                <ControlTemplate TargetType="{x:Type s:DragThumb}">
118
+                    <Rectangle Fill="Transparent" />
119
+                </ControlTemplate>
120
+            </Setter.Value>
121
+        </Setter>
122
+    </Style>
123
+
124
+    <!--  DesignerItem Style  -->
125
+    <Style TargetType="{x:Type s:DesignerItem}">
126
+        <Setter Property="MinWidth" Value="25" />
127
+        <Setter Property="MinHeight" Value="25" />
128
+        <Setter Property="SnapsToDevicePixels" Value="True" />
129
+        <Setter Property="Template">
130
+            <Setter.Value>
131
+                <ControlTemplate TargetType="{x:Type s:DesignerItem}">
132
+                    <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
133
+                        <!--  PART_DragThumb  -->
134
+                        <s:DragThumb x:Name="PART_DragThumb" Cursor="SizeAll" />
135
+                        <!--  PART_ResizeDecorator  -->
136
+                        <Control x:Name="PART_ResizeDecorator"
137
+                                 Template="{StaticResource ResizeDecoratorTemplate}"
138
+                                 Visibility="Collapsed" />
139
+                        <!--  PART_ContentPresenter  -->
140
+                        <ContentPresenter x:Name="PART_ContentPresenter"
141
+                                          Margin="{TemplateBinding ContentControl.Padding}"
142
+                                          HorizontalAlignment="Stretch"
143
+                                          VerticalAlignment="Stretch"
144
+                                          Content="{TemplateBinding ContentControl.Content}" />
145
+                        <!--  PART_ConnectorDecorator  -->
146
+                        <Control x:Name="PART_ConnectorDecorator"
147
+                                 Template="{StaticResource ConnectorDecoratorTemplate}"
148
+                                 Visibility="Hidden" />
149
+                        <Image x:Name="DesignerItemTip"
150
+                               Width="15"
151
+                               Height="15"
152
+                               HorizontalAlignment="Right"
153
+                               VerticalAlignment="Top"
154
+                               Stretch="UniformToFill"
155
+                               Visibility="Collapsed" />
156
+                    </Grid>
157
+
158
+                    <ControlTemplate.Triggers>
159
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True">
160
+                            <Setter TargetName="PART_ResizeDecorator" Property="Visibility" Value="Visible" />
161
+                        </DataTrigger>
162
+                        <Trigger Property="IsMouseOver" Value="true">
163
+                            <Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible" />
164
+                        </Trigger>
165
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SourceTipSymbol}" Value="Error">
166
+                            <Setter TargetName="DesignerItemTip" Property="Visibility" Value="Visible" />
167
+                            <Setter TargetName="DesignerItemTip" Property="Source" Value="{DynamicResource FlowChatError}" />
168
+                        </DataTrigger>
169
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SourceTipSymbol}" Value="Success">
170
+                            <Setter TargetName="DesignerItemTip" Property="Visibility" Value="Visible" />
171
+                            <Setter TargetName="DesignerItemTip" Property="Source" Value="{DynamicResource FlowChatSuccess}" />
172
+                        </DataTrigger>
173
+                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=SourceTipSymbol}" Value="UnHandled">
174
+                            <Setter TargetName="DesignerItemTip" Property="Visibility" Value="Visible" />
175
+                            <Setter TargetName="DesignerItemTip" Property="Source" Value="{DynamicResource FlowChatUndo}" />
176
+                        </DataTrigger>
177
+                        <!--
178
+                            <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsDragConnectionOver}" Value="True">
179
+                            <Setter TargetName="PART_ConnectorDecorator" Property="Visibility" Value="Visible" />
180
+                            </DataTrigger>
181
+                        -->
182
+                    </ControlTemplate.Triggers>
183
+                </ControlTemplate>
184
+            </Setter.Value>
185
+        </Setter>
186
+    </Style>
187
+</ResourceDictionary>

+ 57
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/DiagramDesigner/Resources/NodeControlStyles.xaml 查看文件

@@ -0,0 +1,57 @@
1
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
2
+    <Brush x:Key="ItemStroke">#FF0071C0</Brush>
3
+    <LinearGradientBrush x:Key="ItemBrush" StartPoint="0,0" EndPoint="0,1">
4
+        <LinearGradientBrush.GradientStops>
5
+            <GradientStop Offset="0" Color="#FAFBE9" />
6
+            <GradientStop Offset="1" Color="Orange" />
7
+        </LinearGradientBrush.GradientStops>
8
+    </LinearGradientBrush>
9
+    <Style x:Key="FlowChartItemStyle" TargetType="Path">
10
+        <Setter Property="Fill" Value="{StaticResource ItemBrush}" />
11
+        <Setter Property="Stroke" Value="{StaticResource ItemStroke}" />
12
+        <Setter Property="StrokeThickness" Value="2" />
13
+        <Setter Property="StrokeLineJoin" Value="Round" />
14
+        <Setter Property="Stretch" Value="Fill" />
15
+        <Setter Property="IsHitTestVisible" Value="False" />
16
+        <Setter Property="SnapsToDevicePixels" Value="True" />
17
+        <Setter Property="BitmapEffect">
18
+            <Setter.Value>
19
+                <DropShadowBitmapEffect Direction="315"
20
+                                        Opacity="0.3"
21
+                                        ShadowDepth="10"
22
+                                        Softness="0.5"
23
+                                        Color="#AAA" />
24
+            </Setter.Value>
25
+        </Setter>
26
+    </Style>
27
+    <Style x:Key="NodeStyle" TargetType="{x:Type Label}">
28
+        <Setter Property="Template">
29
+            <Setter.Value>
30
+                <ControlTemplate TargetType="{x:Type Label}">
31
+                    <Grid>
32
+                        <Path x:Name="m_Path"
33
+                              Width="{TemplateBinding Width}"
34
+                              Data="M 0,3 C 30,-7 30,13 60,3 V 37 C 30,47 30,27 0,37 Z"
35
+                              IsHitTestVisible="False"
36
+                              Style="{StaticResource FlowChartItemStyle}" />
37
+                        <ContentPresenter HorizontalAlignment="Center"
38
+                                          VerticalAlignment="Center"
39
+                                          IsHitTestVisible="False"
40
+                                          TextBlock.Foreground="{TemplateBinding Foreground}"
41
+                                          ToolTip="{TemplateBinding Content}" />
42
+                        <TextBlock Margin="2"
43
+                                   HorizontalAlignment="Left"
44
+                                   VerticalAlignment="Top"
45
+                                   Foreground="{TemplateBinding Foreground}"
46
+                                   IsHitTestVisible="False"
47
+                                   Text="{TemplateBinding Tag}"
48
+                                   ToolTip="{TemplateBinding Content}"
49
+                                   Visibility="Visible" />
50
+                    </Grid>
51
+                </ControlTemplate>
52
+            </Setter.Value>
53
+        </Setter>
54
+    </Style>
55
+    <!--  节点  -->
56
+
57
+</ResourceDictionary>

+ 111
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FeeViewer.xaml 查看文件

@@ -0,0 +1,111 @@
1
+<local:ManagerTradePage x:Class="TellerSystem.Controls.Ext.Controls.FeeViewer"
2
+                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                        xmlns:ctrl="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
5
+                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                        xmlns:dhcc="http://www.dhcc.com.cn"
7
+                        xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
8
+                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
+                        d:DesignHeight="500"
10
+                        d:DesignWidth="700"
11
+                        dhcc:FocusManager.EnableFocusControl="True"
12
+                        mc:Ignorable="d">
13
+    <local:ManagerTradePage.Resources>
14
+        <ResourceDictionary Source="/TellerSystem.Controls.Ext;component/ControlsStyle/TradePageElementGeneric.xaml" />
15
+    </local:ManagerTradePage.Resources>
16
+    <Grid Width="700" Height="500">
17
+        <Grid.RowDefinitions>
18
+            <RowDefinition Height="*" />
19
+            <RowDefinition Height="50" />
20
+        </Grid.RowDefinitions>
21
+        <StackPanel Margin="5,0">
22
+            <ctrl:TradePanel Header="收费明细">
23
+                <dhcc:DataBox Name="DB_FeeList"
24
+                              Width="680"
25
+                              Height="150"
26
+                              ctrl:TradePanel.IsCentralAlone="True" />
27
+            </ctrl:TradePanel>
28
+            <ctrl:TradePanel Header="收费汇总">
29
+                <TextBlock Text="总 金 额:" />
30
+                <dhcc:CurrencyEditor Name="TTotal"
31
+                                     ctrl:TradePanel.ColumnSpan="3"
32
+                                     IsEnabled="False" />
33
+                <TextBlock Name="LFEEFLAG" Text="收费方式:" />
34
+                <ComboBox Name="FEEFLAG" dhcc:FocusManager.LostFocus="FEEFLAG_LostFocus" />
35
+            </ctrl:TradePanel>
36
+            <ctrl:TradePanel x:Name="AcInfoCanvas"
37
+                             Header="收费账号"
38
+                             Visibility="Collapsed">
39
+                <TextBlock Name="LACNONAME"
40
+                           Width="80"
41
+                           Height="23"
42
+                           Text="扣费账号 :"
43
+                           TextAlignment="Right" />
44
+                <TextBox Name="FEEACNO"
45
+                         Width="176"
46
+                         dhcc:DeviceManager.SwipeCardReaderTracksReader="ReadCard"
47
+                         dhcc:FocusManager.LostFocus="FEEACNO_LostFocus"
48
+                         dhcc:FocusManagerExt.AssertNotEmpty="True"
49
+                         dhcc:TextBoxHelper.IsShowLength="True" />
50
+                <TextBlock Name="LACSEQN"
51
+                           Width="80"
52
+                           Text="账户序号 :"
53
+                           TextAlignment="Right" />
54
+                <TextBox Name="ACSEQN"
55
+                         Width="100"
56
+                         IsEnabled="False" />
57
+                <TextBlock Name="WITHDRAW"
58
+                           Width="80"
59
+                           Text="支付标志 :"
60
+                           TextAlignment="Right"
61
+                           Visibility="Collapsed" />
62
+                <ComboBox Name="DRAWFLAG"
63
+                          Width="176"
64
+                          Visibility="Collapsed" />
65
+                <TextBlock Name="LPASSWORD"
66
+                           Width="80"
67
+                           Text="账号密码 :"
68
+                           TextAlignment="Right" />
69
+                <PasswordBox Name="GDPWD"
70
+                             Width="80"
71
+                             dhcc:Encrypte.AcctountElementName="FEEACNO"
72
+                             dhcc:Encrypte.EncrypteType="True"
73
+                             dhcc:Encrypte.IsEncrypte="True"
74
+                             dhcc:FocusManager.LostFocus="GDPWD_LostFocus"
75
+                             dhcc:PasswordBoxHelper.IsAutoSelectedAll="True"
76
+                             Style="{StaticResource StylePwd}" />
77
+                <TextBlock Name="IDTYPE"
78
+                           Width="80"
79
+                           Text="证件类型 :"
80
+                           TextAlignment="Right"
81
+                           Visibility="Collapsed" />
82
+                <ComboBox Name="ACIDTYPE"
83
+                          Width="176"
84
+                          Visibility="Collapsed" />
85
+                <TextBlock Name="IDNO"
86
+                           Width="64"
87
+                           Text="证件号码 :"
88
+                           TextAlignment="Right"
89
+                           Visibility="Collapsed" />
90
+                <TextBox Name="ACIDNO"
91
+                         Width="181"
92
+                         dhcc:FocusManager.LostFocus="ACIDNO_LostFocus"
93
+                         dhcc:FocusManagerExt.AssertNotEmpty="True"
94
+                         Style="{DynamicResource StyleIdNo}"
95
+                         Visibility="Collapsed" />
96
+            </ctrl:TradePanel>
97
+        </StackPanel>
98
+        <StackPanel Name="ButtonViewerPanel"
99
+                    Grid.Row="1"
100
+                    Height="50"
101
+                    HorizontalAlignment="Stretch"
102
+                    FlowDirection="RightToLeft"
103
+                    Orientation="Horizontal">
104
+            <Button Name="SubmitButton"
105
+                    Margin="10,0"
106
+                    VerticalAlignment="Center"
107
+                    Click="SubmitButton_Click"
108
+                    Content="确定" />
109
+        </StackPanel>
110
+    </Grid>
111
+</local:ManagerTradePage>

+ 827
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FeeViewer.xaml.cs 查看文件

@@ -0,0 +1,827 @@
1
+ using System;
2
+using System.Collections;
3
+using System.Collections.Generic;
4
+using System.Linq;
5
+using System.Text;
6
+using System.Windows;
7
+using System.Windows.Controls;
8
+using System.Windows.Data;
9
+using System.Windows.Documents;
10
+using System.Windows.Input;
11
+using System.Windows.Media;
12
+using System.Windows.Media.Imaging;
13
+using System.Windows.Navigation;
14
+using System.Windows.Shapes;
15
+using Platform.Common.LogSystem;
16
+using Platform.Common.RunningParameters;
17
+
18
+/******************************平台Dll*****************************/
19
+
20
+using Platform.Controls.ControlsHelper;
21
+using Platform.Library;
22
+using Platform.Presentation.FocusManagers;
23
+using Platform.Presentation.Interfaces;
24
+using Platform.Presentation.PageFunctions;
25
+using TellerSystem.Communication;
26
+using TellerSystem.Library.Ext.Function;
27
+using TellerSystem.Library.Ext.TradeExtension;
28
+using TellerSystem.Library.Ext.Variables;
29
+using TellerSystem.Controls.Ext.ControlsHelper;
30
+using TellerSystem.Contract.Function;
31
+using TellerSystem.Contract.ContractBase;
32
+using System.IO;
33
+using TellerSystem.Controls.Ext.PrintsHelper;
34
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
35
+using TellerSystem.Controls.Ext.ControlEntity;
36
+
37
+namespace TellerSystem.Controls.Ext.Controls
38
+{
39
+    /// <summary>
40
+    /// FeeViewer.xaml 的交互逻辑
41
+    /// </summary>
42
+    public partial class FeeViewer
43
+    {
44
+        #region 交易内部变量
45
+
46
+        /* 定义变量 */
47
+
48
+        /// <summary>
49
+        /// 是否是网银
50
+        /// </summary>
51
+        private bool _is_Wy;
52
+        public bool Is_Wy
53
+        {
54
+            get { return _is_Wy; }
55
+            set { _is_Wy = value; }
56
+        }
57
+
58
+        public bool _is_Cunkuan = false;
59
+        /// <summary>
60
+        /// 是否二代支付
61
+        /// </summary>
62
+        private bool _is_Canps2 = false;
63
+
64
+        public bool Is_Canps2
65
+        {
66
+            get { return _is_Canps2; }
67
+            set { _is_Canps2 = value; }
68
+        }
69
+
70
+        /// <summary>
71
+        /// 是否打印客户收费凭条
72
+        /// </summary>
73
+        public static bool _is_print = true;
74
+
75
+        /// <summary>
76
+        /// 主交易消息对象
77
+        /// </summary>
78
+        private Message _message;
79
+
80
+        //shangyongchao 20120710 增加黑名单标志
81
+        /// <summary>
82
+        /// 黑名单标志 1表示该账户列入黑名单
83
+        /// </summary>
84
+        private string BlackFlag = string.Empty;
85
+
86
+        //shangyongchao 20120809 增加后台返回的允许的收费方式
87
+        /// <summary>
88
+        ///   后台返回的允许的收费方式
89
+        /// </summary>
90
+        private string ModeChrg = string.Empty;
91
+
92
+        /// <summary>
93
+        /// 扣费账号户名 商永超 20120810
94
+        /// </summary>
95
+        private string FeeAcName = string.Empty;
96
+
97
+        private decimal TOTAMT;
98
+
99
+        /// <summary>
100
+        /// 转账时的收费账号 商永超20120813
101
+        /// </summary>
102
+        private string TmpAcNo = string.Empty;
103
+
104
+        /// <summary>
105
+        /// 标识是否完成收费操作
106
+        /// </summary>
107
+        public bool IsFinishFee
108
+        {
109
+            get;
110
+            set;
111
+        }
112
+
113
+        /// <summary>
114
+        /// 收费凭条打印对象
115
+        /// </summary>
116
+        public Print_Fee PrintFee { get; private set; }
117
+        /// <summary>
118
+        ///收费凭条客户回单
119
+        /// </summary>
120
+        public Print_FeeGuest PrintFeeGuest { get; private set; }
121
+
122
+        /// <summary>
123
+        /// 二磁道信息
124
+        /// </summary>
125
+        private string _msr2bak = "";
126
+
127
+        /// <summary>
128
+        /// 三磁道信息
129
+        /// </summary>
130
+        private string _msr3bak = "";
131
+
132
+        /// <summary>
133
+        /// 扣费账户户名
134
+        /// </summary>
135
+        private string kfzhhm = string.Empty;
136
+
137
+        /// <summary>
138
+        /// 户名
139
+        /// </summary>
140
+        private string hm = string.Empty;
141
+        /// <summary>
142
+        /// 证件类型
143
+        /// </summary>
144
+        private string zjlx = string.Empty;
145
+
146
+        /// <summary>
147
+        /// 证件号码
148
+        /// </summary>
149
+        private string zjhm = string.Empty;
150
+
151
+        /// <summary>
152
+        /// 版本控制标志
153
+        /// </summary>
154
+        private string FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
155
+
156
+        /// <summary>
157
+        /// 收费项目
158
+        /// </summary>
159
+        public string sfxm = string.Empty;
160
+
161
+        /// <summary>
162
+        /// 账户名称
163
+        /// </summary>
164
+        public string zhmc = string.Empty;
165
+
166
+        /// <summary>
167
+        /// 验印流水-中牟
168
+        /// </summary>
169
+        string _yyls = string.Empty;
170
+
171
+        #endregion 交易内部变量
172
+
173
+        internal FeeViewer(Message msg)
174
+        {
175
+            InitializeComponent();
176
+            _message = msg;
177
+
178
+            ////初始化金额控件,处理外币开户的情况
179
+            //if (_message.Fd16 == "2100")
180
+            //{
181
+            //    T1.ChangeMoneySymbol(_message.Fd103_3);
182
+            //    T2.ChangeMoneySymbol(_message.Fd103_3);
183
+            //    T3.ChangeMoneySymbol(_message.Fd103_3);
184
+            //    SF_VAL1.ChangeMoneySymbol(_message.Fd103_3);
185
+            //    SF_VAL2.ChangeMoneySymbol(_message.Fd103_3);
186
+            //    SF_VAL3.ChangeMoneySymbol(_message.Fd103_3);
187
+            //    TTotal.ChangeMoneySymbol(_message.Fd103_3);
188
+            //}
189
+        }
190
+
191
+        #region 逻辑代码
192
+
193
+        /// <summary>
194
+        /// 初始化页面元素
195
+        /// </summary>
196
+        public override bool InitPage()
197
+        {
198
+            TOTAMT = 0;
199
+            if (string.IsNullOrEmpty(_message.FileData))
200
+            {
201
+                this.ShowErrorMessageBox("传入的收费内容为空");
202
+                IsFinishFee = false;
203
+                SubmitButton.Visibility = Visibility.Hidden;
204
+                return false;
205
+            }
206
+            else
207
+            {
208
+                //解析数据
209
+                var reader = new StringReader(_message.FileData);
210
+                //控制行  [收费方式|黑名单标志|主账号]
211
+                var line = reader.ReadLine();
212
+                var tmp = line.Split('|');
213
+                if (tmp.Count() < 3 || tmp[0].Length != 4)
214
+                {
215
+                    this.ShowErrorMessageBox("收费模式配置错误!");
216
+                    IsFinishFee = false;
217
+                    SubmitButton.Visibility = Visibility.Hidden;
218
+                    return false;
219
+                }
220
+                //收费方式
221
+                ModeChrg = tmp[0];
222
+                //黑名单标志
223
+                BlackFlag = tmp[1];
224
+                //收费项目
225
+                TmpAcNo = tmp[2];
226
+                var ac = this.TradeAPIs.TF_Deposit_QueryDepositAccount(new QueryDepositAccount.Input()
227
+                {
228
+                    ZH = TmpAcNo
229
+                });
230
+                if (!ac.IsFailed)
231
+                    hm = ac.HM;
232
+                //收费明细
233
+                line = reader.ReadLine();
234
+                var data = new StringBuilder();
235
+                data.AppendLine("~收费条目|应收金额|实收金额|");
236
+                while (!string.IsNullOrEmpty(line))
237
+                {
238
+                    tmp = line.Split('|');
239
+                    if (tmp.Count() < 3) continue;
240
+                    data.AppendLine(string.Format("{0}|{1}|{2}|", tmp[0], tmp[1], tmp[2]));
241
+                    sfxm += tmp[0] + "  ";
242
+                    //累计
243
+                    TOTAMT += decimal.Parse(tmp[2]);
244
+                    line = reader.ReadLine();
245
+                }
246
+                DB_FeeList.DataBinding(data.ToString());
247
+                TTotal.Text = TOTAMT.ToString();
248
+                if (Is_Wy)
249
+                {
250
+                    //网银全部不收费
251
+                    FEEFLAG.SetItems(new Dictionary<string, string> { { "不收", "4" } });
252
+                    FEEFLAG.SetSelectedValue("4");
253
+                }
254
+                if (_is_Cunkuan)
255
+                {
256
+                    FEEFLAG.SetItems(new Dictionary<string, string> { { "现金", "1" }, { "输入账号", "3" }, { "不收", "4" } });
257
+                    FEEFLAG.SetSelectedValue("1");
258
+                }
259
+                if (_is_Canps2)
260
+                {
261
+                    FEEFLAG.SetItems(new Dictionary<string, string> { { "现金", "1" }, { "转账", "2" }, { "输入账号", "3" }, { "不收", "4" } });
262
+                    FEEFLAG.SetSelectedValue("2");
263
+                }
264
+                else
265
+                {
266
+                    FEEFLAG.SetItems(UserVariable.GetFeeFlag(ModeChrg, BlackFlag));
267
+                    //默认收费方式
268
+                    FEEFLAG.SelectedValue = _message.Fd9_3;
269
+                    //if (FEEFLAG.SelectedIndex == -1)
270
+                    //    FEEFLAG.SelectedIndex = 0;
271
+                    if (FEEFLAG.SelectedIndex == -1)
272
+                    {
273
+                        if (_message.Fd16 == "2405" && FLAG == "V6" && (_message.Fd66.Equals("1") || _message.Fd66.Equals("2")))//淇县  挂失:“默认收费”改为“默认不收”
274
+                        {
275
+                            FEEFLAG.SelectedIndex = 1;
276
+                        }
277
+                        else
278
+                        {
279
+                            FEEFLAG.SelectedIndex = 0;
280
+                        }
281
+                    }
282
+                    //if (BlackFlag == "0")
283
+                    //{
284
+                    //    this.ShowMessageBox("该账号/客户在收费白名单内,费用全免!");
285
+
286
+                    //    FEEFLAG.SetSelectedValue("5"); //收费方式 默认设置为5-费用全免
287
+                    //    FEEFLAG.IsEnabled = false;
288
+                    //}
289
+                    //else if (BlackFlag == "1")
290
+                    //{
291
+                    //    this.ShowMessageBox("该账号/客户在收费黑名单内,按标准收费,无优惠!");
292
+                    //}
293
+                }
294
+                if (FLAG == "V11" && _message.Fd16 == "2105")//2300交易 对公活期开户
295
+                {
296
+                    zhmc = _message.Fd103_8;
297
+                }
298
+                if (FLAG == "V0" && this.TradeModel.Code.Trim() == "2998" && _message.Fd16 == "2410")//更换介质
299
+                {
300
+                    DeviceManager.SetSwipeCardReaderTracksReader(FEEACNO, SwipeCardReaderType.ReadCardOrInput);
301
+                }
302
+                this.SetFocus(FEEFLAG);
303
+                return true;
304
+            }
305
+            /* 初始化界面逻辑,页面加载后执行*/
306
+        }
307
+
308
+        private void SubmitButton_Click(object sender, RoutedEventArgs e)
309
+        {
310
+            _message.Fd9_3 = (string)FEEFLAG.SelectedValue;
311
+            string tmp = TTotal.Text;
312
+            if (_message.Fd122_F == "1")
313
+            {
314
+                _message.Fd122_1 = string.Empty;
315
+                _message.Fd122_2 = string.Empty;
316
+                _message.Fd122_3 = string.Empty;
317
+                _message.Fd122_4 = string.Empty;
318
+                _message.Fd122_5 = string.Empty;
319
+                _message.Fd122_6 = string.Empty;
320
+                _message.Fd122_7 = string.Empty;
321
+                _message.Fd122_8 = string.Empty;
322
+                _message.Fd122_9 = tmp;
323
+                _message.Fd122_A = string.Empty;
324
+                _message.Fd122_B = string.Empty;
325
+                _message.Fd122_C = string.Empty;
326
+                _message.Fd122_D = FEEACNO.Text;
327
+                _message.Fd122_E = FeeAcName;
328
+                _message.Fd122_F = "1";
329
+                _message.Fd122_G = string.IsNullOrEmpty(ACSEQN.Text) ? string.Empty : ACSEQN.Text;
330
+                //_message.Fd122_H = GDPWD.Password;//增加密码的赋值 商永超20120810
331
+                //国密改造
332
+                if (TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("EncrypteGM") == "true")
333
+                {
334
+                    _message.Fd122_K = GDPWD.Password;//增加密码的赋值
335
+                }
336
+                else
337
+                {
338
+                    _message.Fd122_H = GDPWD.Password;//增加密码的赋值 商永超20120810
339
+                }
340
+            }
341
+            else
342
+            {
343
+                _message.Fd122_1 = string.Empty;
344
+                _message.Fd122_2 = string.Empty;
345
+                _message.Fd122_3 = string.Empty;
346
+                _message.Fd122_4 = string.Empty;
347
+                _message.Fd122_5 = string.Empty;
348
+                _message.Fd122_6 = string.Empty;
349
+                _message.Fd122_7 = string.Empty;
350
+                _message.Fd122_8 = string.Empty;
351
+                _message.Fd122_9 = tmp;
352
+                _message.Fd122_A = string.Empty;
353
+                _message.Fd122_B = string.Empty;
354
+                _message.Fd122_C = string.Empty;
355
+                _message.Fd122_D = FEEACNO.Text;
356
+                _message.Fd122_E = FeeAcName;//增加扣费账号户名 商永超20120810
357
+                _message.Fd122_F = string.Empty;
358
+                _message.Fd122_G = string.IsNullOrEmpty(ACSEQN.Text) ? string.Empty : ACSEQN.Text;
359
+                //_message.Fd122_H = GDPWD.Password;//增加密码的赋值 商永超20120810
360
+                //国密改造
361
+                if (TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("EncrypteGM") == "true")
362
+                {
363
+                    _message.Fd122_K = GDPWD.Password;//增加密码的赋值
364
+                }
365
+                else
366
+                {
367
+                    _message.Fd122_H = GDPWD.Password;//增加密码的赋值 商永超20120810
368
+                }
369
+				
370
+            }
371
+            //传输磁道信息:
372
+            _message.Fd122_J = _msr2bak;
373
+            //国密改造
374
+            if (TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("EncrypteGM") != "true")
375
+            {
376
+                _message.Fd122_K = _msr3bak;
377
+            }
378
+
379
+            IsFinishFee = true;
380
+            //将收费信息上传到总线
381
+            //收费方式标识
382
+            this.TradeBus.F000 = this.FEEFLAG.GetSelectedValue();
383
+            //收费方式
384
+            this.TradeBus.F001 = this.FEEFLAG.GetSelectedKey();
385
+            this.TradeBus.F002 = this.DB_FeeList.GetDataForString();
386
+            this.TradeBus.F003 = this.TTotal.Text;
387
+            this.TradeBus.F004 = this.FEEACNO.Text;
388
+            this.TradeBus.F005 = this.ACSEQN.Text;
389
+            this.TradeBus.F006 = sfxm;
390
+            if (FLAG == "V0")
391
+            {
392
+                this.TradeBus.F007 = kfzhhm;
393
+            }
394
+            if (FLAG == "V11" && _message.Fd16 == "2105")
395
+            {
396
+                this.TradeBus.T343 = _message.Fd16;//Fd16
397
+            }
398
+            if (FLAG == "V11" && _message.Fd16 == "5155")//大石桥2375 不收费也打印收费凭条
399
+            {
400
+                if (this.FEEFLAG.GetSelectedValue() == "4")
401
+                {
402
+                    this.TTotal.Text = "";
403
+                }
404
+                //创建收费凭条
405
+                this.PrintFee = new Print_Fee(new Print_Fee.Print_FeeEntry
406
+                {
407
+                    HM = hm,
408
+                    ZH = TmpAcNo,
409
+                    XZH = "",
410
+                    SFXM = sfxm,
411
+                    SFFS = this.TradeBus.F001,
412
+                    SFJE = this.TTotal.Text,
413
+                    KFZH = this.FEEACNO.Text,
414
+                    KFZHHM = kfzhhm,
415
+                    ZHMC = zhmc,
416
+                    JYM = this.TradeBus.T343,
417
+                    yyls = _yyls
418
+                });
419
+                this.PrintFeeGuest = new Print_FeeGuest(new Print_FeeGuest.Print_FeeGuestEntry
420
+                {
421
+                    HM = hm,
422
+                    ZH = TmpAcNo,
423
+                    XZH = "",
424
+                    SFXM = sfxm,
425
+                    SFFS = this.TradeBus.F001,
426
+                    SFJE = this.TTotal.Text,
427
+                    KFZH = this.FEEACNO.Text,
428
+                    KFZHHM = kfzhhm,
429
+                    ZHMC = zhmc,
430
+                    JYM = this.TradeBus.T343,
431
+                    yyls = _yyls
432
+                });
433
+            }
434
+            else
435
+            {
436
+                //创建收费凭条
437
+                if (this.FEEFLAG.GetSelectedValue() != "4")
438
+                    this.PrintFee = new Print_Fee(new Print_Fee.Print_FeeEntry
439
+                    {
440
+                        HM = hm,
441
+                        ZH = TmpAcNo,
442
+                        XZH = "",
443
+                        SFXM = sfxm,
444
+                        SFFS = this.TradeBus.F001,
445
+                        SFJE = this.TTotal.Text,
446
+                        KFZH = this.FEEACNO.Text,
447
+                        KFZHHM = kfzhhm,
448
+                        ZHMC = zhmc,
449
+                        JYM = this.TradeBus.T343
450
+                    });
451
+                if (_is_print && this.FEEFLAG.GetSelectedValue() != "4")
452
+                {
453
+                    this.PrintFeeGuest = new Print_FeeGuest(new Print_FeeGuest.Print_FeeGuestEntry
454
+                    {
455
+                        HM = hm,
456
+                        ZH = TmpAcNo,
457
+                        XZH = "",
458
+                        SFXM = sfxm,
459
+                        SFFS = this.TradeBus.F001,
460
+                        SFJE = this.TTotal.Text,
461
+                        KFZH = this.FEEACNO.Text,
462
+                        KFZHHM = kfzhhm,
463
+                        ZHMC = zhmc,
464
+                        JYM = this.TradeBus.T343
465
+                    });
466
+                }
467
+            }
468
+            _is_print = true;
469
+            this.Close();
470
+        }
471
+
472
+        #endregion 逻辑代码
473
+
474
+        private void FEEFLAG_LostFocus(object sender, RoutedEventArgs e)
475
+        {
476
+            FEEACNO.Text = "";//重新选择清空已经输入的账号 商永超20120711
477
+            //选择输入账号
478
+            if ((string)FEEFLAG.SelectedValue == "3")
479
+            {
480
+                AcInfoCanvas.Visibility = Visibility.Visible;
481
+            }
482
+            else
483
+            {
484
+                FEEACNO.Text = string.Empty;
485
+                GDPWD.Password = string.Empty;
486
+                AcInfoCanvas.Visibility = Visibility.Collapsed;
487
+            }
488
+
489
+            var cash = this.SubStr(ModeChrg, 0, 1);  //现金
490
+            var tran = this.SubStr(ModeChrg, 1, 1);  //转账
491
+            var other = this.SubStr(ModeChrg, 2, 1); //其他账号
492
+            var nofee = this.SubStr(ModeChrg, 3, 1); //不收
493
+            //增加现转标志的判断和黑名单的处理 商永超 20120710
494
+            if (cash == "0" && FEEFLAG.SelectedValue.ToString() == "1")
495
+            {
496
+                this.ShowMessageBox("本交易费用不能收取现金!");
497
+                this.SetFocus(FEEFLAG);
498
+                //FEEFLAG.KeepFocus();
499
+                return;
500
+            }
501
+            if (tran == "0" && FEEFLAG.SelectedValue.ToString() == "2")
502
+            {
503
+                this.ShowMessageBox("本交易费用不能转账收取!");
504
+                this.SetFocus(FEEFLAG);
505
+                //FEEFLAG.KeepFocus();
506
+                return;
507
+            }
508
+            if (other == "0" && FEEFLAG.SelectedValue.ToString() == "3")
509
+            {
510
+                this.ShowMessageBox("本交易费用不能从第三账号收取!");
511
+                this.SetFocus(FEEFLAG);
512
+                //FEEFLAG.KeepFocus();
513
+                return;
514
+            }
515
+            if (nofee == "0" && FEEFLAG.SelectedValue.ToString() == "4" && TTotal.Text.ToDecimal() != 0m)
516
+            {
517
+                this.ShowMessageBox("本交易费用必须收取!");
518
+                this.SetFocus(FEEFLAG);
519
+                //FEEFLAG.KeepFocus();
520
+                return;
521
+            }
522
+            if (BlackFlag == "1" && FEEFLAG.SelectedValue.ToString() == "4")
523
+            {
524
+                this.ShowMessageBox("该客户被列入收费黑名单,必须收费!");
525
+                this.SetFocus(FEEFLAG);
526
+                //FEEFLAG.KeepFocus();
527
+                return;
528
+            }
529
+            if (FEEFLAG.SelectedValue.ToString() != "4" && TTotal.Text.ToDecimal() == 0m)
530
+            {
531
+                this.ShowMessageBox("没有收费,请选择不收!");
532
+                this.SetFocus(FEEFLAG);
533
+                //FEEFLAG.KeepFocus();
534
+                return;
535
+            }
536
+
537
+            //7997 5801 5834 2364 交易码
538
+            string tradecodes1 = "5105|2405";//7997 2364
539
+            string tradecodes2 = "6233|6234";//5801 5834 对公户且转账
540
+
541
+            if (FEEFLAG.GetSelectedValue() == "2")
542
+            {
543
+                if ((tradecodes2.Contains(_message.Fd16) && this.TradeBus.T340 == "1") || tradecodes1.Contains(_message.Fd16))//T340 对公1 个人2
544
+                {
545
+                    _yyls = string.Empty;
546
+                    //var yyCheck = this.TradeAPIs.YYCheck();
547
+                    //if (!yyCheck.IsComplated)
548
+                    //{
549
+                    //    this.TradeAPIs.ShowInfoMessageBox("验印未通过,请继续进行验印!");
550
+                    //    this.TradeAPIs.SetFocus();
551
+                    //    return;
552
+                    //}
553
+                    DzyyEntity dzyyentity = new TellerSystem.Controls.Ext.ControlEntity.DzyyEntity { AccNo = FEEACNO.Text, Amt = TTotal.Text, Voucher = "", VoucherNo = "", VoucherDate = "" };
554
+                    if (this.TradeAPIs.YYCheck(dzyyentity) == false)
555
+                    {
556
+                        this.TradeAPIs.ShowInfoMessageBox(dzyyentity.Message);
557
+                        this.SetFocus();
558
+                        return;
559
+                    }
560
+                    string FeeZH = string.Empty;
561
+                    string FeeJE = string.Empty;
562
+
563
+                    _yyls = dzyyentity.SerialNo;
564
+                    switch (_message.Fd16)
565
+                    {
566
+                        case "5105"://7997
567
+                            FeeZH = this.TradeBus.T344.Trim();
568
+                            this.TradeBus.T222 = _yyls;//7997 收费不打印凭证,需要把验印流水打印在通用凭证上
569
+                            break;
570
+                        case "2405"://2364
571
+                            FeeZH = this.TradeBus.T131.Trim();
572
+                            this.TradeBus.T222 = _yyls;//2364 收费打印凭证,需要把验印流水打印在通用凭证上
573
+                            break;
574
+                        case "6233"://5801 5834
575
+                        case "6234"://5801 5834
576
+                            FeeZH = this.TradeBus.T339.Trim();
577
+                            this.TradeBus.T222 = _yyls;//5801 5834 收费不打印凭证,需要把验印流水打印在通用凭证上
578
+                            break;
579
+                    }
580
+                    //string zh = yyCheck.ZH == FeeZH ? string.Empty : "账号,";
581
+                    //string je = yyCheck.JE == TTotal.Text ? string.Empty : "金额,";
582
+                    //string type = yyCheck.Type == "收费凭证" ? string.Empty : "收费凭证";
583
+                    //string _zh = yyCheck.ZH == FeeZH ? string.Empty : yyCheck.ZH + ",";
584
+                    //string _je = yyCheck.JE == TTotal.Text ? string.Empty : yyCheck.JE + ",";
585
+                    //string _type = yyCheck.Type == "收费凭证" ? string.Empty : yyCheck.Type;
586
+                    //if (yyCheck.IsOnline)
587
+                    //{
588
+                    //    if (FeeZH != yyCheck.ZH || TTotal.Text != yyCheck.JE || "收费凭证" != yyCheck.Type)
589
+                    //    {
590
+                    //        this.TradeAPIs.ShowInfoMessageBox("当前" + zh + je + type + "与验印结果:" + _zh + _je + _type + "不一致,请确认!");
591
+                    //        this.TradeAPIs.SetFocus();
592
+                    //        return;
593
+                    //    }
594
+                    //}
595
+                }
596
+            }
597
+        }
598
+
599
+        /// <summary>
600
+        /// 扣费账号
601
+        /// </summary>
602
+        /// <param name="sender"></param>
603
+        /// <param name="e"></param>
604
+        private void FEEACNO_LostFocus(object sender, RoutedEventArgs e)
605
+        {
606
+            if (!(FLAG == "V0" && this.TradeModel.Code.Trim() == "2998" && _message.Fd16 == "2410"))//更换介质
607
+            {
608
+                if (this.Delspace(TmpAcNo) == this.Delspace(FEEACNO.Text))
609
+                {
610
+                    this.ShowMessageBox("其他账号不能是交易主账号!");
611
+                    this.SetFocus(FEEFLAG);
612
+                    //FEEACNO.KeepFocus();
613
+                    return;
614
+                }
615
+            }
616
+            ////读取磁道信息
617
+            //if (TellerSystem.Devices.Config.DeviceConfig.SwipeCardEnabled)
618
+            //{
619
+            //    try
620
+            //    {
621
+            //        _msr2bak = DeviceManager.GetSwipeCardData(FEEACNO).Data.TracksTwo;
622
+            //        _msr3bak = DeviceManager.GetSwipeCardData(FEEACNO).Data.TracksThree;
623
+            //    }
624
+            //    catch
625
+            //    {
626
+            //        this.ShowMessageBox("刷卡错误,请重试!");
627
+            //        this.SetFocus(FEEACNO);
628
+            //        return;
629
+            //    }
630
+            //}
631
+            //update by ZhangYongheng @2014年4月25日
632
+            //在后台查询活期帐户,检查账号,返回子账户列表
633
+            var acinfo = this.TradeAPIs.TF_Deposit_QueryChildAccountList(new QueryChildAccountList.Input()
634
+                {
635
+                    ZH = FEEACNO.Text.Trim()
636
+                }
637
+            );
638
+            if (acinfo.IsFailed)
639
+            {
640
+                FEEACNO.Text = string.Empty;
641
+                this.TradeAPIs.ShowTip(acinfo.FailureCause);
642
+                this.TradeAPIs.SetFocus();
643
+                return;
644
+            }
645
+            if (acinfo.ZZHXXData.Count > 0)
646
+            {
647
+                //账户序号|开户日期|产品名称|账户余额|账户状态|冻结状态|止付状态|
648
+                var selectedData = this.ShowDataBoxViewer(acinfo.ZZHXX, new string[] { "账户序号", "开户日期", "产品名称", "账户余额", "账户状态" });
649
+                if (selectedData == null)
650
+                {
651
+                    ACSEQN.Text = string.Empty;
652
+                    this.TradeAPIs.ShowTip(this.TradeAPIs.GetNotifyMessage(NotifyMessage.N039));
653
+                    this.TradeAPIs.SetFocus();
654
+                    return;
655
+                }
656
+                ACSEQN.Text = selectedData["账户序号"].ToString();
657
+            }
658
+            else
659
+            {
660
+                this.TradeAPIs.ShowTip("没有可选账号信息");
661
+                this.SetFocus();
662
+                return;
663
+            }
664
+
665
+            //查询账号信息
666
+            var acInfos = this.TradeAPIs.TF_Deposit_QueryDepositAccount(new QueryDepositAccount.Input()
667
+            {
668
+                ZH = FEEACNO.Text.Trim(),
669
+                XH = ACSEQN.Text.Trim()
670
+            });
671
+            if (acInfos.IsFailed)
672
+            {
673
+                this.TradeAPIs.ShowTip(acInfos.FailureCause);
674
+                this.TradeAPIs.SetFocus();
675
+                return;
676
+            }
677
+            kfzhhm = acInfos.HM;
678
+            zjlx = acInfos.ZJLX;//获取证件类型,供校验
679
+            zjhm = acInfos.ZJHM;//获取证件号码,供校验
680
+            if (_message.Fd103_3 != acInfos.BZ && _message.Fd16 == "2100")
681
+            {
682
+                this.ShowMessageBox("该账号的币种与收费币种不一致!");
683
+                this.SetFocus(FEEFLAG);
684
+                return;
685
+            }
686
+            if (acInfos.KHLX != "1" && acInfos.KHLX != "5")
687
+            {
688
+                //对公账户
689
+                //判断账号是否允许通存通兑
690
+                var zyhshortTrade = this.TradeAPIs.TF_Deposit_QueryAccountTCTD(
691
+                    new QueryAccountTCTD.Input()
692
+                    {
693
+                        ZH = acInfos.ZH
694
+                    }
695
+                    );
696
+                if (zyhshortTrade.IsFailed)
697
+                {
698
+                    this.TradeAPIs.ShowTip(zyhshortTrade.FailureCause);
699
+                    this.TradeAPIs.SetFocus();
700
+                    return;
701
+                }
702
+                //如果不允许通兑
703
+                if (zyhshortTrade.SFTD == "N")
704
+                {
705
+                    if (acInfos.KHJG != LoginUserInfo.KinbrNo)
706
+                    {
707
+                        this.TradeAPIs.ShowTip("该账号不允许通兑:" + this.TradeAPIs.GetNotifyMessage(NotifyMessage.N017));
708
+                        this.TradeAPIs.SetFocus();
709
+                        return;
710
+                    }
711
+                }
712
+                //对公不验密,手动验印
713
+                LPASSWORD.Visibility = Visibility.Collapsed;
714
+                GDPWD.Visibility = Visibility.Collapsed;
715
+            }
716
+            else
717
+            {
718
+                if (acInfos.SFPM == "N")  /*无密户*/
719
+                {
720
+                    //AcSeqCanvas.Visibility = Visibility.Collapsed;
721
+                    LPASSWORD.Visibility = Visibility.Collapsed;
722
+                    GDPWD.Visibility = Visibility.Collapsed;
723
+                }
724
+                else
725
+                {
726
+                    //AcSeqCanvas.Visibility = Visibility.Visible;
727
+                    LPASSWORD.Visibility = Visibility.Visible;
728
+                    GDPWD.Visibility = Visibility.Visible;
729
+                }
730
+                #region 凭证支取校验
731
+                switch(FLAG)
732
+                {
733
+                    case"V2"://鄢陵要求,账号凭证支取,需校验证件号码 addby wangheng
734
+                        DRAWFLAG.Visibility=Visibility.Visible;
735
+                        WITHDRAW.Visibility=Visibility.Visible;
736
+                        if (acInfos.SFPZJZQ =="Y")  /*证件支取*/
737
+                        {
738
+                            DRAWFLAG.SetItems(new Dictionary<string, string> { { "证件支付", "1" } });
739
+                            DRAWFLAG.SelectedIndex = 0;
740
+                            ACIDTYPE.SetItems(UserVariable.GetIdType()); 
741
+                            ACIDTYPE.SetSelectedValue(acInfos.ZJLX);
742
+                            ACIDTYPE.IsEnabled=false;
743
+                            ACIDTYPE.Visibility=Visibility.Visible;
744
+                            IDTYPE.Visibility=Visibility.Visible;
745
+                            ACIDNO.Visibility=Visibility.Visible;
746
+                            IDNO.Visibility=Visibility.Visible;
747
+                        }
748
+                        else if(acInfos.SFPM == "Y")//凭密支取
749
+                        {
750
+                            DRAWFLAG.SetItems(new Dictionary<string, string> { { "密码支付", "1" } });
751
+                            DRAWFLAG.SelectedIndex = 0;
752
+                            ACIDTYPE.Visibility=Visibility.Collapsed;
753
+                            IDTYPE.Visibility=Visibility.Collapsed;
754
+                            ACIDNO.Visibility=Visibility.Collapsed;
755
+                            IDNO.Visibility=Visibility.Collapsed;
756
+                        }
757
+                        else //不凭证也不凭密
758
+                        {
759
+                            ACIDTYPE.Visibility=Visibility.Collapsed;
760
+                            IDTYPE.Visibility=Visibility.Collapsed;
761
+                            ACIDNO.Visibility=Visibility.Collapsed;
762
+                            IDNO.Visibility=Visibility.Collapsed;
763
+                            WITHDRAW.Visibility=Visibility.Collapsed;
764
+                            DRAWFLAG.Visibility=Visibility.Collapsed;
765
+                            LPASSWORD.Visibility=Visibility.Collapsed;
766
+                            GDPWD.Visibility=Visibility.Collapsed;
767
+                        }
768
+                        break;
769
+                    default: //中牟郏县无要求
770
+                        break;
771
+                }
772
+                #endregion 凭证支取校验
773
+                
774
+            }
775
+            
776
+        }
777
+
778
+        /// <summary>
779
+        /// 校验密码
780
+        /// </summary>
781
+        /// <param name="sender"></param>
782
+        /// <param name="e"></param>
783
+        private void GDPWD_LostFocus(object sender, RoutedEventArgs e)
784
+        {
785
+            //密码验证
786
+            var mmcheck = this.TradeAPIs.TF_Deposit_PasswordAuthentication(new PasswordAuthentication.Input()
787
+            {
788
+                MM = GDPWD.Password,
789
+                ZH = FEEACNO.Text.Trim()
790
+            });
791
+            if (mmcheck.IsFailed)
792
+            {
793
+                GDPWD.Password = string.Empty;
794
+                this.TradeAPIs.ShowTip(mmcheck.FailureCause);
795
+                this.TradeAPIs.SetFocus();
796
+                return;
797
+            }
798
+        }
799
+
800
+        /// <summary>
801
+        /// 凭证支取时校验证件号码
802
+        /// </summary>
803
+        private void ACIDNO_LostFocus(object sender, RoutedEventArgs e)
804
+        {
805
+            //证件号码校验
806
+            if (ACIDNO.Text.Trim()!=zjhm)
807
+            {
808
+                ACIDNO.Text = string.Empty;
809
+                this.TradeAPIs.ShowTip("证件号码不正确");
810
+                this.TradeAPIs.SetFocus();
811
+                return;
812
+            }
813
+        }
814
+
815
+        //private void ACIDTYPE_LostFocus(object sender, RoutedEventArgs e)
816
+        //{
817
+        //    //证件类型校验
818
+        //    if (ACIDTYPE.GetSelectedValue() != zjlx)
819
+        //    {
820
+        //        this.TradeAPIs.ShowTip("证件类型不符");
821
+        //        this.TradeAPIs.SetFocus();
822
+        //        return;
823
+        //    }
824
+
825
+        //}
826
+    }
827
+}

+ 282
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FileViewer.xaml 查看文件

@@ -0,0 +1,282 @@
1
+<local:ManagerTradePage x:Class="TellerSystem.Controls.Ext.Controls.FileViewer"
2
+                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                        xmlns:dhcc="http://www.dhcc.com.cn"
6
+                        xmlns:local="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
7
+                        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                        Width="830"
9
+                        Height="600"
10
+                        KeyDown="TradePage_KeyDown"
11
+                        mc:Ignorable="d">
12
+    <dhcc:TradePage.Resources>
13
+        <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
14
+            <Setter Property="FontSize" Value="12" />
15
+            <Setter Property="Foreground" Value="Black" />
16
+            <Setter Property="Width" Value="79" />
17
+            <Setter Property="Height" Value="23" />
18
+            <!--  修改模板属性  -->
19
+            <Setter Property="Template">
20
+                <Setter.Value>
21
+                    <!--  控件模板  -->
22
+                    <ControlTemplate TargetType="Button">
23
+                        <!--  背景色  -->
24
+                        <Border x:Name="back"
25
+                                CornerRadius="3"
26
+                                Opacity="1">
27
+                            <Border.BitmapEffect>
28
+                                <OuterGlowBitmapEffect GlowColor="{Binding RelativeSource={RelativeSource TemplatedParent},
29
+                                                                           Path=(Button.Background).(SolidColorBrush.Color)}"
30
+                                                       GlowSize="0"
31
+                                                       Opacity="0.7" />
32
+                            </Border.BitmapEffect>
33
+                            <Border.Background>
34
+                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1.5">
35
+                                    <GradientBrush.GradientStops>
36
+                                        <GradientStopCollection>
37
+                                            <GradientStop Offset="0" Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Button.Background).(SolidColorBrush.Color)}" />
38
+                                            <GradientStop Offset="0.4" Color="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(Button.Background).(SolidColorBrush.Color)}" />
39
+                                            <GradientStop Offset="1" Color="#FF0B6BD6" />
40
+                                        </GradientStopCollection>
41
+                                    </GradientBrush.GradientStops>
42
+                                </LinearGradientBrush>
43
+                            </Border.Background>
44
+                            <!--  前景色及边框  -->
45
+                            <Border x:Name="fore"
46
+                                    BorderBrush="#5555"
47
+                                    BorderThickness="1"
48
+                                    CornerRadius="3">
49
+                                <Border.Background>
50
+                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
51
+                                        <GradientBrush.GradientStops>
52
+                                            <GradientStopCollection>
53
+                                                <GradientStop Offset="0.5" Color="#6FFF" />
54
+                                                <GradientStop Offset="0.51" Color="#1111" />
55
+                                            </GradientStopCollection>
56
+                                        </GradientBrush.GradientStops>
57
+                                    </LinearGradientBrush>
58
+                                </Border.Background>
59
+                                <!--  按钮内容  -->
60
+                                <ContentPresenter x:Name="content"
61
+                                                  HorizontalAlignment="Center"
62
+                                                  VerticalAlignment="Center"
63
+                                                  Content="{TemplateBinding Content}">
64
+                                    <!--  反应说这个效果不好  -->
65
+                                    <!--
66
+                                        <ContentPresenter.BitmapEffect>
67
+                                        <DropShadowBitmapEffect Direction="-90"
68
+                                        Opacity="0.3"
69
+                                        ShadowDepth="2"
70
+                                        Softness="0.1"
71
+                                        Color="#FF333333" />
72
+                                        </ContentPresenter.BitmapEffect>
73
+                                    -->
74
+                                </ContentPresenter>
75
+                            </Border>
76
+                        </Border>
77
+                        <!--  触发器  -->
78
+                        <ControlTemplate.Triggers>
79
+                            <!--  按钮失效  -->
80
+                            <Trigger Property="IsEnabled" Value="False">
81
+                                <Setter Property="Foreground" Value="#B444" />
82
+                                <Trigger.EnterActions>
83
+                                    <BeginStoryboard>
84
+                                        <Storyboard>
85
+                                            <!--
86
+                                                <DoubleAnimation Duration="0:0:0.3"
87
+                                                Storyboard.TargetName="back"
88
+                                                Storyboard.TargetProperty="(Border.BitmapEffect).(OuterGlowBitmapEffect.GlowSize)"
89
+                                                To="0" />
90
+                                            -->
91
+                                            <!--
92
+                                                <DoubleAnimation Duration="0:0:0.1"
93
+                                                Storyboard.TargetName="content"
94
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Opacity)"
95
+                                                To="1" />
96
+                                            -->
97
+                                            <!--
98
+                                                <DoubleAnimation Duration="0:0:0.1"
99
+                                                Storyboard.TargetName="content"
100
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Direction)"
101
+                                                To="-135" />
102
+                                            -->
103
+                                            <!--
104
+                                                <ColorAnimation Duration="0:0:0.3"
105
+                                                Storyboard.TargetName="content"
106
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Color)"
107
+                                                To="#FFF" />
108
+                                            -->
109
+                                            <ColorAnimation Duration="0:0:0.3"
110
+                                                            Storyboard.TargetName="fore"
111
+                                                            Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)"
112
+                                                            To="#D555" />
113
+                                            <ColorAnimation Duration="0:0:0.3"
114
+                                                            Storyboard.TargetName="fore"
115
+                                                            Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)"
116
+                                                            To="#CEEE" />
117
+                                            <ColorAnimation Duration="0:0:0.3"
118
+                                                            Storyboard.TargetName="fore"
119
+                                                            Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
120
+                                                            To="#CDDD" />
121
+                                        </Storyboard>
122
+                                    </BeginStoryboard>
123
+                                </Trigger.EnterActions>
124
+                                <Trigger.ExitActions>
125
+                                    <BeginStoryboard>
126
+                                        <Storyboard>
127
+                                            <!--
128
+                                                <DoubleAnimation Duration="0:0:0.1"
129
+                                                Storyboard.TargetName="back"
130
+                                                Storyboard.TargetProperty="(Border.BitmapEffect).(OuterGlowBitmapEffect.GlowSize)" />
131
+                                            -->
132
+                                            <!--
133
+                                                <DoubleAnimation Duration="0:0:0.1"
134
+                                                Storyboard.TargetName="content"
135
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Opacity)" />
136
+                                            -->
137
+                                            <!--
138
+                                                <DoubleAnimation Duration="0:0:0.1"
139
+                                                Storyboard.TargetName="content"
140
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Direction)" />
141
+                                            -->
142
+                                            <!--
143
+                                                <ColorAnimation Duration="0:0:0.1"
144
+                                                Storyboard.TargetName="content"
145
+                                                Storyboard.TargetProperty="(ContentPresenter.BitmapEffect).(DropShadowBitmapEffect.Color)" />
146
+                                            -->
147
+                                            <ColorAnimation Duration="0:0:0.1"
148
+                                                            Storyboard.TargetName="fore"
149
+                                                            Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" />
150
+                                            <ColorAnimation Duration="0:0:0.1"
151
+                                                            Storyboard.TargetName="fore"
152
+                                                            Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)" />
153
+                                            <ColorAnimation Duration="0:0:0.1"
154
+                                                            Storyboard.TargetName="fore"
155
+                                                            Storyboard.TargetProperty="(Border.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)" />
156
+                                        </Storyboard>
157
+                                    </BeginStoryboard>
158
+                                </Trigger.ExitActions>
159
+                            </Trigger>
160
+                        </ControlTemplate.Triggers>
161
+                    </ControlTemplate>
162
+                </Setter.Value>
163
+            </Setter>
164
+        </Style>
165
+        <Style x:Key="TextBlockStyle" TargetType="{x:Type TextBlock}">
166
+            <Setter Property="FontSize" Value="12" />
167
+            <Setter Property="Foreground" Value="Black" />
168
+        </Style>
169
+        <Style x:Key="TextBoxStyle" TargetType="{x:Type TextBox}">
170
+            <Setter Property="FontSize" Value="12" />
171
+            <Setter Property="Foreground" Value="Black" />
172
+            <Setter Property="Width" Value="30" />
173
+            <Setter Property="Height" Value="18" />
174
+            <Setter Property="Margin" Value="5" />
175
+        </Style>
176
+    </dhcc:TradePage.Resources>
177
+    <Grid>
178
+        <Grid.RowDefinitions>
179
+            <RowDefinition Height="35" />
180
+            <RowDefinition Height="auto" />
181
+            <RowDefinition Height="*" />
182
+        </Grid.RowDefinitions>
183
+        <ToolBar x:Name="toolBar"
184
+                 Grid.Row="0"
185
+                 ToolBarTray.IsLocked="True">
186
+            <Button x:Name="btnPrint"
187
+                    Click="PrintCommand"
188
+                    Content="打 印(P)"
189
+                    IsEnabled="False"
190
+                    Style="{StaticResource ButtonStyle}" />
191
+            <Separator Margin="5" />
192
+            <Button x:Name="btnQuickPrint"
193
+                    Click="PrintQuickCommand"
194
+                    Content="快速打印(F)"
195
+                    IsEnabled="False"
196
+                    Style="{StaticResource ButtonStyle}" />
197
+            <Separator Margin="5" />
198
+            <Button x:Name="btnExit"
199
+                    Click="ExitCommand"
200
+                    Content="退 出(ESC)"
201
+                    Style="{StaticResource ButtonStyle}" />
202
+            <Separator Margin="5" />
203
+            <Button x:Name="BtnFirstPage"
204
+                    Click="FirstPageCommand"
205
+                    Content="首页(Home)"
206
+                    IsEnabled="False"
207
+                    Style="{StaticResource ButtonStyle}" />
208
+            <Separator Margin="5" />
209
+            <Button x:Name="BtnPreviouePage"
210
+                    Click="PreviouePageCommand"
211
+                    Content="上一页(↑)"
212
+                    IsEnabled="False"
213
+                    Style="{StaticResource ButtonStyle}" />
214
+            <Separator Margin="5" />
215
+            <Button x:Name="BtnNextPage"
216
+                    Click="NextPageCommand"
217
+                    Content="下一页(↓)"
218
+                    IsEnabled="False"
219
+                    Style="{StaticResource ButtonStyle}" />
220
+            <Separator Margin="5" />
221
+            <Button x:Name="BtnLastPage"
222
+                    Click="LastPageCommand"
223
+                    Content="尾页(End)"
224
+                    IsEnabled="False"
225
+                    Style="{StaticResource ButtonStyle}" />
226
+            <Separator Margin="5" />
227
+            <Button x:Name="btnGoToPage"
228
+                    Click="GoToPageCommand"
229
+                    Content="跳 转"
230
+                    IsEnabled="False"
231
+                    Style="{StaticResource ButtonStyle}" />
232
+            <Separator Margin="5" />
233
+            <Button x:Name="btnExport"
234
+                    Click="ExportCommand"
235
+                    Content="导 出"
236
+                    IsEnabled="True"
237
+                    Style="{StaticResource ButtonStyle}"
238
+                    Visibility="Collapsed" />
239
+            <TextBox Name="pageNumberTextBox"
240
+                     DataObject.Pasting="pageNumberPasting"
241
+                     InputMethod.IsInputMethodEnabled="False"
242
+                     IsTabStop="False"
243
+                     PreviewKeyDown="pageNumberPreviewKeyDown"
244
+                     PreviewTextInput="pageNumberPreviewTextInput"
245
+                     Style="{StaticResource TextBoxStyle}" />
246
+            <Button x:Name="btnExportlast"
247
+                    Click="ExportpagesCommand"
248
+                    Content="导 出"
249
+                    IsEnabled="True"
250
+                    Style="{StaticResource ButtonStyle}"
251
+                    Visibility="Collapsed" />
252
+        </ToolBar>
253
+        <RichTextBox x:Name="reportTextBox"
254
+                     Grid.Row="1"
255
+                     Height="510"
256
+                     Margin="0"
257
+                     HorizontalAlignment="Center"
258
+                     AcceptsReturn="True"
259
+                     FontFamily="宋体"
260
+                     FontSize="9pt"
261
+                     HorizontalScrollBarVisibility="Visible"
262
+                     VerticalScrollBarVisibility="Visible">
263
+            <RichTextBox.Document>
264
+                <FlowDocument x:Name="flowDocument" PageWidth="2000" />
265
+            </RichTextBox.Document>
266
+        </RichTextBox>
267
+        <StackPanel Grid.Row="2" Orientation="Horizontal">
268
+            <TextBlock x:Name="DownCurrentPage"
269
+                       Margin="100,5,4,4"
270
+                       Style="{StaticResource TextBlockStyle}"
271
+                       Text="" />
272
+            <TextBlock x:Name="CurrentPage"
273
+                       Margin="100,5,4,4"
274
+                       Style="{StaticResource TextBlockStyle}"
275
+                       Text="第1页" />
276
+            <TextBlock x:Name="SumPage"
277
+                       Margin="50,5,4,4"
278
+                       Style="{StaticResource TextBlockStyle}"
279
+                       Text="共1页" />
280
+        </StackPanel>
281
+    </Grid>
282
+</local:ManagerTradePage>

+ 1307
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/FileViewer.xaml.cs
文件差异内容过多而无法显示
查看文件


+ 121
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/IdCheckViewer.xaml 查看文件

@@ -0,0 +1,121 @@
1
+<tp:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.IdCheckViewer"
2
+                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                   xmlns:dhcc="http://www.dhcc.com.cn"
6
+                   xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
7
+                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                   xmlns:tp="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
9
+                   dhcc:FocusManager.EnableFocusControl="True"
10
+                   FontFamily="Simsun"
11
+                   Loaded="TradePage_Loaded"
12
+                   mc:Ignorable="d">
13
+    <StackPanel VerticalAlignment="Top">
14
+        <Grid>
15
+            <local:TradePanel x:Name="sfhcxx"
16
+                              Height="210"
17
+                              Header="身份核查信息">
18
+                <TextBlock Text="身份证号" />
19
+                <TextBox x:Name="tb_txtID"
20
+                         Width="180"
21
+                         dhcc:FocusManager.LostFocus="txtID_LostFocus"
22
+                         dhcc:FocusManagerExt.AssertNotEmpty="True"
23
+                         dhcc:TextBoxHelper.InputType="IDCard"
24
+                         dhcc:TextBoxHelper.IsShowLength="True"
25
+                         local:TradePanel.ColumnSpan="3"
26
+                         MaxLength="18" />
27
+                <TextBlock Text="姓    名" />
28
+                <TextBox x:Name="tb_txtName"
29
+                         Width="180"
30
+                         dhcc:FocusManager.LostFocus="InputName_LostFocus"
31
+                         dhcc:FocusManagerExt.AssertNotEmpty="True"
32
+                         local:TradePanel.ColumnSpan="3" />
33
+                <TextBlock Text="业务种类" />
34
+                <ComboBox Name="cb_busType"
35
+                          Width="180"
36
+                          local:TradePanel.ColumnSpan="3" />
37
+                <TextBlock Name="tbrlbd"
38
+                           Text="人脸比对"
39
+                           Visibility="Collapsed" />
40
+                <ComboBox Name="cb_rlbd"
41
+                          Width="180"
42
+                          dhcc:FocusManager.LostFocus="cb_rlbd_LostFocus"
43
+                          local:TradePanel.ColumnSpan="3"
44
+                          Visibility="Collapsed" />
45
+                <TextBlock Text="核查原因" />
46
+                <TextBox x:Name="tb_reason"
47
+                         Width="400"
48
+                         Height="80"
49
+                         MaxLength="100"
50
+                         TextWrapping="Wrap" />
51
+            </local:TradePanel>
52
+            <Border Width="146"
53
+                    Height="180"
54
+                    Margin="0,10,20,0"
55
+                    HorizontalAlignment="Right"
56
+                    BorderBrush="Black"
57
+                    BorderThickness="1">
58
+                <Image x:Name="imgPhoto_device" Source="{StaticResource MenutoolReloginNormal}" />
59
+            </Border>
60
+        </Grid>
61
+        <StackPanel Margin="10"
62
+                    FlowDirection="RightToLeft"
63
+                    Orientation="Horizontal">
64
+            <Button x:Name="btnBack"
65
+                    Width="80"
66
+                    Height="25"
67
+                    Click="btnBack_Click"
68
+                    Content="返  回" />
69
+            <Button x:Name="btnPrint"
70
+                    Width="80"
71
+                    Height="25"
72
+                    Click="btnPrint_Click"
73
+                    Content="打  印"
74
+                    IsEnabled="False" />
75
+            <Button x:Name="btnCheck"
76
+                    Width="80"
77
+                    Height="25"
78
+                    Click="btnCheck_Click"
79
+                    Content="核  查" />
80
+        </StackPanel>
81
+        <Grid x:Name="CheckResult">
82
+            <local:TradePanel Height="210"
83
+                              Header="身份核查结果"
84
+                              IsEnabled="False">
85
+                <TextBlock Text="核对结果" />
86
+                <ComboBox x:Name="cbb_Result"
87
+                          Width="400"
88
+                          local:TradePanel.ColumnSpan="3" />
89
+                <TextBlock Text="签发机关" />
90
+                <TextBox x:Name="tb_IssuingAuthority"
91
+                         Width="400"
92
+                         Height="50"
93
+                         local:TradePanel.ColumnSpan="3"
94
+                         TextWrapping="Wrap" />
95
+                <TextBlock Text="姓    名" />
96
+                <TextBox x:Name="tb_NameResult"
97
+                         Width="180"
98
+                         local:TradePanel.ColumnSpan="3" />
99
+                <TextBlock Text="身份证号" />
100
+                <TextBox x:Name="tb_IdNumber"
101
+                         Width="180"
102
+                         local:TradePanel.ColumnSpan="3" />
103
+                <TextBlock Name="tl_grade"
104
+                           Text="人脸比对结果"
105
+                           Visibility="Collapsed" />
106
+                <TextBox x:Name="grade"
107
+                         Width="180"
108
+                         local:TradePanel.ColumnSpan="3"
109
+                         Visibility="Collapsed" />
110
+            </local:TradePanel>
111
+            <Border Width="146"
112
+                    Height="180"
113
+                    Margin="0,10,20,0"
114
+                    HorizontalAlignment="Right"
115
+                    BorderBrush="Black"
116
+                    BorderThickness="1">
117
+                <Image x:Name="imgPhoto" Source="{StaticResource MenutoolReloginNormal}" />
118
+            </Border>
119
+        </Grid>
120
+    </StackPanel>
121
+</tp:BlankTradePage>

+ 589
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/IdCheckViewer.xaml.cs 查看文件

@@ -0,0 +1,589 @@
1
+using System;
2
+using System.Windows;
3
+using System.Windows.Media;
4
+using System.Windows.Media.Imaging;
5
+using System.IO;
6
+using System.Text.RegularExpressions;
7
+using Platform.Controls.ControlsHelper;
8
+using Platform.Library;
9
+using TellerSystem.Communication;
10
+using TellerSystem.Library.Ext.Function;
11
+using Platform.Common.RunningParameters;
12
+using TellerSystem.ServiceProxy.Ext.ServiceEntitys;
13
+using TellerSystem.Devices.Interface;
14
+using TellerSystem.Library.Ext.Variables;
15
+using TellerSystem.Controls.Ext.PrintsHelper;
16
+using TellerSystem.Library.Ext.TradeExtension;
17
+using TellerSystem.PrintTemplate.Extension;
18
+using System.Windows.Controls;
19
+using System.Printing;
20
+using Platform.Print;
21
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
22
+using System.Collections.Generic;
23
+using System.Drawing;
24
+using System.ComponentModel;
25
+using TellerSystem.ServiceProxy.Ext;
26
+using TellerSystem.Controls.Ext.ControlsHelper;
27
+using System.Diagnostics;
28
+using System.Text;
29
+using TellerSystem.ServiceProxy.Ext.WebAPI.Auth.Entity;
30
+using System.Net;
31
+using System.Net.Cache;
32
+using Newtonsoft.Json;
33
+using Newtonsoft.Json.Linq;
34
+using TellerSystem.Contract.Function;
35
+
36
+/******************************平台Dll*****************************/
37
+
38
+namespace TellerSystem.Controls.Ext.Controls
39
+{
40
+    /// <summary>
41
+    /// IdCheckViewer.xaml 的交互逻辑
42
+    /// </summary>
43
+    public partial class IdCheckViewer
44
+    {
45
+        #region Ctor
46
+        /// <summary>
47
+        /// 核查完毕后是否联动人脸识别
48
+        /// </summary>
49
+        public bool Link2RLSB { get; private set; }
50
+
51
+        public IdCheckViewer(IdentityCardEntity info, bool RLSB = true)
52
+        {
53
+            InitializeComponent();
54
+            Link2RLSB = RLSB;
55
+            Info = info;
56
+            Record = new IdCheckerResult();
57
+            Record.DeviceInfo = info;
58
+            Record.IsOnline = SystemSettingsHelper.Instance.IsIdCheck;
59
+        }
60
+        string FLAG = TradeManagerHandle.TT_SYSCONFIG_GetConfigValueByConfigID("2ea3a7e6cfa04f89a335bf1e363295de");
61
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
62
+        {
63
+            /* 初始化界面逻辑,页面加载后执行*/
64
+            if (this.Info != null)
65
+            {
66
+                tb_txtID.Text = Info.IdNumber.Trim();
67
+                tb_txtID.IsReadOnly = true;
68
+                if (!string.IsNullOrEmpty(Info.Name))
69
+                {
70
+                    tb_txtName.Text = Info.Name.Trim();
71
+                    tb_txtName.IsReadOnly = true;
72
+                }
73
+                if (Info.MyProperty != null) imgPhoto_device.Source = Info.MyProperty;
74
+            }
75
+            this.TradeAPIs.SetItems(cb_busType, UserVariable.GetIdCheckReasonType());
76
+            cbb_Result.SetItems(new Dictionary<string, string> { { "公民身份证号码与姓名一致,且存在照片", "00" }, { "公民身份证号码与姓名一致,但不存在照片", "01" }, { "公民身份证号码存在,但与姓名不一致", "02" }, { "公民身份证号码不存在", "03" }, { "其他错误", "04" }, { "输入的参数有误", "05" }, { "认证码错误", "06" } });
77
+            if (FLAG == "V0" || FLAG == "V2" || FLAG == "V3" || FLAG == "V4" || FLAG == "V23" || FLAG == "V24") //郑银接入联网核查
78
+            {
79
+                cbb_Result.SetItems(new Dictionary<string, string> { 
80
+                { "公民身份号码与姓名一致,且存在照片", "00" }, 
81
+                { "公民身份号码与姓名一致,但不存在照片", "01" }, 
82
+                { "公民身份证号码存在,但与姓名不匹配", "02" }, 
83
+                { "公民身份证号码不存在", "03" }, 
84
+                { "其他错误", "04" }, 
85
+                { "输入的参数有误", "05" },
86
+                { "上传机构代码错误", "06" }, 
87
+                { "身份证信息一致,照片相符(文字+相片)", "07" },
88
+                { "公民姓名与身份证号码一致,相片不一致(文字+相片)", "08" },
89
+                { "公民姓名与身份证号码一致(文字)", "09" },
90
+                { "非最新证件", "10" } });
91
+            }
92
+            if (AICapacity.GetInstence().IsOpen && string.Compare(this.TradeAPIs.GetTradeMetadata("isRlsb"), "true", true) == 0)
93
+            {
94
+                tl_grade.Visibility = grade.Visibility = Visibility.Visible;
95
+            }
96
+            if (AICapacity.GetInstence().IsOpen && FLAG != "V5" && string.Compare(this.TradeAPIs.GetTradeMetadata("isRlsb"), "true", true) == 0)
97
+            {
98
+                cb_rlbd.Visibility = tbrlbd.Visibility = Visibility.Visible;
99
+                cb_rlbd.SetItems(new Dictionary<string, string> { { "是", "1" }, { "否", "0" } });
100
+                sfhcxx.Height = 230;
101
+                grade.Width = 400;
102
+            }
103
+        }
104
+        #endregion
105
+
106
+        #region Property
107
+        /// <summary>
108
+        /// 核查的主体信息
109
+        /// </summary>
110
+        public IdentityCardEntity Info { get; private set; }
111
+
112
+        /// <summary>
113
+        /// 核查结果
114
+        /// </summary>
115
+        public IdCheckerResult Record { get; private set; }
116
+        #endregion
117
+
118
+        #region Internal
119
+        /// <summary>
120
+        ///   15位身份证转换成18位
121
+        /// </summary>
122
+        /// <param name="StrCard15">15位身份证</param>
123
+        /// <param name="StrYear">出生年份</param>
124
+        /// <returns></returns>
125
+        private string Convert15to18(string StrCard15, string StrYear)
126
+        {
127
+            if (StrCard15 == null || StrCard15.Length != 15)
128
+            {
129
+                return StrCard15;
130
+            }
131
+            string year = "19";
132
+            if (!string.IsNullOrEmpty(StrYear) && StrYear.Length == 2)
133
+            {
134
+                year = StrYear;
135
+            }
136
+            //生成17位号  
137
+            String StrCard17 = StrCard15.Substring(0, 6) + year + StrCard15.Substring(6);
138
+            //计算校验位,返回18位号
139
+            return StrCard17 + GetLastNumber(StrCard17);
140
+        }
141
+
142
+        /// <summary>
143
+        ///   根据17位号生成校验位
144
+        /// </summary>
145
+        /// <param name="StrCard17"></param>
146
+        /// <returns></returns>
147
+        private string GetLastNumber(string StrCard17)
148
+        {
149
+            //权重值
150
+            int[] WI = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };
151
+            string Str18 = "10X98765432";
152
+            int num = 0;
153
+            for (int i = 0; i < 17; i++)
154
+            {
155
+                num += int.Parse(StrCard17[i].ToString()) * WI[i];
156
+            }
157
+            num = num % 11;
158
+            return Str18[num].ToString();
159
+        }
160
+
161
+        /// <summary>
162
+        /// 解析图像数据
163
+        /// </summary>
164
+        /// <param name="imageStream"></param>
165
+        private ImageSource CreateImage(String imageStream)
166
+        {
167
+            ImageSource ret = null;
168
+            try
169
+            {
170
+                if (!string.IsNullOrEmpty(imageStream))
171
+                {
172
+                    //把BASE64转码字符串,转成byte数组
173
+                    byte[] arr = Convert.FromBase64String(imageStream);
174
+                    //定义流
175
+                    MemoryStream ms = new MemoryStream(arr);
176
+                    var bitImg = new BitmapImage();
177
+                    bitImg.BeginInit();
178
+                    //ms.Seek(0, SeekOrigin.Begin);
179
+                    bitImg.StreamSource = ms;
180
+                    bitImg.EndInit();
181
+                    ret = bitImg;
182
+                }
183
+            }
184
+            catch (Exception e)
185
+            {
186
+                this.ShowWarnMessageBox("加载身份照片数据出错!");//.ShowMessageBox("转换照片出错");
187
+            }
188
+            return ret;
189
+        }
190
+        #endregion
191
+
192
+        #region Event
193
+        private void txtID_LostFocus(object sender, RoutedEventArgs e)
194
+        {
195
+            if (tb_txtID.Text.Trim().Length == 15)
196
+            {
197
+                tb_txtID.Text = Convert15to18(tb_txtID.Text.Trim(), "19");
198
+            }
199
+        }
200
+
201
+        private void InputName_LostFocus(object sender, RoutedEventArgs e)
202
+        {
203
+            Regex rx = new Regex("^.+$");
204
+
205
+            if (!rx.IsMatch(tb_txtName.Text))
206
+            {
207
+                this.ShowMessageBox("请输入合法的姓名!");
208
+                this.SetFocus();
209
+            }
210
+        }
211
+
212
+        /// <summary>
213
+        /// 联网核查
214
+        /// </summary>
215
+        private void btnCheck_Click(object sender, RoutedEventArgs e)
216
+        {
217
+            #region  注释调以前默认核查成功代码
218
+            ///add by likai 20141020 start
219
+            ///衡水演示隐掉喝茶通讯,默认成功
220
+
221
+            //cbb_Result.SetSelectedValue("0");
222
+            //tb_IssuingAuthority.Text = Info.IssuingAuthority;
223
+            //tb_NameResult.Text = tb_txtName.Text;
224
+            //tb_IdNumber.Text = tb_txtID.Text;
225
+
226
+
227
+            ////填充返回数据和打印数据
228
+            //Record.IsComplated = cbb_Result.GetSelectedValue() == "0" || cbb_Result.GetSelectedValue() == "1";
229
+            //Record.Result = cbb_Result.GetSelectedValue();
230
+            //_print.Result = cbb_Result.GetSelectedKey();
231
+            //Record.Type = cb_busType.GetSelectedValue();
232
+            //_print.Type = cb_busType.GetSelectedKey();
233
+            //Record.IdNumber = _print.Number = tb_IdNumber.Text.Trim();
234
+            //Record.Name = _print.Name = tb_NameResult.Text.Trim();
235
+            //Record.IssuingAuthority = _print.Branch = tb_IssuingAuthority.Text.Trim();
236
+            //_print.Reason = tb_reason.Text.Trim();
237
+
238
+            //if (Record.IsComplated)
239
+            //{
240
+            //    btnPrint.IsEnabled = true;
241
+            //    this.SetFocus(btnBack);
242
+            //}
243
+            ///add by likai 20141020 end
244
+
245
+            /******************
246
+            //核查交易
247
+            var msg = new Message(Message.BitMap.Agn);
248
+            this.CommSend(msg);
249
+            msg.Fd16 = "0001";
250
+            msg.Fd60 = "IDC";
251
+            msg.Fd89 = cb_busType.SelectedValue.ToString();
252
+            msg.Fd27 = LoginUserInfo.TellerNo;
253
+            msg.Fd62 = tb_txtID.Text;
254
+            msg.Fd25 = tb_txtName.Text;
255
+            //渠道无法连接,用于考试系统
256
+            if (!ExamSystem.Instance.InExamMode)
257
+            {
258
+                this.CallAgnIDC(msg);
259
+            }
260
+            else
261
+            {
262
+                msg.Fd12 = "0000";
263
+                msg.Fd90 = "00";
264
+                msg.Fd82 = "河北市承德";
265
+                msg.Fd25 = tb_txtName.Text;
266
+                msg.Fd62 = tb_txtID.Text;
267
+                msg.FileData = string.Empty;
268
+            }
269
+            if (msg.Fd12 != "0000")
270
+            {
271
+                this.ShowErrorMessageBox(this.GetError(msg));
272
+                this.SetFocus();
273
+                return;
274
+            }
275
+            //解析结果 注意 核心改成了1位标识
276
+            cbb_Result.SetSelectedValue(msg.Fd90.Trim()[1]);
277
+            tb_IssuingAuthority.Text = msg.Fd82;
278
+            tb_NameResult.Text = msg.Fd25;
279
+            tb_IdNumber.Text = msg.Fd62;
280
+            if (cbb_Result.GetSelectedValue() == "0")
281
+            {
282
+                imgPhoto.Source = CreateImage(msg.FileData);
283
+                _print.Photo = msg.FileData;
284
+            }
285
+            //填充返回数据和打印数据
286
+            Record.IsComplated = cbb_Result.GetSelectedValue() == "0" || cbb_Result.GetSelectedValue() == "1";
287
+            Record.Result = cbb_Result.GetSelectedValue();
288
+            _print.Result = cbb_Result.GetSelectedKey();
289
+            Record.Type = cb_busType.GetSelectedValue();
290
+            _print.Type = cb_busType.GetSelectedKey();
291
+            Record.IdNumber = _print.Number = tb_IdNumber.Text.Trim();
292
+            Record.Name = _print.Name = tb_NameResult.Text.Trim();
293
+            Record.IssuingAuthority = _print.Branch = tb_IssuingAuthority.Text.Trim();
294
+            _print.Reason = tb_reason.Text.Trim();
295
+
296
+            if (Record.IsComplated)
297
+            {
298
+                btnPrint.IsEnabled = true;
299
+                this.SetFocus(btnPrint);
300
+            }
301
+             * ******************/
302
+            #endregion
303
+            Message message = new Message(Message.BitMap.Agn);
304
+            this.InitFd(message);
305
+            this.CommSend(message);
306
+            if (FLAG == "V9")
307
+            {//辰州汇通
308
+                message.Fd16 = "1011";//交易代码
309
+                message.Fd18 = "IDCK";
310
+                message.Fd25 = tb_txtName.Text.Trim();//户名
311
+                message.Fd62 = tb_txtID.Text.Trim();//身份证号
312
+                message.Fd24 = cb_busType.GetSelectedValue();//业务类型
313
+                this.TradeAPIs.CallAgnSHCZ(message);
314
+                if (message.Fd12 != "0000")
315
+                {
316
+                    this.TradeAPIs.ShowInfoMessageBox("身份核查不通过!");
317
+                    this.SetFocus();
318
+                    return;
319
+                }
320
+                tb_NameResult.Text = message.Fd25;
321
+                tb_IssuingAuthority.Text = message.Fd82;
322
+                cbb_Result.SetSelectedValue(message.Fd28.Trim());
323
+                tb_IdNumber.Text = message.Fd62;
324
+            }
325
+            else
326
+            {
327
+                //message.Fd16 = "7077";
328
+                //message.Fd25 = tb_txtName.Text;
329
+                //message.Fd62 = tb_txtID.Text;
330
+                //this.CallAgn(message);
331
+                #region 调用平台核查
332
+                //var msg = new Message(Message.BitMap.Agn);
333
+                //this.TradeAPIs.InitFd(msg);
334
+                //this.TradeAPIs.CommSend(msg);
335
+                //msg.Fd4 = this.CreateSerialNumber();
336
+                message.Fd16 = "2001";
337
+                message.Fd18 = "C101";
338
+                message.Fd24 = string.IsNullOrEmpty(Info.Name) ? "0" : "1";//证件号录入方式 手工 0 、设备 1
339
+                message.Fd23 = this.TradeAPIs.GetSelectedValue(cb_busType);
340
+                message.Fd26 = LoginUserInfo.TellerNo;
341
+                message.Fd62 = tb_txtID.Text;
342
+                message.Fd25 = tb_txtName.Text;
343
+                this.TradeAPIs.CallAgnIDC(message);
344
+                if (message.Fd12 != "0000")
345
+                {
346
+                    this.TradeAPIs.ShowInfoMessageBox(string.IsNullOrWhiteSpace(message.Fd13) ? this.TradeAPIs.GetError(message) : message.Fd13);
347
+                    this.TradeAPIs.SetFocus();
348
+                    return;
349
+                }
350
+                cbb_Result.SetSelectedValue(message.Fd89.Trim());
351
+                tb_IssuingAuthority.Text = message.Fd83;//签发机关
352
+                tb_NameResult.Text = message.Fd25;
353
+                tb_IdNumber.Text = message.Fd62;
354
+
355
+                //if (message.Fd89.Trim() != "00" || string.IsNullOrWhiteSpace(message.FileData)) return;
356
+                //try
357
+                //{
358
+                //    //把BASE64转码字符串,转成byte数组 
359
+                //    photo = message.FileData;
360
+                //    var arr = Convert.FromBase64String(message.FileData);
361
+                //    //定义流
362
+                //    var ms = new MemoryStream(arr);
363
+                //    var bitImg = new BitmapImage();
364
+                //    bitImg.BeginInit();
365
+                //    ms.Seek(0, SeekOrigin.Begin);
366
+                //    bitImg.StreamSource = ms;
367
+                //    bitImg.EndInit();
368
+                //    imgPhoto.Source = bitImg;
369
+                //}
370
+                //catch
371
+                //{
372
+                //    this.TradeAPIs.ShowInfoMessageBox("转换照片出错!");
373
+                //}
374
+                #endregion
375
+            }
376
+
377
+            btnPrint.IsEnabled = true;
378
+            this.SetFocus(btnPrint);
379
+
380
+            if (cbb_Result.GetSelectedValue() == "00")
381
+            {
382
+                imgPhoto.Source = CreateImage(message.FileData);
383
+                _print.Photo = message.FileData;
384
+            }
385
+            //填充返回数据和打印数据
386
+            Record.IsComplated = cbb_Result.GetSelectedValue() == "00" || cbb_Result.GetSelectedValue() == "01";
387
+            Record.Result = cbb_Result.GetSelectedValue();
388
+            Record.ResultKey = cbb_Result.GetSelectedKey();
389
+            _print.Result = cbb_Result.GetSelectedKey();
390
+            Record.Type = cb_busType.GetSelectedValue();
391
+            _print.Type = cb_busType.GetSelectedKey();
392
+            Record.IdNumber = _print.Number = tb_IdNumber.Text.Trim();
393
+            Record.Name = _print.Name = tb_NameResult.Text.Trim();
394
+            Record.IssuingAuthority = _print.Branch = tb_IssuingAuthority.Text.Trim();
395
+            _print.Reason = tb_reason.Text.Trim();
396
+            _print.frontPhoto = Info.FrontImg == null ? "" : Info.FrontImg;
397
+            _print.BackPhoto = Info.BackImg == null ? "" : Info.BackImg;
398
+            //人脸比对
399
+            if (Link2RLSB && AICapacity.GetInstence().IsOpen && string.Compare(this.TradeAPIs.GetTradeMetadata("isRlsb"), "true", true) == 0 && (FLAG == "V5" || (FLAG != "V5" && cb_rlbd.GetSelectedValue() == "1")))
400
+            {
401
+                //身份核查返回的客户照片
402
+                img_SFHC = message.FileData;
403
+                result = "";
404
+                ret = false;
405
+                var ext = new AICapacity.ExtData(this.CreateSerialNumber(), new Dictionary<string, string> { { "idno", Record.IdNumber }, { "name", Record.Name }, { "trade", this.TradeInfo.TradeCode } });
406
+                this.OwnerContainer.ModalInvoke(new Action(() =>
407
+                {
408
+                    ret = AICapacity.GetInstence().GetResultFromRLBD(img_SFHC, out result, ext);
409
+                }), "正在人脸比对中...");
410
+                grade.Text = result;
411
+                _print.Grade = grade.Text;
412
+                if (ret != true)
413
+                {
414
+                    Record.Reject2RLSB = true;
415
+                    if (FLAG == "V8")
416
+                    {
417
+                        if (this.TradeAPIs.ShowQuestionMessageBox("人脸比对不通过是否进行授权操作?") == MessageBoxResult.Yes)
418
+                        {
419
+                            if (AuthAction(new Message() { Fd96_W = "airlsb" }))
420
+                                Record.Reject2RLSB = false;
421
+                        }
422
+                    }
423
+                    else
424
+                    {
425
+                        if (this.TradeAPIs.ShowQuestionMessageBox("人脸比对不通过是否进行授权操作?") == MessageBoxResult.Yes)
426
+                        {
427
+                            if (AuthAction(new Message() { Fd96_W = "fd96w" }))
428
+                                Record.Reject2RLSB = false;
429
+                        }
430
+                    }
431
+                    
432
+                }
433
+                
434
+                
435
+            }
436
+        }
437
+        /// <summary>
438
+        /// 授权方法
439
+        /// </summary>
440
+        /// <param name="msg"></param>
441
+        /// <returns></returns>
442
+        private bool AuthAction(Message msg)
443
+        {
444
+            // 组织授权检查要素
445
+            TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData[] page = new TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData[1];
446
+            page[0] = new TellerSystem.ServiceProxy.Ext.ServiceEntitys.PageData() { index = 1, datas = this.SaveTradePage((FrameworkElement)this.Content) };
447
+            AuthConditionElement element = new AuthConditionElement();
448
+
449
+            AuthManager c = new AuthManager();
450
+            c.AsksuperResultMessage += new AuthManager.AsksuperResultHandle(AsksuperResultMessage);
451
+            return c.DoAuth(this, element, msg, page, "0", "", "", "", "", "人脸比对", "");
452
+        }
453
+
454
+        private void AsksuperResultMessage(AsksuperResultType result, TradeBusData busData)
455
+        {
456
+            switch (result)
457
+            {
458
+                case AsksuperResultType.Success:
459
+                    this.ShowMessageBox("授权已经通过。");
460
+                    break;
461
+                case AsksuperResultType.Failed:
462
+                    this.ShowMessageBox("授权没有通过。");
463
+                    break;
464
+                case AsksuperResultType.Undo:
465
+                    this.ShowMessageBox("授权已撤销。");
466
+                    break;
467
+                default:
468
+                    break;
469
+            }
470
+        }
471
+        private Print_IdChecker.Print_IdCheckerEntry _print = new Print_IdChecker.Print_IdCheckerEntry();
472
+        private string img_SFHC;
473
+        private string result;
474
+        private bool? ret;
475
+
476
+
477
+        private void btnPrint_Click(object sender, RoutedEventArgs e)
478
+        {
479
+            try
480
+            {
481
+                var p = new Print_IdChecker(_print);
482
+                p.PrintData.LoadData(this, new Message());
483
+                PrintContainerExt.SetPrintElement(p, this.GetPrintAttributes());
484
+                p.LoadPrintData();
485
+                var xpsFile = p.PrintToXps();
486
+                this.IsHitTestVisible = false;
487
+                var dialog = new PrintDialog();
488
+                var flag = dialog.ShowDialog();
489
+                this.IsHitTestVisible = true;
490
+                if (flag == true)
491
+                {
492
+                    PrintManager.SendToPrinter(xpsFile, p.ActualWidth, p.ActualHeight, "联网核查打印", dialog.PrintQueue.FullName);
493
+                    //dialog.PrintQueue.AddJob("联网核查打印", xpsFile.FullName, false);
494
+                    //var xpsWriter = PrintQueue.CreateXpsDocumentWriter(dialog.PrintQueue);
495
+                    //xpsWriter.Write(xpsFile.FullName);
496
+                    this.SetFocus(btnBack);
497
+                }
498
+            }
499
+            catch
500
+            {
501
+                this.ShowErrorMessageBox("打印发生异常!");
502
+            }
503
+            //this.PrintCertificate(new Platform.Print.PrintContainer[] { p });
504
+        }
505
+
506
+        private void btnBack_Click(object sender, RoutedEventArgs e)
507
+        {
508
+            this.Close();
509
+        }
510
+        #endregion
511
+
512
+        private void cb_rlbd_LostFocus(object sender, RoutedEventArgs e)
513
+        {
514
+            if (cb_rlbd.GetSelectedValue() == "1")
515
+                grade.Visibility = tl_grade.Visibility = Visibility.Visible;
516
+            else
517
+            {
518
+                grade.Visibility = tl_grade.Visibility = Visibility.Collapsed;
519
+                grade.Text = string.Empty;
520
+            }
521
+        }
522
+    }
523
+
524
+    /// <summary>
525
+    /// 核查记录
526
+    /// </summary>
527
+    public class IdCheckerResult
528
+    {
529
+        /// <summary>
530
+        /// 是否联网核查
531
+        /// </summary>
532
+        public bool IsOnline { get; internal set; }
533
+
534
+        /// <summary>
535
+        /// 是否完成核查 - 注意当IsOnline为false时,该值必定为true
536
+        /// </summary>
537
+        public bool IsComplated { get; internal set; }
538
+
539
+        /// <summary>
540
+        /// 人脸比对拒绝标志
541
+        /// </summary>
542
+        public bool Reject2RLSB { get; internal set; }
543
+
544
+        /// <summary>
545
+        /// 核查结果 - 结果参考 UserVariable.GetIdCheckResultType()
546
+        /// </summary>
547
+        public string Result { get; internal set; }
548
+
549
+        /// <summary>
550
+        /// 核查结果值
551
+        /// </summary>
552
+        public string ResultKey { get; internal set; }
553
+
554
+        /// <summary>
555
+        /// 核查原因
556
+        /// </summary>
557
+        public string Reason { get; internal set; }
558
+
559
+        /// <summary>
560
+        /// 核查种类 - 结果参考 UserVariable.GetIdCheckReasonType()
561
+        /// </summary>
562
+        public string Type { get; internal set; }
563
+
564
+        /// <summary>
565
+        /// 身份证号码
566
+        /// </summary>
567
+        public string IdNumber { get; internal set; }
568
+
569
+        /// <summary>
570
+        /// 姓名
571
+        /// </summary>
572
+        public string Name { get; internal set; }
573
+
574
+        /// <summary>
575
+        /// 签发机构
576
+        /// </summary>
577
+        public string IssuingAuthority { get; internal set; }
578
+
579
+        /// <summary>
580
+        /// 从身份证读卡器设备上拿取的信息集合
581
+        /// </summary>
582
+        public IdentityCardEntity DeviceInfo { get; internal set; }
583
+    }
584
+}
585
+
586
+
587
+
588
+
589
+

+ 61
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ImageManager.xaml 查看文件

@@ -0,0 +1,61 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.ImageManager"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:dhcc="http://www.dhcc.com.cn"
6
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+             d:DesignHeight="300"
8
+             d:DesignWidth="600"
9
+             dhcc:FocusManager.IsInternalKeyboardControlling="True"
10
+             mc:Ignorable="d">
11
+    <ListView Name="DataList"
12
+              HorizontalContentAlignment="Center"
13
+              SelectionMode="Single">
14
+        <ListView.View>
15
+            <GridView>               
16
+                <GridViewColumn Width="400" Header="图像描述">
17
+                    <GridViewColumn.CellTemplate>
18
+                        <DataTemplate>
19
+                            <TextBlock Text="{Binding Description}" />
20
+                        </DataTemplate>
21
+                    </GridViewColumn.CellTemplate>
22
+                </GridViewColumn>
23
+                <GridViewColumn Width="50" Header="状态">
24
+                    <GridViewColumn.CellTemplate>
25
+                        <DataTemplate>
26
+                            <StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
27
+                                <CheckBox IsChecked="{Binding IsCollected}" IsEnabled="False" />
28
+                                <Ellipse x:Name="State"
29
+                                         Width="15"
30
+                                         Height="15"
31
+                                         Fill="Gray" />
32
+                            </StackPanel>
33
+                            <DataTemplate.Triggers>
34
+                                <DataTrigger Binding="{Binding IsCollected}" Value="true">
35
+                                    <Setter TargetName="State" Property="Ellipse.Fill" Value="Green" />
36
+                                    <Setter TargetName="State" Property="Ellipse.ToolTip">
37
+                                        <Setter.Value>
38
+                                            <Image MaxWidth="700"
39
+                                                   MaxHeight="600"
40
+                                                   Source="{Binding ImageSource}"
41
+                                                   Stretch="Uniform" />
42
+                                        </Setter.Value>
43
+                                    </Setter>
44
+                                </DataTrigger>
45
+                            </DataTemplate.Triggers>
46
+                        </DataTemplate>
47
+                    </GridViewColumn.CellTemplate>
48
+                </GridViewColumn>
49
+                <GridViewColumn Width="100" Header="操作">
50
+                    <GridViewColumn.CellTemplate>
51
+                        <DataTemplate>
52
+                            <Button Click="CollectButton_Click"
53
+                                    Content="采集"
54
+                                    Tag="{Binding}" />
55
+                        </DataTemplate>
56
+                    </GridViewColumn.CellTemplate>
57
+                </GridViewColumn>
58
+            </GridView>
59
+        </ListView.View>
60
+    </ListView>
61
+</UserControl>

+ 213
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ImageManager.xaml.cs 查看文件

@@ -0,0 +1,213 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using Platform.Presentation.Interfaces;
15
+using System.IO;
16
+using System.ComponentModel;
17
+
18
+namespace TellerSystem.Controls.Ext.Controls
19
+{
20
+    /// <summary>
21
+    /// ImageManager.xaml 的交互逻辑
22
+    /// </summary>
23
+    [DesignTimeVisible(false)]
24
+    public partial class ImageManager : UserControl
25
+    {
26
+        public ImageManager()
27
+        {
28
+            InitializeComponent();
29
+        }
30
+        /// <summary>
31
+        /// 注册的图像采集信息列表
32
+        /// </summary>
33
+        private List<ImageCollectInfo> _registerImageCollectInfo = new List<ImageCollectInfo>();
34
+
35
+        /// <summary>
36
+        /// 注册图像采集动作
37
+        /// </summary>
38
+        /// <param name="name"></param>
39
+        /// <param name="description"></param>
40
+        public void RegisterImageCollectInfo(string name, string description)
41
+        {
42
+            if (_registerImageCollectInfo.Exists(x => x.Name == name))
43
+            {
44
+                throw new ArgumentOutOfRangeException(string.Format("图像采集控件:{0}采集项已经注册!", name));
45
+            }
46
+            _registerImageCollectInfo.Add(new ImageCollectInfo { Name = name, Description = description, Collectable = false });
47
+        }
48
+
49
+        /// <summary>
50
+        /// 设置是否执行采集动作
51
+        /// </summary>
52
+        /// <param name="name"></param>
53
+        /// <param name="flag"></param>
54
+        public void SetCollectable(string name, bool flag, string description = null)
55
+        {
56
+            var item = _registerImageCollectInfo.FirstOrDefault(x => x.Name == name);
57
+            if (item != null)
58
+            {
59
+                if (!string.IsNullOrEmpty(description))
60
+                    item.Description = description;
61
+                item.IsCollected = false;
62
+                item.Collectable = flag;
63
+                //更新数据源
64
+                DataList.ItemsSource = _registerImageCollectInfo.Where(x => x.Collectable);
65
+                DataList.Items.Refresh();
66
+            }
67
+        }
68
+
69
+        /// <summary>
70
+        /// 获取指定的图像采集数据
71
+        /// </summary>
72
+        /// <param name="name"></param>
73
+        /// <returns></returns>
74
+        public byte[] GetCollectImage(string name)
75
+        {
76
+            byte[] ret = null;
77
+            var item = _registerImageCollectInfo.FirstOrDefault(x => x.Name == name && x.Collectable && x.IsCollected);
78
+            if (item != null)
79
+            {
80
+                //将图片转换成数据
81
+                ret = item.Data;
82
+            }
83
+            return ret;
84
+        }
85
+
86
+        /// <summary>
87
+        /// 取出所有已采集的图像信息
88
+        /// </summary>
89
+        /// <returns></returns>
90
+        public Dictionary<string, byte[]> GetAllCollectImage()
91
+        {
92
+            var ret = new Dictionary<string, byte[]>();
93
+            var list = _registerImageCollectInfo.FindAll(x => x.Collectable && x.IsCollected);
94
+            foreach (var item in list)
95
+            {
96
+                if (item.IsCollected)
97
+                {
98
+                    //取出图像数据 
99
+                    ret.Add(item.Name, item.Data);
100
+                }
101
+            }
102
+            return ret;
103
+        }
104
+
105
+        /// <summary>
106
+        /// 是否全部采集完毕
107
+        /// </summary>
108
+        /// <returns></returns>
109
+        public bool IsCollectAll()
110
+        {
111
+            var list = _registerImageCollectInfo.Find(x => x.Collectable && !x.IsCollected);
112
+            return list == null;
113
+        }
114
+
115
+        class ImageCollectInfo
116
+        {
117
+            /// <summary>
118
+            /// 图像id
119
+            /// </summary>
120
+            public string Name { get; set; }
121
+            /// <summary>
122
+            /// 描述
123
+            /// </summary>
124
+            public string Description { get; set; }
125
+            /// <summary>
126
+            /// 是否已采集
127
+            /// </summary>
128
+            public bool IsCollected { get; set; }
129
+            /// <summary>
130
+            /// 是否参与采集
131
+            /// </summary>
132
+            public bool Collectable { get; set; }
133
+            /// <summary>
134
+            /// 数据图像
135
+            /// </summary>
136
+            public ImageSource ImageSource { get; set; }
137
+            /// <summary>
138
+            /// 图像数据
139
+            /// </summary>
140
+            public byte[] Data { get; set; }
141
+        }
142
+
143
+        private void CollectButton_Click(object sender, RoutedEventArgs e)
144
+        {
145
+            //调用采集方法采集图片
146
+            var btn = sender as Button;
147
+            if (btn != null && btn.Tag is ImageCollectInfo)
148
+            {
149
+                var info = btn.Tag as ImageCollectInfo;
150
+                //若为身份证,则采用去黑边
151
+                var data = CollectImage(info.Description.Contains("身份证"));
152
+                if (data == null) return;
153
+                info.Data = data;
154
+                var imageSourceConverter = new ImageSourceConverter();
155
+                info.ImageSource = imageSourceConverter.ConvertFrom(new System.IO.MemoryStream(info.Data)) as ImageSource;
156
+                info.IsCollected = true;
157
+
158
+                DataList.Items.Refresh();
159
+            }
160
+        }
161
+
162
+        private byte[] CollectImage(bool isIDCard)
163
+        {
164
+            ////采用文件录入
165
+            var dialog = new Microsoft.Win32.OpenFileDialog();
166
+            dialog.ShowDialog(Application.Current.MainWindow);
167
+            if (string.IsNullOrEmpty(dialog.FileName)) return null;
168
+            return File.ReadAllBytes(dialog.FileName);
169
+
170
+            //采集图片
171
+            //var page = new CameraViewer(isIDCard);
172
+            //ParentIPage.ShowPage(page, "扫描图像");
173
+            //page.CloseCamera();
174
+            //return page.ViewStateData.GetDictionaryItem<byte[]>("ImageData");
175
+        }
176
+
177
+        #region ParentIPage
178
+        private IPage _parentIPage;
179
+        /// <summary>
180
+        /// Owner
181
+        /// </summary>
182
+        public IPage ParentIPage
183
+        {
184
+            get
185
+            {
186
+                if (_parentIPage == null)
187
+                {
188
+                    _parentIPage = GetCurrentIPage(this);
189
+                }
190
+                return _parentIPage;
191
+            }
192
+            set { _parentIPage = value; }
193
+        }
194
+        private IPage GetCurrentIPage(DependencyObject visual)
195
+        {
196
+            IPage ret = null;
197
+            if (visual != null)
198
+            {
199
+                var parent = LogicalTreeHelper.GetParent(visual);
200
+                if (parent != null)
201
+                {
202
+                    if (parent is IPage)
203
+                        ret = parent as IPage;
204
+                    else
205
+                        ret = GetCurrentIPage(parent);
206
+                }
207
+            }
208
+            return ret;
209
+        }
210
+        #endregion
211
+
212
+    }
213
+}

+ 108
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/Imageshow.xaml 查看文件

@@ -0,0 +1,108 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Controls.Ext.Controls.Imageshow"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:local="clr-namespace:TellerSystem.Library.Ext.Function"
7
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                d:DesignHeight="1000"
9
+                d:DesignWidth="700"
10
+                dhcc:FocusManager.EnableFocusControl="True"
11
+                mc:Ignorable="d">
12
+    <dhcc:TradePage.Resources>
13
+
14
+
15
+
16
+        <Style x:Key="SelectedImage" TargetType="Border">
17
+            <Setter Property="Padding" Value="4" />
18
+            <Setter Property="Background" Value="White" />
19
+            <Setter Property="BorderThickness" Value="1" />
20
+            <Setter Property="BorderBrush" Value="Black" />
21
+            <Setter Property="Image.Margin" Value="4" />
22
+        </Style>
23
+
24
+        <Style x:Key="SelectedImagesPanel" TargetType="ItemsControl">
25
+            <Setter Property="ItemsControl.ItemTemplate">
26
+                <Setter.Value>
27
+                    <DataTemplate>
28
+                        <Button Background="Transparent" Tag="{Binding ElementName=imgItem, Path=Source}">
29
+                            <Border Style="{StaticResource SelectedImage}">
30
+                                <Image x:Name="imgItem" Source="{Binding}" />
31
+                            </Border>
32
+                        </Button>
33
+                    </DataTemplate>
34
+                </Setter.Value>
35
+            </Setter>
36
+            <Setter Property="Template">
37
+                <Setter.Value>
38
+                    <ControlTemplate TargetType="{x:Type ItemsControl}">
39
+                        <Border Background="{TemplateBinding Background}"
40
+                                BorderBrush="{TemplateBinding BorderBrush}"
41
+                                BorderThickness="{TemplateBinding BorderThickness}"
42
+                                Padding="{TemplateBinding Padding}"
43
+                                SnapsToDevicePixels="true">
44
+                            <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden">
45
+                                <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
46
+                            </ScrollViewer>
47
+                        </Border>
48
+                    </ControlTemplate>
49
+                </Setter.Value>
50
+            </Setter>
51
+
52
+        </Style>
53
+    </dhcc:TradePage.Resources>
54
+
55
+    <Grid>
56
+
57
+        <Grid>
58
+            <Grid.RowDefinitions>
59
+                <RowDefinition Height="400" />
60
+                <RowDefinition Height="150" />
61
+                <RowDefinition Height="*" />
62
+            </Grid.RowDefinitions>
63
+            <Image x:Name="mainimg"
64
+                   Grid.Row="0"
65
+                   Width="680"
66
+                   Height="380"
67
+                   HorizontalAlignment="Center" />
68
+            <ItemsControl Name="itemscontrol"
69
+                          Grid.Row="1"
70
+                          Focusable="True"
71
+                          Style="{StaticResource SelectedImagesPanel}">
72
+                <ItemsControl.ItemsPanel>
73
+                    <ItemsPanelTemplate>
74
+                        <StackPanel Orientation="Horizontal" />
75
+                    </ItemsPanelTemplate>
76
+                </ItemsControl.ItemsPanel>
77
+                <ItemsControl.ItemTemplate>
78
+                    <DataTemplate>
79
+                        <Button Width="120"
80
+                                Height="98"
81
+                                Background="Gray"
82
+                                Command="local:Commands.ClickImage"
83
+                                Tag="{Binding ElementName=imgItem,
84
+                                              Path=Source}">
85
+
86
+                            <Grid>
87
+                                <Grid.RowDefinitions>
88
+                                    <RowDefinition Height="15" />
89
+                                    <RowDefinition Height="*" />
90
+                                </Grid.RowDefinitions>
91
+                                <Grid.ColumnDefinitions />
92
+                                <Border Grid.Row="1"
93
+                                        Margin="2,2,2,2"
94
+                                        Style="{StaticResource SelectedImage}">
95
+                                    <Image x:Name="imgItem"
96
+                                           Width="120"
97
+                                           Height="98"
98
+                                           Source="{Binding}"
99
+                                           x:Uid="123" />
100
+                                </Border>
101
+                            </Grid>
102
+                        </Button>
103
+                    </DataTemplate>
104
+                </ItemsControl.ItemTemplate>
105
+            </ItemsControl>
106
+        </Grid>
107
+    </Grid>
108
+</dhcc:TradePage>

+ 91
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/Imageshow.xaml.cs 查看文件

@@ -0,0 +1,91 @@
1
+using System.Collections.Generic;
2
+using System.Windows.Controls;
3
+using System.Windows.Documents;
4
+using System.Windows.Input;
5
+using System.Windows.Media;
6
+using System.Windows.Media.Imaging;
7
+using System.IO;
8
+using System.ComponentModel;
9
+using Platform.ServiceProxy.ServiceFunction.Entitys;
10
+using Platform.ServiceProxy.ServiceHelper;
11
+using Platform.Library;
12
+using TellerSystem.Library.Ext.Function;
13
+using TellerSystem.Library.Ext.TradeExtension;
14
+
15
+namespace TellerSystem.Controls.Ext.Controls
16
+{
17
+    /// <summary>
18
+    /// Imageshow.xaml 的交互逻辑
19
+    /// </summary>
20
+    [DesignTimeVisible(false)]
21
+    public partial class Imageshow 
22
+    {
23
+        public Imageshow(string[] Imgid)
24
+        {
25
+            InitializeComponent();
26
+            //点击缩略图事件绑定
27
+            CommandBindings.Add(new CommandBinding(Commands.ClickImage,
28
+                new ExecutedRoutedEventHandler(ClickImage_Executed)));
29
+            AttchedFiles[] imagedata = FilesHandle.GetAttachedFiles(Imgid);
30
+            itemscontrol.ItemsSource = InitialImg(imagedata);
31
+            bitmapsor = InitialImg(imagedata);
32
+            if (bitmapsor!=null)
33
+            {
34
+                mainimg.Source = bitmapsor[0];
35
+            }
36
+            
37
+        }
38
+        #region 变量
39
+        List<BitmapSource> bitmapsor = new List<BitmapSource>();
40
+        #endregion
41
+        #region 方法
42
+            
43
+        public static BitmapImage ByteArrayToBitmapImage(byte[] byteArray)
44
+        {
45
+            BitmapImage bmp = null;
46
+
47
+            try
48
+            {
49
+                bmp = new BitmapImage();
50
+                bmp.BeginInit();
51
+                bmp.StreamSource = new MemoryStream(byteArray);
52
+                bmp.EndInit();
53
+            }
54
+            catch
55
+            {
56
+                bmp = null;
57
+            }
58
+
59
+            return bmp;
60
+        }
61
+
62
+        public List<BitmapSource> InitialImg(AttchedFiles[] imagedata)
63
+        {
64
+            List<BitmapSource> bitmg = new List<System.Windows.Media.Imaging.BitmapSource>();
65
+            for (int i = 0; i < imagedata.Length;i++ )
66
+            {
67
+                BitmapSource bitsource = ByteArrayToBitmapImage(imagedata[i].Filedata);
68
+                bitmg.Add(bitsource);
69
+            }
70
+            return bitmg;
71
+        }
72
+#endregion
73
+        #region  ClickImageCommand
74
+        /// <summary>
75
+        /// Click Image brcapture will get source
76
+        /// </summary>
77
+        private void ClickImage_Executed(object sender, ExecutedRoutedEventArgs e)
78
+        {
79
+            Button b = (Button)e.OriginalSource;
80
+            mainimg.Source = b.Tag
81
+                as ImageSource;
82
+        }
83
+
84
+        #endregion
85
+
86
+        private void imgItem_MouseDown(object sender, MouseButtonEventArgs e)
87
+        {
88
+           
89
+        }
90
+    }
91
+}

+ 78
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/LeadTradeViewer.xaml 查看文件

@@ -0,0 +1,78 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.LeadTradeViewer"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:dhcc="http://www.dhcc.com.cn"
6
+             xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
7
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+             xmlns:tp="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
9
+             mc:Ignorable="d">
10
+    <UserControl.Resources>
11
+        <Style x:Key="ControlStyle1" TargetType="{x:Type ContentControl}">
12
+            <Setter Property="Template">
13
+                <Setter.Value>
14
+                    <ControlTemplate TargetType="{x:Type ContentControl}">
15
+                        <Grid>
16
+                            <Border Width="800"
17
+                                    Background="White"
18
+                                    BorderBrush="White">
19
+                                <Grid>
20
+                                    <ContentPresenter Width="800" />
21
+                                </Grid>
22
+                            </Border>
23
+                        </Grid>
24
+                    </ControlTemplate>
25
+                </Setter.Value>
26
+            </Setter>
27
+        </Style>
28
+    </UserControl.Resources>
29
+    <!--
30
+        dhcc:FocusManager.IsOnlyMouseControl="True"
31
+
32
+        <UserControl.Resources>
33
+        <ItemsPanelTemplate x:Key="ListViewPanleTemplate">
34
+        <StackPanel Loaded="StackPanel_Loaded" Orientation="Horizontal" />
35
+        </ItemsPanelTemplate>
36
+        </UserControl.Resources>
37
+    -->
38
+    <StackPanel VerticalAlignment="Top">
39
+
40
+        <WrapPanel Name="LeadHeader"
41
+                   Height="30"
42
+                   Margin="0,5" />
43
+
44
+        <Ellipse Height="1" Stroke="Green" />
45
+
46
+        <ContentControl x:Name="lv_Leads"
47
+                        Height="400"
48
+                        Margin="0,5"
49
+                        Loaded="StackPanel_Loaded"
50
+                        ScrollViewer.HorizontalScrollBarVisibility="Auto"
51
+                        ScrollViewer.VerticalScrollBarVisibility="Auto"
52
+                        Style="{DynamicResource ControlStyle1}" />
53
+
54
+        <Ellipse Height="1" Stroke="Green" />
55
+        <StackPanel Margin="10"
56
+                    FlowDirection="RightToLeft"
57
+                    Orientation="Horizontal">
58
+
59
+            <Button x:Name="btnPrevious"
60
+                    Width="80"
61
+                    Height="25"
62
+                    Click="btnPrevious_Click"
63
+                    Content="上一步"
64
+                    IsEnabled="False" />
65
+            <Button x:Name="btnStep"
66
+                    Width="80"
67
+                    Height="25"
68
+                    Click="btnStep_Click"
69
+                    Content="跳  过"
70
+                    Visibility="Collapsed" />
71
+            <Button x:Name="btnNext"
72
+                    Width="80"
73
+                    Height="25"
74
+                    Click="btnNext_Click"
75
+                    Content="下一步" />
76
+        </StackPanel>
77
+    </StackPanel>
78
+</UserControl>

+ 622
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/LeadTradeViewer.xaml.cs 查看文件

@@ -0,0 +1,622 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.IO;
4
+using System.Printing;
5
+using System.Text.RegularExpressions;
6
+using System.Windows;
7
+using System.Windows.Controls;
8
+using System.Windows.Media;
9
+using System.Windows.Media.Animation;
10
+using System.Windows.Media.Imaging;
11
+using Platform.Common.BasicFunctions;
12
+using Platform.Common.RunningParameters;
13
+using Platform.Controls.ControlsHelper;
14
+using Platform.Controls.TradeExtension;
15
+using Platform.Library;
16
+using Platform.Presentation.Interfaces;
17
+using Platform.Presentation.PageFunctions;
18
+using Platform.Presentation.PagesHelper;
19
+using Platform.Print;
20
+using TellerSystem.Communication;
21
+using TellerSystem.Controls.Ext.PrintsHelper;
22
+using TellerSystem.Devices.Interface;
23
+using TellerSystem.Library.Ext.Function;
24
+using TellerSystem.Library.Ext.TradeExtension;
25
+using TellerSystem.Library.Ext.Variables;
26
+using TellerSystem.PMS.XML;
27
+using TellerSystem.PrintTemplate.Extension;
28
+using TellerSystem.ServiceProxy.Ext.ServiceEntitys;
29
+
30
+/******************************平台Dll*****************************/
31
+
32
+namespace TellerSystem.Controls.Ext.Controls
33
+{
34
+    /// <summary>
35
+    /// IdCheckViewer.xaml 的交互逻辑
36
+    /// </summary>
37
+    public partial class LeadTradeViewer
38
+    {
39
+        #region Field
40
+
41
+        /// <summary>
42
+        ///     打印页面容器
43
+        /// </summary>
44
+        private ContentControl _panle;
45
+
46
+        private bool[] _title;
47
+
48
+        /// <summary>
49
+        ///     偏移控制
50
+        /// </summary>
51
+        private TranslateTransform _ttf;
52
+
53
+        private int _preIndex = 0;
54
+
55
+        #endregion Field
56
+
57
+        #region Ctor
58
+
59
+        public LeadTradeViewer()
60
+        {
61
+            InitializeComponent();
62
+        }
63
+
64
+        #endregion Ctor
65
+
66
+        #region 公开的属性与方法
67
+
68
+        /// <summary>
69
+        /// 公共报文对象
70
+        /// </summary>
71
+        public Message Msg { get; set; }
72
+
73
+        /// <summary>
74
+        /// 数据总线,用于交易间的数据传递
75
+        /// </summary>
76
+        public Dictionary<string, object> DataBus = new Dictionary<string, object>();
77
+
78
+        /// <summary>
79
+        ///公共的xml报文,用于存放各个交易的xml报文对象
80
+        /// </summary>
81
+        private Dictionary<string, XML_reader_mgr> xml_reade_list = new Dictionary<string, XML_reader_mgr>();
82
+
83
+        /// <summary>
84
+        ///取值公共的xml报文,用于存放各个交易的xml报文对象
85
+        /// </summary>
86
+        public Dictionary<string, XML_reader_mgr> Xml_reade_list
87
+        {
88
+            get { return this.xml_reade_list; }
89
+        }
90
+
91
+        /// <summary>
92
+        /// 如果新增加key,则保存对象
93
+        /// 如果已经存在key对应的对象,则修改
94
+        /// </summary>
95
+        /// <param name="key"></param>
96
+        /// <param name="xml_read_handle"></param>
97
+        public void SetItemXmlReaderMgr(string key, XML_reader_mgr xml_read_handle)
98
+        {
99
+            if (this.xml_reade_list.ContainsKey(key))
100
+            {
101
+                this.xml_reade_list[key] = xml_read_handle;
102
+            }
103
+            else
104
+            {
105
+                this.xml_reade_list.Add(key, xml_read_handle);
106
+            }
107
+        }
108
+
109
+        /// <summary>
110
+        /// 当前页的索引,从0开始
111
+        /// </summary>
112
+        public int CurrentLeadIndex { get; set; }
113
+
114
+        /// <summary>
115
+        /// 数据源
116
+        /// </summary>
117
+        public IList<LeadItem> LeadSource { get; set; }
118
+
119
+        /// <summary>
120
+        /// 设置或获取下一步按钮的可用性
121
+        /// </summary>
122
+        public bool IsNextBtnEnable
123
+        {
124
+            set { btnNext.IsEnabled = value; }
125
+        }
126
+
127
+        private int _stepIndex;
128
+
129
+        /// <summary>
130
+        /// 跳转到指定步骤,从0开始
131
+        /// </summary>
132
+        public int StepIndex
133
+        {
134
+            get { return _stepIndex; }
135
+            set
136
+            {
137
+                _stepIndex = value;
138
+                btnStep.Visibility = Visibility.Visible;
139
+            }
140
+        }
141
+
142
+        #endregion 公开的属性与方法
143
+
144
+        #region 路由 下一步事件
145
+
146
+        //创建和注册ReFlesh事件,该事件路由策略为Direct
147
+        public static readonly RoutedEvent LeadNextEvent = EventManager.RegisterRoutedEvent("LeadNext",
148
+            RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(LeadTradeViewer));
149
+
150
+        //CLR事件的包装器
151
+        public event RoutedEventHandler LeadNext
152
+        {
153
+            add { AddHandler(LeadNextEvent, value); }
154
+            remove { RemoveHandler(LeadNextEvent, value); }
155
+        }
156
+
157
+        //触发ReFleshEvent
158
+        private void RaiseLeadNextEvent()
159
+        {
160
+            var newEventArgs = new RoutedEventArgs(LeadTradeViewer.LeadNextEvent);
161
+            RaiseEvent(newEventArgs);
162
+        }
163
+
164
+        #endregion 路由 下一步事件
165
+
166
+        #region 路由 完成事件
167
+
168
+        //创建和注册ReFlesh事件,该事件路由策略为Direct
169
+        public static readonly RoutedEvent LeadCompletedEvent = EventManager.RegisterRoutedEvent("LeadCompleted",
170
+            RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(LeadTradeViewer));
171
+
172
+        public event RoutedEventHandler LeadCompleted
173
+        {
174
+            add { AddHandler(LeadCompletedEvent, value); }
175
+            remove { RemoveHandler(LeadCompletedEvent, value); }
176
+        }
177
+
178
+        private void RaiseLeadCompletedEvent()
179
+        {
180
+            var newEventArgs = new RoutedEventArgs(LeadTradeViewer.LeadCompletedEvent);
181
+            RaiseEvent(newEventArgs);
182
+        }
183
+
184
+        #endregion 路由 完成事件
185
+
186
+        #region 路由 该步完成事件
187
+
188
+        //创建和注册ReFlesh事件,该事件路由策略为Direct
189
+        public static readonly RoutedEvent TradeCompletedEvent = EventManager.RegisterRoutedEvent("TradeCompleted",
190
+            RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(LeadTradeViewer));
191
+
192
+        public event RoutedEventHandler TradeCompleted
193
+        {
194
+            add { AddHandler(TradeCompletedEvent, value); }
195
+            remove { RemoveHandler(TradeCompletedEvent, value); }
196
+        }
197
+
198
+        private void RaiseTradeCompletedEvent()
199
+        {
200
+            var newEventArgs = new RoutedEventArgs(TradeCompletedEvent);
201
+            RaiseEvent(newEventArgs);
202
+        }
203
+
204
+        #endregion 路由 该步完成事件
205
+
206
+        #region 初始化
207
+
208
+        /// <summary>
209
+        ///     存储初始信息
210
+        /// </summary>
211
+        /// <param name="sender"></param>
212
+        /// <param name="e"></param>
213
+        private void StackPanel_Loaded(object sender, RoutedEventArgs e)
214
+        {
215
+            if (LeadSource == null || LeadHeader.Children.Count >= LeadSource.Count) return;
216
+
217
+            _panle = sender as ContentControl;
218
+            _ttf = new TranslateTransform();
219
+            if (_panle != null)
220
+            {
221
+                _panle.RenderTransform = _ttf;
222
+            }
223
+            _title = new bool[LeadSource.Count];
224
+            InitTitle(Direction.None);
225
+            DisplayBtnContent();
226
+        }
227
+
228
+        #endregion 初始化
229
+
230
+        #region 事件
231
+
232
+        /// <summary>
233
+        /// 上一步
234
+        /// </summary>
235
+        /// <param name="sender"></param>
236
+        /// <param name="e"></param>
237
+        private void btnPrevious_Click(object sender, RoutedEventArgs e)
238
+        {
239
+            if (CurrentLeadIndex <= 0) return;
240
+            if (CurrentLeadIndex > LeadSource.Count - 1) CurrentLeadIndex = LeadSource.Count - 1;
241
+            CurrentLeadIndex -= 1;
242
+            InitTitle(Direction.Up);
243
+            DisplayBtnContent();
244
+            //滑动效果
245
+            AnimateControl(FlowDirection.RightToLeft);
246
+        }
247
+
248
+        /// <summary>
249
+        /// 下一步
250
+        /// </summary>
251
+        /// <param name="sender"></param>
252
+        /// <param name="e"></param>
253
+        private void btnNext_Click(object sender, RoutedEventArgs e)
254
+        {
255
+            if (CurrentLeadIndex > LeadSource.Count - 1)
256
+            {
257
+                return;
258
+            }
259
+
260
+            if (CurrentLeadIndex < LeadSource.Count - 1)  // "下一步"
261
+            {
262
+                CurrentLeadIndex += 1;
263
+                InitTitle(Direction.Next);
264
+                DisplayBtnContent();
265
+                //滑动效果
266
+                AnimateControl(FlowDirection.LeftToRight);
267
+
268
+                //公开路由方法
269
+                RaiseLeadNextEvent();
270
+            }
271
+            else   // "完成"
272
+            {
273
+                CurrentLeadIndex += 1;
274
+                //公开路由方法
275
+                RaiseLeadCompletedEvent();
276
+            }
277
+        }
278
+
279
+        /// <summary>
280
+        /// 跳过
281
+        /// </summary>
282
+        /// <param name="sender"></param>
283
+        /// <param name="e"></param>
284
+        private void btnStep_Click(object sender, RoutedEventArgs e)
285
+        {
286
+            if (StepIndex < 0 || StepIndex > LeadSource.Count - 1) return;
287
+            CurrentLeadIndex = StepIndex;
288
+            InitTitle(Direction.Jump);
289
+            DisplayBtnContent();
290
+            //滑动效果
291
+            AnimateControl(FlowDirection.LeftToRight);
292
+
293
+            btnStep.Visibility = Visibility.Hidden;
294
+        }
295
+
296
+        /// <summary>
297
+        /// 动画
298
+        /// </summary>
299
+        /// <param name="dir"></param>
300
+        private void AnimateControl(FlowDirection dir)
301
+        {
302
+            //var sb = new Storyboard();
303
+
304
+            //var ks = new DoubleAnimationUsingKeyFrames();
305
+            ////偏移量为实际宽度
306
+            //var width = 710;
307
+            //width *= Math.Abs(CurrentLeadIndex - _preIndex);
308
+            //var k1 = new EasingDoubleKeyFrame
309
+            //{
310
+            //    KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5)),
311
+            //    Value = dir == FlowDirection.LeftToRight ? _ttf.X - width : _ttf.X + width,
312
+            //    EasingFunction = new SineEase { EasingMode = EasingMode.EaseIn }
313
+            //};
314
+
315
+            //ks.KeyFrames.Add(k1);
316
+            //sb.Children.Add(ks);
317
+            //Storyboard.SetTarget(ks, _panle);
318
+            //Storyboard.SetTargetProperty(ks, new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
319
+
320
+            //sb.Begin();
321
+
322
+            //记录本次索引
323
+            _preIndex = CurrentLeadIndex;
324
+        }
325
+
326
+        /// <summary>
327
+        /// 页面显示要素的处理
328
+        /// </summary>
329
+        private void DisplayBtnContent()
330
+        {
331
+            FleshThemes();
332
+
333
+            LeadSource[CurrentLeadIndex].PageContent.SetValue(Platform.Presentation.FocusManagers.FocusManager.EnableFocusControlProperty, false);
334
+            //去掉提交模版的提交
335
+            var submit = LeadSource[CurrentLeadIndex].PageContent as TellerSystem.Controls.Ext.TradePageBase.SubmitPage;
336
+            if (submit != null)
337
+            {
338
+                submit.Loaded -= (sender, e) => { };
339
+                submit.Loaded += (sender, e) =>
340
+                {
341
+                    if (submit.SubmitButton != null)
342
+                    {
343
+                        submit.SubmitButton.Visibility = Visibility.Hidden;
344
+                    }
345
+                };
346
+                lv_Leads.Content = submit;
347
+            }
348
+            else
349
+            {
350
+                lv_Leads.Content = LeadSource[CurrentLeadIndex].PageContent;
351
+            }
352
+            //解决databox弹出窗时,trademodel为空的问题
353
+            var model = new TradeModel()
354
+            {
355
+                Type = "trade",
356
+            };
357
+            PageHelper.SetTradeModel(lv_Leads.Content as DependencyObject, model);
358
+            FleshPage();
359
+        }
360
+
361
+        /// <summary>
362
+        /// 刷新流程显示
363
+        /// </summary>
364
+        private void FleshThemes()
365
+        {
366
+            var parent = GetParentObject<ContentPresenter>(lv_Leads, "tradepageviewer");
367
+            if (parent != null) parent.Width = lv_Leads.Width;
368
+
369
+            //按钮
370
+            btnPrevious.IsEnabled = true;
371
+            if (CurrentLeadIndex == 0) btnPrevious.IsEnabled = false;
372
+            if (CurrentLeadIndex == LeadSource.Count - 1) btnNext.Content = "完成";
373
+            if (CurrentLeadIndex > 0)
374
+            {
375
+                btnPrevious.IsEnabled = true;
376
+            }
377
+            if (CurrentLeadIndex < LeadSource.Count - 1)
378
+            {
379
+                btnNext.Content = "下一步";
380
+            }
381
+
382
+            #region 处理标题滚动
383
+
384
+            var i = 0;
385
+            //标题
386
+            LeadHeader.Children.Clear();
387
+            foreach (var item in LeadSource)
388
+            {
389
+                var tb = new TextBlock
390
+                 {
391
+                     Text = string.IsNullOrEmpty(item.Description) ? " " : item.Description,
392
+                     Margin = new Thickness(8, 0, 0, 0),
393
+                     FontSize = 14,
394
+                     //Height = 30,
395
+                     Padding = new Thickness(2, 5, 2, 5),
396
+                     //Background = Brushes.Blue,
397
+                     Foreground = Brushes.Blue,
398
+                 };
399
+                TextBlock txt = new TextBlock();
400
+                txt.FontSize = 20;
401
+                txt.Text = " >";
402
+                //i++;
403
+                if (CurrentLeadIndex == i++)
404
+                {
405
+                    tb.Background = Brushes.Blue;
406
+                    tb.Foreground = Brushes.White;
407
+                }
408
+
409
+                if (!_title[i - 1])
410
+                {
411
+                    //前面需要隐藏时,只处理一次。并继续下一步操作
412
+                    if (i - 1 < CurrentLeadIndex)
413
+                    {
414
+                        if (_title[i])
415
+                        {
416
+                            tb.Text = "...";
417
+                            LeadHeader.Children.Add(tb);
418
+                        }
419
+                        continue;
420
+                    }
421
+                    //后面需要隐藏时,只处理一次。并中断
422
+                    else
423
+                    {
424
+                        tb.Text = "...";
425
+                        LeadHeader.Children.Add(tb);
426
+                        break;
427
+                    }
428
+                }
429
+
430
+                LeadHeader.Children.Add(tb);
431
+                if (i != _title.Length)
432
+                {
433
+                    LeadHeader.Children.Add(txt);
434
+                }
435
+            }
436
+
437
+            #endregion 处理标题滚动
438
+        }
439
+
440
+        /// <summary>
441
+        /// 记录动态变化标题
442
+        /// </summary>
443
+        private void InitTitle(Direction direction)
444
+        {
445
+            var txtLen = LeadHeader.ActualWidth - 16;
446
+
447
+            if (CurrentLeadIndex == 0)
448
+            {
449
+                for (var i = 0; i < LeadSource.Count; i++)
450
+                {
451
+                    _title[i] = true;
452
+                    txtLen -= SystemFunction.Len(string.IsNullOrEmpty(LeadSource[i].Description) ? " " : LeadSource[i].Description) * 7 + 12;
453
+                    if (txtLen < 0)
454
+                    {
455
+                        _title[i] = false;
456
+                    }
457
+                }
458
+            }
459
+            else
460
+            {
461
+                var num = 0;
462
+                if (direction == Direction.Next)
463
+                {
464
+                    for (var i = 0; i < _title.Length; i++)
465
+                    {
466
+                        if (_title[i]) num++;
467
+                        if (!_title[i] && CurrentLeadIndex == i - 2)
468
+                        {
469
+                            _title[i - num] = false;
470
+                            _title[i] = true;
471
+                            break;
472
+                        }
473
+                    }
474
+                }
475
+                else if (direction == Direction.Up)
476
+                {
477
+                    for (var j = _title.Length - 1; j >= 0; j--)
478
+                    {
479
+                        if (_title[j]) num++;
480
+                        if (!_title[j] && CurrentLeadIndex == j + 2)
481
+                        {
482
+                            _title[j + num] = false;
483
+                            _title[j] = true;
484
+                            break;
485
+                        }
486
+                    }
487
+                }
488
+            }
489
+        }
490
+
491
+        /// <summary>
492
+        ///  刷新焦点列表
493
+        /// </summary>
494
+        private void FleshPage()
495
+        {
496
+            var page = this.FindVisualTreeAncestor(x => x is IPage);
497
+            if (page != null)
498
+            {
499
+                this.Dispatcher.BeginInvoke(new Action(() =>
500
+                {
501
+                    var fm = Platform.Presentation.FocusManagers.FocusManager.GetManagerInstance(page);
502
+                    if (fm != null)
503
+                    {
504
+                        fm.Refresh();
505
+                    }
506
+                }), System.Windows.Threading.DispatcherPriority.Render, null);
507
+            }
508
+        }
509
+
510
+        /// <summary>
511
+        /// 查找父节点
512
+        /// </summary>
513
+        /// <typeparam name="T"></typeparam>
514
+        /// <param name="obj"></param>
515
+        /// <param name="name"></param>
516
+        /// <returns></returns>
517
+        public T GetParentObject<T>(DependencyObject obj, string name = "") where T : FrameworkElement
518
+        {
519
+            DependencyObject parent = VisualTreeHelper.GetParent(obj);
520
+            while (parent != null)
521
+            {
522
+                if (parent is T && ((T)parent).Name.ToLower() == name)
523
+                {
524
+                    return (T)parent;
525
+                }
526
+                parent = VisualTreeHelper.GetParent(parent);
527
+            }
528
+            return null;
529
+        }
530
+
531
+        #endregion 事件
532
+    }
533
+
534
+    public class LeadTradeViewerCtl
535
+    {
536
+        /// <summary>
537
+        /// 向导容器
538
+        /// </summary>
539
+        private LeadTradeViewer _lt;
540
+
541
+        public LeadTradeViewer lt
542
+        {
543
+            get { return _lt; }
544
+            set { _lt = value; }
545
+        }
546
+
547
+        /// <summary>
548
+        /// 设置或获取下一步按钮的可用性
549
+        /// </summary>
550
+        public bool IsNextBtnEnable
551
+        {
552
+            set
553
+            {
554
+                if (_lt != null)
555
+                {
556
+                    _lt.btnNext.IsEnabled = value;
557
+                }
558
+            }
559
+        }
560
+
561
+        /// <summary>
562
+        /// 如果新增加key,则保存对象
563
+        /// 如果已经存在key对应的对象,则修改
564
+        /// </summary>
565
+        /// <param name="key"></param>
566
+        /// <param name="xml_read_handle"></param>
567
+        public void SetItemXmlReaderMgr(string key, XML_reader_mgr xml_read_handle)
568
+        {
569
+            if (_lt != null)
570
+            {
571
+                _lt.SetItemXmlReaderMgr(key, xml_read_handle);
572
+            }
573
+        }
574
+
575
+        /// <summary>
576
+        /// 放置数据
577
+        /// </summary>
578
+        /// <param name="key"></param>
579
+        /// <param name="obj"></param>
580
+        public void SetDataBus(string key, object obj)
581
+        {
582
+            //只在流程控制中使用
583
+            if (_lt != null)
584
+            {
585
+                _lt.DataBus.SetDictionaryItem(key, obj);
586
+            }
587
+        }
588
+
589
+        public object GetDataBus(string key)
590
+        {
591
+            if (_lt.DataBus.ContainsKey(key))
592
+            {
593
+                return lt.DataBus[key];
594
+            }
595
+            else
596
+            {
597
+                return "";
598
+            }
599
+        }
600
+    }
601
+
602
+    public class LeadItem
603
+    {
604
+        /// <summary>
605
+        /// 页面路径
606
+        /// </summary>
607
+        public ContentControl PageContent { get; set; }
608
+
609
+        /// <summary>
610
+        /// 描述
611
+        /// </summary>
612
+        public string Description { get; set; }
613
+    }
614
+
615
+    public enum Direction
616
+    {
617
+        Next,
618
+        Up,
619
+        Jump,
620
+        None,
621
+    }
622
+}

+ 275
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridLineDecorator.cs 查看文件

@@ -0,0 +1,275 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Markup;
8
+using System.Windows.Media;
9
+using System.Windows.Threading;
10
+
11
+namespace TellerSystem.Controls.Ext.Controls.ListviewPager
12
+{
13
+    [ContentProperty("Target")]
14
+    public class GridLineDecorator : FrameworkElement
15
+    {
16
+        private ListView _target;
17
+        private DrawingVisual _gridLinesVisual = new DrawingVisual();
18
+        private GridViewHeaderRowPresenter _headerRowPresenter = null;
19
+
20
+        public GridLineDecorator()
21
+        {
22
+            this.AddVisualChild(_gridLinesVisual);
23
+            this.AddHandler(ScrollViewer.ScrollChangedEvent, new RoutedEventHandler(OnScrollChanged));
24
+        }
25
+
26
+        #region GridLineBrush
27
+
28
+        /// <summary>
29
+        /// GridLineBrush Dependency Property
30
+        /// </summary>
31
+        public static readonly DependencyProperty GridLineBrushProperty =
32
+            DependencyProperty.Register("GridLineBrush", typeof(Brush), typeof(GridLineDecorator),
33
+                new FrameworkPropertyMetadata(Brushes.DarkGray,
34
+                    new PropertyChangedCallback(OnGridLineBrushChanged)));
35
+
36
+        /// <summary>
37
+        /// Gets or sets the GridLineBrush property.  This dependency property 
38
+        /// indicates ....
39
+        /// </summary>
40
+        public Brush GridLineBrush
41
+        {
42
+            get { return (Brush)GetValue(GridLineBrushProperty); }
43
+            set { SetValue(GridLineBrushProperty, value); }
44
+        }
45
+
46
+        /// <summary>
47
+        /// Handles changes to the GridLineBrush property.
48
+        /// </summary>
49
+        private static void OnGridLineBrushChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
50
+        {
51
+            ((GridLineDecorator)d).OnGridLineBrushChanged(e);
52
+        }
53
+
54
+        /// <summary>
55
+        /// Provides derived classes an opportunity to handle changes to the GridLineBrush property.
56
+        /// </summary>
57
+        protected virtual void OnGridLineBrushChanged(DependencyPropertyChangedEventArgs e)
58
+        {
59
+            DrawGridLines();
60
+        }
61
+
62
+        #endregion
63
+
64
+        #region Target
65
+
66
+        public ListView Target
67
+        {
68
+            get { return _target; }
69
+            set
70
+            {
71
+                if (_target != value)
72
+                {
73
+                    if (_target != null) Detach();
74
+                    RemoveVisualChild(_target);
75
+                    RemoveLogicalChild(_target);
76
+
77
+                    _target = value;
78
+
79
+                    AddVisualChild(_target);
80
+                    AddLogicalChild(_target);
81
+                    if (_target != null) Attach();
82
+
83
+                    InvalidateMeasure();
84
+                }
85
+            }
86
+        }
87
+
88
+        private void GetGridViewHeaderPresenter()
89
+        {
90
+            if (Target == null)
91
+            {
92
+                _headerRowPresenter = null;
93
+                return;
94
+            }
95
+            _headerRowPresenter = Target.GetDesendentChild<GridViewHeaderRowPresenter>();
96
+        }
97
+
98
+        #endregion
99
+
100
+        #region DrawGridLines
101
+
102
+        private void DrawGridLines()
103
+        {
104
+            var itemCount = Target.Items.Count;
105
+            var gridView = Target.View as GridView;
106
+            // 获取drawingContext
107
+            var drawingContext = _gridLinesVisual.RenderOpen();
108
+            var startPoint = new Point(0, 0);
109
+            if(Target == null||_headerRowPresenter == null||itemCount == 0||gridView == null)
110
+            {
111
+                drawingContext.Close();
112
+                return;
113
+            }
114
+            
115
+
116
+            // 为了对齐到像素的计算参数,否则就会看到有些线是模糊的
117
+            var dpiFactor = this.GetDpiFactor();
118
+            var pen = new Pen(this.GridLineBrush, 1 * dpiFactor);
119
+            var halfPenWidth = pen.Thickness / 2;
120
+            var guidelines = new GuidelineSet();
121
+
122
+            // 计算表头的偏移量和大小
123
+            var headerOffset = _headerRowPresenter.TranslatePoint(startPoint, this);
124
+            var headerSize = _headerRowPresenter.RenderSize;
125
+            var headerBottomY = headerOffset.Y + headerSize.Height;
126
+
127
+            // 计算ScrollViewer的可视区域大小
128
+            var item0 = _target.ItemContainerGenerator.ContainerFromIndex(0);
129
+            if (item0 == null) return;
130
+
131
+            var scrollViewer = item0.GetAncestor<ScrollViewer>();
132
+            if (scrollViewer == null) return;
133
+
134
+            var contentElement = scrollViewer.Content as UIElement;
135
+            var maxLineX = scrollViewer.ViewportWidth;
136
+            var maxLineY = headerBottomY + contentElement.RenderSize.Height;
137
+
138
+            var vLineY = 0.0;
139
+
140
+            // 画横线
141
+            for (int i = 0; i < itemCount; i++)
142
+            {
143
+                var item = Target.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
144
+                if (item != null)
145
+                {
146
+                    var renderSize = item.RenderSize;
147
+                    var offset = item.TranslatePoint(startPoint, this);
148
+
149
+                    var hLineX1 = offset.X;
150
+                    var hLineX2 = offset.X + renderSize.Width;
151
+                    var hLineY = offset.Y + renderSize.Height;
152
+                    vLineY = hLineY;
153
+
154
+                    // 小于视图起始位置的不绘制
155
+                    if (hLineY <= headerBottomY) continue;
156
+
157
+                    // 大于视图结束位置之后的不绘制
158
+                    if (hLineY > maxLineY) break;
159
+
160
+                    // 如果大于横向宽度,取横向宽度
161
+                    if (hLineX2 > maxLineX) hLineX2 = maxLineX;
162
+
163
+                    // 加入参考线,对齐到像素
164
+                    guidelines.GuidelinesY.Add(hLineY + halfPenWidth);
165
+                    drawingContext.PushGuidelineSet(guidelines);
166
+                    drawingContext.DrawLine(pen, new Point(hLineX1, hLineY), new Point(hLineX2, hLineY));
167
+                    drawingContext.Pop();
168
+                }
169
+            }
170
+
171
+            // 画竖线
172
+            var columns = gridView.Columns;
173
+            var vLineX = headerOffset.X;
174
+            if (vLineY > maxLineY) vLineY = maxLineY;
175
+
176
+            foreach (var column in columns)
177
+            {
178
+                var columnWidth = column.GetColumnWidth();
179
+                vLineX += columnWidth;
180
+
181
+                if (vLineX > maxLineX) break;
182
+
183
+                // 加入参考线,对齐到像素
184
+                guidelines.GuidelinesX.Add(vLineX + halfPenWidth);
185
+                drawingContext.PushGuidelineSet(guidelines);
186
+                drawingContext.DrawLine(pen, new Point(vLineX, headerBottomY), new Point(vLineX, vLineY));
187
+                drawingContext.Pop();
188
+            }
189
+
190
+            drawingContext.Close();
191
+        }
192
+
193
+        #endregion
194
+
195
+        #region Overrides to show Target and grid lines
196
+
197
+        protected override int VisualChildrenCount
198
+        {
199
+            get { return Target == null ? 1 : 2; }
200
+        }
201
+
202
+        protected override System.Collections.IEnumerator LogicalChildren
203
+        {
204
+            get { yield return Target; }
205
+        }
206
+
207
+        protected override Visual GetVisualChild(int index)
208
+        {
209
+            if (index == 0) return _target;
210
+            if (index == 1) return _gridLinesVisual;
211
+            throw new IndexOutOfRangeException(string.Format("Index of visual child '{0}' is out of range", index));
212
+        }
213
+
214
+        protected override Size MeasureOverride(Size availableSize)
215
+        {
216
+            if (Target != null)
217
+            {
218
+                Target.Measure(availableSize);
219
+                return Target.DesiredSize;
220
+            }
221
+
222
+            return base.MeasureOverride(availableSize);
223
+        }
224
+
225
+        protected override Size ArrangeOverride(Size finalSize)
226
+        {
227
+            if (Target != null)
228
+                Target.Arrange(new Rect(new Point(0, 0), finalSize));
229
+
230
+            return base.ArrangeOverride(finalSize);
231
+        }
232
+
233
+        #endregion
234
+
235
+        #region Handle Events
236
+
237
+        private void Attach()
238
+        {
239
+            _target.Loaded += OnTargetLoaded;
240
+            _target.Unloaded += OnTargetUnloaded;
241
+            _target.SizeChanged += OnTargetSizeChanged;
242
+        }
243
+
244
+        private void Detach()
245
+        {
246
+            _target.Loaded -= OnTargetLoaded;
247
+            _target.Unloaded -= OnTargetUnloaded;
248
+            _target.SizeChanged -= OnTargetSizeChanged;
249
+        }
250
+
251
+        private void OnTargetLoaded(object sender, RoutedEventArgs e)
252
+        {
253
+            if (_headerRowPresenter == null)
254
+                GetGridViewHeaderPresenter();
255
+            DrawGridLines();
256
+        }
257
+
258
+        private void OnTargetUnloaded(object sender, RoutedEventArgs e)
259
+        {
260
+            DrawGridLines();
261
+        }
262
+
263
+        private void OnTargetSizeChanged(object sender, SizeChangedEventArgs e)
264
+        {
265
+            DrawGridLines();
266
+        }
267
+
268
+        private void OnScrollChanged(object sender, RoutedEventArgs e)
269
+        {
270
+            DrawGridLines();
271
+        }
272
+
273
+        #endregion
274
+    }
275
+}

+ 250
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridLineDecorator.ts 查看文件

@@ -0,0 +1,250 @@
1
+import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
2
+import { getDesendentChild, getAncestor, getDpiFactor } from './utils'; // 假设这些工具函数在 utils.ts 中实现
3
+
4
+interface ListView {
5
+    Items: {
6
+        Count: number;
7
+    };
8
+    View: {
9
+        Columns: {
10
+            GetColumnWidth(): number;
11
+        }[];
12
+    };
13
+    ItemContainerGenerator: {
14
+        ContainerFromIndex(index: number): any;
15
+    };
16
+    Loaded: {
17
+        addListener(callback: (sender: any, e: any) => void): void;
18
+        removeListener(callback: (sender: any, e: any) => void): void;
19
+    };
20
+    Unloaded: {
21
+        addListener(callback: (sender: any, e: any) => void): void;
22
+        removeListener(callback: (sender: any, e: any) => void): void;
23
+    };
24
+    SizeChanged: {
25
+        addListener(callback: (sender: any, e: any) => void): void;
26
+        removeListener(callback: (sender: any, e: any) => void): void;
27
+    };
28
+}
29
+
30
+interface GridViewHeaderRowPresenter {
31
+    TranslatePoint(point: { x: number; y: number }, relativeTo: any): { x: number; y: number };
32
+    RenderSize: {
33
+        Width: number;
34
+        Height: number;
35
+    };
36
+}
37
+
38
+interface ScrollViewer {
39
+    ViewportWidth: number;
40
+    Content: {
41
+        RenderSize: {
42
+            Width: number;
43
+            Height: number;
44
+        };
45
+    };
46
+}
47
+
48
+interface ListViewItem {
49
+    TranslatePoint(point: { x: number; y: number }, relativeTo: any): { x: number; y: number };
50
+    RenderSize: {
51
+        Width: number;
52
+        Height: number;
53
+    };
54
+}
55
+
56
+interface Brush {
57
+    // 这里可以根据实际需求补充 Brush 的属性和方法
58
+}
59
+
60
+class DrawingVisual {
61
+    // 模拟 DrawingVisual 的方法
62
+    RenderOpen() {
63
+        return {
64
+            DrawLine: (pen: any, startPoint: { x: number; y: number }, endPoint: { x: number; y: number }) => {
65
+                // 实际绘制逻辑可以在这里添加
66
+            },
67
+            PushGuidelineSet: (guidelines: any) => {
68
+                // 实际逻辑
69
+            },
70
+            Pop: () => {
71
+                // 实际逻辑
72
+            },
73
+            Close: () => {
74
+                // 实际逻辑
75
+            }
76
+        };
77
+    }
78
+}
79
+
80
+class Pen {
81
+    Thickness: number;
82
+    constructor(brush: Brush, thickness: number) {
83
+        this.Thickness = thickness;
84
+    }
85
+}
86
+
87
+class GuidelineSet {
88
+    GuidelinesX: number[] = [];
89
+    GuidelinesY: number[] = [];
90
+}
91
+
92
+export default {
93
+    setup() {
94
+        const _target = ref<ListView | null>(null);
95
+        const _gridLinesVisual = new DrawingVisual();
96
+        const _headerRowPresenter = ref<GridViewHeaderRowPresenter | null>(null);
97
+        const GridLineBrush = ref<Brush>({ /* 初始化 Brush */ } as Brush);
98
+
99
+        const DrawGridLines = () => {
100
+            const itemCount = _target.value?.Items.Count || 0;
101
+            const gridView = _target.value?.View as { Columns: { GetColumnWidth(): number }[] } | null;
102
+            const drawingContext = _gridLinesVisual.RenderOpen();
103
+            const startPoint = { x: 0, y: 0 };
104
+
105
+            if (!_target.value || !_headerRowPresenter.value || itemCount === 0 || !gridView) {
106
+                drawingContext.Close();
107
+                return;
108
+            }
109
+
110
+            const dpiFactor = getDpiFactor();
111
+            const pen = new Pen(GridLineBrush.value, 1 * dpiFactor);
112
+            const halfPenWidth = pen.Thickness / 2;
113
+            const guidelines = new GuidelineSet();
114
+
115
+            const headerOffset = _headerRowPresenter.value.TranslatePoint(startPoint, { /* 这里传入合适的对象 */ });
116
+            const headerSize = _headerRowPresenter.value.RenderSize;
117
+            const headerBottomY = headerOffset.y + headerSize.Height;
118
+
119
+            const item0 = _target.value.ItemContainerGenerator.ContainerFromIndex(0);
120
+            if (!item0) return;
121
+
122
+            const scrollViewer = getAncestor<ScrollViewer>(item0);
123
+            if (!scrollViewer) return;
124
+
125
+            const contentElement = scrollViewer.Content;
126
+            const maxLineX = scrollViewer.ViewportWidth;
127
+            const maxLineY = headerBottomY + contentElement.RenderSize.Height;
128
+
129
+            let vLineY = 0;
130
+
131
+            // 画横线
132
+            for (let i = 0; i < itemCount; i++) {
133
+                const item = _target.value.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem | null;
134
+                if (item) {
135
+                    const renderSize = item.RenderSize;
136
+                    const offset = item.TranslatePoint(startPoint, { /* 这里传入合适的对象 */ });
137
+
138
+                    let hLineX1 = offset.x;
139
+                    let hLineX2 = offset.x + renderSize.Width;
140
+                    const hLineY = offset.y + renderSize.Height;
141
+                    vLineY = hLineY;
142
+
143
+                    if (hLineY <= headerBottomY) continue;
144
+                    if (hLineY > maxLineY) break;
145
+                    if (hLineX2 > maxLineX) hLineX2 = maxLineX;
146
+
147
+                    guidelines.GuidelinesY.push(hLineY + halfPenWidth);
148
+                    drawingContext.PushGuidelineSet(guidelines);
149
+                    drawingContext.DrawLine(pen, { x: hLineX1, y: hLineY }, { x: hLineX2, y: hLineY });
150
+                    drawingContext.Pop();
151
+                }
152
+            }
153
+
154
+            // 画竖线
155
+            let vLineX = headerOffset.x;
156
+            if (vLineY > maxLineY) vLineY = maxLineY;
157
+
158
+            gridView.Columns.forEach((column) => {
159
+                const columnWidth = column.GetColumnWidth();
160
+                vLineX += columnWidth;
161
+
162
+                if (vLineX > maxLineX) return;
163
+
164
+                guidelines.GuidelinesX.push(vLineX + halfPenWidth);
165
+                drawingContext.PushGuidelineSet(guidelines);
166
+                drawingContext.DrawLine(pen, { x: vLineX, y: headerBottomY }, { x: vLineX, y: vLineY });
167
+                drawingContext.Pop();
168
+            });
169
+
170
+            drawingContext.Close();
171
+        };
172
+
173
+        const GetGridViewHeaderPresenter = () => {
174
+            if (!_target.value) {
175
+                _headerRowPresenter.value = null;
176
+                return;
177
+            }
178
+            _headerRowPresenter.value = getDesendentChild<GridViewHeaderRowPresenter>(_target.value);
179
+        };
180
+
181
+        const Attach = () => {
182
+            if (_target.value) {
183
+                _target.value.Loaded.addListener(OnTargetLoaded);
184
+                _target.value.Unloaded.addListener(OnTargetUnloaded);
185
+                _target.value.SizeChanged.addListener(OnTargetSizeChanged);
186
+            }
187
+        };
188
+
189
+        const Detach = () => {
190
+            if (_target.value) {
191
+                _target.value.Loaded.removeListener(OnTargetLoaded);
192
+                _target.value.Unloaded.removeListener(OnTargetUnloaded);
193
+                _target.value.SizeChanged.removeListener(OnTargetSizeChanged);
194
+            }
195
+        };
196
+
197
+        const OnTargetLoaded = (sender: any, e: any) => {
198
+            if (!_headerRowPresenter.value) {
199
+                GetGridViewHeaderPresenter();
200
+            }
201
+            DrawGridLines();
202
+        };
203
+
204
+        const OnTargetUnloaded = (sender: any, e: any) => {
205
+            DrawGridLines();
206
+        };
207
+
208
+        const OnTargetSizeChanged = (sender: any, e: any) => {
209
+            DrawGridLines();
210
+        };
211
+
212
+        const OnScrollChanged = (sender: any, e: any) => {
213
+            DrawGridLines();
214
+        };
215
+
216
+        const setTarget = (value: ListView | null) => {
217
+            if (_target.value !== value) {
218
+                if (_target.value) Detach();
219
+
220
+                _target.value = value;
221
+
222
+                if (_target.value) Attach();
223
+
224
+                // 这里可以添加与 Measure 和 Arrange 相关的逻辑,根据 Vue 的渲染机制调整
225
+            }
226
+        };
227
+
228
+        const setGridLineBrush = (value: Brush) => {
229
+            GridLineBrush.value = value;
230
+            DrawGridLines();
231
+        };
232
+
233
+        onMounted(() => {
234
+            // 可以在这里添加初始化逻辑
235
+        });
236
+
237
+        onBeforeUnmount(() => {
238
+            Detach();
239
+        });
240
+
241
+        watch(GridLineBrush, () => {
242
+            DrawGridLines();
243
+        });
244
+
245
+        return {
246
+            setTarget,
247
+            setGridLineBrush
248
+        };
249
+    }
250
+};

+ 20
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridViewColumnHelper.cs 查看文件

@@ -0,0 +1,20 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Reflection;
5
+using System.Text;
6
+using System.Windows.Controls;
7
+
8
+namespace TellerSystem.Controls.Ext.Controls.ListviewPager
9
+{
10
+    internal static class GridViewColumnHelper
11
+    {
12
+        private static PropertyInfo DesiredWidthProperty =
13
+            typeof(GridViewColumn).GetProperty("DesiredWidth", BindingFlags.NonPublic | BindingFlags.Instance);
14
+
15
+        public static double GetColumnWidth(this GridViewColumn column)
16
+        {
17
+            return (double.IsNaN(column.Width)) ? (double)DesiredWidthProperty.GetValue(column, null) : column.Width;
18
+        }
19
+    }
20
+}

+ 13
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/GridViewColumnHelper.ts 查看文件

@@ -0,0 +1,13 @@
1
+// 假设GridViewColumn是一个自定义类型,这里简单用any表示,实际需要根据具体情况定义
2
+type GridViewColumn = any;
3
+
4
+// 定义一个获取GridViewColumn宽度的工具函数
5
+export const getColumnWidth = (column: GridViewColumn): number => {
6
+    // 模拟获取DesiredWidth属性
7
+    const getDesiredWidth = (col: GridViewColumn) => {
8
+        // 这里假设DesiredWidth是一个属性,实际需要根据具体情况实现
9
+        return (col as any).DesiredWidth || 0; 
10
+    };
11
+
12
+    return isNaN(column.Width) ? getDesiredWidth(column) : column.Width;
13
+};

+ 61
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/Listviewpg.xaml 查看文件

@@ -0,0 +1,61 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.ListviewPager.Listviewpg"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:ctrl="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
5
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+             xmlns:dhcc="http://www.dhcc.com.cn"
7
+             xmlns:l="clr-namespace:TellerSystem.Controls.Ext.Controls.ListviewPager"
8
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9
+             dhcc:FocusManager.IsInternalKeyboardControlling="True"
10
+             mc:Ignorable="d">
11
+    <UserControl.Resources>
12
+        <Style TargetType="ListViewItem">
13
+            <EventSetter Event="MouseDoubleClick" Handler="HanderDoubleClick" />
14
+        </Style>
15
+        <Style TargetType="GridViewColumnHeader">
16
+            <Setter Property="Background" Value="Lightgray" />
17
+        </Style>
18
+    </UserControl.Resources>
19
+    <ctrl:TradePanel x:Name="gourpbox"
20
+                     LostFocus="gourpbox_LostFocus"
21
+                     ToolTipService.ShowDuration="300000">
22
+        <l:GridLineDecorator ctrl:TradePanel.IsCentralAlone="True" GridLineBrush="{Binding ElementName=cb_GridLineBrush, Path=SelectedItem.Content}">
23
+            <ListView Name="listview1"
24
+                      VerticalContentAlignment="Top"
25
+                      AllowDrop="True"
26
+                      Background="#FF90D490"
27
+                      DragEnter="listview1_DragEnter"
28
+                      DragOver="listview1_DragOver"
29
+                      Drop="listview1_Drop"
30
+                      PreviewMouseLeftButtonDown="listview1_PreviewMouseLeftButtonDown"
31
+                      PreviewMouseMove="listview1_PreviewMouseMove"
32
+                      PreviewMouseRightButtonUp="listview1_PreviewMouseRightButtonUp"
33
+                      SelectionChanged="listview1_SelectionChanged">
34
+                <ListView.View>
35
+                    <GridView x:Name="gridView" />
36
+                </ListView.View>
37
+            </ListView>
38
+        </l:GridLineDecorator>
39
+        <DockPanel ctrl:TradePanel.IsCentralAlone="True">
40
+            <dhcc:ImageButton Name="Export"
41
+                              Width="25"
42
+                              Height="25"
43
+                              Click="Export_Click"
44
+                              DockPanel.Dock="Right"
45
+                              ImageSource="/TellerSystem.Resources;Component/img/cert_storage.png"
46
+                              ToolTip="导出" />
47
+
48
+            <dhcc:DataPager x:Name="dataPager"
49
+                            Height="34"
50
+                            IsEnabled="False"
51
+                            PageChanged="dataPager_PageChanged"
52
+                            PageSizeList="{Binding PageSizeLis}"
53
+                            Total="{Binding Total,
54
+                                            Mode=TwoWay,
55
+                                            UpdateSourceTrigger=PropertyChanged}" />
56
+
57
+        </DockPanel>
58
+    </ctrl:TradePanel>
59
+
60
+
61
+</UserControl>

+ 519
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/Listviewpg.xaml.cs 查看文件

@@ -0,0 +1,519 @@
1
+using Platform.Controls.ComponentContainer;
2
+using System;
3
+using System.Collections;
4
+using System.Collections.Generic;
5
+using System.ComponentModel;
6
+using System.Data;
7
+using System.Linq;
8
+using System.Text;
9
+using System.Windows;
10
+using System.Windows.Controls;
11
+using System.Windows.Data;
12
+using System.Windows.Documents;
13
+using System.Windows.Input;
14
+using System.Windows.Media;
15
+using System.Windows.Media.Imaging;
16
+using System.Windows.Navigation;
17
+using System.Windows.Shapes;
18
+using Excel = Microsoft.Office.Interop.Excel;
19
+using System.Xml;
20
+using System.Windows.Controls.Primitives;
21
+
22
+namespace TellerSystem.Controls.Ext.Controls.ListviewPager
23
+{
24
+    /// <summary>
25
+    /// Listview.xaml 的交互逻辑
26
+    /// </summary>
27
+    public partial class Listviewpg : UserControl, INotifyPropertyChanged
28
+    {
29
+        Point startPoint;
30
+        ListBoxItem contact;
31
+        XmlElement Destelement;
32
+        XmlElement Startelement;
33
+        private int _total;
34
+        public delegate void HyperlinkClicked(string primarykey, string value, string tablename);
35
+        public HyperlinkClicked Hyperlinkclick;
36
+        public delegate void SetButtonIsNoEnable();
37
+        public delegate void ListviewDoublueClick();
38
+        public ListviewDoublueClick ListviewClick;
39
+        public SetButtonIsNoEnable SetEnable;
40
+        public SetButtonIsNoEnable SetDisable;
41
+        private string FilterString = string.Empty;
42
+        public event PropertyChangedEventHandler PropertyChanged;
43
+        public event EventHandler SelectionChange;
44
+        private string s_ToolTip = string.Empty;
45
+        /// <summary>
46
+        /// 设置要选中的值
47
+        /// </summary>
48
+        //public bool EnableDrag
49
+        //{
50
+        //    get { return (bool)GetValue(EnableDragProperty); }
51
+        //    set { SetValue(EnableDragProperty, value); }
52
+        //}
53
+
54
+        //public static readonly DependencyProperty EnableDragProperty =
55
+        //    DependencyProperty.Register("EnableDrag", typeof(bool), typeof(DateSpanControl), new UIPropertyMetadata(-1));
56
+        public static readonly RoutedEvent ListviewLostFocus = EventManager.RegisterRoutedEvent("ListviewLostFocus", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TBC_Curreny));
57
+        public event RoutedEventHandler ListviewLostFocusEvent
58
+        {
59
+            add { base.AddHandler(ListviewLostFocus, value); }
60
+
61
+            remove { base.RemoveHandler(ListviewLostFocus, value); }
62
+
63
+        }
64
+        public string ToolTips
65
+        {
66
+            get { return s_ToolTip; }
67
+            set { s_ToolTip = value; }
68
+        }
69
+
70
+        private Dictionary<string, List<string>> dc_table;
71
+        public Listviewpg()
72
+        {
73
+            //EnableDrag = false;
74
+            InitializeComponent();
75
+            dc_table = new Dictionary<string, List<string>>();
76
+            dataPager.SetBinding(DataPager.TotalProperty, new Binding("Total") { Source = this });
77
+
78
+        }
79
+        public double height
80
+        {
81
+            get
82
+            {
83
+                return this.gourpbox.Height;
84
+            }
85
+            set
86
+            {
87
+                this.gourpbox.Height = value;
88
+            }
89
+        }
90
+        public double width
91
+        {
92
+            get
93
+            {
94
+                return this.gourpbox.Width;
95
+            }
96
+            set
97
+            {
98
+                this.gourpbox.Width = value;
99
+            }
100
+        }
101
+        private XmlDataProvider _xdp;
102
+        public int Total
103
+        {
104
+            get { return _total; }
105
+            private set
106
+            {
107
+                _total = value;
108
+
109
+
110
+                RaisePropertyChanged("Total");
111
+            }
112
+        }
113
+        public IList SelectedItems
114
+        {
115
+            get
116
+            {
117
+                return this.listview1.SelectedItems;
118
+            }
119
+        }
120
+
121
+        public XmlDataProvider Xdp
122
+        {
123
+            get
124
+            {
125
+                return _xdp;
126
+            }
127
+            set
128
+            {
129
+                _xdp = value;
130
+            }
131
+        }
132
+        //  public void add(Dictionary<string> )
133
+        public void Bind(XmlDataProvider xdp)
134
+        {
135
+
136
+            _xdp = xdp;
137
+            if (xdp != null)
138
+            {
139
+                _xdp.XPath = @"//Result";
140
+                this.listview1.DataContext = _xdp;
141
+                this.listview1.SetBinding(ListView.ItemsSourceProperty, new Binding());
142
+
143
+                Total = _xdp.Document.SelectNodes(@"//Result").Count;
144
+
145
+                dataPager.RaisePageChanged();
146
+                dataPager.PageIndex = 1;
147
+                dataPager_PageChanged(null, new PageChangedEventArgs(null, dataPager.PageSize, dataPager.PageIndex));
148
+                dataPager.RaisePageChanged();
149
+                dataPager.IsEnabled = true;
150
+                
151
+            }
152
+            else
153
+            {
154
+                this.listview1.DataContext = _xdp;
155
+                this.listview1.SetBinding(ListView.ItemsSourceProperty, new Binding());
156
+                Total = 0;
157
+                dataPager.RaisePageChanged();
158
+                dataPager.PageIndex = 1;
159
+
160
+            }
161
+            
162
+        }
163
+        /// <summary>
164
+        /// 设置列宽
165
+        /// </summary>
166
+        /// <param name="index">索引</param>
167
+        /// <param name="value">列宽值</param>
168
+        public void SetColumnsWidth(int index, double value)
169
+        {
170
+            if (gridView != null && gridView.Columns.Count > index)
171
+                gridView.Columns[index].Width = value;
172
+        }
173
+        public void Setfilter(Dictionary<string, string> dc)
174
+        {
175
+            if (dc == null)
176
+            {
177
+                FilterString = string.Empty;
178
+            }
179
+            else
180
+            {
181
+
182
+                foreach (KeyValuePair<string, string> kv in dc)
183
+                {
184
+                    FilterString = "@" + kv.Key + "=\"" + kv.Value + "\" and ";
185
+                }
186
+
187
+            }
188
+            dataPager.RaisePageChanged();
189
+        }
190
+        private void dataPager_PageChanged(object sender, Platform.Controls.ComponentContainer.PageChangedEventArgs args)
191
+        {
192
+            //_xdp.XPath=@"//Result[prdt_no=]";
193
+            if (_xdp != null)
194
+            {
195
+                //if (EnableDrag == false)
196
+                //{
197
+
198
+                    _xdp.XPath = @"//Result[" + (args.PageIndex - 1) * args.PageSize + "<position() and position()<" + (args.PageIndex * args.PageSize + 1) + "]";
199
+                    autosetcolumnwidth(args.PageIndex, args.PageSize);
200
+                //}
201
+            }
202
+        }
203
+        //初始化界面元素 titile:goupbox的标题;dc:listview的列名跟绑定对应值的字典
204
+        public void Initialize(string title, Dictionary<string, string> dc_data, Dictionary<string, List<string>> dc_linkview = null)
205
+        {
206
+            listview1.AddHandler(System.Windows.Controls.Primitives.ButtonBase.MouseEnterEvent, new RoutedEventHandler(HandleEnter));
207
+            if (dc_linkview != null)
208
+            {
209
+                dc_table = dc_linkview;
210
+            }
211
+            this.gourpbox.Header = title;
212
+
213
+            GridView gv = this.listview1.View as GridView;
214
+            gv.Columns.Clear();
215
+            foreach (KeyValuePair<string, string> kvp in dc_data)
216
+            {
217
+                //增加column
218
+
219
+                GridViewColumn gvc = new GridViewColumn();
220
+
221
+                gvc.Header = kvp.Key;
222
+                gvc.Width = kvp.Key.Length * 20;
223
+
224
+                Binding b = new Binding();
225
+                b.XPath = kvp.Value;
226
+
227
+
228
+                //
229
+                if ((dc_linkview != null) && (dc_linkview.Keys.Contains(kvp.Value)))
230
+                {
231
+
232
+                    DataTemplate dataTempControl = new DataTemplate();
233
+                    FrameworkElementFactory tbContent = new FrameworkElementFactory(typeof(TextBlock));
234
+                    //FrameworkElementFactory hl = new FrameworkElementFactory(typeof(Hyperlink));
235
+                    tbContent.SetValue(TextBlock.NameProperty, kvp.Value);
236
+
237
+                    tbContent.SetBinding(TextBlock.TextProperty, b);
238
+                    //hl.AppendChild(tbContent);
239
+                    //FrameworkElementFactory tb = new FrameworkElementFactory(typeof(TextBlock));
240
+                    tbContent.AddHandler(TextBlock.MouseLeftButtonUpEvent, new MouseButtonEventHandler(hyperlink_click));
241
+                    tbContent.SetValue(TextBlock.CursorProperty, Cursors.Hand);
242
+                    tbContent.SetValue(TextBlock.ForegroundProperty, Brushes.Red);
243
+                    //tb.AppendChild(hl);
244
+
245
+                    dataTempControl.VisualTree = tbContent;
246
+                    dataTempControl.VisualTree.Name = kvp.Value;
247
+                    gvc.CellTemplate = dataTempControl;
248
+
249
+
250
+                }
251
+                else
252
+                {
253
+                    gvc.DisplayMemberBinding = b;
254
+                }
255
+
256
+                //
257
+                gv.Columns.Add(gvc);
258
+            }
259
+            this.listview1.Height = gourpbox.Height - 70;
260
+        }
261
+
262
+        public void RaisePropertyChanged(string propertyName)
263
+        {
264
+            if (PropertyChanged != null)
265
+            {
266
+                PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
267
+            }
268
+
269
+        }
270
+
271
+        private void listview1_SelectionChanged(object sender, SelectionChangedEventArgs e)
272
+        {
273
+            if (this.listview1.SelectedItems.Count == 0)
274
+                SetDisable();
275
+            else
276
+                SetEnable();
277
+        }
278
+        private void autosetcolumnwidth(int pageindex, int pagesize)
279
+        {
280
+            GridView gv = this.listview1.View as GridView;
281
+            int columncount = gv.Columns.Count;
282
+            int datalen=0;
283
+            int maxlen=0;
284
+            XmlNodeList xnl = _xdp.Document.SelectNodes("//Result");
285
+            if (columncount > 10)
286
+            {
287
+                return;
288
+            }
289
+            for (int columnindex = 0; columnindex < columncount; columnindex++)
290
+            {
291
+                for (int i = (pageindex - 1) * pagesize; (i < (pageindex * pagesize + 1)) && (i < xnl.Count); i++)
292
+                {
293
+                    try
294
+                    {
295
+                        datalen = System.Text.Encoding.Default.GetByteCount(xnl[i].SelectSingleNode((gv.Columns[columnindex].DisplayMemberBinding as Binding).XPath).InnerText);
296
+                    }
297
+                    catch (Exception ex)
298
+                    {
299
+                        datalen = System.Text.Encoding.Default.GetByteCount(xnl[i].SelectSingleNode(gv.Columns[columnindex].CellTemplate.VisualTree.Name).InnerText);
300
+                    }
301
+                    maxlen = datalen > maxlen ? datalen : maxlen; 
302
+                }
303
+                gridView.Columns[columnindex].Width = gridView.Columns[columnindex].Width > maxlen * 10 ? gridView.Columns[columnindex].Width : maxlen * 10;
304
+                maxlen=0;
305
+
306
+            }
307
+           
308
+        }
309
+        /**这个方法只能生成listview里面显示的列的内容的excel,感觉意义不大**/
310
+        public void GenerateExcel(string SheetName)
311
+        {
312
+            //
313
+            int rowcount = Total;     /*行数等于查询到的记录总条数*/
314
+            if (rowcount == 0)
315
+            {
316
+                return;
317
+            }
318
+            string SavedPath = string.Empty;                         //Excel文件保存路径
319
+            //string CurPath = System.Environment.CurrentDirectory;    //程序运行的当前目录
320
+            //if (!System.IO.Directory.Exists(CurPath + @"\Excel"))    //判断目录是否存在
321
+            //{
322
+            //    System.IO.Directory.CreateDirectory(CurPath + @"\Excel");
323
+            //}
324
+            //SavedPath = String.Format(@"{0}\Excel\{1}.xlsx", CurPath, SheetName);
325
+            System.Windows.Forms.SaveFileDialog dlg = new System.Windows.Forms.SaveFileDialog();
326
+            dlg.Title = "请选择保存位置";
327
+            dlg.Filter = "xls文件(*.xls)|*.txt|xlsx文件(*.xlsx)|*.xlsx";
328
+            dlg.FileName = SheetName + ".xlsx";
329
+            if (dlg.ShowDialog() == System.Windows.Forms.DialogResult.Cancel)
330
+            {
331
+                return;
332
+            }
333
+            SavedPath = dlg.FileName;//获取选择的文件路径和文件名
334
+
335
+            //open excel application
336
+            Excel.Application Excel_APP = new Excel.Application();
337
+            Excel_APP.Visible = false;
338
+            Excel_APP.DisplayAlerts = false;
339
+            //create excel workbook
340
+            Excel.Workbook excelWorkbook = Excel_APP.Workbooks.Add();
341
+            //get excel worksheet
342
+            Excel.Worksheet excelWorksheet = excelWorkbook.ActiveSheet;
343
+            excelWorksheet.Name = SheetName;
344
+
345
+
346
+            GridView gv = this.listview1.View as GridView;/*将listview里的内容以网格布局显示*/
347
+
348
+            int columncount = gv.Columns.Count;      /*列数为listview中显示的列*/
349
+            int rowindex = 0;
350
+            int columnindex = 0;
351
+
352
+            for (; columnindex < columncount; columnindex++)/*生成execl表头*/
353
+            {
354
+                excelWorksheet.Cells[1, columnindex + 1] = gv.Columns[columnindex].Header;
355
+            }
356
+
357
+            XmlNodeList xnl_td = _xdp.Document.SelectNodes(@"//Result");
358
+            for (; rowindex < rowcount; rowindex++)/*逐行打印*/
359
+            {
360
+                XmlNode xn_td = xnl_td.Item(rowindex);
361
+                for (columnindex = 0; columnindex < columncount; columnindex++)/*打印单行每个列的数据*/
362
+                {
363
+                    try
364
+                    {
365
+                        excelWorksheet.Cells[2 + rowindex, columnindex + 1] = "\'" + xn_td.SelectSingleNode((gv.Columns[columnindex].DisplayMemberBinding as Binding).XPath).InnerText;
366
+                    }
367
+                    catch (Exception ex)
368
+                    {
369
+                        excelWorksheet.Cells[2 + rowindex, columnindex + 1] = "\'" + xn_td.SelectSingleNode(gv.Columns[columnindex].CellTemplate.VisualTree.Name).InnerText;
370
+                    }
371
+                }
372
+            }
373
+            excelWorkbook.SaveAs(SavedPath);
374
+            excelWorkbook.Close();
375
+            Excel_APP.Quit();
376
+            //
377
+
378
+        }
379
+
380
+        private void hyperlink_click(object sender, RoutedEventArgs e)
381
+        {
382
+            TextBlock selectedElement = sender as TextBlock;
383
+            selectedElement.SetValue(TextBlock.ForegroundProperty, Brushes.PaleVioletRed);
384
+            Hyperlinkclick(dc_table[selectedElement.Name][0], selectedElement.Text, dc_table[selectedElement.Name][1]);
385
+        }
386
+
387
+        private void Export_Click(object sender, RoutedEventArgs e)
388
+        {
389
+            this.GenerateExcel(gourpbox.Header.ToString());
390
+        }
391
+
392
+        private void HanderDoubleClick(object sender, MouseButtonEventArgs e)
393
+        {
394
+            ListviewClick();
395
+        }
396
+        private void HandleEnter(object sender, RoutedEventArgs e)
397
+        {
398
+            if (s_ToolTip != "")
399
+            {
400
+                ToolTip tooltip = new ToolTip();
401
+                tooltip.StaysOpen = true;
402
+                
403
+                tooltip.Placement = PlacementMode.Right;
404
+                tooltip.PlacementRectangle = new Rect(50, 0, 0, 0);
405
+                tooltip.Content = s_ToolTip;
406
+                tooltip.HorizontalOffset = 730;
407
+                tooltip.VerticalOffset = 20;
408
+                gourpbox.ToolTip = tooltip;
409
+                
410
+            }
411
+        }
412
+
413
+
414
+     
415
+        private void gourpbox_LostFocus(object sender, RoutedEventArgs e)
416
+        {
417
+            RaiseEvent(new RoutedEventArgs(Listviewpg.ListviewLostFocus, this));
418
+        }
419
+
420
+        private void listview1_DragEnter(object sender, DragEventArgs e)
421
+        {
422
+            
423
+        }
424
+
425
+        private void listview1_Drop(object sender, DragEventArgs e)
426
+        {
427
+           
428
+           // MessageBox.Show(Destelement.ChildNodes[0].InnerText);
429
+            //XmlDocument xd = ((XmlDataProvider)listview1.DataContext).Document;
430
+            Destelement = (XmlElement)Element_undercursor;
431
+            
432
+            Destelement.ParentNode.InsertBefore(Startelement, Destelement);
433
+            
434
+            ;
435
+
436
+        }
437
+
438
+        private void listview1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
439
+        {
440
+            startPoint = e.GetPosition(null);
441
+            Startelement =(XmlElement) Element_undercursor;
442
+        }
443
+        private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
444
+        {
445
+            do
446
+            {
447
+                if (current is T)
448
+                {
449
+                    return (T)current;
450
+                }
451
+                current = VisualTreeHelper.GetParent(current);
452
+            }
453
+            while (current != null);
454
+
455
+            return null;
456
+        }
457
+
458
+        private void listview1_PreviewMouseMove(object sender, MouseEventArgs e)
459
+        {
460
+            Point mousPos = e.GetPosition(null);
461
+            Vector diff = startPoint - mousPos;
462
+
463
+            if ((e.LeftButton == MouseButtonState.Pressed) && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance) && (Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
464
+            {
465
+                ListView listView = sender as ListView;
466
+                ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
467
+                if (listViewItem == null) { return; }
468
+                
469
+                DataObject dataObject = new DataObject("MyFormat", listViewItem);
470
+                DragDrop.DoDragDrop(listViewItem, dataObject, DragDropEffects.Move);
471
+            }
472
+        }
473
+        bool IsMouseOver(Visual target)
474
+        {
475
+            // We need to use MouseUtilities to figure out the cursor
476
+            // coordinates because, during a drag-drop operation, the WPF
477
+            // mechanisms for getting the coordinates behave strangely.
478
+
479
+            Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
480
+            Point mousePos = MouseUtilities.GetMousePosition(target);
481
+            return bounds.Contains(mousePos);
482
+        }
483
+        public XmlElement Element_undercursor 
484
+        {
485
+            get 
486
+            {
487
+                XmlElement ret = null;
488
+                if (listview1.Items.Count == 0)
489
+                {
490
+                    return ret;
491
+                }
492
+                ret=(XmlElement)listview1.Items[0];
493
+                for (int i = 0; i < this.listview1.Items.Count; ++i)
494
+                {
495
+                    ListViewItem item = this.listview1.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;
496
+                    if (this.IsMouseOver(item))
497
+                    {
498
+                        ret=(XmlElement)listview1.Items[i];
499
+                        break;
500
+                    }
501
+                }
502
+                
503
+                return ret;
504
+            }
505
+        } 
506
+        private void listview1_DragOver(object sender, DragEventArgs e)
507
+        {
508
+            
509
+            
510
+        }
511
+
512
+        private void listview1_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
513
+        {
514
+            
515
+        }
516
+
517
+
518
+    }
519
+}

+ 52
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/MouseUtilities.cs 查看文件

@@ -0,0 +1,52 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Runtime.InteropServices;
6
+using System.Windows;
7
+using System.Windows.Media;
8
+
9
+namespace TellerSystem.Controls.Ext.Controls.ListviewPager
10
+{
11
+    class MouseUtilities
12
+    {
13
+        [StructLayout(LayoutKind.Sequential)]
14
+        private struct Win32Point
15
+        {
16
+            public Int32 X;
17
+            public Int32 Y;
18
+        };
19
+
20
+        [DllImport("user32.dll")]
21
+        private static extern bool GetCursorPos(ref Win32Point pt);
22
+
23
+        [DllImport("user32.dll")]
24
+        private static extern bool ScreenToClient(IntPtr hwnd, ref Win32Point pt);
25
+
26
+        /// <summary>
27
+        /// Returns the mouse cursor location.  This method is necessary during 
28
+        /// a drag-drop operation because the WPF mechanisms for retrieving the
29
+        /// cursor coordinates are unreliable.
30
+        /// </summary>
31
+        /// <param name="relativeTo">The Visual to which the mouse coordinates will be relative.</param>
32
+        public static Point GetMousePosition(Visual relativeTo)
33
+        {
34
+            Win32Point mouse = new Win32Point();
35
+            GetCursorPos(ref mouse);
36
+
37
+            // Using PointFromScreen instead of Dan Crevier's code (commented out below)
38
+            // is a bug fix created by William J. Roberts.  Read his comments about the fix
39
+            // here: http://www.codeproject.com/useritems/ListViewDragDropManager.asp?msg=1911611#xx1911611xx
40
+            return relativeTo.PointFromScreen(new Point((double)mouse.X, (double)mouse.Y));
41
+
42
+            #region Commented Out
43
+            //System.Windows.Interop.HwndSource presentationSource =
44
+            //    (System.Windows.Interop.HwndSource)PresentationSource.FromVisual( relativeTo );
45
+            //ScreenToClient( presentationSource.Handle, ref mouse );
46
+            //GeneralTransform transform = relativeTo.TransformToAncestor( presentationSource.RootVisual );
47
+            //Point offset = transform.Transform( new Point( 0, 0 ) );
48
+            //return new Point( mouse.X - offset.X, mouse.Y - offset.Y );
49
+            #endregion // Commented Out
50
+        }
51
+    }
52
+}

+ 52
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/MouseUtilities.ts 查看文件

@@ -0,0 +1,52 @@
1
+import { ref } from 'vue';
2
+import { Visual } from 'vue'; // 这里假设Visual类型有对应的定义,如果没有需要补充
3
+
4
+// 模拟Win32Point结构体
5
+interface Win32Point {
6
+    X: number;
7
+    Y: number;
8
+}
9
+
10
+// 模拟DllImport的功能,这里可以在实际使用时实现具体的调用逻辑
11
+function getCursorPos(pt: Win32Point): boolean {
12
+    // 这里需要实现获取鼠标位置的逻辑,例如使用浏览器的API
13
+    const { clientX, clientY } = window.event as MouseEvent;
14
+    pt.X = clientX;
15
+    pt.Y = clientY;
16
+    return true;
17
+}
18
+
19
+// 模拟ScreenToClient的功能,这里可以在实际使用时实现具体的调用逻辑
20
+function screenToClient(hwnd: number, pt: Win32Point): boolean {
21
+    // 这里需要实现将屏幕坐标转换为客户端坐标的逻辑
22
+    return true;
23
+}
24
+
25
+export class MouseUtilities {
26
+    /**
27
+     * Returns the mouse cursor location.  This method is necessary during 
28
+     * a drag-drop operation because the WPF mechanisms for retrieving the
29
+     * cursor coordinates are unreliable.
30
+     * 
31
+     * @param relativeTo The Visual to which the mouse coordinates will be relative.
32
+     */
33
+    public static getMousePosition(relativeTo: Visual): { x: number; y: number } {
34
+        const mouse: Win32Point = { X: 0, Y: 0 };
35
+        getCursorPos(mouse);
36
+
37
+        // 假设这里有一个PointFromScreen的方法来转换坐标
38
+        const pointFromScreen = (relativeTo as any).PointFromScreen;
39
+        if (pointFromScreen) {
40
+            return pointFromScreen({ x: mouse.X, y: mouse.Y });
41
+        }
42
+
43
+        // 注释掉的代码在TypeScript中暂时不实现
44
+        // const presentationSource = (PresentationSource.FromVisual(relativeTo) as any);
45
+        // screenToClient(presentationSource.Handle, mouse);
46
+        // const transform = relativeTo.TransformToAncestor(presentationSource.RootVisual);
47
+        // const offset = transform.Transform({ x: 0, y: 0 });
48
+        // return { x: mouse.X - offset.x, y: mouse.Y - offset.y };
49
+
50
+        return { x: 0, y: 0 };
51
+    }
52
+}

+ 50
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/VisualService.cs 查看文件

@@ -0,0 +1,50 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows.Media;
6
+using System.Windows;
7
+
8
+namespace TellerSystem.Controls.Ext.Controls.ListviewPager
9
+{
10
+    public static class VisualService
11
+    {
12
+        public static double GetDpiFactor(this Visual target)
13
+        {
14
+            var source = PresentationSource.FromVisual(target);
15
+            return source == null ? 1.0 : 1 / source.CompositionTarget.TransformToDevice.M11;
16
+        }
17
+
18
+        public static T GetAncestor<T>(this DependencyObject target)
19
+            where T : DependencyObject
20
+        {            
21
+            var parent = VisualTreeHelper.GetParent(target);
22
+            if (parent is T)
23
+                return (T)parent;
24
+
25
+            if (parent != null)
26
+                return parent.GetAncestor<T>();
27
+
28
+            return null;
29
+        }
30
+
31
+        public static T GetDesendentChild<T>(this DependencyObject target)
32
+            where T : DependencyObject
33
+        {
34
+            var childCount = VisualTreeHelper.GetChildrenCount(target);
35
+            if (childCount == 0) return null;
36
+
37
+            for (int i = 0; i < childCount; i++)
38
+            {
39
+                var current = VisualTreeHelper.GetChild(target, i);
40
+                if (current is T)
41
+                    return (T)current;
42
+
43
+                var desendent = current.GetDesendentChild<T>();
44
+                if (desendent != null)
45
+                    return desendent;
46
+            }
47
+            return null;
48
+        }
49
+    }
50
+}

+ 43
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ListviewPager/VisualService.ts 查看文件

@@ -0,0 +1,43 @@
1
+// 为了在Vue中模拟WPF的功能,这里需要一些浏览器的API来替代
2
+// 注意:在Vue中,没有直接对应的Visual和DependencyObject概念,这里使用Element和HTMLElement来模拟
3
+
4
+// 获取DPI因子
5
+export const getDpiFactor = (target: HTMLElement): number => {
6
+    const source = window.document.defaultView;
7
+    if (!source) {
8
+        return 1.0;
9
+    }
10
+    const devicePixelRatio = window.devicePixelRatio || 1;
11
+    return 1 / devicePixelRatio;
12
+};
13
+
14
+// 获取指定类型的祖先元素
15
+export const getAncestor = <T extends HTMLElement>(target: HTMLElement): T | null => {
16
+    let parent = target.parentElement;
17
+    if (parent instanceof HTMLElement) {
18
+        if (parent instanceof HTMLElement as unknown as T) {
19
+            return parent as T;
20
+        }
21
+        return getAncestor<T>(parent);
22
+    }
23
+    return null;
24
+};
25
+
26
+// 获取指定类型的后代元素
27
+export const getDesendentChild = <T extends HTMLElement>(target: HTMLElement): T | null => {
28
+    const childCount = target.children.length;
29
+    if (childCount === 0) {
30
+        return null;
31
+    }
32
+    for (let i = 0; i < childCount; i++) {
33
+        const current = target.children[i] as HTMLElement;
34
+        if (current instanceof HTMLElement as unknown as T) {
35
+            return current as T;
36
+        }
37
+        const desendent = getDesendentChild<T>(current);
38
+        if (desendent) {
39
+            return desendent;
40
+        }
41
+    }
42
+    return null;
43
+};

+ 62
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ManageButtonGroup.xaml 查看文件

@@ -0,0 +1,62 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.ManageButtonGroup"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
+             mc:Ignorable="d">
7
+    <StackPanel Margin="10,5,0,5" Orientation="Horizontal">
8
+        <Button x:Name="Button_Add"
9
+                Margin="15,0,0,0"
10
+                HorizontalAlignment="Left"
11
+                Click="Button_Add_Click">
12
+            <Button.Content>
13
+                <StackPanel Orientation="Horizontal">
14
+                    <Image Width="20" Source="/TellerSystem.Resources;Component/img/addChr.png" />
15
+                    <TextBlock Text=" 新增 " />
16
+                </StackPanel>
17
+            </Button.Content>
18
+        </Button>
19
+        <Button x:Name="Button_Modify"
20
+                Margin="15,0,0,0"
21
+                HorizontalAlignment="Left"
22
+                Click="Button_Modify_Click"
23
+                IsEnabled="False">
24
+            <Button.Content>
25
+                <StackPanel Orientation="Horizontal">
26
+                    <Image Width="20" Source="/TellerSystem.Resources;Component/img/edit.png" />
27
+                    <TextBlock Text=" 修改 " />
28
+                </StackPanel>
29
+            </Button.Content>
30
+        </Button>
31
+        <Button x:Name="Button_Del"
32
+                Margin="15,0,0,0"
33
+                HorizontalAlignment="Left"
34
+                Click="Button_Click_del"
35
+                IsEnabled="False">
36
+            <Button.Content>
37
+                <StackPanel Orientation="Horizontal">
38
+                    <Image Width="20" Source="/TellerSystem.Resources;Component/img/del.png" />
39
+                    <TextBlock Text=" 删除 " />
40
+                </StackPanel>
41
+            </Button.Content>
42
+        </Button>
43
+        <Button x:Name="Button_Qry"
44
+                Margin="15,0,0,0"
45
+                HorizontalAlignment="Left"
46
+                Click="Button_Click_Qry"
47
+                IsEnabled="False">
48
+            <Button.Content>
49
+                <StackPanel Orientation="Horizontal">
50
+                    <Image Width="20" Source="/TellerSystem.Resources;Component/img/search.png" />
51
+                    <TextBlock Text=" 查看 " />
52
+                </StackPanel>
53
+            </Button.Content>
54
+        </Button>
55
+
56
+
57
+
58
+
59
+
60
+
61
+    </StackPanel>
62
+</UserControl>

+ 69
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ManageButtonGroup.xaml.cs 查看文件

@@ -0,0 +1,69 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+
15
+namespace TellerSystem.Controls.Ext.Controls
16
+{
17
+    /// <summary>
18
+    /// ManageButtonGroup.xaml 的交互逻辑
19
+    /// </summary>
20
+    public partial class ManageButtonGroup : UserControl
21
+    {
22
+        public delegate void Button_click();
23
+        public  enum Buttonobj { add,del,modify,qry }
24
+        public Button_click ButtonAddClick;
25
+        public Button_click ButtonModifyClick;
26
+        public Button_click ButtonDelClick;
27
+        public Button_click ButtonQryClick;
28
+        public ManageButtonGroup()
29
+        {
30
+            InitializeComponent();
31
+        }
32
+
33
+        private void Button_Add_Click(object sender, RoutedEventArgs e)
34
+        {
35
+            ButtonAddClick();
36
+        }
37
+
38
+        private void Button_Modify_Click(object sender, RoutedEventArgs e)
39
+        {
40
+            ButtonModifyClick();
41
+        }
42
+
43
+        private void Button_Click_del(object sender, RoutedEventArgs e)
44
+        {
45
+            ButtonDelClick();
46
+        }
47
+
48
+        private void Button_Click_Qry(object sender, RoutedEventArgs e)
49
+        {
50
+            ButtonQryClick();
51
+        }
52
+        public void SetButtonVisualbillity(Buttonobj obj,Visibility vb)
53
+        {
54
+            switch (obj)
55
+            {
56
+                case Buttonobj.add: Button_Add.Visibility = vb; break;
57
+                case Buttonobj.del: Button_Del.Visibility = vb; break;
58
+                case Buttonobj.modify: Button_Modify.Visibility = vb; break;
59
+                case Buttonobj.qry: Button_Qry.Visibility = vb; break;
60
+            }
61
+        }
62
+        public void SetButtonEnable(bool isEnable)
63
+        {
64
+            this.Button_Modify.IsEnabled = isEnable;
65
+            this.Button_Del.IsEnabled = isEnable;
66
+            this.Button_Qry.IsEnabled = isEnable;
67
+        }
68
+    }
69
+}

+ 122
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MessageBox/TellerMessageBox.xaml 查看文件

@@ -0,0 +1,122 @@
1
+<Window x:Class="TellerSystem.Controls.Ext.Controls.TellerMessageBox"
2
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+        x:Name="MessageBoxWindow"
5
+        Title="MessageBox"
6
+        MaxWidth="550"
7
+        AllowsTransparency="True"
8
+        Background="Transparent"
9
+        Closing="MessageBoxWindow_Closing"
10
+        Loaded="Window_Loaded"
11
+        MouseDown="Window_MouseDown"
12
+        RenderTransformOrigin="0.5, 0.5"
13
+        ResizeMode="NoResize"
14
+        ShowInTaskbar="False"
15
+        SizeToContent="WidthAndHeight"
16
+        WindowStartupLocation="CenterOwner"
17
+        WindowStyle="None">
18
+    <Window.RenderTransform>
19
+        <ScaleTransform x:Name="Scale" />
20
+    </Window.RenderTransform>
21
+    <Window.Resources>
22
+        <!--  Brushes  -->
23
+        <LinearGradientBrush x:Key="BackgroundBrush" StartPoint="0,0" EndPoint="0,1">
24
+            <GradientStop Offset="0" Color="#E4E9F0" />
25
+            <GradientStop Offset="1" Color="#D5DDED" />
26
+        </LinearGradientBrush>
27
+        <!--  Styles  -->
28
+        <Style TargetType="Label">
29
+            <Setter Property="VerticalContentAlignment" Value="Center" />
30
+            <Setter Property="HorizontalContentAlignment" Value="Left" />
31
+            <Setter Property="FontFamily" Value="Segoe UI" />
32
+            <Setter Property="FontSize" Value="12pt" />
33
+            <Setter Property="Foreground" Value="#FF003399" />
34
+        </Style>
35
+        <Style TargetType="Image">
36
+            <Setter Property="Height" Value="32" />
37
+            <Setter Property="Width" Value="32" />
38
+            <Setter Property="Margin" Value="3" />
39
+        </Style>
40
+        <Style BasedOn="{StaticResource {x:Type Button}}" TargetType="Button">
41
+            <Setter Property="Height" Value="23" />
42
+            <Setter Property="Width" Value="75" />
43
+            <Setter Property="Margin" Value="3" />
44
+
45
+        </Style>
46
+        <!--  Animation  -->
47
+        <Storyboard x:Key="LoadAnimation">
48
+            <DoubleAnimation AccelerationRatio="0.4"
49
+                             Duration="00:00:00.15"
50
+                             From="0.6"
51
+                             Storyboard.TargetName="Scale"
52
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
53
+                             To="1.1" />
54
+            <DoubleAnimation AccelerationRatio="0.4"
55
+                             Duration="00:00:00.15"
56
+                             From="0.6"
57
+                             Storyboard.TargetName="Scale"
58
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
59
+                             To="1.1" />
60
+            <DoubleAnimation AccelerationRatio="0.4"
61
+                             Duration="00:00:00.15"
62
+                             From="0"
63
+                             Storyboard.TargetName="MessageBoxWindow"
64
+                             Storyboard.TargetProperty="(Window.Opacity)"
65
+                             To="1" />
66
+            <DoubleAnimation BeginTime="00:00:00.15"
67
+                             Duration="00:00:00.1"
68
+                             From="1.1"
69
+                             Storyboard.TargetName="Scale"
70
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
71
+                             To="1" />
72
+            <DoubleAnimation BeginTime="00:00:00.15"
73
+                             Duration="00:00:00.1"
74
+                             From="1.1"
75
+                             Storyboard.TargetName="Scale"
76
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
77
+                             To="1" />
78
+        </Storyboard>
79
+        <Storyboard x:Key="UnloadAnimation">
80
+            <DoubleAnimation AccelerationRatio="0.4"
81
+                             Duration="00:00:00.2"
82
+                             From="1"
83
+                             Storyboard.TargetName="Scale"
84
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleX)"
85
+                             To="0.6" />
86
+            <DoubleAnimation AccelerationRatio="0.4"
87
+                             Duration="00:00:00.2"
88
+                             From="1"
89
+                             Storyboard.TargetName="Scale"
90
+                             Storyboard.TargetProperty="(ScaleTransform.ScaleY)"
91
+                             To="0.6" />
92
+            <DoubleAnimation AccelerationRatio="0.4"
93
+                             Duration="00:00:00.2"
94
+                             From="1"
95
+                             Storyboard.TargetName="MessageBoxWindow"
96
+                             Storyboard.TargetProperty="(Window.Opacity)"
97
+                             To="0" />
98
+        </Storyboard>
99
+    </Window.Resources>
100
+    <!--
101
+        Border with Margin = 50 to allow the animation to grow beyond the window's original size.
102
+        If this was omitted the window would just get cropped when it reached it's original size and try to grow
103
+    -->
104
+    <Border Margin="50"
105
+            Background="{StaticResource BackgroundBrush}"
106
+            BorderBrush="CornflowerBlue"
107
+            BorderThickness="2"
108
+            Padding="7">
109
+        <DockPanel LastChildFill="True">
110
+            <!--  placeholder for the buttons  -->
111
+            <StackPanel x:Name="ButtonsPanel"
112
+                        HorizontalAlignment="Center"
113
+                        DockPanel.Dock="Bottom"
114
+                        Orientation="Horizontal" />
115
+            <Image x:Name="ImagePlaceholder" DockPanel.Dock="Left" />
116
+            <!--  The label contains a text block to enable text wrapping  -->
117
+            <Label x:Name="MessageLabel" DockPanel.Dock="Right">
118
+                <TextBlock x:Name="MessageText" TextWrapping="Wrap" />
119
+            </Label>
120
+        </DockPanel>
121
+    </Border>
122
+</Window>

+ 335
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MessageBox/TellerMessageBox.xaml.cs 查看文件

@@ -0,0 +1,335 @@
1
+/*
2
+ * 消息弹出
3
+ * 2014、12、25
4
+ * 郝成阳
5
+ * 
6
+ * 
7
+ * */
8
+using System;
9
+using System.ComponentModel;
10
+using System.Drawing;
11
+using System.Windows;
12
+using System.Windows.Controls;
13
+using System.Windows.Input;
14
+using System.Windows.Media.Animation;
15
+using System.Windows.Media;
16
+
17
+namespace TellerSystem.Controls.Ext.Controls
18
+{
19
+    /// <summary>
20
+    /// 消息弹出
21
+    /// </summary>
22
+    public partial class TellerMessageBox : INotifyPropertyChanged
23
+    {
24
+        
25
+        private bool _animationRan;
26
+
27
+        public TellerMessageBox(string message, MessageBoxButton button, MessageBoxImage icon, string[] buttonConent)
28
+        {
29
+            _animationRan = false;
30
+
31
+            InitializeComponent();
32
+
33
+            Owner = Application.Current.MainWindow;
34
+
35
+            CreateButtons(button, buttonConent);
36
+
37
+            CreateImage(icon);
38
+
39
+            MessageText.Text = message;
40
+        }
41
+        /// <summary>
42
+        /// 提示消息返回值
43
+        /// </summary>
44
+        public MessageBoxResult MessageBoxResult { get; set; }
45
+
46
+        #region INotifyPropertyChanged 成员
47
+
48
+        public event PropertyChangedEventHandler PropertyChanged;
49
+
50
+        #endregion
51
+
52
+        #region 创建按钮
53
+
54
+        /// <summary>
55
+        /// 根据需求创建消息框的按钮
56
+        /// </summary>
57
+        /// <param name="button">按钮选择</param>
58
+        /// <param name="defaultResult"></param>
59
+        private void CreateButtons(MessageBoxButton button, string[] buttonConent)
60
+        {
61
+            switch (button)
62
+            {
63
+                case MessageBoxButton.OK:
64
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[0], MessageBoxResult.OK));
65
+                    break;
66
+                case MessageBoxButton.OKCancel:
67
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[0], MessageBoxResult.OK));
68
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[1], MessageBoxResult.Cancel));
69
+                    break;
70
+                case MessageBoxButton.YesNoCancel:
71
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[0], MessageBoxResult.Yes));
72
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[1], MessageBoxResult.No));
73
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[2], MessageBoxResult.Cancel));
74
+                    break;
75
+                case MessageBoxButton.YesNo:
76
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[0], MessageBoxResult.Yes));
77
+                    ButtonsPanel.Children.Add(CreateButton(buttonConent[1], MessageBoxResult.No));
78
+                    break;
79
+                default:
80
+                    throw new ArgumentOutOfRangeException("button");
81
+            }
82
+        }
83
+
84
+        /// <summary>
85
+        /// 创建按钮
86
+        /// </summary>
87
+        /// <param name="defaultResult"></param>
88
+        /// <param name="content"></param>
89
+        /// <returns></returns>
90
+        private Button CreateButton(string content, MessageBoxResult result)
91
+        {
92
+            var okButton = new Button
93
+                             {
94
+                                 Name = "okButton",
95
+                                 Content = content,
96
+                                 IsDefault = true,
97
+                                 Tag = result,
98
+                             };
99
+
100
+            okButton.Click += ButtonClick;
101
+
102
+            return okButton;
103
+        }
104
+        /// <summary>
105
+        /// 按钮触发事件
106
+        /// </summary>
107
+        /// <param name="sender"></param>
108
+        /// <param name="e"></param>
109
+        private void ButtonClick(object sender, RoutedEventArgs e)
110
+        {
111
+            MessageBoxResult = (MessageBoxResult)(sender as Button).Tag;
112
+
113
+            Close();
114
+        }
115
+
116
+        #endregion
117
+
118
+
119
+
120
+        /// <summary>
121
+        /// 创建图标图像
122
+        /// </summary>
123
+        /// <param name="icon"></param>
124
+        private void CreateImage(MessageBoxImage icon)
125
+        {
126
+            switch (icon)
127
+            {
128
+                case MessageBoxImage.None:
129
+                    ImagePlaceholder.Visibility = Visibility.Collapsed;
130
+                    break;
131
+                case MessageBoxImage.Information:
132
+                    ImagePlaceholder.Source = Application.Current.Resources["MessageBoxMetroInfo"] as ImageSource;
133
+                    break;
134
+                case MessageBoxImage.Question:
135
+                    ImagePlaceholder.Source = Application.Current.Resources["MessageBoxMetroInfo"] as ImageSource;
136
+                    break;
137
+                case MessageBoxImage.Warning:
138
+                    ImagePlaceholder.Source = Application.Current.Resources["MessageBoxMetroWarn"] as ImageSource;
139
+                    break;
140
+                case MessageBoxImage.Error:
141
+                    ImagePlaceholder.Source = Application.Current.Resources["MessageBoxMetroError"] as ImageSource;
142
+                    break;
143
+                default:
144
+                    throw new ArgumentOutOfRangeException("icon");
145
+            }
146
+        }
147
+
148
+        public void OnPropertyChanged(string propertyName)
149
+        {
150
+            PropertyChangedEventHandler temp = PropertyChanged;
151
+            if (temp != null)
152
+            {
153
+                temp(this, new PropertyChangedEventArgs(propertyName));
154
+            }
155
+        }
156
+
157
+        /// <summary>
158
+        ///拖动
159
+        /// </summary>
160
+        /// <param name="sender"></param>
161
+        /// <param name="e"></param>
162
+        private void Window_MouseDown(object sender, MouseButtonEventArgs e)
163
+        {
164
+            DragMove();
165
+        }
166
+
167
+        /// <summary>
168
+        /// 加载显示动画
169
+        /// </summary>
170
+        /// <param name="sender"></param>
171
+        /// <param name="e"></param>
172
+        private void Window_Loaded(object sender, RoutedEventArgs e)
173
+        {
174
+            // 这是在设定高度后的宽度
175
+            SizeToContent = SizeToContent.Height;
176
+
177
+            var animation = TryFindResource("LoadAnimation") as Storyboard;
178
+
179
+            animation.Begin(this);
180
+        }
181
+
182
+        /// <summary>
183
+        /// 关闭动画显示
184
+        /// </summary>
185
+        /// <param name="sender"></param>
186
+        /// <param name="e"></param>
187
+        private void MessageBoxWindow_Closing(object sender, CancelEventArgs e)
188
+        {
189
+            if (!_animationRan)
190
+            {
191
+                e.Cancel = true;
192
+
193
+                var animation = TryFindResource("UnloadAnimation") as Storyboard;
194
+
195
+                animation.Completed += AnimationCompleted;
196
+
197
+                animation.Begin(this);
198
+            }
199
+        }
200
+
201
+        /// <summary>
202
+        /// 信号关闭动画并关闭窗口
203
+        /// </summary>
204
+        /// <param name="sender"></param>
205
+        /// <param name="e"></param>
206
+        private void AnimationCompleted(object sender, EventArgs e)
207
+        {
208
+            _animationRan = true;
209
+
210
+            Close();
211
+        }
212
+
213
+        #region 消息提醒
214
+        /// <summary>
215
+        /// 消息提醒
216
+        /// </summary>
217
+        /// <param name="message"></param>
218
+        /// <returns></returns>
219
+        public static MessageBoxResult ShowInfoMessageBox(string message)
220
+        {
221
+            return Show(message, new []{"确定"},MessageBoxButton.OK,
222
+                       MessageBoxImage.Information, MessageBoxResult.OK);
223
+        }
224
+        /// <summary>
225
+        /// 自定义消息提醒
226
+        /// </summary>
227
+        /// <param name="message"></param>
228
+        /// <param name="details"></param>
229
+        /// <param name="showCancel"></param>
230
+        /// <param name="options"></param>
231
+        /// <returns></returns>
232
+        public static MessageBoxResult ShowInfoMessageBox(string message, string[] buttonConent, MessageBoxButton button)
233
+        {
234
+            return Show(message, buttonConent, button,
235
+                       MessageBoxImage.Information, MessageBoxResult.OK);
236
+        }
237
+        #endregion
238
+
239
+        #region 询问消息提醒
240
+        /// <summary>
241
+        /// 询问消息
242
+        /// </summary>
243
+        /// <param name="message"></param>
244
+        /// <param name="details"></param>
245
+        /// <param name="showCancel"></param>
246
+        /// <param name="options"></param>
247
+        /// <returns></returns>
248
+        public static MessageBoxResult ShowQuestion(string message, string[] buttonConent, MessageBoxButton button)
249
+        {
250
+            return Show(message, buttonConent, button,
251
+                     MessageBoxImage.Question, MessageBoxResult.Yes);
252
+        }
253
+        #endregion
254
+
255
+        #region 警告消息
256
+
257
+        /// <summary>
258
+        /// 提示警告消息
259
+        /// </summary>
260
+        /// <param name="message"></param>
261
+        /// <param name="details"></param>
262
+        /// <param name="showCancel"></param>
263
+        /// <param name="options"></param>
264
+        /// <returns></returns>
265
+        public static MessageBoxResult ShowWarning(string message, string[] buttonConent, MessageBoxButton button)
266
+        {
267
+            return Show(message, buttonConent, button,
268
+                        MessageBoxImage.Warning, MessageBoxResult.OK);
269
+        }
270
+        #endregion
271
+
272
+        #region 错误信息
273
+        /// <summary>
274
+        /// 错误消息提示
275
+        /// </summary>
276
+        /// <param name="message"></param>
277
+        /// <param name="details"></param>
278
+        /// <param name="showCancel"></param>
279
+        /// <param name="options"></param>
280
+        /// <returns></returns>
281
+        public static MessageBoxResult ShowError(string message, MessageBoxButton button = MessageBoxButton.OK)
282
+        {
283
+            return Show(message, new string[] { "确定" }, button,
284
+                       MessageBoxImage.Error, MessageBoxResult.OK);
285
+        }
286
+        #endregion
287
+
288
+        #region 弹出
289
+        /// <summary>
290
+        /// 显示消息对话框
291
+        /// </summary>
292
+        /// <param name="owner">该消息框的父窗口</param>
293
+        /// <param name="message">消息文本</param>
294
+        /// <param name="button">要显示的按钮</param>
295
+        /// <param name="icon">消息图标</param>
296
+        /// <param name="defaultResult">默认返回值</param>
297
+        /// <param name="options">消息类型</param>
298
+        /// <returns></returns>
299
+        public static MessageBoxResult Show(string message, string[] buttonConent,
300
+                                            MessageBoxButton button,
301
+                                            MessageBoxImage icon = MessageBoxImage.None,
302
+                                            MessageBoxResult defaultResult = MessageBoxResult.None)
303
+        {
304
+            return ShowDialog(message, buttonConent, button, icon);
305
+        }
306
+
307
+        /// <summary>
308
+        /// 显示指定的参数消息框
309
+        /// </summary>
310
+        /// <param name="owner">该消息框的父窗口</param>
311
+        /// <param name="message">消息文本</param>
312
+        /// <param name="details">其他文本</param>
313
+        /// <param name="button">要显示的按钮</param>
314
+        /// <param name="icon">消息图标</param>
315
+        /// <param name="defaultResult">默认返回值</param>
316
+        /// <param name="options">消息类型</param>
317
+        /// <returns>选择的按钮</returns>
318
+        public static MessageBoxResult ShowDialog(string message, string[] buttonConent,
319
+                                            MessageBoxButton button, MessageBoxImage icon = MessageBoxImage.None)
320
+        {
321
+            var result = Application.Current.Dispatcher.Invoke(new Func<MessageBoxResult>(() =>
322
+            {
323
+                var messageBox = new TellerMessageBox(message, button, icon, buttonConent);
324
+
325
+                messageBox.ShowDialog();
326
+
327
+                return messageBox.MessageBoxResult;
328
+            }));
329
+
330
+            return result is MessageBoxResult ? (MessageBoxResult)result : MessageBoxResult.None;
331
+        }
332
+
333
+        #endregion
334
+    }
335
+}

+ 95
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MobilePhoneCheckViewer.xaml 查看文件

@@ -0,0 +1,95 @@
1
+<tp:BlankTradePage x:Class="TellerSystem.Controls.Ext.Controls.MobilePhoneCheckViewer"
2
+                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                   xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                   xmlns:dhcc="http://www.dhcc.com.cn"
6
+                   xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
7
+                   xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8
+                   xmlns:tp="clr-namespace:TellerSystem.Controls.Ext.TradePageBase"
9
+                   dhcc:FocusManager.EnableFocusControl="True"
10
+                   FontFamily="Simsun"
11
+                   Loaded="TradePage_Loaded"
12
+                   mc:Ignorable="d">
13
+    <StackPanel VerticalAlignment="Top">
14
+        <local:TradePanel x:Name="xxinfo"
15
+                          Height="150"
16
+                          Header="手机号三要素核验">
17
+            <TextBlock Text="手机号" />
18
+            <TextBox Name="zikrsjh"
19
+                     Width="180"
20
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
21
+                     dhcc:TextBoxHelper.IsShowLength="True"
22
+                     IsEnabled="False" />
23
+            <TextBlock Text="是否号主本人" />
24
+            <ComboBox x:Name="isBr"
25
+                      Width="180"
26
+                      dhcc:FocusManager.LostFocus="isBr_LostFocus"
27
+                      dhcc:FocusManagerExt.AssertNotEmpty="True" />
28
+            <TextBlock Text="姓名" />
29
+            <TextBox x:Name="zikrxm"
30
+                     Width="180"
31
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
32
+                     IsEnabled="False" />
33
+            <TextBlock Text="身份证号" />
34
+            <TextBox x:Name="zikrsfzh"
35
+                     Width="180"
36
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
37
+                     dhcc:TextBoxHelper.InputType="IDCard"
38
+                     dhcc:TextBoxHelper.IsShowLength="True"
39
+                     IsEnabled="False"
40
+                     MaxLength="18" />
41
+            <TextBlock x:Name="tbhzxm"
42
+                       Text="号主姓名"
43
+                       Visibility="Collapsed" />
44
+            <TextBox x:Name="hzxm"
45
+                     Width="180"
46
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
47
+                     Visibility="Collapsed" />
48
+            <TextBlock x:Name="tbhzsfzh"
49
+                       Text="号主身份证号"
50
+                       Visibility="Collapsed" />
51
+            <TextBox x:Name="hzsfzh"
52
+                     Width="180"
53
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
54
+                     dhcc:TextBoxHelper.InputType="IDCard"
55
+                     dhcc:TextBoxHelper.IsShowLength="True"
56
+                     MaxLength="18"
57
+                     Visibility="Collapsed" />
58
+            <TextBlock Name="tbbz"
59
+                       Text="关系备注"
60
+                       Visibility="Collapsed" />
61
+            <TextBox x:Name="bz"
62
+                     Width="480"
63
+                     dhcc:FocusManagerExt.AssertNotEmpty="True"
64
+                     MaxLength="18"
65
+                     Visibility="Collapsed" />
66
+        </local:TradePanel>
67
+        <StackPanel Margin="5"
68
+                    FlowDirection="RightToLeft"
69
+                    Orientation="Horizontal">
70
+            <Button x:Name="btnBack"
71
+                    Width="80"
72
+                    Height="25"
73
+                    Click="btnBack_Click"
74
+                    Content="返  回" />
75
+            <Button x:Name="btnCheck"
76
+                    Width="80"
77
+                    Height="25"
78
+                    Click="btnCheck_Click"
79
+                    Content="查  验" />
80
+        </StackPanel>
81
+        <local:TradePanel Height="96" Header="核查结果">
82
+            <TextBlock Text="查验结果" />
83
+            <TextBox x:Name="hdjg"
84
+                     Width="300"
85
+                     IsEnabled="False"
86
+                     local:TradePanel.ColumnSpan="3" />
87
+            <TextBlock Text="运营商" />
88
+            <TextBox x:Name="yys"
89
+                     Width="300"
90
+                     IsEnabled="False"
91
+                     local:TradePanel.ColumnSpan="3" />
92
+        </local:TradePanel>
93
+    </StackPanel>
94
+
95
+</tp:BlankTradePage>

+ 148
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MobilePhoneCheckViewer.xaml.cs 查看文件

@@ -0,0 +1,148 @@
1
+using System;
2
+using System.Windows;
3
+using System.Windows.Media;
4
+using System.Windows.Media.Imaging;
5
+using System.IO;
6
+using System.Text.RegularExpressions;
7
+using Platform.Controls.ControlsHelper;
8
+using Platform.Library;
9
+using TellerSystem.Communication;
10
+using TellerSystem.Library.Ext.Function;
11
+using Platform.Common.RunningParameters;
12
+using TellerSystem.ServiceProxy.Ext.ServiceEntitys;
13
+using TellerSystem.Devices.Interface;
14
+using TellerSystem.Library.Ext.Variables;
15
+using TellerSystem.Controls.Ext.PrintsHelper;
16
+using TellerSystem.Library.Ext.TradeExtension;
17
+using TellerSystem.PrintTemplate.Extension;
18
+using System.Windows.Controls;
19
+using System.Printing;
20
+using Platform.Print;
21
+using TellerSystem.ServiceProxy.Ext.ServiceHelper;
22
+using System.Collections.Generic;
23
+using System.Drawing;
24
+using System.ComponentModel;
25
+using TellerSystem.ServiceProxy.Ext;
26
+using TellerSystem.Controls.Ext.ControlsHelper;
27
+using System.Diagnostics;
28
+using System.Text;
29
+using TellerSystem.ServiceProxy.Ext.WebAPI.Auth.Entity;
30
+using System.Net;
31
+using System.Net.Cache;
32
+using Newtonsoft.Json;
33
+using Newtonsoft.Json.Linq;
34
+using TellerSystem.Contract.Function;
35
+
36
+/******************************平台Dll*****************************/
37
+
38
+namespace TellerSystem.Controls.Ext.Controls
39
+{
40
+    /// <summary>
41
+    /// PhoneElement.xaml 的交互逻辑
42
+    /// </summary>
43
+    public partial class MobilePhoneCheckViewer
44
+    {
45
+        #region Ctor
46
+
47
+        public MobilePhoneCheckViewer(string idno, string name, string phone)
48
+        {
49
+            _idCard = idno;
50
+            _name = name;
51
+            _phone = phone;
52
+            InitializeComponent();
53
+            Result = false;
54
+        }
55
+        private string _idCard;
56
+        private string _name;
57
+        private string _phone;
58
+
59
+        private void TradePage_Loaded(object sender, RoutedEventArgs e)
60
+        {
61
+            /* 初始化界面逻辑,页面加载后执行*/
62
+            zikrxm.Text = _name;
63
+            zikrsjh.Text = _phone;
64
+            zikrsfzh.Text = _idCard;
65
+            isBr.SetItems(new Dictionary<string, string> { { "是", "1" }, { "否", "0" } });
66
+            xxinfo.Height = 90;
67
+            Window.GetWindow(this).Closing += (s1, e1) =>
68
+            {
69
+                e1.Cancel = !Result && this.TradeAPIs.ShowQuestionMessageBox("当前手机号码三要素查验未完成,确认继续业务?") != MessageBoxResult.Yes;
70
+            };
71
+        }
72
+        #endregion
73
+
74
+        private void btnBack_Click(object sender, RoutedEventArgs e)
75
+        {
76
+            this.Close();
77
+        }
78
+
79
+        private void btnCheck_Click(object sender, RoutedEventArgs e)
80
+        {
81
+            AICapacity.Resp resp = null;
82
+            AICapacity.ExtData ext = new AICapacity.ExtData(this.CreateSerialNumber(), new Dictionary<string, string>
83
+                {
84
+                    {"idno",_idCard},
85
+                    {"name",_name},
86
+                    {"phone",_phone},
87
+                    {"self","是"},
88
+                });
89
+            if (isBr.GetSelectedKey() == "否")
90
+            {
91
+                _name = hzxm.Text;
92
+                _idCard = hzsfzh.Text;
93
+                ext.ExtInfo["self"] = "否";
94
+                ext.ExtInfo["other"] = bz.Text;
95
+                ext.ExtInfo["oname"] = _name;
96
+                ext.ExtInfo["oidno"] = _idCard;
97
+            }
98
+            this.OwnerContainer.ModalInvoke(new Action(() =>
99
+            {
100
+                resp = AICapacity.GetInstence().AIRequest2Universal("PhoneVerification"
101
+                , new Dictionary<string, object>
102
+                    {
103
+                        {"IdCard",_idCard},
104
+                        {"Name",_name},
105
+                        {"Phone",_phone},
106
+                    }, ext);
107
+            }), "正在手机号三要素核验中...");
108
+            if (resp == null)
109
+            {
110
+                this.TradeAPIs.ShowErrorMessageBox("调用失败,请检查网络并重试!");
111
+                return;
112
+            }
113
+            if (resp.HasError)
114
+            {
115
+                hdjg.Text = resp.ErrorMsg;
116
+                yys.Text = string.Empty;
117
+            }
118
+            else
119
+            {
120
+                var dict = resp.Value("data.result.responseJson", new Dictionary<string, string> { });
121
+                Result = dict["Result"] == "0";
122
+                hdjg.Text = dict["Description"];
123
+                yys.Text = dict["Isp"];
124
+            }
125
+        }
126
+
127
+        public bool Result { get; private set; }
128
+
129
+        private void isBr_LostFocus(object sender, RoutedEventArgs e)
130
+        {
131
+            if (isBr.GetSelectedValue() == "0")
132
+            {
133
+                bz.Visibility = tbbz.Visibility = tbhzxm.Visibility = hzxm.Visibility = tbhzsfzh.Visibility = hzsfzh.Visibility = Visibility.Visible;
134
+                xxinfo.Height = 150;
135
+            }
136
+            else
137
+            {
138
+                bz.Visibility = tbbz.Visibility = tbhzxm.Visibility = hzxm.Visibility = tbhzsfzh.Visibility = hzsfzh.Visibility = Visibility.Collapsed;
139
+                xxinfo.Height = 90;
140
+            }
141
+        }
142
+    }
143
+}
144
+
145
+
146
+
147
+
148
+

+ 12
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MoneyGrid.xaml 查看文件

@@ -0,0 +1,12 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.MoneyGrid"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
+             d:DesignHeight="300"
7
+             d:DesignWidth="300"
8
+             mc:Ignorable="d">
9
+    <UniformGrid Name="UG_DataHost"
10
+                 Columns="11"
11
+                 Rows="1" />
12
+</UserControl>

+ 84
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MoneyGrid.xaml.cs 查看文件

@@ -0,0 +1,84 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+
15
+namespace TellerSystem.Controls.Ext.Controls
16
+{
17
+    /// <summary>
18
+    /// MoneyGrid.xaml 的交互逻辑
19
+    /// </summary>
20
+    public partial class MoneyGrid : UserControl
21
+    {
22
+        public MoneyGrid()
23
+        {
24
+            InitializeComponent();
25
+        }
26
+
27
+        public bool SetText(string text)
28
+        {
29
+            decimal d;
30
+            if (decimal.TryParse(text.Replace(",", "").Replace(",", ""), out d))
31
+            {
32
+                Val = d;
33
+                return true;
34
+            }
35
+            return false;
36
+        }
37
+
38
+        public string Text
39
+        {
40
+            set
41
+            {
42
+                decimal d;
43
+                if (decimal.TryParse(value.Replace(",", "").Replace(",", ""), out d))
44
+                {
45
+                    Val = d;
46
+                }
47
+            }
48
+        }
49
+
50
+        private decimal _val;
51
+        /// <summary>
52
+        /// 显示金额
53
+        /// </summary>
54
+        public decimal Val
55
+        {
56
+            get { return _val; }
57
+            set
58
+            {
59
+                _val = value;
60
+                Refresh();
61
+            }
62
+        }
63
+
64
+        private void Refresh()
65
+        {
66
+            //扩大100倍,舍弃多余部分
67
+            //TODO:四舍五入
68
+            var value = decimal.Truncate(Val * 100).ToString();
69
+            //超出亿位
70
+            if (value.Length > 11)
71
+            {
72
+                value = "数据错误,无法正常显示";
73
+            }
74
+            else if (value.Length < 11)
75
+            {
76
+                value = ("¥" + value).PadLeft(11, ' ');
77
+            }
78
+            foreach (var item in value)
79
+            {
80
+                UG_DataHost.Children.Add(new TextBlock { Text = item.ToString(), TextAlignment = TextAlignment.Center, VerticalAlignment = System.Windows.VerticalAlignment.Center });
81
+            }
82
+        }
83
+    }
84
+}

+ 110
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MultiSelectComboBox.xaml 查看文件

@@ -0,0 +1,110 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.MultiSelectComboBox"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
5
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
6
+             xmlns:dhcc="http://www.dhcc.com.cn"
7
+            dhcc:FocusManager.IsInternalKeyboardControlling="True"
8
+             dhcc:FocusManagerExt.IsFocusAdorner="True"
9
+             dhcc:FocusManagerExt.ValidationField="SelectedValueList"
10
+             x:Name="multiSelectComboBox"
11
+             mc:Ignorable="d"  Height="23" Width="120" >
12
+    <UserControl.Resources>
13
+        <Style TargetType="{x:Type TreeViewItem}">
14
+            <Setter Property="Background" Value="Transparent" />
15
+            <Setter Property="OverridesDefaultStyle" Value="True" />
16
+            <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
17
+            <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
18
+            <Setter Property="Padding" Value="1,0,0,0" />
19
+            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
20
+            <Setter Property="FocusVisualStyle" Value="{StaticResource TreeViewItemFocusVisual}" />
21
+            <Setter Property="Template">
22
+                <Setter.Value>
23
+                    <ControlTemplate TargetType="{x:Type TreeViewItem}">
24
+                        <Grid>
25
+                            <Grid.ColumnDefinitions>
26
+                                <ColumnDefinition Width="Auto" MinWidth="19" />
27
+                                <ColumnDefinition Width="Auto" />
28
+                                <ColumnDefinition Width="*" />
29
+                            </Grid.ColumnDefinitions>
30
+                            <Grid.RowDefinitions>
31
+                                <RowDefinition Height="18" />
32
+                                <RowDefinition />
33
+                            </Grid.RowDefinitions>
34
+                            <ToggleButton x:Name="Expander"
35
+                                          ClickMode="Press"
36
+                                          IsChecked="{Binding Path=IsExpanded,
37
+                                                              RelativeSource={RelativeSource TemplatedParent}}"
38
+                                          Style="{StaticResource ExpandCollapseToggleStyle}" />
39
+                            <Border Name="Bd"
40
+                                    Grid.Column="1"
41
+                                    Background="{TemplateBinding Background}"
42
+                                    BorderBrush="{TemplateBinding BorderBrush}"
43
+                                    BorderThickness="{TemplateBinding BorderThickness}"
44
+                                    Padding="{TemplateBinding Padding}">
45
+                                <ContentPresenter x:Name="PART_Header"
46
+                                                  HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
47
+                                                  ContentSource="Header" />
48
+                            </Border>
49
+                            <ItemsPresenter x:Name="ItemsHost"
50
+                                            Grid.Row="1"
51
+                                            Grid.Column="1"
52
+                                            Grid.ColumnSpan="2" />
53
+                        </Grid>
54
+                        <ControlTemplate.Triggers>
55
+                            <Trigger Property="IsExpanded" Value="false">
56
+                                <Setter TargetName="ItemsHost" Property="Visibility" Value="Collapsed" />
57
+                            </Trigger>
58
+                            <Trigger Property="HasItems" Value="false">
59
+                                <Setter TargetName="Expander" Property="Visibility" Value="Hidden" />
60
+                            </Trigger>
61
+                            <MultiTrigger>
62
+                                <MultiTrigger.Conditions>
63
+                                    <Condition Property="HasHeader" Value="false" />
64
+                                    <Condition Property="Width" Value="Auto" />
65
+                                </MultiTrigger.Conditions>
66
+                                <Setter TargetName="PART_Header" Property="MinWidth" Value="75" />
67
+                            </MultiTrigger>
68
+                            <MultiTrigger>
69
+                                <MultiTrigger.Conditions>
70
+                                    <Condition Property="HasHeader" Value="false" />
71
+                                    <Condition Property="Height" Value="Auto" />
72
+                                </MultiTrigger.Conditions>
73
+                                <Setter TargetName="PART_Header" Property="MinHeight" Value="19" />
74
+                            </MultiTrigger>
75
+                            <Trigger Property="IsSelected" Value="true">
76
+                                <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" />
77
+                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
78
+                            </Trigger>
79
+                            <MultiTrigger>
80
+                                <MultiTrigger.Conditions>
81
+                                    <Condition Property="IsSelected" Value="true" />
82
+                                    <Condition Property="IsSelectionActive" Value="false" />
83
+                                </MultiTrigger.Conditions>
84
+                                <Setter TargetName="Bd" Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
85
+                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
86
+                            </MultiTrigger>
87
+                            <Trigger Property="IsEnabled" Value="false">
88
+                                <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
89
+                            </Trigger>
90
+                        </ControlTemplate.Triggers>
91
+                    </ControlTemplate>
92
+                </Setter.Value>
93
+            </Setter>
94
+        </Style>
95
+        <HierarchicalDataTemplate x:Key="TreeViewTemplate" ItemsSource="{Binding Children}">
96
+            <CheckBox Content="{Binding Path=Title}" IsChecked="{Binding IsSelected}" Click="checkbox_Click" Style="{x:Null}"></CheckBox>
97
+        </HierarchicalDataTemplate>
98
+    </UserControl.Resources>
99
+    <dhcc:FocusManagerExt.FieldEmptyPolicies>
100
+        <dhcc:FieldPolicyCollection>
101
+            <dhcc:ShowTipPolicy />
102
+        </dhcc:FieldPolicyCollection>
103
+    </dhcc:FocusManagerExt.FieldEmptyPolicies>
104
+    <Border>
105
+        <ComboBox Style="{x:Null}" Name="combobox" Width="{Binding Width, ElementName=multiSelectComboBox}" >
106
+            <TreeView Name="tree"  ItemTemplate="{StaticResource TreeViewTemplate}" MinWidth="{Binding Width, ElementName=combobox}" MaxHeight="260"  >
107
+            </TreeView>
108
+        </ComboBox>
109
+    </Border>
110
+</UserControl>

+ 391
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/MultiSelectComboBox.xaml.cs 查看文件

@@ -0,0 +1,391 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using System.ComponentModel;
15
+using System.Collections;
16
+using System.Xml.Linq;
17
+using Platform.Presentation.FocusManagers;
18
+using Platform.Common.BasicFunctions;
19
+
20
+namespace TellerSystem.Controls.Ext.Controls
21
+{
22
+    public partial class MultiSelectComboBox : UserControl
23
+    {
24
+        public MultiSelectComboBox()
25
+        {
26
+            InitializeComponent();
27
+            this.PreviewKeyDown += new System.Windows.Input.KeyEventHandler(MultiSelectComboBox_PreviewKeyDown);
28
+            this.Loaded += new RoutedEventHandler(MultiSelectComboBox_Loaded);
29
+        }
30
+
31
+        #region 字段
32
+        StringBuilder _sb = new StringBuilder();
33
+        StringBuilder _sb1 = new StringBuilder();
34
+        private Platform.Presentation.FocusManagers.FocusManager _focus;
35
+        #endregion
36
+
37
+        #region 属性
38
+        public string SelectedValueList
39
+        {
40
+            get { return (string)GetValue(SelectedValueListProperty); }
41
+            private set { SetValue(SelectedValueListProperty, value); }
42
+        }
43
+
44
+        public static readonly DependencyProperty SelectedValueListProperty =
45
+            DependencyProperty.Register("SelectedValueList", typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty));
46
+
47
+        public string SelectedValue
48
+        {
49
+            get
50
+            {
51
+                return _sb1.Length == 0 ? string.Empty : _sb1.ToString(1, _sb1.Length - 1);
52
+            }
53
+            set
54
+            {
55
+                ClearSelectedValue();
56
+                var select = (value ?? string.Empty).Split(',');
57
+                if (select.Length == 0) return;
58
+                var nodeList = tree.ItemsSource as IEnumerable<MultiSelectComboBoxNode>;
59
+                if (nodeList == null) return;
60
+                foreach (var item in select)
61
+                {
62
+                    nodeList.ToList().ForEach(x =>
63
+                    {
64
+                        SetSelectedValue(x, item);
65
+
66
+                    });
67
+                }
68
+                Refresh();
69
+            }
70
+        }
71
+        #endregion
72
+
73
+        #region 方法
74
+
75
+        /// <summary>
76
+        /// 为该控件指定数据源
77
+        /// </summary>
78
+        /// <param name="data">可迭代的数据源</param>
79
+        public void SetItems(IEnumerable data)
80
+        {
81
+            //组装数据源
82
+            var source = new List<MultiSelectComboBoxNode>();
83
+            var items = data.Cast<KeyValuePair<string, string>>();
84
+            foreach (var item in items)
85
+            {
86
+                source.Add(new MultiSelectComboBoxNode { Title = item.Key, Value = item.Value, IsSelected = false });
87
+            }
88
+            tree.ItemsSource = source;
89
+        }
90
+
91
+        /// <summary>
92
+        /// 为该控件指定形如XML的数据源
93
+        /// </summary>
94
+        /// <param name="xmlData">可转化为XML的数据</param>
95
+        /// <param name="nodeName">一级结点标签名</param>
96
+        /// <param name="titleName">结点标签对应的Title属性名称</param>
97
+        /// <param name="valueName">结点标签对应的Value属性名称</param>
98
+        public void SetItems(string xmlData, string nodeName = "org", string titleName = "name", string valueName = "id")
99
+        {
100
+            XDocument doc = XDocument.Parse(xmlData);
101
+            XElement root = doc.Root;
102
+            var elements = root.Elements(nodeName);
103
+            var source = new List<MultiSelectComboBoxNode>();
104
+            foreach (var element in elements)
105
+            {
106
+                source.Add(CreateTopLevelNode(element, nodeName, titleName, valueName));
107
+            }
108
+            tree.ItemsSource = source;
109
+        }
110
+
111
+        /// <summary>
112
+        /// 设置选中结点的值
113
+        /// </summary>
114
+        /// <param name="value">选中结点的值</param>
115
+        public void Setvalue(string value)
116
+        {
117
+            this.SelectedValue = value;
118
+        }
119
+
120
+        /// <summary>
121
+        /// 根据给定的value值对相应的叶子结点进行勾选
122
+        /// </summary>
123
+        /// <param name="node">一级结点</param>
124
+        /// <param name="value">给定的Value值</param>
125
+        private void SetSelectedValue(MultiSelectComboBoxNode node, string value)
126
+        {
127
+
128
+            if (node.Children.Count > 0)
129
+            {
130
+                foreach (var item in node.Children)
131
+                {
132
+                    SetSelectedValue(item, value);
133
+                }
134
+            }
135
+            else//叶子节点
136
+            {
137
+                if (node.Value == value)
138
+                {
139
+                    node.IsSelected = true;
140
+                    SetParentState(node);
141
+                }
142
+            }
143
+
144
+        }
145
+
146
+        void MultiSelectComboBox_Loaded(object sender, RoutedEventArgs e)
147
+        {
148
+            if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;
149
+            _focus = Platform.Presentation.FocusManagers.FocusManager.GetManagerInstance((DependencyObject)this) as Platform.Presentation.FocusManagers.FocusManager;
150
+            //if (_focus == null) return;
151
+            combobox.SetBinding(ComboBox.ToolTipProperty, new Binding("SelectedValueList") { Source = this, Mode = BindingMode.OneWay });
152
+            var child = VisualTreeHelper.GetChild(combobox, 0);
153
+            var children=  child.FindVisualTreeChildren((x) => { return (x is ContentPresenter); });
154
+            if (children != null)
155
+            {
156
+                var cp = children[0] as ContentPresenter;
157
+                if (cp != null)
158
+                {
159
+                    cp.ContentTemplate = null;
160
+                    cp.SetBinding(ContentPresenter.ContentProperty, new Binding("SelectedValueList") { Source = this, Mode = BindingMode.OneWay });
161
+                }
162
+            }
163
+           
164
+        }
165
+
166
+        private void checkbox_Click(object sender, RoutedEventArgs e)
167
+        {
168
+            var node = (sender as CheckBox).DataContext as MultiSelectComboBoxNode;
169
+            SelectCascade(node);
170
+            SetParentState(node);
171
+            Refresh();
172
+        }
173
+
174
+        void MultiSelectComboBox_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
175
+        {
176
+
177
+            if (e.Key == Key.Up)
178
+            {
179
+                _focus.MoveFocus(FocusNavigation.Backward);
180
+            }
181
+            else if (e.Key == Key.Down || e.Key == Key.Tab || e.Key == Key.Enter)
182
+            {
183
+
184
+                _focus.MoveFocus(FocusNavigation.Forward);
185
+            }
186
+            else if (e.Key == Key.Left)
187
+            {
188
+
189
+                _focus.MoveFocus(FocusNavigation.Backward);
190
+            }
191
+            else if (e.Key == Key.Right)
192
+            {
193
+
194
+                _focus.MoveFocus(FocusNavigation.Forward);
195
+            }
196
+        }
197
+
198
+        /// <summary>
199
+        /// 用递归算法根据XML元素生成第一级节点(含子节点)
200
+        /// </summary>
201
+        /// <param name="ele">指定的XML元素</param>
202
+        /// <returns></returns>
203
+        private MultiSelectComboBoxNode CreateTopLevelNode(XElement ele, string nodeName, string titleName, string valueName)
204
+        {
205
+
206
+            if (ele.Elements(nodeName).Count() > 0)
207
+            {
208
+                MultiSelectComboBoxNode node = new MultiSelectComboBoxNode() { Title = ele.Attribute(titleName).Value, Value = ele.Attribute(valueName).Value, IsSelected = false };
209
+                foreach (var item in ele.Elements(nodeName))
210
+                {
211
+                    var childNode = CreateTopLevelNode(item, nodeName, titleName, valueName);
212
+                    childNode.Parent = node;
213
+                    node.Children.Add(childNode);
214
+                }
215
+                return node;
216
+            }
217
+            else
218
+            {
219
+                MultiSelectComboBoxNode node = new MultiSelectComboBoxNode() { Title = ele.Attribute(titleName).Value, Value = ele.Attribute(valueName).Value, IsSelected = false };
220
+                return node;
221
+            }
222
+        }
223
+
224
+        /// <summary>
225
+        /// 根据指点结点寻找所有选中的叶子节点
226
+        /// </summary>
227
+        /// <param name="node"></param>
228
+        private void FindSelectedLeaf(MultiSelectComboBoxNode node)
229
+        {
230
+            if (node.Children.Count > 0)
231
+            {
232
+                foreach (var item in node.Children)
233
+                {
234
+                    FindSelectedLeaf(item);
235
+                }
236
+            }
237
+            else//叶子节点
238
+            {
239
+                if (node.IsSelected == true)
240
+                {
241
+                    _sb.Append("," + node.Title);
242
+                    _sb1.Append("," + node.Value);
243
+                }
244
+            }
245
+        }
246
+
247
+        /// <summary>
248
+        /// 撤消或选中指点结点本身及其所有子结点
249
+        /// </summary>
250
+        /// <param name="node">指定的结点</param>
251
+        private void SelectCascade(MultiSelectComboBoxNode node)
252
+        {
253
+            if (node.Children.Count > 0)
254
+            {
255
+                node.Children.ForEach(x =>
256
+                {
257
+                    x.IsSelected = node.IsSelected;
258
+                    SelectCascade(x);
259
+                });
260
+            }
261
+        }
262
+
263
+        private void SetParentState(MultiSelectComboBoxNode node)
264
+        {
265
+            if (node.Parent != null)
266
+            {
267
+                MultiSelectComboBoxNode parent = node.Parent;
268
+                if (parent.Children.All(x => { return x.IsSelected == true; }))
269
+                {
270
+                    parent.IsSelected = true;
271
+                }
272
+
273
+                else if (parent.Children.All(x => { return x.IsSelected == false; }))
274
+                {
275
+                    parent.IsSelected = false;
276
+                }
277
+
278
+                else
279
+                {
280
+                    parent.IsSelected = null;
281
+                }
282
+                SetParentState(parent);
283
+            }
284
+        }
285
+
286
+        private void Refresh()
287
+        {
288
+            _sb.Clear();
289
+            _sb1.Clear();
290
+            SelectedValueList = string.Empty;
291
+            var nodeList = tree.ItemsSource as IEnumerable<MultiSelectComboBoxNode>;
292
+            if (nodeList != null)
293
+            {
294
+                nodeList.ToList().ForEach(x =>
295
+                {
296
+
297
+                    FindSelectedLeaf(x);
298
+                });
299
+                SelectedValueList = _sb.Length == 0 ? string.Empty : _sb.ToString(1, _sb.Length - 1);
300
+            }
301
+        }
302
+
303
+        /// <summary>
304
+        /// 通过SelectedValue属性设置选中项时,要将数据源中的所有选项的IsSelected属性置为false
305
+        /// </summary>
306
+        private void ClearSelectedValue()
307
+        {
308
+            var nodeList = tree.ItemsSource as IEnumerable<MultiSelectComboBoxNode>;
309
+            if (nodeList != null)
310
+            {
311
+                foreach (var node in nodeList)
312
+                {
313
+                    node.IsSelected = false;
314
+                    SelectCascade(node);
315
+                }
316
+                Refresh();
317
+            }
318
+        }
319
+        #endregion
320
+
321
+    }
322
+
323
+    public class MultiSelectComboBoxNode : INotifyPropertyChanged
324
+    {
325
+        public MultiSelectComboBoxNode()
326
+        {
327
+            Children = new List<MultiSelectComboBoxNode>();
328
+
329
+        }
330
+        #region 属性
331
+
332
+        private string title;
333
+
334
+        public string Title
335
+        {
336
+            get { return title; }
337
+            set
338
+            {
339
+                title = value;
340
+                NotifyPropertyChanged("Title");
341
+            }
342
+        }
343
+
344
+        private string value;
345
+
346
+        public string Value
347
+        {
348
+            get { return value; }
349
+            set
350
+            {
351
+                this.value = value;
352
+                NotifyPropertyChanged("Value");
353
+            }
354
+        }
355
+
356
+
357
+
358
+        private bool? _isSelected;
359
+
360
+        public bool? IsSelected
361
+        {
362
+            get { return _isSelected; }
363
+            set
364
+            {
365
+                _isSelected = value;
366
+                NotifyPropertyChanged("IsSelected");
367
+            }
368
+        }
369
+
370
+        private MultiSelectComboBoxNode _parent;
371
+
372
+        public MultiSelectComboBoxNode Parent
373
+        {
374
+            get { return _parent; }
375
+            set { _parent = value; }
376
+        }
377
+
378
+        public List<MultiSelectComboBoxNode> Children { get; private set; }
379
+        #endregion
380
+
381
+        public event PropertyChangedEventHandler PropertyChanged;
382
+        protected void NotifyPropertyChanged(string propertyName)
383
+        {
384
+            if (PropertyChanged != null)
385
+            {
386
+                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
387
+            }
388
+        }
389
+
390
+    }
391
+}

+ 17
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PairStateSign.xaml 查看文件

@@ -0,0 +1,17 @@
1
+<UserControl
2
+	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+	xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+	xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
+	mc:Ignorable="d"
7
+	x:Class="TellerSystem.Controls.Ext.Controls.PairStateSign"
8
+	x:Name="UserControl"
9
+	Width="28" Height="28">
10
+
11
+	<Grid x:Name="LayoutRoot">
12
+		<Ellipse x:Name="back" Fill="Gainsboro"/>
13
+        <Path x:Name="forePath" Data="M1,1 L2,2" Visibility="Collapsed" HorizontalAlignment="Right" Margin="-2,0,-2,0" Stretch="Fill" Stroke="#FFFF8A00" StrokeThickness="2" Height="2" />
14
+		<Ellipse x:Name="fore" Fill="#FFBBBBBB" Margin="4" />
15
+        <TextBlock x:Name="tb" TextWrapping="Wrap" Text="1" FontWeight="Bold"  TextAlignment="Center" FontSize="16" Foreground="White" Margin="4"/>
16
+	</Grid>
17
+</UserControl>

+ 57
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PairStateSign.xaml.cs 查看文件

@@ -0,0 +1,57 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Text;
4
+using System.Windows;
5
+using System.Windows.Controls;
6
+using System.Windows.Data;
7
+using System.Windows.Documents;
8
+using System.Windows.Input;
9
+using System.Windows.Media;
10
+using System.Windows.Media.Imaging;
11
+using System.Windows.Navigation;
12
+using System.Windows.Shapes;
13
+
14
+namespace TellerSystem.Controls.Ext.Controls
15
+{
16
+	/// <summary>
17
+	/// PairStateSign.xaml 的交互逻辑
18
+	/// </summary>
19
+	public partial class PairStateSign : UserControl
20
+	{
21
+		public PairStateSign()
22
+		{
23
+			this.InitializeComponent();
24
+		}
25
+
26
+        private int _currentState = 0;
27
+
28
+        /// <summary>
29
+        /// 当前状态,可以使用0,1,2,3...9标识,如果完成使用-1
30
+        /// </summary>
31
+        public int CurrentState
32
+        {
33
+            get { return _currentState; }
34
+            set 
35
+            {
36
+                if (value == -1)
37
+                {
38
+                    tb.Text = "√";
39
+                    _currentState = value;
40
+                    fore.Fill = new SolidColorBrush(Color.FromRgb(255, 138, 0));
41
+                    forePath.Visibility = System.Windows.Visibility.Collapsed;
42
+                }
43
+                else if (value >= 0 && value <= 9)
44
+                {
45
+                    tb.Text = value.ToString();
46
+                    _currentState = value;
47
+                    fore.Fill = new SolidColorBrush(Color.FromRgb(187, 187, 187));
48
+                    forePath.Visibility = System.Windows.Visibility.Collapsed;
49
+                }
50
+                else
51
+                {
52
+                    throw new ArgumentException("只能是-1 - 9之间的整数", "CurrentState");
53
+                }
54
+            }
55
+        }
56
+	}
57
+}

+ 206
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PersonCardInfoViewer.xaml 查看文件

@@ -0,0 +1,206 @@
1
+<dhcc:TradePage
2
+    x:Class="TellerSystem.Controls.Ext.Controls.PersonCardInfoViewer"
3
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6
+                xmlns:dhcc="http://www.dhcc.com.cn"
7
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"                
8
+                d:DesignHeight="700"
9
+                d:DesignWidth="600"
10
+                dhcc:FocusManager.EnableFocusControl="True"
11
+                mc:Ignorable="d"                
12
+                >
13
+    <Grid>
14
+        <GroupBox Margin="2" Header="身份证信息">
15
+            <Grid>
16
+                <Grid.RowDefinitions>
17
+                    <RowDefinition Height="10" />
18
+                    <RowDefinition Height="25" />
19
+                    <RowDefinition Height="10" />
20
+                    <RowDefinition Height="25" />
21
+                    <RowDefinition Height="10" />
22
+                    <RowDefinition Height="25" />
23
+                    <RowDefinition Height="10" />
24
+                    <RowDefinition Height="25" />
25
+                    <RowDefinition Height="10" />
26
+                    <RowDefinition Height="25" />
27
+                    <RowDefinition Height="10" />
28
+                    <RowDefinition Height="25" />
29
+                    <RowDefinition Height="10" />
30
+                    <RowDefinition Height="25" />
31
+                    <RowDefinition Height="10" />
32
+                    <RowDefinition Height="25" />
33
+                    <RowDefinition Height="10" />
34
+                    <RowDefinition Height="25" />
35
+                    <RowDefinition Height="10" />
36
+                    <RowDefinition Height="auto" />
37
+                    <RowDefinition Height="10" />
38
+                    <RowDefinition Height="auto" />
39
+                    <RowDefinition Height="10" />
40
+                </Grid.RowDefinitions>
41
+                <Grid.ColumnDefinitions>
42
+                    <ColumnDefinition Width="100" />
43
+                    <ColumnDefinition Width="120" />
44
+                    <ColumnDefinition Width="10" />
45
+                    <ColumnDefinition Width="*" />
46
+                </Grid.ColumnDefinitions>
47
+                <TextBlock Grid.Row="1"
48
+                           Grid.Column="1"
49
+                           Margin="2"
50
+                           HorizontalAlignment="Right"
51
+                           VerticalAlignment="Center"
52
+                           Text="姓名:" />
53
+                <TextBlock Grid.Row="3"
54
+                           Grid.Column="1"
55
+                           Margin="2"
56
+                           HorizontalAlignment="Right"
57
+                           VerticalAlignment="Center"
58
+                           Text="性别:" />
59
+                <TextBlock Grid.Row="5"
60
+                           Grid.Column="1"
61
+                           Margin="2"
62
+                           HorizontalAlignment="Right"
63
+                           VerticalAlignment="Center"
64
+                           Text="民族:" />
65
+                <TextBlock Grid.Row="7"
66
+                           Grid.Column="1"
67
+                           Margin="2"
68
+                           HorizontalAlignment="Right"
69
+                           VerticalAlignment="Center"
70
+                           Text="出生日期:" />
71
+                <TextBlock Grid.Row="9"
72
+                           Grid.Column="1"
73
+                           Margin="2"
74
+                           HorizontalAlignment="Right"
75
+                           VerticalAlignment="Center"
76
+                           Text="地址:" />
77
+                <TextBlock Grid.Row="11"
78
+                           Grid.Column="1"
79
+                           Margin="2"
80
+                           HorizontalAlignment="Right"
81
+                           VerticalAlignment="Center"
82
+                           Text="身份证号:" />
83
+                <TextBlock Grid.Row="13"
84
+                           Grid.Column="1"
85
+                           Margin="2"
86
+                           HorizontalAlignment="Right"
87
+                           VerticalAlignment="Center"
88
+                           Text="签发机构:" />
89
+                <TextBlock Grid.Row="15"
90
+                           Grid.Column="1"
91
+                           Margin="2"
92
+                           HorizontalAlignment="Right"
93
+                           VerticalAlignment="Center"
94
+                           Text="有效开始日期:" />
95
+                <TextBlock Grid.Row="17"
96
+                           Grid.Column="1"
97
+                           Margin="2"
98
+                           HorizontalAlignment="Right"
99
+                           VerticalAlignment="Center"
100
+                           Text="有效结束日期:" />
101
+                <TextBlock                             
102
+                           Grid.Row="19"
103
+                           Grid.Column="1"
104
+                           Margin="2"
105
+                           HorizontalAlignment="Right"
106
+                           VerticalAlignment="Center"
107
+                           Text="身份证照片:" />
108
+                <TextBox Name="name"
109
+                         Grid.Row="1"
110
+                         Grid.Column="3"
111
+                         Width="240"
112
+                         HorizontalAlignment="Left"
113
+                         VerticalAlignment="Center"  
114
+                         IsEnabled="False"
115
+                          />
116
+                <TextBox Name="sex"
117
+                         Grid.Row="3"
118
+                         Grid.Column="3"
119
+                         Width="30"
120
+                         HorizontalAlignment="Left"
121
+                         VerticalAlignment="Center"
122
+                         IsEnabled="False"
123
+                          />
124
+                <TextBox Name="nation"
125
+                         Grid.Row="5"
126
+                         Grid.Column="3"
127
+                         Width="240"
128
+                         HorizontalAlignment="Left"
129
+                         VerticalAlignment="Center"
130
+                         IsEnabled="False"
131
+                          />
132
+                <TextBox Name="birthday"
133
+                         Grid.Row="7"
134
+                         Grid.Column="3"
135
+                         Width="240"
136
+                         HorizontalAlignment="Left"
137
+                         VerticalAlignment="Center"
138
+                         IsEnabled="False"
139
+                          />
140
+                <TextBox Name="address"
141
+                         Grid.Row="9"
142
+                         Grid.Column="3"
143
+                         Width="240"
144
+                         HorizontalAlignment="Left"
145
+                         VerticalAlignment="Center"
146
+                         IsEnabled="False"
147
+                        />
148
+                <TextBox Name="cardId"
149
+                         Grid.Row="11"
150
+                         Grid.Column="3"
151
+                         Width="240"
152
+                         HorizontalAlignment="Left"
153
+                         VerticalAlignment="Center"
154
+                         IsEnabled="False"
155
+                         />
156
+                <TextBox Name="department"
157
+                         Grid.Row="13"
158
+                         Grid.Column="3"
159
+                         Width="240"
160
+                         HorizontalAlignment="Left"
161
+                         VerticalAlignment="Center"
162
+                         IsEnabled="False"
163
+                         />
164
+               
165
+                <TextBox x:Name="startdate"
166
+                         Grid.Row="15"
167
+                         Grid.Column="3"
168
+                         Width="240"
169
+                         HorizontalAlignment="Left"
170
+                         VerticalAlignment="Center" 
171
+                         IsEnabled="False"
172
+                          />
173
+                <TextBox Name="enddate"
174
+                         Grid.Row="17"
175
+                         Grid.Column="3"
176
+                         Width="240"
177
+                         HorizontalAlignment="Left"
178
+                         VerticalAlignment="Center"
179
+                         IsEnabled="False"
180
+                         />               
181
+                <ScrollViewer 
182
+                    HorizontalScrollBarVisibility="Auto"
183
+                     Grid.Row="19"
184
+                     Grid.Column="3"
185
+                     HorizontalAlignment="Left"
186
+                     VerticalAlignment="Center"  
187
+                    IsEnabled="False"
188
+                    >
189
+                    <Image   Name="Picture" Width="330" Height="270" Source="{Binding}"/>
190
+                </ScrollViewer>
191
+               
192
+                <Button Name="btn_Sure"
193
+                        Grid.Row="21"
194
+                        Grid.Column="3"
195
+                        Width="80"
196
+                        Height="23"
197
+                        Margin="80,25,0,0"
198
+                        HorizontalAlignment="Left"
199
+                        VerticalAlignment="Center"
200
+                        Click="btn_Sure_Click"
201
+                        Content="关闭"
202
+                        Tag="Sure" />
203
+            </Grid>
204
+        </GroupBox>
205
+    </Grid>
206
+</dhcc:TradePage>

+ 63
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PersonCardInfoViewer.xaml.cs 查看文件

@@ -0,0 +1,63 @@
1
+/*****************************************************************************************
2
+系统名     综合业务系统2.0
3
+程序名     交易2301的源代码
4
+类名       T2301      
5
+概要   	   客户信息维护
6
+作成者     XXX
7
+作成日     
8
+履历       No.        日期          Ver.No       修改人          描述
9
+*****************************************************************************************/
10
+using System.Windows;
11
+using System.ComponentModel;
12
+using TellerSystem.Library.Ext.Function;
13
+
14
+
15
+namespace TellerSystem.Controls.Ext.Controls
16
+{
17
+    /// <summary>
18
+    /// PersonCardInfoViewer.xaml 的交互逻辑
19
+    /// </summary>
20
+    [DesignTimeVisible(false)]
21
+    public partial class PersonCardInfoViewer
22
+    {
23
+        #region
24
+        public PersonCardInfoViewer()
25
+        {
26
+            InitializeComponent();
27
+        }
28
+        /// <summary>
29
+        /// 初始化逻辑
30
+        /// </summary>
31
+        protected override void OnTradePageLoaded()
32
+        {
33
+            base.OnTradePageLoaded();
34
+        }
35
+        #endregion
36
+       
37
+        /// <summary>
38
+        /// 绑定数据
39
+        /// </summary>
40
+        /// <param name="aPersonInfo">身份证信息</param>
41
+        //public void BindPersonCardData(PersonInfo aPersonInfo)
42
+        //{
43
+        //    this.name.Text = aPersonInfo.Name;//姓名
44
+        //    this.sex.Text = aPersonInfo.Sex;//性别
45
+        //    this.nation.Text = aPersonInfo.Nation;
46
+        //    this.birthday.Text = aPersonInfo.Birthday;
47
+        //    this.address.Text = aPersonInfo.Address;
48
+        //    this.cardId.Text = aPersonInfo.Id;
49
+        //    this.department.Text = aPersonInfo.Department;
50
+        //    this.startdate.Text = aPersonInfo.Startdate;
51
+        //    this.enddate.Text = aPersonInfo.Enddate;
52
+        //    this.Picture.Source = TradePageExtension.ByteToBitmapSource(aPersonInfo.Photo);
53
+        //}
54
+        //关闭按钮
55
+        private void btn_Sure_Click(object sender, RoutedEventArgs e)
56
+        {
57
+            this.Close();
58
+        }
59
+
60
+
61
+       
62
+    }
63
+}

+ 24
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PictureCaptureViewer.xaml 查看文件

@@ -0,0 +1,24 @@
1
+<dhcc:TradePage x:Class="TellerSystem.Controls.Ext.Controls.PictureCaptureViewer"
2
+                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+                xmlns:dhcc="http://www.dhcc.com.cn"
6
+                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+                Width="700"
8
+                Height="500"
9
+                dhcc:FocusManager.EnableFocusControl="False"
10
+                mc:Ignorable="d">
11
+    <Grid>
12
+        <Grid.RowDefinitions>
13
+            <RowDefinition Height="*"/>
14
+            <RowDefinition Height="50"/>
15
+        </Grid.RowDefinitions>
16
+        <GroupBox Grid.Row="0" Style="{x:Null}" Header="影像采集"  >
17
+            <dhcc:PictureDisplay Name="PictureCapture"/>
18
+        </GroupBox>
19
+        <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center">
20
+            <Button Height="20" Content="完 成" Click="Button_Click"/>
21
+            <Button Height="20" Content="退 出" Click="Button_Click_1"/>
22
+        </StackPanel>
23
+    </Grid>
24
+</dhcc:TradePage>

+ 53
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PictureCaptureViewer.xaml.cs 查看文件

@@ -0,0 +1,53 @@
1
+/*****************************************************************************************
2
+系统名     综合业务系统2.0
3
+程序名     交易2301的源代码
4
+类名       T2301      
5
+概要   	   客户信息维护
6
+作成者     XXX
7
+作成日     
8
+履历       No.        日期          Ver.No       修改人          描述
9
+*****************************************************************************************/
10
+using System;
11
+using System.Collections.Generic;
12
+using System.ComponentModel;
13
+using System.IO;
14
+using System.Linq;
15
+using System.Windows;
16
+using System.Windows.Controls;
17
+using System.Windows.Media;
18
+using AxDOCCAMERAOCXLib;
19
+using Platform.Library;
20
+using Platform.Presentation.PageFunctions;
21
+using TellerSystem.Library.Ext.Function;
22
+using Application = System.Windows.Application;
23
+using TellerSystem.Library.Ext.TradeExtension;
24
+using TellerSystem.Devices.Interface;
25
+
26
+namespace TellerSystem.Controls.Ext.Controls
27
+{
28
+    /// <summary>
29
+    /// CameraViewer.xaml 的交互逻辑
30
+    /// </summary>
31
+    [DesignTimeVisible(false)]
32
+    public partial class PictureCaptureViewer : TradePage
33
+    {
34
+        public List<PictureEntity> Pictures { get; private set; }
35
+        public PictureCaptureViewer(bool cutBorderFlag = false)
36
+        {
37
+            InitializeComponent();
38
+            Pictures = new List<PictureEntity>();
39
+        }
40
+
41
+        private void Button_Click(object sender, RoutedEventArgs e)
42
+        {
43
+            Pictures.AddRange(PictureCapture.PictureList.Select(x => x.Entity));
44
+            this.Close();
45
+        }
46
+
47
+        private void Button_Click_1(object sender, RoutedEventArgs e)
48
+        {
49
+            this.Close();
50
+        }
51
+
52
+    }
53
+}

+ 11
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PropGuide.xaml 查看文件

@@ -0,0 +1,11 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.PropGuide"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:local="clr-namespace:TellerSystem.Controls.Ext.ControlsExt"
6
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7
+             d:DesignHeight="300"
8
+             d:DesignWidth="500"
9
+             mc:Ignorable="d">
10
+    <local:TradePanel x:Name="TP_Host" />
11
+</UserControl>

+ 56
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/PropGuide.xaml.cs 查看文件

@@ -0,0 +1,56 @@
1
+using System;
2
+using System.Collections.Generic;
3
+using System.Linq;
4
+using System.Text;
5
+using System.Windows;
6
+using System.Windows.Controls;
7
+using System.Windows.Data;
8
+using System.Windows.Documents;
9
+using System.Windows.Input;
10
+using System.Windows.Media;
11
+using System.Windows.Media.Imaging;
12
+using System.Windows.Navigation;
13
+using System.Windows.Shapes;
14
+using TellerSystem.Controls.Ext.ControlEntity;
15
+
16
+namespace TellerSystem.Controls.Ext.Controls
17
+{
18
+    /// <summary>
19
+    /// Interaction logic for PropGuide.xaml
20
+    /// </summary>
21
+    public partial class PropGuide : UserControl
22
+    {
23
+        PropGuideEntity[] _source;
24
+
25
+        public PropGuide()
26
+        {
27
+            InitializeComponent();
28
+        }
29
+
30
+        public int ColumnCount { get; set; }
31
+
32
+        public void SetDataSource(IEnumerable<PropGuideEntity> source)
33
+        {
34
+            _source = source.ToArray();
35
+
36
+            BindData();
37
+        }
38
+
39
+        private void BindData()
40
+        {
41
+            if (_source == null || _source.Length == 0) return;
42
+
43
+            TP_Host.Children.Clear();
44
+            foreach (var item in _source)
45
+            {
46
+                if (item.Children == null || item.Children.Count == 0)
47
+                    continue;
48
+                foreach (var property in item.Children)
49
+                {
50
+                    TP_Host.Children.Add(new TextBlock { Text = property.Key });
51
+                    TP_Host.Children.Add(new TextBox { Text = property.Value, IsEnabled = false });
52
+                }
53
+            }
54
+        }
55
+    }
56
+}

+ 70
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ProvinceCityCounty.xaml 查看文件

@@ -0,0 +1,70 @@
1
+<UserControl x:Class="TellerSystem.Controls.Ext.Controls.ProvinceCityCounty"
2
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6
+             d:DesignHeight="50"
7
+             d:DesignWidth="650"
8
+             mc:Ignorable="d">
9
+    <Grid Name="Content" VerticalAlignment="Center">
10
+        <Grid.Resources>
11
+            <Style BasedOn="{StaticResource {x:Type ComboBox}}" TargetType="ComboBox">
12
+                <Setter Property="Margin" Value="0 0 10 0" />
13
+                <Setter Property="MinWidth" Value="60" />
14
+            </Style>
15
+        </Grid.Resources>
16
+        <Grid.ColumnDefinitions>
17
+            <ColumnDefinition />
18
+            <ColumnDefinition Width="20" />
19
+            <ColumnDefinition />
20
+            <ColumnDefinition Width="20" />
21
+            <ColumnDefinition />
22
+            <ColumnDefinition Width="40" />
23
+        </Grid.ColumnDefinitions>
24
+        <ComboBox x:Name="ComboBoxProvince"
25
+                  Grid.Column="0"
26
+                  Width="180"
27
+                  DisplayMemberPath="Key"
28
+                  ItemsSource="{Binding Path=Provinces}"
29
+                  SelectedValue="{Binding Path=Province,
30
+                                          Mode=TwoWay}"
31
+                  SelectedValuePath="Value"
32
+                  SelectionChanged="ComboBoxProvince_SelectionChanged" />
33
+        <TextBlock Grid.Column="1"
34
+                   Margin="2,0,5,0"
35
+                   HorizontalAlignment="Right"
36
+                   VerticalAlignment="Center"
37
+                   Text="省" />
38
+
39
+        <ComboBox x:Name="ComboBoxCity"
40
+                  Grid.Column="2"
41
+                  Width="180"
42
+                  DisplayMemberPath="Key"
43
+                  ItemsSource="{Binding Path=SelectedItem.Child,
44
+                                        ElementName=ComboBoxProvince}"
45
+                  SelectedValue="{Binding Path=City,
46
+                                          Mode=TwoWay}"
47
+                  SelectedValuePath="Value"
48
+                  SelectionChanged="ComboBoxCity_SelectionChanged" />
49
+        <TextBlock Grid.Column="3"
50
+                   Margin="2,0,5,0"
51
+                   HorizontalAlignment="Right"
52
+                   VerticalAlignment="Center"
53
+                   Text="市" />
54
+        <ComboBox x:Name="ComboBoxCounty"
55
+                  Grid.Column="4"
56
+                  Width="180"
57
+                  DisplayMemberPath="Key"
58
+                  ItemsSource="{Binding Path=SelectedItem.Child,
59
+                                        ElementName=ComboBoxCity}"
60
+                  SelectedValue="{Binding Path=County,
61
+                                          Mode=TwoWay}"
62
+                  SelectedValuePath="Value" />
63
+
64
+        <TextBlock Grid.Column="5"
65
+                   Margin="2,0,5,0"
66
+                   HorizontalAlignment="Right"
67
+                   VerticalAlignment="Center"
68
+                   Text="县/区" />
69
+    </Grid>
70
+</UserControl>

+ 0
- 0
ant-design-pro-vue3/src/views/front/develop/Controls.Ext/Controls/ProvinceCityCounty.xaml.cs 查看文件


部分文件因为文件数量过多而无法显示

正在加载...
取消
保存