From 9c0fdac9ba94e89cb6eebc81b66708595608cd29 Mon Sep 17 00:00:00 2001 From: SugarChes Date: Wed, 29 Jul 2026 16:47:42 +0800 Subject: [PATCH] feat(control): add module-backed extended return search --- .../ExtendedReturnModuleSourceResolver.cs | 49 +++++++ .../LabelExtendedReturnSearchEdit.cs | 36 ++++- .../GridControlEx.ExtendedReturn.cs | 126 ++++-------------- 插件库/Lskj.Control/Lskj.Control.csproj | 3 +- 插件库/Lskj.Control/Model/ControlType.cs | 4 +- 插件库/Lskj.Control/Model/MyControl.cs | 9 ++ 6 files changed, 118 insertions(+), 109 deletions(-) create mode 100644 插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnModuleSourceResolver.cs diff --git a/插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnModuleSourceResolver.cs b/插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnModuleSourceResolver.cs new file mode 100644 index 0000000..7ff0cf7 --- /dev/null +++ b/插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnModuleSourceResolver.cs @@ -0,0 +1,49 @@ +using Lskj.Control.MultiModelLookUp; +using System; +using System.Collections.Generic; + +namespace Lskj.Control +{ + /// + /// 按模块编号延迟读取模块数据源 SQL。只缓存 SQL 文本,不加载业务数据。 + /// + internal sealed class ExtendedReturnModuleSourceResolver + { + private readonly object syncRoot = new object(); + private readonly Dictionary sourceSqlByModule = + new Dictionary(StringComparer.OrdinalIgnoreCase); + + public string Resolve(string moduleCode) + { + moduleCode = (moduleCode ?? string.Empty).Trim(); + if (moduleCode.Length == 0) + { + throw new InvalidOperationException("扩展模块搜索的模块编号不能为空。"); + } + + lock (syncRoot) + { + string cachedSql; + if (sourceSqlByModule.TryGetValue(moduleCode, out cachedSql)) + { + return cachedSql; + } + + using (FrmModelLookUp lookup = new FrmModelLookUp(moduleCode, true)) + { + string sourceSql = lookup.SysModel == null + ? string.Empty + : lookup.SysModel.MenuSql; + if (string.IsNullOrWhiteSpace(sourceSql)) + { + throw new InvalidOperationException( + string.Format("模块“{0}”未配置数据源 SQL。", moduleCode)); + } + + sourceSqlByModule.Add(moduleCode, sourceSql); + return sourceSql; + } + } + } + } +} diff --git a/插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs b/插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs index e72130e..957b726 100644 --- a/插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs +++ b/插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs @@ -18,7 +18,7 @@ using System.Windows.Forms; namespace Lskj.Control { /// - /// MyControl 中的 181 扩展搜索控件。业务实际值与界面显示文本相互独立, + /// MyControl 中的 173/174 扩展搜索控件。业务实际值与界面显示文本相互独立, /// 数据源仅在弹出框打开或用户执行查询时按需访问。 /// public sealed class LabelExtendedReturnSearchEdit : BaseUserControl @@ -152,7 +152,7 @@ namespace Lskj.Control /// /// BaseUserControl 的 EditText 仍用于常规赋值入口;读取时返回界面显示文本, - /// MyControl.GetControlValue 对 181 会显式读取 EditValue。 + /// MyControl.GetControlValue 对 173/174 会显式读取 EditValue。 /// public override string EditText { @@ -472,7 +472,14 @@ namespace Lskj.Control { if (Model == null) throw new InvalidOperationException("扩展返回控件配置不存在。"); if (ControlObj == null) throw new InvalidOperationException("扩展返回控件未关联 MyControl。"); - if (string.IsNullOrWhiteSpace(Model.SourceSql)) + if (Model.FieldType == ControlType.LabModuleSelectReturnIdExtended) + { + if (string.IsNullOrWhiteSpace(Model.AddModuleId)) + { + throw new InvalidOperationException("扩展模块搜索的模块编号不能为空。"); + } + } + else if (string.IsNullOrWhiteSpace(Model.SourceSql)) { throw new InvalidOperationException("搜索数据源 SQL 不能为空。"); } @@ -576,7 +583,7 @@ namespace Lskj.Control private string BuildSourceSql() { - string sourceSql = Model.SourceSql; + string sourceSql = GetBaseSourceSql(); if (ControlObj != null) { sourceSql = ControlObj.ReplaceControlValue(sourceSql); @@ -585,6 +592,27 @@ namespace Lskj.Control return ReplaceHelper.ReplaceParam(sourceSql); } + private string GetBaseSourceSql() + { + if (Model == null) + { + throw new InvalidOperationException("扩展返回控件配置不存在。"); + } + if (Model.FieldType == ControlType.LabModuleSelectReturnIdExtended) + { + if (ControlObj == null) + { + throw new InvalidOperationException("扩展返回控件未关联 MyControl。"); + } + return ControlObj.ResolveExtendedReturnModuleSourceSql(Model.AddModuleId); + } + if (string.IsNullOrWhiteSpace(Model.SourceSql)) + { + throw new InvalidOperationException("搜索数据源 SQL 不能为空。"); + } + return Model.SourceSql; + } + private void StartSearch(string keyword) { SearchRequest request = new SearchRequest(); diff --git a/插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs b/插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs index 9c3cc91..1a54285 100644 --- a/插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs +++ b/插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs @@ -8,7 +8,6 @@ using DevExpress.XtraGrid.Views.Base; using DevExpress.XtraGrid.Views.Grid; using Lskj.Business.Impl; using Lskj.Control.Model; -using Lskj.Control.MultiModelLookUp; using Lskj.Core; using Lskj.Util; using System; @@ -31,6 +30,8 @@ namespace Lskj.Control private const int ExtendedLookupMinimumPopupWidth = 360; private readonly object mExtendedReturnSyncRoot = new object(); + private readonly ExtendedReturnModuleSourceResolver mExtendedReturnModuleSourceResolver = + new ExtendedReturnModuleSourceResolver(); private readonly Dictionary mExtendedReturnSearchEditors = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary mExtendedReturnPopupContexts = @@ -84,7 +85,7 @@ namespace Lskj.Control } /// - /// 初始化扩展返回类型。180 仅创建模块选择按钮,181 仅创建空搜索编辑器, + /// 初始化扩展返回类型。173、174 共用空搜索编辑器, /// 两种类型均不在表格初始化时访问业务数据源。 /// private void InitExtendedReturn(GridColumn column, GridColumnModel model) @@ -94,11 +95,7 @@ namespace Lskj.Control CacheExtendedReturnDisplayField(model); AttachExtendedReturnDisplayEvent(); AttachExtendedReturnDisposeEvent(); - if (model.FieldType == ControlType.LabModuleSelectReturnIdExtended) - { - InitExtendedModuleReturn(column, model); - } - else if (model.FieldType == ControlType.LabSearchReturnIdExtended) + if (IsExtendedReturnType(model)) { InitExtendedSearchReturn(column, model); } @@ -125,25 +122,6 @@ namespace Lskj.Control DisposeExtendedReturnRequestTimers(); } - private void InitExtendedModuleReturn(GridColumn column, GridColumnModel model) - { - RepositoryItemButtonEdit buttonEdit = new RepositoryItemButtonEdit(); - buttonEdit.NullText = string.Empty; - buttonEdit.AllowNullInput = DefaultBoolean.True; - buttonEdit.TextEditStyle = TextEditStyles.DisableTextEditor; - buttonEdit.Tag = model; - buttonEdit.Buttons.Clear(); - buttonEdit.Buttons.Add(new EditorButton(ButtonPredefines.Ellipsis)); - buttonEdit.ButtonClick += ExtendedModuleReturn_ButtonClick; - buttonEdit.CustomDisplayText += ExtendedModuleReturn_CustomDisplayText; - - this.gridControl.RepositoryItems.Add(buttonEdit); - column.ColumnEdit = buttonEdit; - column.OptionsColumn.ReadOnly = true; - column.FilterMode = ColumnFilterMode.DisplayText; - this.mControlList.Add(model); - } - private void InitExtendedSearchReturn(GridColumn column, GridColumnModel model) { RepositoryItemPopupContainerEdit searchEdit = CreateExtendedReturnSearchEdit(model); @@ -245,23 +223,6 @@ namespace Lskj.Control } } - private void ExtendedModuleReturn_CustomDisplayText(object sender, CustomDisplayTextEventArgs e) - { - try - { - RepositoryItemButtonEdit editor = sender as RepositoryItemButtonEdit; - GridColumnModel model = editor == null ? null : editor.Tag as GridColumnModel; - DataRow row = this.GridView.GetFocusedDataRow(); - string displayField = GetExtendedReturnDisplayField(model); - if (row == null || string.IsNullOrWhiteSpace(displayField) || !row.Table.Columns.Contains(displayField)) return; - - e.DisplayText = row[displayField] == DBNull.Value ? string.Empty : row[displayField] + string.Empty; - } - catch - { - } - } - private static bool IsExtendedReturnType(GridColumnModel model) { return model != null && @@ -297,7 +258,7 @@ namespace Lskj.Control private void GridView_CustomRowCellEditForEditing_ExtendedReturn(object sender, CustomRowCellEditEventArgs e) { GridColumnModel model = e.Column == null ? null : e.Column.Tag as GridColumnModel; - if (model == null || model.FieldType != ControlType.LabSearchReturnIdExtended) return; + if (!IsExtendedReturnType(model)) return; RepositoryItemPopupContainerEdit searchEdit; if (!mExtendedReturnSearchEditors.TryGetValue(model.FieldName, out searchEdit)) return; @@ -331,8 +292,7 @@ namespace Lskj.Control private void GridView_RowCellClick_ExtendedReturn(object sender, RowCellClickEventArgs e) { GridColumnModel model = e.Column == null ? null : e.Column.Tag as GridColumnModel; - if (e.Button != MouseButtons.Left || model == null || - model.FieldType != ControlType.LabSearchReturnIdExtended || + if (e.Button != MouseButtons.Left || !IsExtendedReturnType(model) || !e.Column.OptionsColumn.AllowEdit) return; this.GridView.FocusedRowHandle = e.RowHandle; @@ -531,7 +491,7 @@ namespace Lskj.Control private string ResolveExtendedReturnSourceSql(GridColumnModel model, DataRow row) { - string sqlValue = model == null ? string.Empty : model.SqlSource; + string sqlValue = GetExtendedReturnBaseSourceSql(model); if (this.ParentControl != null) { sqlValue = this.ParentControl.ReplaceParentControlValue(sqlValue); @@ -546,6 +506,23 @@ namespace Lskj.Control return ReplaceHelper.ReplaceParam(sqlValue); } + private string GetExtendedReturnBaseSourceSql(GridColumnModel model) + { + if (model == null) + { + throw new InvalidOperationException("扩展返回列配置不存在。"); + } + if (model.FieldType == ControlType.LabModuleSelectReturnIdExtended) + { + return mExtendedReturnModuleSourceResolver.Resolve(model.addModuleld); + } + if (string.IsNullOrWhiteSpace(model.SqlSource)) + { + throw new InvalidOperationException("扩展搜索数据源 SQL 不能为空。"); + } + return model.SqlSource; + } + private static void ValidateExtendedReturnMembers(GridColumnModel model) { if (model == null) throw new InvalidOperationException("扩展返回列配置不存在。"); @@ -1158,61 +1135,6 @@ namespace Lskj.Control return TryCommitExtendedReturnValues(businessRow, stagedValues, out error); } - private void ExtendedModuleReturn_ButtonClick(object sender, ButtonPressedEventArgs e) - { - ButtonEdit buttonEdit = sender as ButtonEdit; - GridColumnModel model = buttonEdit == null ? null : buttonEdit.Properties.Tag as GridColumnModel; - if (model == null) return; - - try - { - DataRow businessRow = this.GridView.GetFocusedDataRow(); - IList mappings = ValidateExtendedReturnBusinessConfiguration(model, businessRow); - - using (FrmModelLookUp2 modelLookUp = new FrmModelLookUp2(model.addModuleld, true)) - { - modelLookUp.ConfigureColumnMode = model.ConfigureColumnMode; - modelLookUp.ValueField = model.ValueMember; - modelLookUp.TextField = model.TextMember; - modelLookUp.SourceSQL = model.SqlSource; - modelLookUp.IsType = ControlType.LabSelectReturnIdNew; - modelLookUp.ValueMember = model.ValueMember; - modelLookUp.Tag = model; - modelLookUp.EditText = buttonEdit.Text; - modelLookUp.EditValue = buttonEdit.EditValue + string.Empty; - modelLookUp.CurrentOperColumnKey = Model.ModuleCode + "_" + model.FieldName; - - string sourceSql = modelLookUp.SysModel.MenuSql.Replace("#", string.Empty) + model.SplicingConditions; - if (this.ParentControl != null) - { - sourceSql = this.ParentControl.ReplaceControlValue(sourceSql); - } - sourceSql = ReplaceHelper.ReplaceRowParam(this.GridView.GetFocusedDataRow(), sourceSql); - modelLookUp.NewSourceSQL = sourceSql; - modelLookUp.InitControls(modelLookUp.UnionModuleCodel); - ValidateExtendedReturnSourceColumns(modelLookUp.DataSource.Columns, model, mappings); - - if (modelLookUp.ShowDialog() != DialogResult.OK) return; - - string error; - if (!TryApplyExtendedReturnMappings(businessRow, modelLookUp.GetSelectedResultRow(), model, out error)) - { - MessageUtil.Show("扩展返回字段配置错误:" + error); - return; - } - - buttonEdit.EditValue = businessRow[model.FieldName]; - this.GridView.PostEditor(); - this.GridView.UpdateCurrentRow(); - this.GridView.RefreshRow(this.GridView.FocusedRowHandle); - } - } - catch (Exception ex) - { - MessageUtil.Show("扩展模块选择失败:" + ex.Message); - } - } - /// /// 先在同结构的脱离行上完成全部类型转换,所有值都合法后再写入真实业务行。 /// diff --git a/插件库/Lskj.Control/Lskj.Control.csproj b/插件库/Lskj.Control/Lskj.Control.csproj index 093f543..4b9f67c 100644 --- a/插件库/Lskj.Control/Lskj.Control.csproj +++ b/插件库/Lskj.Control/Lskj.Control.csproj @@ -711,6 +711,7 @@ UserControl + UserControl @@ -1891,4 +1892,4 @@ --> - \ No newline at end of file + diff --git a/插件库/Lskj.Control/Model/ControlType.cs b/插件库/Lskj.Control/Model/ControlType.cs index 444377c..d1da03b 100644 --- a/插件库/Lskj.Control/Model/ControlType.cs +++ b/插件库/Lskj.Control/Model/ControlType.cs @@ -495,11 +495,11 @@ namespace Lskj.Control.Model /// /// 模块选择返回ID-扩展 /// - public const int LabModuleSelectReturnIdExtended = 180; + public const int LabModuleSelectReturnIdExtended = 173; /// /// 搜索返回ID-扩展 /// - public const int LabSearchReturnIdExtended = 181; + public const int LabSearchReturnIdExtended = 174; /// /// 说明:是否为Value类型 diff --git a/插件库/Lskj.Control/Model/MyControl.cs b/插件库/Lskj.Control/Model/MyControl.cs index d05bd53..661e5e8 100644 --- a/插件库/Lskj.Control/Model/MyControl.cs +++ b/插件库/Lskj.Control/Model/MyControl.cs @@ -140,6 +140,8 @@ namespace Lskj.Control.Model new List(); private readonly List> mExtendedReturnPendingChanges = new List>(); + private readonly ExtendedReturnModuleSourceResolver mExtendedReturnModuleSourceResolver = + new ExtendedReturnModuleSourceResolver(); private int mExtendedReturnBatchDepth; /// /// 数据源任务对象 @@ -2258,6 +2260,7 @@ namespace Lskj.Control.Model LabelMultiAutoTextEdit4 moduleReturnsIdNew = ctr as LabelMultiAutoTextEdit4; value = ControlType.LabSelectReturnIdNew == model.FieldType ? moduleReturnsIdNew.EditValue : moduleReturnsIdNew.EditText; break; + case ControlType.LabModuleSelectReturnIdExtended: case ControlType.LabSearchReturnIdExtended: LabelExtendedReturnSearchEdit extendedReturnSearch = ctr as LabelExtendedReturnSearchEdit; value = extendedReturnSearch == null ? string.Empty : extendedReturnSearch.EditValue; @@ -3877,6 +3880,11 @@ namespace Lskj.Control.Model } } + public string ResolveExtendedReturnModuleSourceSql(string moduleCode) + { + return mExtendedReturnModuleSourceResolver.Resolve(moduleCode); + } + /// /// 说明:设置搜索框数据源 /// 创建人:曹屹峰 @@ -4934,6 +4942,7 @@ namespace Lskj.Control.Model if (!isLoadBorder) moduleReturnsIdNew.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder; baseControl = moduleReturnsIdNew; break; + case ControlType.LabModuleSelectReturnIdExtended: case ControlType.LabSearchReturnIdExtended: LabelExtendedReturnSearchEdit extendedReturnSearch = new LabelExtendedReturnSearchEdit(); extendedReturnSearch.ControlObj = this;