38 Commits

Author SHA1 Message Date
cyf 000a69ce15 feat: 更新业务、控件及单据功能 2026-08-10 09:59:46 +08:00
tdx c07220bbf0 fix: 保留未处理异常原始堆栈 2026-08-09 11:33:20 +08:00
tdx 219caba818 fix: optimize large file chunk upload stability 2026-08-06 18:02:11 +08:00
tdx 031fc34f12 fix_WPF_switch_user_main_loop_conflict 2026-08-05 17:27:47 +08:00
cyf 66cab000ea feat: 更新控件及相关业务功能 2026-08-04 13:49:05 +08:00
tdx 4fe8844e86 fix(control): use contains filtering in extended lookup 2026-07-31 14:00:51 +08:00
tdx d71657bcb2 docs: plan contains filtering for extended lookup 2026-07-31 13:56:06 +08:00
tdx a644184078 docs: design contains filtering for extended lookup 2026-07-31 13:51:13 +08:00
tdx 250f65b3d0 fix(core): enable SQL Server idle connection recovery 2026-07-31 11:33:13 +08:00
tdx 004778f2a8 feat(control): add grid extended lookup column search 2026-07-31 10:38:40 +08:00
tdx e06a67f002 feat(control): add form extended lookup column search 2026-07-31 10:35:25 +08:00
tdx 2acae8551f feat(control): add extended lookup filter UI 2026-07-31 10:32:29 +08:00
tdx 7e819b44b7 feat(control): support selected extended search columns 2026-07-31 10:30:15 +08:00
tdx c5b6466fab docs: plan extended return search filters 2026-07-31 10:21:55 +08:00
tdx 5c4682bbbd docs: design extended return search filters 2026-07-31 10:13:14 +08:00
SugarChes cc9bd1f0d1 fix(browser): accept nested values in row callbacks 2026-07-30 15:08:01 +08:00
SugarChes 5e6449cf1f fix(util): preserve complex JSON values in data tables 2026-07-30 15:01:56 +08:00
SugarChes 11e395aa0f docs: plan browser JSON complex field compatibility 2026-07-30 14:49:39 +08:00
SugarChes 79399b0ef4 docs: design browser JSON complex field compatibility 2026-07-30 14:40:04 +08:00
tdx 517d001eb8 fix(http): improve transport compatibility and diagnostics 2026-07-30 12:30:41 +08:00
tdx b9a3dd3b86 fix(control): load result fields for extended types 2026-07-30 12:03:24 +08:00
tdx 4fbe8324fc fix(startup): remove obsolete recursive host entry 2026-07-29 20:19:52 +08:00
tdx dd1e354e2f fix(browser): contain CEF callback failures 2026-07-29 20:12:00 +08:00
tdx b651ea915b fix(session): keep external subsystem errors in WPF 2026-07-29 20:12:00 +08:00
tdx bccccff428 refactor(session): expose WPF-compatible legacy state 2026-07-29 20:12:00 +08:00
tdx a82bc39edf refactor(startup): expose legacy process lifecycle 2026-07-29 20:11:59 +08:00
tdx e50a29c37a fix(startup): suppress legacy splash under WPF shell 2026-07-29 20:11:59 +08:00
tdx e86fb0a5db feat(login): bridge restored login options 2026-07-29 20:11:59 +08:00
tdx 113433f656 feat: expose legacy login connection settings 2026-07-29 20:11:59 +08:00
tdx 94af6e7faa fix: normalize WPF login identities at legacy boundary 2026-07-29 20:11:59 +08:00
tdx b843ee30b1 feat: expose legacy login runtime for WPF host 2026-07-29 20:11:51 +08:00
tdx 9c0fdac9ba feat(control): add module-backed extended return search 2026-07-29 16:47:42 +08:00
tdx 1bbe9c9a4c feat(control): add extended return search for tables and forms 2026-07-29 15:57:29 +08:00
cyf b893e8d8e4 提交单据管理和修改密码功能 2026-07-28 10:16:51 +08:00
tdx e4b40a32d7 feat: 完善 WPF 接管后的子系统选择 2026-07-22 13:41:53 +08:00
tdx a11ef73f1c Merge branch 'main' of http://192.168.0.7:4133/cyf/lserp_cs_6.0 2026-07-21 10:27:53 +08:00
tdx 0a1d027407 feat: 支持外部 WPF 主界面接管 2026-07-21 10:02:11 +08:00
cyf bcf9f1b58c 提交当前本机最新程序 2026-07-18 15:32:50 +08:00
139 changed files with 24893 additions and 1797 deletions
+1
View File
@@ -32,6 +32,7 @@
*.zip
*.rar
*.7z
*.r[0-9]*
# Confirmed unnecessary large files.
/其他程序/工作部署记录/Smart X1 SDK V1.0.zip
@@ -0,0 +1,478 @@
# 浏览器 JSON 复杂字段兼容 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让旧 WinForms 浏览器桥接能够把任意对象或数组字段保留为紧凑 JSON 字符串,并继续安全转换为 `DataTable`
**Architecture:**`Lskj.Util.JsonUtil` 增加一个只供明确调用方选用的转换入口:先扫描整批 JSON 行,确定复杂列,再把这些列统一字符串化,最后复用 Newtonsoft.Json 原有 `DataTableConverter``Lskj.Control` 只在网页右键和返回行两个边界调用新入口,其他 JSON 转换和 WPF 宿主保持不变。
**Tech Stack:** .NET Framework 4.0、C# 7.3、Newtonsoft.Json 13.0.1、`System.Data.DataTable`、MSBuild、无第三方测试框架的控制台回归测试程序。
## Global Constraints
- 保留对象和数组字段,不删除 `$styles` 或其他未来字段。
- 复杂值必须转换成无缩进的紧凑 JSON 字符串。
- 从未出现对象或数组的标量列继续使用现有 Newtonsoft.Json 类型推断。
- 不修改现有 `JsonUtil.ToDataTable``JsonUtil.ToDataRow` 的语义。
- 不修改全局 Newtonsoft.Json 设置,不替换项目中的其他 `DeserializeObject<DataTable>` 调用。
- 不修改 WPF、数据库、菜单查找、参数替换或 DLL 加载逻辑。
- 只接入 `BsOpenModuleHandler.OpenRightModule``BsOpenModuleHandler.AddReturnRow`
- 现有两个目标源码文件只有 CRLF/LF 换行差异;执行前必须确认没有语义差异,再机械归一化,避免产生整文件噪声提交。
---
### Task 1: 建立回归测试并实现公共转换器
**Files:**
- Create: `插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj`
- Create: `插件库/Lskj.Util.Tests/Program.cs`
- Modify: `插件库/Lskj.Util/JsonUtil.cs:1-190`
**Interfaces:**
- Consumes: Newtonsoft.Json `JToken``JArray``JObject` 和现有 `DataTableConverter`
- Produces: `public static DataTable JsonUtil.ToDataTablePreservingComplexValues(string json)`;接受顶层对象或对象数组,返回保留所有字段的 `DataTable`
- [ ] **Step 1: 确认目标源码没有未提交的语义改动**
Run:
```bash
git diff --ignore-space-at-eol --exit-code -- \
'插件库/Lskj.Util/JsonUtil.cs' \
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
```
Expected: exit code `0`,无输出。当前普通 `git diff --numstat` 显示的是 CRLF/LF 差异,不代表业务代码变化。
- [ ] **Step 2: 机械归一化两个目标源码的换行符**
只有 Step 1 成功后执行:
```bash
perl -pi -e 's/\r$//' \
'插件库/Lskj.Util/JsonUtil.cs' \
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
git diff --check -- \
'插件库/Lskj.Util/JsonUtil.cs' \
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
```
Expected: `git diff --check` 无输出;此时两个文件不再显示整文件换行差异。
- [ ] **Step 3: 创建不依赖测试框架的回归测试项目**
Create `插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj`:
```xml
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8E501869-816F-4E3E-81EE-A3BF9C223D61}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Lskj.Util.Tests</RootNamespace>
<AssemblyName>Lskj.Util.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<OutputPath>bin\Debug\</OutputPath>
<PlatformTarget>AnyCPU</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Data" />
<Reference Include="Newtonsoft.Json, Version=13.0.1.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\引用DLL\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Lskj.Util\Lskj.Util.csproj">
<Project>{A51BF642-6543-4DE3-8948-83F558B72BD4}</Project>
<Name>Lskj.Util</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
```
Create `插件库/Lskj.Util.Tests/Program.cs`:
```csharp
using Lskj.Util;
using Newtonsoft.Json;
using System;
using System.Data;
namespace Lskj.Util.Tests
{
internal static class Program
{
private static int Main()
{
try
{
PreservesStylesObjectAsCompactJson();
PreservesArrayAsCompactJson();
NormalizesEveryValueInAMixedComplexColumn();
LeavesScalarColumnsEquivalentToExistingConverter();
AcceptsSingleObject();
RejectsInvalidTopLevelValues();
Console.WriteLine("PASS: JsonUtil complex-value conversion tests");
return 0;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
return 1;
}
}
private static void PreservesStylesObjectAsCompactJson()
{
const string json = "[{\"id\":1,\"$styles\":{\"rowstyle\":\"{color:'#FFFF00','background-color':'#FF0000'}\"}}]";
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
AssertEqual(1, table.Rows.Count, "styles row count");
AssertEqual("{\"rowstyle\":\"{color:'#FFFF00','background-color':'#FF0000'}\"}",
table.Rows[0]["$styles"].ToString(), "styles JSON");
}
private static void PreservesArrayAsCompactJson()
{
const string json = "[{\"id\":1,\"items\":[{\"code\":\"A\"},{\"code\":\"B\"}]}]";
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
AssertEqual("[{\"code\":\"A\"},{\"code\":\"B\"}]",
table.Rows[0]["items"].ToString(), "array JSON");
}
private static void NormalizesEveryValueInAMixedComplexColumn()
{
const string json = "["
+ "{\"id\":1,\"payload\":5},"
+ "{\"id\":2,\"payload\":{\"code\":\"A\"}},"
+ "{\"id\":3,\"payload\":[1,2]},"
+ "{\"id\":4,\"payload\":null},"
+ "{\"id\":5,\"payload\":\"ready\"}]";
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
AssertEqual(typeof(string), table.Columns["payload"].DataType, "mixed column type");
AssertEqual("5", table.Rows[0]["payload"].ToString(), "numeric scalar text");
AssertEqual("{\"code\":\"A\"}", table.Rows[1]["payload"].ToString(), "object text");
AssertEqual("[1,2]", table.Rows[2]["payload"].ToString(), "array text");
AssertTrue(table.Rows[3].IsNull("payload"), "null remains null");
AssertEqual("ready", table.Rows[4]["payload"].ToString(), "string remains string");
}
private static void LeavesScalarColumnsEquivalentToExistingConverter()
{
const string json = "[{\"id\":1,\"title\":\"A\",\"active\":true},{\"id\":2,\"title\":\"B\",\"active\":false}]";
DataTable expected = JsonConvert.DeserializeObject<DataTable>(json);
DataTable actual = JsonUtil.ToDataTablePreservingComplexValues(json);
AssertEqual(expected.Columns.Count, actual.Columns.Count, "scalar column count");
AssertEqual(expected.Rows.Count, actual.Rows.Count, "scalar row count");
foreach (DataColumn column in expected.Columns)
{
AssertEqual(column.DataType, actual.Columns[column.ColumnName].DataType,
"scalar column type " + column.ColumnName);
for (int rowIndex = 0; rowIndex < expected.Rows.Count; rowIndex++)
{
AssertEqual(expected.Rows[rowIndex][column.ColumnName],
actual.Rows[rowIndex][column.ColumnName],
"scalar value " + column.ColumnName + " row " + rowIndex);
}
}
}
private static void AcceptsSingleObject()
{
const string json = "{\"ProductId\":\"P001\",\"meta\":{\"source\":\"web\"}}";
DataTable table = JsonUtil.ToDataTablePreservingComplexValues(json);
AssertEqual(1, table.Rows.Count, "single object row count");
AssertEqual("P001", table.Rows[0]["ProductId"].ToString(), "single object scalar");
AssertEqual("{\"source\":\"web\"}", table.Rows[0]["meta"].ToString(), "single object nested JSON");
}
private static void RejectsInvalidTopLevelValues()
{
AssertThrows<ArgumentException>(delegate { JsonUtil.ToDataTablePreservingComplexValues(" "); }, "empty input");
AssertThrows<JsonReaderException>(delegate { JsonUtil.ToDataTablePreservingComplexValues("{"); }, "invalid JSON");
AssertThrows<JsonSerializationException>(delegate { JsonUtil.ToDataTablePreservingComplexValues("[1]"); }, "non-object row");
}
private static void AssertThrows<TException>(Action action, string name) where TException : Exception
{
try { action(); }
catch (TException) { return; }
throw new InvalidOperationException("Expected " + typeof(TException).Name + ": " + name);
}
private static void AssertTrue(bool value, string name)
{
if (!value) throw new InvalidOperationException("Assertion failed: " + name);
}
private static void AssertEqual<T>(T expected, T actual, string name)
{
if (!object.Equals(expected, actual))
{
throw new InvalidOperationException(name + ": expected <" + expected + ">, actual <" + actual + ">");
}
}
}
}
```
- [ ] **Step 4: 构建测试项目并确认它先失败**
Run in Windows PowerShell from `E:\lserp_project\lserp_cs_6.0`:
```powershell
$msbuild = Get-ChildItem "${env:ProgramFiles(x86)}\Microsoft Visual Studio\2022\*\MSBuild\Current\Bin\MSBuild.exe" |
Select-Object -First 1 -ExpandProperty FullName
if (-not $msbuild) { $msbuild = "$env:WINDIR\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" }
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
```
Expected: build fails with `CS0117` because `JsonUtil.ToDataTablePreservingComplexValues` does not exist yet. Dependency or SDK errors do not satisfy this step。
- [ ] **Step 5: 实现复杂字段归一化方法**
Add `using System.Globalization;` to `插件库/Lskj.Util/JsonUtil.cs`, then add this method to `JsonUtil` without changing existing methods:
```csharp
public static DataTable ToDataTablePreservingComplexValues(string json)
{
if (string.IsNullOrWhiteSpace(json))
{
throw new ArgumentException("网页行 JSON 不能为空。", "json");
}
JToken root = JToken.Parse(json);
JArray rows;
if (root.Type == JTokenType.Array)
{
rows = (JArray)root;
}
else if (root.Type == JTokenType.Object)
{
rows = new JArray(root);
}
else
{
throw new JsonSerializationException("网页行 JSON 的顶层必须是对象或对象数组。");
}
HashSet<string> complexColumns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (JToken rowToken in rows)
{
if (rowToken.Type != JTokenType.Object)
{
throw new JsonSerializationException("网页行 JSON 数组中的每一项都必须是对象。");
}
foreach (JProperty property in ((JObject)rowToken).Properties())
{
if (property.Value.Type == JTokenType.Object || property.Value.Type == JTokenType.Array)
{
complexColumns.Add(property.Name);
}
}
}
foreach (JObject row in rows.Children<JObject>())
{
foreach (JProperty property in row.Properties().ToList())
{
if (!complexColumns.Contains(property.Name)
|| property.Value.Type == JTokenType.Null
|| property.Value.Type == JTokenType.Undefined)
{
continue;
}
string text;
if (property.Value.Type == JTokenType.Object || property.Value.Type == JTokenType.Array)
{
text = property.Value.ToString(Formatting.None);
}
else if (property.Value.Type == JTokenType.String)
{
text = property.Value.Value<string>();
}
else
{
JValue scalar = property.Value as JValue;
text = scalar == null || scalar.Value == null
? null
: Convert.ToString(scalar.Value, CultureInfo.InvariantCulture);
}
property.Value = text == null ? JValue.CreateNull() : new JValue(text);
}
}
return JsonConvert.DeserializeObject<DataTable>(rows.ToString(Formatting.None));
}
```
- [ ] **Step 6: 构建并运行转换级回归测试**
```powershell
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests build failed" }
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
```
Expected: build succeeds and executable prints `PASS: JsonUtil complex-value conversion tests`.
- [ ] **Step 7: 提交公共转换器和回归测试**
```bash
git add \
'插件库/Lskj.Util/JsonUtil.cs' \
'插件库/Lskj.Util.Tests/Lskj.Util.Tests.csproj' \
'插件库/Lskj.Util.Tests/Program.cs'
git diff --cached --check
git commit -m 'fix(util): preserve complex JSON values in data tables'
```
Expected: commit only contains the new test project and the focused `JsonUtil` method.
---
### Task 2: 在旧浏览器桥接的两个入口接入转换器
**Files:**
- Modify: `插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs:101-116`
- Modify: `插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs:322-334`
**Interfaces:**
- Consumes: `JsonUtil.ToDataTablePreservingComplexValues(string json)` from Task 1。
- Produces: `OpenRightModule``AddReturnRow` 对任意对象/数组字段的兼容行为;其他菜单及模块调用接口不变。
- [ ] **Step 1: 将右键入口切换到公共转换器**
Replace:
```csharp
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(arrayItem);
```
with:
```csharp
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(arrayItem);
```
Do not change the `BaseImpl.GetDataRowResult` query, `GridRightMenuModel`, `DynamicModel` or `menu.ExecRightMenu` calls.
- [ ] **Step 2: 将网页返回行入口切换到公共转换器并删除冗余包装**
Replace:
```csharp
JObject rowObject = JsonConvert.DeserializeObject<JObject>(rowdata);
JArray jArray = new JArray();
jArray.Add(rowObject);
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(jArray));
```
with:
```csharp
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(rowdata);
```
Remove the now-unused `using Newtonsoft.Json;` and `using Newtonsoft.Json.Linq;`. Keep product-prefix renaming and `StaticControl.ReturnRowLisy.Add` unchanged.
- [ ] **Step 3: 静态检查浏览器桥接范围**
```bash
rg -n 'DeserializeObject\s*<\s*DataTable\s*>|ToDataTablePreservingComplexValues' \
'插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
git diff --check -- '插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
```
Expected: only two `ToDataTablePreservingComplexValues` calls remain in this file;没有直接的 `DeserializeObject<DataTable>`,且 `git diff --check` 无输出。
- [ ] **Step 4: 重跑转换级测试并构建 Lskj.Control**
```powershell
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
& $msbuild "插件库\Lskj.Control\Lskj.Control.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
if ($LASTEXITCODE -ne 0) { throw "Lskj.Control build failed" }
```
Expected: tests print `PASS``Lskj.Control` build succeeds without new warnings or errors and refreshes `Debug\Lskj.Control.dll` plus referenced `Lskj.Util.dll`.
- [ ] **Step 5: 提交浏览器桥接改动**
```bash
git add '插件库/Lskj.Control/BrowserSetting/BsOpenModuleHandler.cs'
git diff --cached --check
git commit -m 'fix(browser): accept nested values in row callbacks'
```
Expected: commit only changes the two intended browser callback conversions and removes the two unused Newtonsoft `using` directives.
---
### Task 3: 最终构建与业务验收交接
**Files:**
- Verify: `Debug/Lskj.Util.dll`
- Verify: `Debug/Lskj.Control.dll`
- Verify: `Debug/Ls_NERP.exe`
**Interfaces:**
- Consumes: Task 1 的转换器和 Task 2 的浏览器接入。
- Produces: 可由用户分别从旧 WinForms 和 WPF 宿主进行验收的 Debug 运行目录。
- [ ] **Step 1: 执行最终自动验证**
```powershell
& $msbuild "插件库\Lskj.Util.Tests\Lskj.Util.Tests.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests build failed" }
& "插件库\Lskj.Util.Tests\bin\Debug\Lskj.Util.Tests.exe"
if ($LASTEXITCODE -ne 0) { throw "Lskj.Util.Tests failed" }
& $msbuild "插件库\Lskj.Control\Lskj.Control.csproj" /t:Rebuild /p:Configuration=Debug /p:Platform=AnyCPU
if ($LASTEXITCODE -ne 0) { throw "Lskj.Control build failed" }
Get-Item "Debug\Lskj.Util.dll", "Debug\Lskj.Control.dll" |
Select-Object FullName, Length, LastWriteTime
```
Expected: both builds succeed, test executable prints `PASS`, and both runtime DLL timestamps reflect the current build.
- [ ] **Step 2: 核对最终差异和提交历史**
```bash
git diff --check
git status --short
git log -4 --oneline --decorate
```
Expected: no uncommitted implementation changes;历史包含设计提交、公共转换器提交和浏览器桥接提交。构建输出和原有忽略文件不应进入 Git。
- [ ] **Step 3: 交给用户执行业务验收**
Provide this exact checklist:
```text
1. 从 WPF 宿主启动,进入同一待办任务页面并点击“待办任务”。
2. 确认不再出现 Path '[0].$styles' / StartObject 的 DataTable 反序列化错误。
3. 确认右键配置继续解析到 PUR_4004,并正常进入原有客户端模块加载流程。
4. 使用一个不包含对象/数组字段的旧网页右键功能,确认行为未变化。
5. 如可用,再从旧 WinForms 入口重复步骤 1-4,确认两个宿主行为一致。
6. 验证网页返回行功能,确认 ProductId 前缀和原有回填逻辑未变化。
```
No additional source commit is required for this manual acceptance step.
@@ -0,0 +1,96 @@
# 173/174 Popup Contains Filtering Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Make the DevExpress auto-filter row in 173/174 extended-return result popups use contains matching instead of starts-with matching.
**Architecture:** Keep the shared popup and query flow unchanged. Set `GridColumn.OptionsFilter.AutoFilterCondition` when each host dynamically creates result columns, following the existing `AutoFilterCondition.Contains` pattern already used elsewhere in Lskj.Control.
**Tech Stack:** C# on .NET Framework 4.0, WinForms, DevExpress GridControl/GridView.
## Global Constraints
- Work in `E:\lserp_project\lserp_cs_6.0` on `main` and preserve unrelated work.
- Do not change database search SQL, search-column selection, ResultFields mapping, clear, selection, or display translation behavior.
- Apply the behavior to both MyControl and GridControlEx 173/174 popup result columns.
- Do not add dependencies or require a framework newer than .NET Framework 4.0.
- Do not push unless the user explicitly requests it.
---
### Task 1: Set dynamic popup result columns to contains filtering
**Files:**
- Modify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`
- Modify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`
**Interfaces:**
- Consumes: DevExpress `GridColumn.OptionsFilter.AutoFilterCondition` and `DevExpress.XtraGrid.Columns.AutoFilterCondition.Contains`.
- Produces: Contains-based local auto-filter behavior for every visible and hidden dynamic result column in both popup hosts.
- [ ] **Step 1: Run the failing structural contract**
Run from the repository root:
```powershell
$formPath = '插件库\Lskj.Control\AutoGridLookUp\LabelExtendedReturnSearchEdit.cs'
$gridPath = '插件库\Lskj.Control\GridControlEx.ExtendedReturn.cs'
$form = Get-Content -LiteralPath $formPath -Raw
$grid = Get-Content -LiteralPath $gridPath -Raw
$setting = 'column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;'
if (-not $form.Contains($setting)) { throw 'MyControl result columns do not use contains filtering.' }
if (-not $grid.Contains($setting)) { throw 'GridControlEx result columns do not use contains filtering.' }
```
Expected: fail on the MyControl assertion because neither dynamic result-column loop currently sets the condition.
- [ ] **Step 2: Implement the minimal per-column setting**
In `LabelExtendedReturnSearchEdit.ConfigureResultColumns`, immediately after assigning `column.Visible`, add:
```csharp
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
```
In `GridControlEx.ConfigureExtendedReturnViewColumns`, immediately after assigning `column.Visible`, add the identical line:
```csharp
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
```
Both files already import `DevExpress.XtraGrid.Columns`, so no new using directive is needed.
- [ ] **Step 3: Re-run the structural contract**
Run the exact PowerShell contract from Step 1.
Expected: exit code `0` with no exception.
- [ ] **Step 4: Compile the dependency chain in isolation**
Upload `/Users/langsukeji/Documents/MyApps/lserp_project/codex_compile_project.ps1` to `E:\lserp_project\codex_compile_project.ps1`. Create `E:\lserp_project\lserp_cs_6.0\DebugCodexFilterContains`, copy `Debug\*.dll` into it, then invoke the helper for these projects in order, using the temporary directory as both `DebugDirectory` and the output DLL directory:
1. `插件库\Lskj.Model\Lskj.Model.csproj`
2. `插件库\Lskj.Util\Lskj.Util.csproj`
3. `插件库\Lskj.Business\Lskj.Business.csproj`
4. `插件库\Lskj.Control\Lskj.Control.csproj`
Expected: all compiler exits are `0`; the existing `CS2023 /noconfig` warning is acceptable.
Delete the uploaded helper and `DebugCodexFilterContains` after compilation.
- [ ] **Step 5: Inspect and commit only the two source files**
```bat
git diff --check
git add -- "插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs" "插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs"
git diff --cached --check
git commit -m "fix(control): use contains filtering in extended lookup"
git status --short
```
Expected: commit succeeds and the working tree is clean.
- [ ] **Step 6: Hand off runtime verification**
Ask the user to verify both MyControl and GridControlEx 173/174 popups by entering a middle substring such as `板` into the auto-filter row for a value such as `钢板/Q235B`. Do not push automatically.
@@ -0,0 +1,652 @@
# 173/174 Extended Return Search Column and Local Filter Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a persistent search-column selector and DevExpress in-memory auto-filter row to the shared 173/174 popup without changing existing value display, ResultFields mapping, clearing, or selection behavior.
**Architecture:** Extend the shared SQL builder to distinguish visible searchable columns from hidden technical columns, then extend the shared popup to own column selection and local filtering state. The MyControl and grid hosts continue to own caption translation and asynchronous schema/query lifecycles; each request snapshots the selected real field name so background execution is deterministic.
**Tech Stack:** C# on .NET Framework 4.0, WinForms, DevExpress `PopupContainerEdit`/`ComboBoxEdit`/`GridControl`/`GridView`, ADO.NET provider factory, SQL Server-compatible derived-table SQL.
## Global Constraints
- Work in `E:\lserp_project\lserp_cs_6.0` on the current `main` branch and preserve unrelated work.
- Do not add NuGet dependencies or require a framework newer than .NET Framework 4.0.
- Keep 173 module SQL resolution and 174 configured SourceSql resolution unchanged.
- Keep ResultFields, ValueMember, TextMember, display-value translation, clear, mouse selection, arrow navigation, and Enter selection unchanged.
- Do not load complete lookup data during parent control initialization.
- Opening the popup may asynchronously execute only the existing `top 0` structure query.
- The selector displays translated result-grid captions but stores real source field names.
- Columns whose real names start with `_` are hidden from the selector and excluded from “所有列” database predicates.
- A new database search clears old DevExpress local filters and old results.
- DevExpress auto-filtering operates only on the returned result table and must not issue a database request.
- Preserve the last valid selector choice per popup instance; fall back to “所有列” only after a loaded schema proves that field no longer exists.
- The automatic popup-open lookup for an existing business value always searches all visible columns; it must not consume or reset the user's preserved selector choice.
- Keep the database result limit at 100 rows and continue using `@lookupKeyword` with existing LIKE escaping.
---
## File Map
- Modify `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs`: central hidden-column rule and selected-column SQL generation.
- Modify `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs`: selector UI, selection persistence, result/filter reset, and auto-filter row.
- Modify `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`: MyControl schema-only requests, translated selector options, and selected-field request snapshots.
- Modify `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`: grid schema-only requests, source-aware schema cache, translated selector options, and selected-field request snapshots.
- Do not add production source files or change `Lskj.Control.csproj`.
---
### Task 1: Make selected-column SQL generation a tested shared contract
**Files:**
- Modify: `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs:22-149`
- Test temporarily: `E:\lserp_project\codex_extended_return_support_tests.cs`
**Interfaces:**
- Consumes: `string sourceSql`, `DataColumnCollection columns`, `int maxRows`, and optional real `string searchField`.
- Produces: `IsSearchableColumn(string columnName)` and the overload `BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows, string searchField)` while preserving the existing three-argument overload.
- [ ] **Step 1: Write the failing SQL contract harness**
Create the temporary test source with this exact behavior:
```csharp
using System;
using System.Data;
using Lskj.Control.Model;
internal static class ExtendedReturnSupportContractTests
{
private static void Require(bool value, string message)
{
if (!value) throw new InvalidOperationException(message);
}
private static void RequireThrows(Action action, string message)
{
try
{
action();
}
catch (InvalidOperationException)
{
return;
}
throw new InvalidOperationException(message);
}
public static int Main()
{
DataTable schema = new DataTable();
schema.Columns.Add("productid");
schema.Columns.Add("appellation");
schema.Columns.Add("_rowid");
string allSql = ExtendedReturnSupport.BuildSearchSql(
"select productid, appellation, _rowid from p_ProductTab",
schema.Columns,
100,
string.Empty);
Require(allSql.Contains("[productid]"), "all columns omitted productid");
Require(allSql.Contains("[appellation]"), "all columns omitted appellation");
Require(!allSql.Contains("[_rowid]"), "all columns included hidden field");
string oneSql = ExtendedReturnSupport.BuildSearchSql(
"select productid, appellation, _rowid from p_ProductTab",
schema.Columns,
100,
"appellation");
Require(oneSql.Contains("[appellation]"), "selected column omitted appellation");
Require(!oneSql.Contains("[productid]"), "selected column included productid");
Require(!oneSql.Contains("[_rowid]"), "selected column included hidden field");
Require(!ExtendedReturnSupport.IsSearchableColumn("_rowid"), "hidden field is searchable");
Require(ExtendedReturnSupport.IsSearchableColumn("productid"), "business field is not searchable");
RequireThrows(delegate
{
ExtendedReturnSupport.BuildSearchSql("select 1", schema.Columns, 100, "_rowid");
}, "hidden selected field did not fail");
RequireThrows(delegate
{
ExtendedReturnSupport.BuildSearchSql("select 1", schema.Columns, 100, "missing");
}, "missing selected field did not fail");
Console.WriteLine("ExtendedReturnSupport contract tests passed.");
return 0;
}
}
```
- [ ] **Step 2: Compile the harness to prove it fails before implementation**
Run the production support file and harness through the installed Roslyn compiler with .NET Framework 4.0 references:
```bat
dotnet "C:\Program Files\dotnet\sdk\10.0.201\Roslyn\bincore\csc.dll" /nologo /target:exe /out:"E:\lserp_project\codex_extended_return_support_tests.exe" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" /reference:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Data.dll" "插件库\Lskj.Control\Model\ExtendedReturnSupport.cs" "E:\lserp_project\codex_extended_return_support_tests.cs"
```
Expected: compilation fails because the four-argument overload and `IsSearchableColumn` do not exist.
- [ ] **Step 3: Implement the visible-column rule and overload**
Keep the old overload as a compatibility wrapper and select columns using case-insensitive real field names:
```csharp
public static bool IsSearchableColumn(string columnName)
{
return !string.IsNullOrWhiteSpace(columnName) &&
!columnName.StartsWith("_", StringComparison.Ordinal);
}
public static string BuildSearchSql(
string sourceSql,
DataColumnCollection columns,
int maxRows)
{
return BuildSearchSql(sourceSql, columns, maxRows, string.Empty);
}
public static string BuildSearchSql(
string sourceSql,
DataColumnCollection columns,
int maxRows,
string searchField)
{
if (columns == null || columns.Count == 0)
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
if (maxRows <= 0)
throw new ArgumentOutOfRangeException("maxRows", "最大返回行数必须大于零。");
List<DataColumn> selectedColumns = new List<DataColumn>();
foreach (DataColumn column in columns)
{
if (!IsSearchableColumn(column.ColumnName)) continue;
if (string.IsNullOrWhiteSpace(searchField) ||
string.Equals(column.ColumnName, searchField, StringComparison.OrdinalIgnoreCase))
{
selectedColumns.Add(column);
}
}
if (selectedColumns.Count == 0)
{
throw new InvalidOperationException(string.IsNullOrWhiteSpace(searchField)
? "搜索 SQL 没有返回可见业务列。"
: string.Format("搜索字段“{0}”不存在或属于隐藏技术列。", searchField));
}
string alias = QuoteIdentifier(SearchAlias);
StringBuilder builder = new StringBuilder();
builder.AppendFormat("select top ({0}) * from ({1}) as {2} where ",
maxRows, NormalizeSourceSql(sourceSql), alias);
for (int i = 0; i < selectedColumns.Count; i++)
{
if (i > 0) builder.Append(" or ");
builder.Append("convert(nvarchar(4000), ");
builder.Append(alias);
builder.Append('.');
builder.Append(QuoteIdentifier(selectedColumns[i].ColumnName));
builder.Append(") like ");
builder.Append(SearchParameterName);
builder.Append(" escape N'\\'");
}
return builder.ToString();
}
```
- [ ] **Step 4: Compile and run the contract harness**
Run the same compiler command, then:
```bat
E:\lserp_project\codex_extended_return_support_tests.exe
```
Expected: exit code `0` and `ExtendedReturnSupport contract tests passed.`
- [ ] **Step 5: Remove temporary harness artifacts and commit Task 1**
```bat
del "E:\lserp_project\codex_extended_return_support_tests.cs"
del "E:\lserp_project\codex_extended_return_support_tests.exe"
git add -- "插件库/Lskj.Control/Model/ExtendedReturnSupport.cs"
git diff --cached --check
git commit -m "feat(control): support selected extended search columns"
```
---
### Task 2: Add selector persistence and local filter UI to the shared popup
**Files:**
- Modify: `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs:14-232`
**Interfaces:**
- Consumes: translated column options as `IEnumerable<KeyValuePair<string, string>>`, where key is the real field and value is the displayed caption.
- Produces: `SelectedSearchField`, `SetSearchColumns(...)`, and `ClearResultAndFilter()` for both hosts.
- [ ] **Step 1: Record failing structural assertions**
Run this PowerShell check before editing:
```powershell
$path = '插件库\Lskj.Control\AutoGridLookUp\ExtendedReturnSearchPopup.cs'
$text = Get-Content -LiteralPath $path -Raw
$required = @(
'ComboBoxEdit searchFieldEdit',
'searchPanel.ColumnCount = 4',
'ShowAutoFilterRow = true',
'SelectedSearchField',
'SetSearchColumns',
'ClearResultAndFilter'
)
foreach ($item in $required) {
if (-not $text.Contains($item)) { throw "Missing popup contract: $item" }
}
```
Expected: failure on the first missing popup contract.
- [ ] **Step 2: Add the selector option model and public popup contract**
Add `using Lskj.Control.Model;` and `using System.Collections.Generic;`. Inside `ExtendedReturnSearchPopup`, add a private option object and the host-facing API:
```csharp
private sealed class SearchColumnOption
{
public SearchColumnOption(string fieldName, string caption)
{
FieldName = fieldName ?? string.Empty;
Caption = caption ?? string.Empty;
}
public string FieldName { get; private set; }
public string Caption { get; private set; }
public override string ToString() { return Caption; }
}
public string SelectedSearchField
{
get
{
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
return option == null ? string.Empty : option.FieldName;
}
}
public void SetSearchColumns(IEnumerable<KeyValuePair<string, string>> columns)
{
string preferredField = selectedSearchField;
searchFieldEdit.Properties.BeginUpdate();
try
{
searchFieldEdit.Properties.Items.Clear();
SearchColumnOption all = new SearchColumnOption(string.Empty, "所有列");
searchFieldEdit.Properties.Items.Add(all);
SearchColumnOption selected = null;
if (columns != null)
{
foreach (KeyValuePair<string, string> column in columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.Key)) continue;
SearchColumnOption option = new SearchColumnOption(column.Key, column.Value);
searchFieldEdit.Properties.Items.Add(option);
if (string.Equals(option.FieldName, preferredField, StringComparison.OrdinalIgnoreCase))
selected = option;
}
}
searchFieldEdit.SelectedItem = selected ?? all;
selectedSearchField = selected == null ? string.Empty : selected.FieldName;
}
finally
{
searchFieldEdit.Properties.EndUpdate();
}
}
```
Add `selectedSearchField` and update it from `SelectedIndexChanged`; `PrepareForOpen()` must not reset it.
- [ ] **Step 3: Change the top layout and keep input focus behavior**
Instantiate a `ComboBoxEdit`, set `TextEditStyle = TextEditStyles.DisableTextEditor`, and change the layout to four columns:
```csharp
searchPanel.ColumnCount = 4;
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
searchPanel.Controls.Add(searchFieldEdit, 0, 0);
searchPanel.Controls.Add(searchEdit, 1, 0);
searchPanel.Controls.Add(queryButton, 2, 0);
searchPanel.Controls.Add(clearButton, 3, 0);
```
Set selector/input/query/clear tab indices to `0/1/2/3`. Keep `FocusSearchEditor()` focused on `searchEdit` so opening the popup still allows immediate typing.
- [ ] **Step 4: Enable and reset DevExpress local filtering**
Enable the built-in filter row and centralize clearing:
```csharp
resultView.OptionsView.ShowAutoFilterRow = true;
public void ClearResultAndFilter()
{
resultView.ClearColumnsFilter();
resultGrid.DataSource = null;
}
public void PrepareForOpen()
{
searchEdit.Text = string.Empty;
ClearResultAndFilter();
}
```
Do not attach the selector or auto-filter row to `SearchRequested`; only Enter in `searchEdit` and the query button raise database search events.
- [ ] **Step 5: Run structural assertions and compile `Lskj.Control`**
Run the Step 1 PowerShell check and the repositorys isolated C# compile helper. Expected: structural check exit `0` and `Lskj.Control` compile exit `0`.
- [ ] **Step 6: Commit Task 2**
```bat
git add -- "插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs"
git diff --cached --check
git commit -m "feat(control): add extended lookup filter UI"
```
---
### Task 3: Integrate schema-only loading and selected fields in MyControl
**Files:**
- Modify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs:37-60,294-360,616-760`
**Interfaces:**
- Consumes: `popup.SelectedSearchField`, `popup.SetSearchColumns(...)`, the existing `GetSchema(...)`, and the four-argument SQL builder.
- Produces: schema-only asynchronous requests and result delivery that configures selector options before optionally binding rows.
- [ ] **Step 1: Record failing MyControl integration assertions**
```powershell
$path = '插件库\Lskj.Control\AutoGridLookUp\LabelExtendedReturnSearchEdit.cs'
$text = Get-Content -LiteralPath $path -Raw
$required = @(
'public string SearchField;',
'public bool SchemaOnly;',
'public DataTable Schema;',
'popup.SelectedSearchField',
'popup.SetSearchColumns',
'MaxRows, request.SearchField'
)
foreach ($item in $required) {
if (-not $text.Contains($item)) { throw "Missing MyControl integration: $item" }
}
```
Expected: failure before implementation.
- [ ] **Step 2: Extend request/result snapshots**
Add exact state to the existing nested classes:
```csharp
private sealed class SearchRequest
{
public int Version;
public string SourceSql;
public string Keyword;
public string SearchField;
public string ConnectionString;
public bool SchemaOnly;
}
private sealed class QueryResult
{
public DataTable Schema;
public DataTable Table;
public Exception Error;
}
```
- [ ] **Step 3: Queue schema-only work on popup open**
Resolve `sourceSql` once in `PopupEdit_QueryPopUp`. After `PrepareForOpen()`:
```csharp
DataTable cachedSchema = TryGetSchema(sourceSql);
if (cachedSchema != null) ConfigureSearchColumns(cachedSchema);
if (!string.IsNullOrWhiteSpace(EditValue))
QueueSearch(sourceSql, EditValue, string.Empty, false);
else if (cachedSchema == null)
QueueSearch(sourceSql, string.Empty, string.Empty, true);
else
CancelSearch();
```
`TryGetSchema` must take `schemaSyncRoot` and return the cached table only when `schemaSql` equals the resolved SQL. `QueueSearch` replaces the old `StartSearch` request construction and snapshots `SearchField` and `SchemaOnly`. The popup-open lookup deliberately uses an empty search field so an existing actual ID is found independently of the preserved selector; only explicit Enter/query actions use `popup.SelectedSearchField`.
- [ ] **Step 4: Build translated options from schema**
Use existing caption translation and shared visibility rules:
```csharp
private void ConfigureSearchColumns(DataTable sourceSchema)
{
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
IList<ExtendedReturnFieldMapping> mappings =
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
foreach (DataColumn column in sourceSchema.Columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
options.Add(new KeyValuePair<string, string>(
column.ColumnName,
GetColumnCaption(column.ColumnName, mappings)));
}
popup.SetSearchColumns(options);
}
```
- [ ] **Step 5: Make query and delivery schema-aware**
`Query(SearchRequest request)` must always load and validate schema, set `result.Schema`, and execute row SQL only when `!request.SchemaOnly`:
```csharp
DataTable sourceSchema = GetSchema(request.SourceSql, request.ConnectionString);
result.Schema = sourceSchema;
IList<ExtendedReturnFieldMapping> mappings =
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
ValidateSourceColumns(sourceSchema.Columns, mappings);
if (!request.SchemaOnly)
{
string searchSql = ExtendedReturnSupport.BuildSearchSql(
request.SourceSql, sourceSchema.Columns, MaxRows, request.SearchField);
result.Table = ExecuteQuery(
searchSql,
ExtendedReturnSupport.BuildLikeParameterValue(request.Keyword),
request.ConnectionString);
}
```
Change delivery to receive the request, reject stale versions, call `ConfigureSearchColumns(result.Schema)`, and bind/configure result rows only when `result.Table != null`.
- [ ] **Step 6: Clear local filters on explicit database search**
In `Popup_SearchRequested`, call `popup.ClearResultAndFilter()` before queuing any non-empty keyword. Capture `popup.SelectedSearchField` in that same UI event. Empty keywords cancel work and leave a cleared result.
- [ ] **Step 7: Run assertions and compile through `Lskj.Control`**
Run the Step 1 check. Compile `Lskj.Model`, `Lskj.Util`, `Lskj.Business`, then `Lskj.Control` into an isolated dependency directory. Expected: all exits `0`.
- [ ] **Step 8: Commit Task 3**
```bat
git add -- "插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs"
git diff --cached --check
git commit -m "feat(control): add form extended lookup column search"
```
---
### Task 4: Integrate schema-only loading and selected fields in GridControlEx
**Files:**
- Modify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs:32-85,323-449,621-905,1189-1220`
**Interfaces:**
- Consumes: the shared popup contract and selected-column SQL builder from Tasks 1-2.
- Produces: per-grid-column source-aware schema caching, schema-only requests, and selected-field request snapshots within the existing serialized request state machine.
- [ ] **Step 1: Record failing grid integration assertions**
```powershell
$path = '插件库\Lskj.Control\GridControlEx.ExtendedReturn.cs'
$text = Get-Content -LiteralPath $path -Raw
$required = @(
'mExtendedReturnSchemaSqls',
'public string SearchField;',
'public bool SchemaOnly;',
'public DataTable Schema;',
'popup.SelectedSearchField',
'popup.SetSearchColumns',
'request.SearchField'
)
foreach ($item in $required) {
if (-not $text.Contains($item)) { throw "Missing grid integration: $item" }
}
```
Expected: failure before implementation.
- [ ] **Step 2: Make cached schemas source-aware**
Add:
```csharp
private readonly Dictionary<string, string> mExtendedReturnSchemaSqls =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
```
`GetExtendedReturnSchema` and a new `TryGetExtendedReturnSchema` must return a cached table only when both field name and resolved `sourceSql` match. Store the SQL beside each cached table and clear both dictionaries in `ResetExtendedReturnState()`.
- [ ] **Step 3: Extend grid request/result snapshots**
Add `SearchField` and `SchemaOnly` to `ExtendedLookupRequest`, plus `Schema` to `ExtendedLookupQueryResult`. Preserve the existing version, pending-request, and single-worker-per-field rules.
- [ ] **Step 4: Configure or asynchronously load schema on popup open**
In `ExtendedReturnSearch_QueryPopUp`, resolve source SQL after the business row is known. Configure selector options immediately from a matching cache. If the actual business value is empty and no schema is cached, enqueue a schema-only request; if it is non-empty, enqueue the normal initial search with an empty search field so it searches all visible columns without changing the preserved selector.
Use the existing caption method when building options:
```csharp
private void ConfigureExtendedReturnSearchColumns(
ExtendedReturnPopupContext context,
DataTable sourceSchema)
{
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
IList<ExtendedReturnFieldMapping> mappings =
ExtendedReturnSupport.ParseResultFields(context.Model.ResultFields);
foreach (DataColumn column in sourceSchema.Columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
options.Add(new KeyValuePair<string, string>(
column.ColumnName,
GetExtendedReturnColumnCaption(column.ColumnName, mappings)));
}
context.Popup.SetSearchColumns(options);
}
```
- [ ] **Step 5: Snapshot selector state for explicit searches**
`ExtendedReturnSearch_SearchRequested` must pass `popup.SelectedSearchField`. `StartExtendedReturnSearch` must clear the popups filters/results, reject an empty keyword, validate business configuration, resolve SQL, and enqueue a non-schema-only request containing the selected field.
- [ ] **Step 6: Make the worker result schema-aware without weakening stale-result guards**
`QueryExtendedReturn` must always populate `result.Schema`; it calls the four-argument SQL builder only for non-schema-only requests. In `BeginInvokeExtendedReturnResult`:
1. Keep every existing editor, focused column, business row, and request-version guard.
2. Configure selector options from `result.Schema`.
3. For schema-only requests, stop without setting `DeliveredVersion` or binding a result table.
4. For row requests, set `DeliveredVersion`, bind the result table, configure result columns, and retain existing popup visibility behavior.
- [ ] **Step 7: Run assertions and compile through `Lskj.Control`**
Run the Step 1 check and the isolated four-project compile chain. Expected: all exits `0`.
- [ ] **Step 8: Commit Task 4**
```bat
git add -- "插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs"
git diff --cached --check
git commit -m "feat(control): add grid extended lookup column search"
```
---
### Task 5: Final compatibility verification and delivery
**Files:**
- Verify: `插件库/Lskj.Control/Model/ExtendedReturnSupport.cs`
- Verify: `插件库/Lskj.Control/AutoGridLookUp/ExtendedReturnSearchPopup.cs`
- Verify: `插件库/Lskj.Control/AutoGridLookUp/LabelExtendedReturnSearchEdit.cs`
- Verify: `插件库/Lskj.Control/GridControlEx.ExtendedReturn.cs`
- Verify: `docs/superpowers/specs/2026-07-31-extended-return-search-column-filter-design.md`
**Interfaces:**
- Consumes: all contracts created in Tasks 1-4.
- Produces: a clean, compiled local `main` ready for user runtime verification and later push authorization.
- [ ] **Step 1: Re-run the SQL contract harness from a clean temporary file**
Recreate the exact Task 1 harness, compile it with the final support source, run it, and confirm exit `0`. Delete the temporary `.cs` and `.exe` afterward.
- [ ] **Step 2: Run final structural behavior checks**
Assert all of the following exact invariants with PowerShell `Get-Content -Raw` checks:
- Popup layout has four columns and `ShowAutoFilterRow = true`.
- `PrepareForOpen()` does not reset `selectedSearchField`.
- Both explicit search handlers read `SelectedSearchField` and call `ClearResultAndFilter()`.
- Both query paths call the four-argument SQL builder.
- Both schema delivery paths call `SetSearchColumns`.
- Grid reset clears both schema dictionaries.
- Existing `ClearRequested`, `ResultSelected`, row indicator, arrow-key, and Enter-key event hookups remain present.
- [ ] **Step 3: Compile the final dependency chain in isolation**
Use `E:\lserp_project\codex_compile_project.ps1` with a fresh `DebugCodexExtendedFilter` directory. Compile in this exact order:
1. `插件库\Lskj.Model\Lskj.Model.csproj`
2. `插件库\Lskj.Util\Lskj.Util.csproj`
3. `插件库\Lskj.Business\Lskj.Business.csproj`
4. `插件库\Lskj.Control\Lskj.Control.csproj`
Expected: each compiler exit is `0`; the known `CS2023 /noconfig` warning is acceptable.
- [ ] **Step 4: Inspect repository scope**
```bat
git diff --check origin/main...main
git status --short
git log --oneline --decorate -8
```
Expected: no whitespace errors, no temporary artifacts, and only the approved design/plan documents plus four production source files differ from the pre-feature base.
- [ ] **Step 5: Hand off runtime verification scenarios**
Report the ten scenarios in the design spec, emphasizing:
- selector captions and hidden-column exclusion;
- all-column versus single-column database behavior;
- selector persistence and fallback;
- auto-filter row local-only behavior and reset on new search;
- mouse/keyboard selection, clear, display translation, and ResultFields mapping for MyControl/grid with both 173 and 174.
Do not push until the user explicitly requests it.
@@ -0,0 +1,124 @@
# 浏览器 JSON 复杂字段兼容设计
## 背景
网页通过 `OpenOnRightClick` 将选中行 JSON 传入旧 WinForms 客户端。当前代码直接使用 Newtonsoft.Json 将 JSON 数组反序列化为 `DataTable`。当行数据包含对象或数组字段时,例如:
```json
{
"$styles": {
"rowstyle": "{color:'#FFFF00','background-color':'#FF0000'}"
}
}
```
`DataTableConverter` 无法把 `StartObject``StartArray` 直接写入普通 `DataColumn`,因此抛出 `Unexpected JSON token when reading DataTable`。字段名 `$styles` 本身合法,真正的问题是字段值为嵌套对象。
## 目标
- 保留对象和数组字段,不删除 `$styles` 或其他未来字段。
- 将复杂值转换成紧凑 JSON 字符串后再生成 `DataTable`
- 保持纯标量字段现有的列名、值和类型推断行为。
- 只影响网页与旧客户端交互的数据边界,不改变全局 Newtonsoft.Json 行为。
- 同时兼容右键调用和网页返回行两个浏览器入口。
## 非目标
- 不修改 WPF 启动、窗口或宿主逻辑。
- 不修改数据库中的 JSON。
- 不扁平化嵌套对象,不删除未知字段。
- 不替换项目中所有 `DeserializeObject<DataTable>` 调用。
- 不改变旧模块的菜单查找、参数替换和 DLL 加载流程。
## 方案比较
### 方案一:在浏览器边界归一化复杂列(采用)
解析网页 JSON,扫描整批记录,找出任一行中出现对象或数组值的列。将这些列的所有非空值统一转换为字符串,其中对象和数组使用紧凑 JSON;其他纯标量列保持不变。归一化后继续使用现有 Newtonsoft.Json `DataTable` 转换。
优点:影响范围小;保留现有标量类型;能处理未来任意字段名;可复用在两个浏览器入口。
### 方案二:手工构造全部为 `object` 的 DataTable
可以容纳复杂值,但会改变所有列的类型,可能影响比较、筛选、参数替换和旧模块中的类型判断,兼容风险较大。
### 方案三:注册全局 Newtonsoft.Json 转换器
可以统一处理,但会影响整个旧系统中大量 JSON 反序列化入口,难以证明不会改变其他模块行为,范围过宽。
## 详细设计
### 公共转换入口
`Lskj.Util.JsonUtil` 中增加一个含义明确的新方法,专门把可能包含复杂字段的网页行 JSON 转为 `DataTable`。不修改现有 `ToDataTable``ToDataRow` 的语义,避免影响未知调用方。
该方法接受:
- 顶层 JSON 数组,用于网页右键选中行。
- 顶层单个 JSON 对象,用于网页返回一行数据;内部统一包装成数组处理。
空输入、非对象行或其他不符合约定的顶层结构视为无效输入,抛出可诊断异常,继续交给当前宿主的既有异常保护策略处理。
### 复杂列识别
必须先扫描全部记录,再执行转换。只要某列在任意一行中的值为 `JObject``JArray`,该列就被标记为复杂列。
不能只转换当前遇到的复杂值。例如第一行是数字、第二行是对象时,如果第一行已让 `DataTable` 将列推断为数值类型,第二行即使变成字符串仍会发生类型冲突。
### 值归一化规则
对于复杂列:
- `JObject` 转换为不带缩进和额外空白的 JSON 字符串。
- `JArray` 转换为不带缩进和额外空白的 JSON 字符串。
- 同列中的字符串保持原字符串内容。
- 同列中的数字、布尔值等标量转换为稳定的字符串表示,确保整列类型一致。
- `null` 保留为空值,不转换为空字符串。
对于从未出现对象或数组的列,不进行任何预处理,由现有 `DataTableConverter` 继续推断原有类型。
### 调用点
仅替换以下两个浏览器桥接入口的直接反序列化:
1. `Lskj.Control.BrowserSetting.BsOpenModuleHandler.OpenRightModule`
2. `Lskj.Control.BrowserSetting.BsOpenModuleHandler.AddReturnRow`
`OpenRightModule` 后续仍把原有 `DataRow[]` 交给 `BaseRightMenu.ExecRightMenu`。菜单 ID 查询、占位符替换、`PUR_4004` 模块解析和 DLL 加载逻辑不变。
`AddReturnRow` 后续仍执行现有产品前缀处理并加入 `StaticControl.ReturnRowLisy`
### 下游兼容性
经过归一化的 `DataRow` 再序列化传给动态模块时,复杂字段已经是普通字符串。下游 `DynamicModuleModel``DynamicModuleDetailModel` 等现有 `DataTable` 反序列化可继续工作,无需全局改造。
## 异常处理
- 合法对象/数组字段不再产生 `StartObject``StartArray` 异常。
- 语法错误的 JSON、非对象行等仍作为真实错误报告,不静默删除数据。
- 转换方法不吞异常;沿用当前宿主已经建立的异常保护策略,避免用空表或残缺数据掩盖真实输入错误。
- 错误信息应保留原始异常,便于定位具体字段和输入。
## 验证方案
### 转换级测试
1. 当前实际 `$styles` 对象:成功生成一行,`$styles` 为紧凑 JSON 字符串。
2. 任意名称的嵌套对象字段:成功并保留字段名和内容。
3. 数组字段:成功并保留为紧凑 JSON 字符串。
4. 同一复杂列在不同行中分别为对象、字符串、数字和 `null`:整列稳定转换,不发生类型冲突。
5. 只有标量的原有 JSON:列和值与修改前一致。
6. 单对象输入:用于 `AddReturnRow` 时成功生成一行。
7. 无效 JSON 和非对象数组元素:明确失败,不产生不完整数据。
### 集成验证
1. 使用当前待办任务 JSON 点击网页“待办任务”,不再出现 `$styles``DataTable` 反序列化错误。
2. 右键配置 ID 能继续解析,模块编号 `PUR_4004` 正常传入原 DLL 加载流程。
3. 不含复杂字段的网页右键功能行为不变。
4. 网页返回行功能仍可回填,包含复杂字段时不崩溃。
5. 分别通过旧 WinForms 启动和 WPF 宿主启动验证相同行为。
## 构建与交付
改动位于旧代码项目。完成后重新编译并更新运行目录使用的 `Lskj.Util.dll``Lskj.Control.dll`WPF 项目无需为本修复修改代码。
@@ -0,0 +1,32 @@
# 173/174 弹窗本地筛选改为包含匹配
## 目标
将 173/174 扩展返回弹窗中 DevExpress 自动筛选行的文本匹配方式,从默认的“开头匹配”改为“包含匹配”。例如在“物料名称”筛选框输入“板”,应匹配“钢板/Q235B”。
## 根因
共享弹窗已经启用 `ShowAutoFilterRow`,但 MyControl 与 GridControlEx 在查询完成后动态创建结果列时,没有设置 `GridColumn.OptionsFilter.AutoFilterCondition`,因此沿用了 DevExpress 默认的开头匹配。
项目内其他表格列已普遍使用 `AutoFilterCondition.Contains`,可直接沿用这一兼容写法。
## 设计
仅修改两处动态结果列创建逻辑:
- `LabelExtendedReturnSearchEdit.ConfigureResultColumns`
- `GridControlEx.ConfigureExtendedReturnViewColumns`
每个结果列创建后设置:
```csharp
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
```
不修改共享弹窗事件,不增加自定义筛选处理,不改变数据库查询 SQL、搜索列下拉框、ResultFields 映射、清空、选择和显示翻译逻辑。
## 验证
- 结构检查确认两处动态列均设置 `Contains`
- 编译 `Lskj.Model``Lskj.Util``Lskj.Business``Lskj.Control`
- 运行时由用户确认:自动筛选行输入位于文本中间的内容时仍能命中结果。
@@ -0,0 +1,130 @@
# 173/174 扩展返回搜索列与本地筛选设计
## 背景
173“模块选择返回 Id-扩展”和 174“搜索返回 Id-扩展”目前共用 `ExtendedReturnSearchPopup`。弹窗只提供一个搜索输入框,数据库查询会对数据源返回的全部列拼接 `OR LIKE`。结果表格已使用 DevExpress `GridView`,但没有显示自动筛选行。
本次改动在不改变现有数据源解析、ResultFields 回填、显示值翻译和键盘选择行为的前提下,增加数据库搜索列选择及结果集本地二次筛选。
## 目标
- 弹窗顶部增加搜索列下拉框。
- 支持“所有列”数据库搜索和指定单列数据库搜索。
- 下拉项显示与结果表头一致的中文标题,内部使用真实数据源字段名。
- `_` 开头的隐藏技术列不进入下拉,也不参与“所有列”搜索。
- 下方 DevExpress 表格显示自动筛选行,对数据库已返回的数据进行本地二次筛选。
- 173、174 在表格控件和 MyControl 中保持一致行为。
- 保留原有清空、选择、回填、显示和键盘操作。
## 非目标
- 不修改 173 的模块数据源解析规则。
- 不修改 174 的 SourceSql 配置规则。
- 不修改 ResultFields、ValueMember、TextMember 的含义或校验。
- 不把 DevExpress 自动筛选条件发送到数据库。
- 不在控件初始化阶段加载完整业务数据。
- 不跨应用重启持久化搜索列选择。
## 交互设计
弹窗顶部从左到右排列:
1. 搜索列下拉框。
2. 搜索文本输入框。
3. “查询”按钮。
4. “清空”按钮。
下拉框规则:
- 第一项固定为“所有列”。
- 后续项来自实际数据源结构,只包含名称不以 `_` 开头的列。
- 显示文本复用结果表格现有列标题翻译逻辑;选项内部保存真实字段名。
- 每个 173/174 控件实例在内存中保留最后一次选择,关闭并重新打开弹窗时不重置。
- 数据源结构变化且原选择字段已不存在时,自动回退到“所有列”。
输入框仍按现有方式仅在回车或点击“查询”时访问数据库。上下键进入结果表、结果表回车选择、鼠标点击选择和“清空”按钮行为保持不变。
## 数据结构加载
弹窗打开时只异步执行现有 `top 0` 结构查询,用于取得列名,不加载完整业务数据。
- 已有缓存结构时立即构建下拉项,不重复访问数据库。
- 首次打开且尚无缓存时,下拉先保留“所有列”,结构查询完成后补充列项。
- 如果当前业务值非空,现有首次搜索请求同时取得并缓存结构,无需额外加载完整数据。
- 弹窗关闭、控件销毁或请求版本已过期时丢弃后台返回结果,不更新已经失效的界面。
## 数据库搜索
`ExtendedReturnSupport.BuildSearchSql` 增加可选搜索字段参数:
- “所有列”:只对所有可见业务列生成 `OR LIKE` 条件。
- 指定列:校验字段存在且不是隐藏列,只为该列生成 `LIKE` 条件。
- 返回结果仍保留数据源的全部列,包括隐藏技术列,以免破坏 ResultFields 回填。
- 继续使用现有 `@lookupKeyword` 参数、LIKE 转义和字段名引用,不把输入文本或下拉显示标题直接拼入 SQL。
- 最大返回行数继续保持 100。
搜索请求必须在提交时同时快照关键字和真实字段名,避免后台查询期间用户切换下拉导致请求含义变化。
## 本地二次筛选
共享结果 `GridView` 启用 DevExpress `OptionsView.ShowAutoFilterRow`
- 自动筛选只作用于当前绑定的最多 100 行结果,不触发数据库查询。
- 每次按回车或点击“查询”发起新的数据库搜索前,清除全部本地筛选条件和旧结果。
- 关闭并重新打开弹窗时不保留上一次的本地筛选条件。
- 自动筛选后的焦点行仍可通过回车或鼠标点击执行原有 ResultFields 回填。
## 代码边界
### `ExtendedReturnSearchPopup`
- 负责下拉框、输入框、按钮和结果表的布局。
- 暴露当前真实搜索字段,不包含 SQL 或业务映射逻辑。
- 接收调用方生成的“真实字段名 + 中文标题”选项。
- 负责保留有效选择、无效选择回退、清空本地筛选及启用自动筛选行。
### `ExtendedReturnSupport`
- 统一生成“所有可见列”或“指定可见列”的参数化搜索 SQL。
- 统一判定 `_` 开头的隐藏技术列,避免表格和 MyControl 产生不同规则。
- 对不存在、隐藏或空白的指定字段给出明确配置错误。
### `LabelExtendedReturnSearchEdit`
- 为 MyControl 173/174 异步加载和缓存数据源结构。
- 使用现有业务控件标签生成中文列标题。
- 把下拉选择快照带入后台搜索请求。
### `GridControlEx.ExtendedReturn`
- 为表格 173/174 异步加载和缓存每个字段的数据源结构。
- 使用现有表格列标题翻译逻辑生成中文列标题。
- 把下拉选择快照带入现有每列串行查询状态机。
## 兼容性与错误处理
- 默认选择“所有列”时,用户操作方式与现有版本一致,但隐藏技术列不再参与模糊搜索。
- 173 继续通过模块编号解析 SQL,174 继续直接使用配置 SQL。
- 结构查询或业务查询失败时沿用现有提示机制,不能覆盖当前业务值或 ResultFields 字段。
- 后台返回旧版本结果时继续丢弃,不覆盖更新的搜索结果。
- 清空按钮仍清空当前业务行全部 ResultFields 映射字段并关闭弹窗。
- 原业务列仍为只读弹出编辑器,弹窗搜索文本不参与业务字段显示或保存。
## 验收场景
1. 首次打开空值控件,只执行结构查询,下拉最终显示“所有列”和所有可见中文列名。
2. 选择“所有列”搜索时,SQL 条件只包含非 `_` 开头的列。
3. 选择单列搜索时,SQL 条件只包含该真实字段。
4. 关闭后重开同一控件,保留上次有效搜索列;数据源缺少该列时回退到“所有列”。
5. 新数据库搜索会清除旧自动筛选条件。
6. 自动筛选行改变可见结果但不产生数据库请求。
7. 筛选后鼠标点击、上下键和回车仍能选择正确 DataRow 并完成 ResultFields 回填。
8. `_` 开头的列不显示、不进入下拉、不参与“所有列”搜索,但仍可作为 ResultFields 映射来源。
9. 表格和 MyControl 的 173、174 四种组合行为一致。
10. 原有清空、显示值翻译、实际值保存和模块数据源加载保持正常。
## 验证范围
- 对 SQL 构建规则、隐藏列排除、指定列校验和选择回退进行结构化检查。
- 编译 `Lskj.Model``Lskj.Util``Lskj.Business``Lskj.Control`
- 运行时验收由实际 ERP 界面对上述十个场景进行人工验证。
+3 -3
View File
@@ -21,14 +21,14 @@ namespace NewMyFormDesigner
{
MyFormDesigner myFormDesigner = new MyFormDesigner();
//myFormDesigner.FrmKey = "{83184D92-F406-487E-9110-2CB991BFA817}";//B32C9D6E-EB85-4CE1-9B81-2B22EDF2D125 56F43621-6C15-4BDD-8870-98D235ECAB91
//myFormDesigner.FrmKey = "{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}";//B32C9D6E-EB85-4CE1-9B81-2B22EDF2D125 56F43621-6C15-4BDD-8870-98D235ECAB91
//myFormDesigner.SelectSQL = @"select b.orderid,b.id as fieldid,fieldname,username1 as username,
// fieldsqltag as fieldtypeid,defaultdate as defaultValue
// from p_systemDlltab a
// left join p_systemwordbooktab b on a.DllCoid=b.tab where a.formkey='{83184D92-F406-487E-9110-2CB991BFA817}' and fieldsqltag<>3 and username1 is not null and isnull(addVisible,0)=0";
// left join p_systemwordbooktab b on a.DllCoid=b.tab where a.formkey='{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}' and fieldsqltag<>3 and username1 is not null and isnull(addVisible,0)=0";
//myFormDesigner.updateSQL = @"update p_systemwordbooktab set controlleft=b.controlleft ,controlTop=b.controlTop, controlHeight=b.controlHeight,controlWidth=b.controlWidth, tabOrder=b.tabOrder from p_systemControlLocation b where p_systemwordbooktab.formKey=b.formKey and p_systemwordbooktab.id=b.fieldId and b.formkey='{83184D92-F406-487E-9110-2CB991BFA817}'";
//myFormDesigner.updateSQL = @"update p_systemwordbooktab set controlleft=b.controlleft ,controlTop=b.controlTop, controlHeight=b.controlHeight,controlWidth=b.controlWidth, tabOrder=b.tabOrder from p_systemControlLocation b where p_systemwordbooktab.formKey=b.formKey and p_systemwordbooktab.id=b.fieldId and b.formkey='{D50D2D31-2120-4AE5-9F27-6F363AB6E76C}'";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+15 -6
View File
@@ -162,18 +162,27 @@ namespace Lskj.AutoWordFile
}
private DataSet Worddata(string modid, int tagid, int mid)
{
SqlParameter[] param =
try
{
SqlParameter[] param =
{
new SqlParameter("@modid",SqlDbType.VarChar,15),
new SqlParameter("@tagid",SqlDbType.Int),
new SqlParameter("@Mid",SqlDbType.Int)
};
param[0].Value = modid;
param[1].Value = tagid;
param[2].Value = mid;
DataSet ds = SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "pr_system_File01", "#ba_firstpage", param);
return ds;
param[0].Value = modid;
param[1].Value = tagid;
param[2].Value = mid;
DataSet ds = SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "pr_system_File01", "#ba_firstpage", param);
return ds;
}
catch (Exception ex)
{
throw;
}
}
public void Mulu()
{
@@ -615,7 +615,7 @@ namespace Lskj.BaseAccraditation
{
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
}
this.UpdateCirculationData();
string billType = this._flowRowData != null ? _flowRowData[this.ModuleModelObj.BillType] + "" : "";
if (string.IsNullOrEmpty(billType) || billType == "0")
{
@@ -1733,6 +1733,7 @@ namespace Lskj.BaseAccraditation
{
string printFile = e.Item.Tag + "";
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
this.UpdateCirculationData();
string printPath = PubUtil.PrintFileAbsolutelyPath;
if (!File.Exists(printPath))
{
@@ -1911,6 +1912,7 @@ namespace Lskj.BaseAccraditation
if (this.ModuleModelObj.SaveSuccessfullyRefresh && !isSuccess) return;//保存成功才刷新
// 刷新主表
this._flowRowData = BaseAuditImpl.GetCurrentFlowRowData(this.ModuleModelObj.MenuTable, this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
this.UpdateCirculationData();
this._baseRowData = BaseAuditImpl.GetCurrentControlData(ReplaceHelper.ReplaceWhereCond(ReplaceHelper.ReplaceUserInfo(this.ModuleModelObj.MenuSql)), this.ModuleModelObj.ParmaryKey, this.SysModel.PrimaryValue);
if (this._baseRowData == null) this._baseRowData = this._flowRowData;
this.ControlObj.CanExecControl = false;
@@ -2915,5 +2917,25 @@ namespace Lskj.BaseAccraditation
}
}
/// <summary>
/// 更新当前流转数据
/// </summary>
public void UpdateCirculationData()
{
if (SystemInfo.Instance.IsSpecialAuditSave)
{
DataTable snapshotTable = this._flowRowData.Table.Clone();
DataRow snapshotRow = snapshotTable.NewRow();
snapshotRow.ItemArray = (object[])this._flowRowData.ItemArray.Clone();
snapshotTable.Rows.Add(snapshotRow);
snapshotTable.AcceptChanges();
this.ControlObj.beforeData = snapshotRow;
}
}
}
}
+10 -9
View File
@@ -290,15 +290,16 @@ namespace Lskj.Business.Impl
return 1;
}
//2026-08-08 pz说不要判断,工具统一处理
//P_MessageToolLinkDllTab表中cardId=-99为通用模块(右侧快捷通道通用模块),默认有权限 2023-12-4 徐成说的cardId=-99的配置
string sql = string.Format("select a.*,b.PurviewId,b.MouseOutImg,b.MouseOverImg1 from("
+ " select * from P_MessageToolLinkDllTab where cardId=-99 and ( grouptagid=2 or grouptagid=1) "
+ ")a join p_formmenuconfigtab b on a.LMenuId=b.MenuId where LinkModeTag=1 and LMenuid='{1}' order by grouptagid,ItemTagId", ERPInfo.Instance.UserId, menuId);
DataTable table = SqlHelper.ExecuteDataTable(sql);
if (table.Rows.Count > 0)
{
return 1;
}
//string sql = string.Format("select a.*,b.PurviewId,b.MouseOutImg,b.MouseOverImg1 from("
// + " select * from P_MessageToolLinkDllTab where cardId=-99 and ( grouptagid=2 or grouptagid=1) "
// + ")a join p_formmenuconfigtab b on a.LMenuId=b.MenuId where LinkModeTag=1 and LMenuid='{1}' order by grouptagid,ItemTagId", ERPInfo.Instance.UserId, menuId);
//DataTable table = SqlHelper.ExecuteDataTable(sql);
//if (table.Rows.Count > 0)
//{
// return 1;
//}
if (ERPInfo.Instance.UserName == ERPInfo.Instance.UserManager)
return 1;
@@ -1234,7 +1235,7 @@ namespace Lskj.Business.Impl
public static bool GetOpenRestrictions(string MenuId)
{
if (BaseImpl.HasExistsColumn("p_formmenuconfigtab", "SingleOpenMode"))
if (ERPInfo.Instance.SingleOpenMode)
{
string sqlValue = string.Format("SELECT SingleOpenMode from p_formmenuconfigtab where MenuId='{0}'", MenuId);
DataTable dtTable = SqlHelper.ExecuteDataTable(sqlValue);
+178 -42
View File
@@ -1059,6 +1059,28 @@ namespace Lskj.Business.Impl
table.Columns["tagid"].ColumnName = "nullable";
}
if (!table.Columns.Contains("resultfields") && HasExistsColumn("p_systemwordbooktab", "resultfields"))
{
table.Columns.Add("resultfields", typeof(string));
DataTable resultFieldsTable = SqlHelper.ExecuteDataTable(
"select id,isnull(resultfields,'') resultfields from p_systemwordbooktab where tab=@modid",
new SqlParameter[] { new SqlParameter("@modid", menuCode) });
Dictionary<string, string> resultFieldsById = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (DataRow row in resultFieldsTable.Rows)
{
resultFieldsById[row["id"] + ""] = row["resultfields"] + "";
}
foreach (DataRow row in table.Rows)
{
string resultFields;
if (table.Columns.Contains("id") && resultFieldsById.TryGetValue(row["id"] + "", out resultFields))
{
row["resultfields"] = resultFields;
}
}
}
return table;
}
/// <summary>
@@ -1146,26 +1168,86 @@ namespace Lskj.Business.Impl
where = " and isnull(menutype,0)=0";
break;
}
string sqlTemplate = @"WITH UserRoles AS (
SELECT r.roleName
FROM p_systemRoleOperSetTab AS ro
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
WHERE ro.operatorname = '{0}'
)
SELECT pm.*
FROM P_systempopupmenu AS pm WITH (NOLOCK)
WHERE ISNULL(pm.visible, 0) = 0
AND pm.tab = '{1}'
AND (
ISNULL(pm.privilegeOper, '') = ''
OR CHARINDEX(',' + '{0}' + ',', ',' + pm.privilegeOper + ',') > 0
OR EXISTS (
SELECT 1
FROM UserRoles AS ur
WHERE CHARINDEX('{{&' + ur.roleName + '&}}', pm.privilegeOper) > 0)
) {2} ORDER BY pm.orderid;";
string sqlValue = string.Format(sqlTemplate, ERPInfo.Instance.UserName, key, where);
return SqlHelper.ExecuteDataTable(sqlValue);
string sqlValue = string.Format(@"SELECT pm.*
FROM P_systempopupmenu AS pm WITH (NOLOCK)
WHERE ISNULL(pm.visible, 0) = 0
AND pm.tab = @tab {0}
ORDER BY pm.orderid;", where);
DataTable rightMenuTable = SqlHelper.ExecuteDataTable(sqlValue,
new SqlParameter[] { new SqlParameter("@tab", key) });
return FilterRowsByOperatorPrivilege(rightMenuTable, "privilegeOper");
}
/// <summary>
/// 根据人员或角色权限过滤配置数据,只有存在角色配置时才读取角色表。
/// </summary>
internal static DataTable FilterRowsByOperatorPrivilege(DataTable sourceTable, string privilegeField)
{
if (sourceTable == null || !sourceTable.Columns.Contains(privilegeField))
{
return sourceTable;
}
string operatorName = ERPInfo.Instance.UserName;
string operatorToken = "," + operatorName + ",";
List<DataRow> rolePermissionRows = new List<DataRow>();
HashSet<DataRow> allowedRows = new HashSet<DataRow>();
foreach (DataRow row in sourceTable.Rows)
{
string privilegeOper = row[privilegeField] + "";
if (string.IsNullOrWhiteSpace(privilegeOper) ||
("," + privilegeOper + ",").IndexOf(operatorToken, StringComparison.OrdinalIgnoreCase) >= 0)
{
allowedRows.Add(row);
continue;
}
// 只配置人员且当前人员不匹配时,无需读取角色表。
if (privilegeOper.IndexOf("{&", StringComparison.Ordinal) >= 0 &&
privilegeOper.IndexOf("&}", StringComparison.Ordinal) >= 0)
{
rolePermissionRows.Add(row);
}
}
if (rolePermissionRows.Count == 0)
{
DataTable resultTable = sourceTable.Clone();
foreach (DataRow row in sourceTable.Rows)
{
if (allowedRows.Contains(row)) resultTable.ImportRow(row);
}
return resultTable;
}
string roleSql = @"SELECT r.roleName
FROM p_systemRoleOperSetTab AS ro
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
WHERE ro.operatorname = @operatorname";
DataTable roleTable = SqlHelper.ExecuteDataTable(roleSql,
new SqlParameter[] { new SqlParameter("@operatorname", operatorName) });
string[] roleTokens = roleTable.Rows.Cast<DataRow>()
.Select(row => row["roleName"] + "")
.Where(roleName => !string.IsNullOrWhiteSpace(roleName))
.Select(roleName => "{&" + roleName + "&}")
.ToArray();
foreach (DataRow row in rolePermissionRows)
{
string privilegeOper = row[privilegeField] + "";
if (roleTokens.Any(token => privilegeOper.IndexOf(token, StringComparison.OrdinalIgnoreCase) >= 0))
{
allowedRows.Add(row);
}
}
DataTable resultTableWithRoles = sourceTable.Clone();
foreach (DataRow row in sourceTable.Rows)
{
if (allowedRows.Contains(row)) resultTableWithRoles.ImportRow(row);
}
return resultTableWithRoles;
}
/// <summary>
/// 获取单个右键菜单
@@ -1272,7 +1354,73 @@ namespace Lskj.Business.Impl
p[1].Value = menuCode;
p[2].Value = ERPInfo.Instance.UserName;
return SqlHelper.ExecuteDataSet(CommandType.StoredProcedure, "p_getControlLocation", "temp", p).Tables[0];
DataTable table = SqlHelper.ExecuteDataSet(
CommandType.StoredProcedure,
"p_getControlLocation",
"temp",
p).Tables[0];
AppendExtendedReturnResultFields(table, menuCode);
return table;
}
/// <summary>
/// p_getControlLocation 的旧版本不返回 resultfields。
/// 仅当窗体包含 173/174 扩展返回控件时按模块补取,普通窗体不增加查询。
/// </summary>
private static void AppendExtendedReturnResultFields(DataTable table, string menuCode)
{
if (table == null || table.Rows.Count == 0 ||
!table.Columns.Contains("id") || !table.Columns.Contains("fieldTypeId"))
{
return;
}
List<DataRow> extendedRows = new List<DataRow>();
bool allConfigured = table.Columns.Contains("resultfields");
foreach (DataRow row in table.Rows)
{
int fieldType;
if (!int.TryParse(row["fieldTypeId"] + "", out fieldType) ||
(fieldType != 173 && fieldType != 174))
{
continue;
}
extendedRows.Add(row);
if (!table.Columns.Contains("resultfields") ||
string.IsNullOrWhiteSpace(row["resultfields"] + ""))
{
allConfigured = false;
}
}
if (extendedRows.Count == 0 || allConfigured) return;
if (!HasExistsColumn("p_systemwordbooktab", "resultfields")) return;
if (!table.Columns.Contains("resultfields"))
{
table.Columns.Add("resultfields", typeof(string));
}
DataTable resultFieldsTable = SqlHelper.ExecuteDataTable(
"select id,isnull(resultfields,'') resultfields " +
"from p_systemwordbooktab where tab=@modid",
new SqlParameter[] { new SqlParameter("@modid", menuCode) });
Dictionary<string, string> resultFieldsById =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
foreach (DataRow row in resultFieldsTable.Rows)
{
resultFieldsById[row["id"] + ""] = row["resultfields"] + "";
}
foreach (DataRow row in extendedRows)
{
string resultFields;
if (resultFieldsById.TryGetValue(row["id"] + "", out resultFields))
{
row["resultfields"] = resultFields;
}
}
}
/// <summary>
/// <para>说明:获取添加界面多标签</para>
@@ -1313,26 +1461,14 @@ namespace Lskj.Business.Impl
{
try
{
string sqlTemplate = @"WITH UserRoles AS (
SELECT r.roleName
FROM p_systemRoleOperSetTab AS ro
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
WHERE ro.operatorname = '{0}'
)
SELECT pm.*
FROM p_systemDlltabDetail AS pm WITH (NOLOCK)
WHERE ISNULL(pm.isvisible, 0) = 0
AND pm.tab = '{1}'
AND (
ISNULL(pm.privilegeOper, '') = ''
OR CHARINDEX(',' + '{0}' + ',', ',' + pm.privilegeOper + ',') > 0
OR EXISTS (
SELECT 1
FROM UserRoles AS ur
WHERE CHARINDEX('{{&' + ur.roleName + '&}}', pm.privilegeOper) > 0)
) ORDER BY pm.orderid;";
string sqlValue = string.Format(sqlTemplate, ERPInfo.Instance.UserName, menuCode);
return SqlHelper.ExecuteDataTable(sqlValue);
string sqlValue = @"SELECT pm.*
FROM p_systemDlltabDetail AS pm WITH (NOLOCK)
WHERE ISNULL(pm.isvisible, 0) = 0
AND pm.tab = @tab
ORDER BY pm.orderid;";
DataTable detailPageTable = SqlHelper.ExecuteDataTable(sqlValue,
new SqlParameter[] { new SqlParameter("@tab", menuCode) });
return FilterRowsByOperatorPrivilege(detailPageTable, "privilegeOper");
}
catch (Exception)
{
@@ -1436,4 +1572,4 @@ namespace Lskj.Business.Impl
}
}
}
}
+27 -19
View File
@@ -461,6 +461,8 @@ namespace Lskj.Business.Impl
sumCond += ",a.ColumnAnnotation ";
if (dataTable.Columns.Contains("TitleColor"))
sumCond += ",a.TitleColor ";
if (dataTable.Columns.Contains("resultfields"))
sumCond += ",a.resultfields ";
string columsSql = string.Format(@"SELECT DISTINCT
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
@@ -559,6 +561,8 @@ namespace Lskj.Business.Impl
sumCond += ",a.ColumnAnnotation ";
if (dataTable.Columns.Contains("TitleColor"))
sumCond += ",a.TitleColor ";
if (dataTable.Columns.Contains("resultfields"))
sumCond += ",a.resultfields ";
string columsSql = string.Format(@"SELECT DISTINCT
isnull(CASE WHEN ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'' OR isnull(isVisible,0)=1 THEN 0 ELSE width END,0) width,
@@ -673,33 +677,37 @@ namespace Lskj.Business.Impl
conditions = "and isnull(mxflag,0)=0";
}
string cond = !string.IsNullOrEmpty(sourceCond) ? string.Format(" and id in ({0})", sourceCond.Trim(',')) : string.Empty;
string sqlValue = string.Format(@"WITH UserRoles AS (
SELECT r.roleName
FROM p_systemRoleOperSetTab AS ro
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
WHERE ro.operatorname = '{0}'
)
select * from p_systembillsource where typeCode=@typeCode" + cond +
@" and isnull(isVisible,0)=0 and (isnull(viewOper,'')='' or CHARINDEX(',' + '{0}' + ',', ',' + viewOper + ',')>0 OR EXISTS (
SELECT 1 FROM UserRoles AS ur WHERE CHARINDEX('{{&' + ur.roleName + '&}}', viewOper) > 0)) order by orderid", ERPInfo.Instance.UserName);
string sqlDetail = string.Format(@"WITH UserRoles AS (
SELECT r.roleName
FROM p_systemRoleOperSetTab AS ro
JOIN p_systemRoleSetTab AS r ON r.id = ro.roleId
WHERE ro.operatorname = '{1}'
)
SELECT id,sourceId,fieldName,sysName,userName,orderid,isVisible,sourceKey,privilegeView,DataFormat,isSum,ifmerge,{2}
string sqlValue = @"select * from p_systembillsource
where typeCode=@typeCode" + cond + @"
and isnull(isVisible,0)=0
order by orderid";
DataTable sourceTable = SqlHelper.ExecuteDataTable(sqlValue,
new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
sourceTable = BaseModuleImpl.FilterRowsByOperatorPrivilege(sourceTable, "viewOper");
htTable["master"] = sourceTable;
string sqlDetail = string.Format(@"SELECT id,sourceId,fieldName,sysName,userName,orderid,isVisible,sourceKey,privilegeView,DataFormat,isSum,ifmerge,{2}
isnull(CASE WHEN isVisible=1 OR (ISNULL(b.userList,'')='' AND ISNULL(a.PrivilegeView,'')<>'') THEN 0 ELSE width END,0) width
FROM p_systembillsourcedetail a
LEFT JOIN (
SELECT userList,privTypeId from p_systemPrivilege b where modId = '{0}'
AND CHARINDEX(',' + '{1}' + ',', ',' + userList + ',') > 0
) b on CHARINDEX(',' + CAST(b.privTypeId AS VARCHAR(5)) + ',',',' + PrivilegeView + ',') > 0
where sourceId in (select id from p_systembillsource where typeCode=@typeCode" + cond + @" and isnull(isVisible,0)=0 and (isnull(viewOper,'')='' or CHARINDEX(',' + '{1}' + ',', ',' + viewOper + ',')>0) OR EXISTS (
SELECT 1 FROM UserRoles AS ur WHERE CHARINDEX('{{&' + ur.roleName + '&}}', viewOper) > 0)) {3} ", menuCode, ERPInfo.Instance.UserName, otherfield, conditions);
htTable["master"] = SqlHelper.ExecuteDataTable(sqlValue, new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
where sourceId in (select id from p_systembillsource where typeCode=@typeCode" + cond + @" and isnull(isVisible,0)=0) {3} ", menuCode, ERPInfo.Instance.UserName, otherfield, conditions);
DataTable detailTable= SqlHelper.ExecuteDataTable(sqlDetail, new SqlParameter[] { new SqlParameter("@typeCode", menuCode) });
HashSet<string> sourceIds = new HashSet<string>(
sourceTable.Rows.Cast<DataRow>().Select(row => row["id"] + ""));
if (detailTable != null && detailTable.Rows.Count > 0)
{
DataTable allowedDetailTable = detailTable.Clone();
foreach (DataRow row in detailTable.Rows)
{
if (sourceIds.Contains(row["sourceId"] + "")) allowedDetailTable.ImportRow(row);
}
detailTable = allowedDetailTable;
}
// order by sourceId,orderid 数据库不排序,在表格中排序(解决慢查询)
if (detailTable != null && detailTable.Rows.Count > 0)
{
+20 -20
View File
@@ -42,18 +42,18 @@ namespace Lskj.Business
{
try
{
if (!BaseImpl.HasExistsColumn("P_LogTab", "IPAddress"))
{
SqlHelper.ExecuteNonQuery("alter table P_LogTab add IPAddress varchar(500)");
}
if (!BaseImpl.HasExistsColumn("P_LogTab", "MacAddress"))
{
SqlHelper.ExecuteNonQuery("alter table P_LogTab add MacAddress varchar(500)");
}
if (!BaseImpl.HasExistsColumn("P_LogTab", "ModuleId"))
{
SqlHelper.ExecuteNonQuery("alter table P_LogTab add ModuleId varchar(500)");
}
//if (!BaseImpl.HasExistsColumn("P_LogTab", "IPAddress"))
//{
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add IPAddress varchar(500)");
//}
//if (!BaseImpl.HasExistsColumn("P_LogTab", "MacAddress"))
//{
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add MacAddress varchar(500)");
//}
//if (!BaseImpl.HasExistsColumn("P_LogTab", "ModuleId"))
//{
// SqlHelper.ExecuteNonQuery("alter table P_LogTab add ModuleId varchar(500)");
//}
//string ModuleCode = string.Empty;
//string ModuleId = string.Empty;
@@ -108,14 +108,14 @@ namespace Lskj.Business
string exmessage = Regex.Replace(ex.Message, "'", "''");
if (!BaseImpl.HasExistsColumn("p_errlogtab", "IPAddress"))
{
SqlHelper.ExecuteNonQuery("alter table p_errlogtab add IPAddress varchar(500)");
}
if (!BaseImpl.HasExistsColumn("p_errlogtab", "MacAddress"))
{
SqlHelper.ExecuteNonQuery("alter table p_errlogtab add MacAddress varchar(500)");
}
//if (!BaseImpl.HasExistsColumn("p_errlogtab", "IPAddress"))
//{
// SqlHelper.ExecuteNonQuery("alter table p_errlogtab add IPAddress varchar(500)");
//}
//if (!BaseImpl.HasExistsColumn("p_errlogtab", "MacAddress"))
//{
// SqlHelper.ExecuteNonQuery("alter table p_errlogtab add MacAddress varchar(500)");
//}
string sqlValue = string.Format("insert into p_errlogtab(Operatedate,Operator,Content,ErrMsg,Ws,IPAddress,MacAddress) values(getdate(),'{0}','{1}','{2}','{3}','{4}','{5}')",
ERPInfo.Instance.UserName, content, exmessage + "\r\n" + ex.StackTrace, ERPInfo.Instance.WindowName, ERPInfo.Instance.LoginIPV4, ERPInfo.Instance.MacAddress);
+21
View File
@@ -293,6 +293,27 @@ namespace Lskj.Business.Impl
{
return false;
}
}
/// <summary>
/// 记录修改后的密码
/// </summary>
/// <param name="userId"></param>
/// <param name="afterPass"></param>
/// <returns></returns>
public static bool RecordPassword(string afterPass,string text)
{
try
{
//加密密码
afterPass = AESUtil.Encrypt(afterPass);
LogUtil.WriteDebug("", text, afterPass, "");
return true;
}
catch (Exception ex)
{
return false;
}
}
+21
View File
@@ -6,6 +6,7 @@ using System.Text;
using System.Data.SqlClient;
using Lskj.Util;
using Lskj.Model;
using Lskj.Core;
namespace Lskj.Business.Impl
{
@@ -202,6 +203,26 @@ namespace Lskj.Business.Impl
public static bool SaveRoleOperDate(string OperId, string OperName, string departemnt, string readdate, string editdate)
{
string sqlValue = string.Format(" if exists (select * from p_systemRoleOperSetTab s where s.operatorid='{0}' and roleId='0' ) update p_systemRoleOperSetTab set ReadPurview='{4}',EditPurview='{5}' where operatorid = '{0}' and roleId='0' ELSE insert into p_systemRoleOperSetTab (roleId,roleOperatorId,operatorid,operatorname,operatedate,department,ReadPurview,EditPurview) values ('0','{0}','{0}','{1}','{2}','{3}','{4}','{5}')", OperId, OperName, DateTime.Now, departemnt, readdate, editdate);
if (SqlHelper.ConnectionType == ConnectionType.DmServer)
{
string dmOperId = (OperId ?? string.Empty).Replace("'", "''");
string dmOperName = (OperName ?? string.Empty).Replace("'", "''");
string dmDepartment = (departemnt ?? string.Empty).Replace("'", "''");
string dmReadDate = (readdate ?? string.Empty).Replace("'", "''");
string dmEditDate = (editdate ?? string.Empty).Replace("'", "''");
sqlValue = string.Format(@"
MERGE INTO p_systemRoleOperSetTab t
USING (SELECT '{0}' operatorid, '0' roleId FROM DUAL) s
ON (t.operatorid = s.operatorid AND t.roleId = s.roleId)
WHEN MATCHED THEN
UPDATE SET ReadPurview = '{3}', EditPurview = '{4}'
WHEN NOT MATCHED THEN
INSERT (roleId, roleOperatorId, operatorid, operatorname, operatedate, department, ReadPurview, EditPurview)
VALUES ('0', '{0}', '{0}', '{1}', SYSDATE, '{2}', '{3}', '{4}')",
dmOperId, dmOperName, dmDepartment, dmReadDate, dmEditDate);
}
return ExecSqlValue(sqlValue) > 0;
}
+25 -1
View File
@@ -16,6 +16,7 @@ using System.Xml;
using Lskj.Business.Impl;
using Lskj.Core;
using Lskj.Model;
using Lskj.Data;
namespace Lskj.Business
{
@@ -65,6 +66,9 @@ namespace Lskj.Business
if (item.Table.Columns.Contains("UpdateAddressXp") && ERPInfo.Instance.SystemVersion.Contains("Windows XP"))
Instance.UpdateAddress = !string.IsNullOrEmpty(item["UpdateAddressXp"] + "") ? item["UpdateAddressXp"] + "" : "";
//内网对应的升级地址
Instance.UpdateAddress = DBConfig.Instance.IsInternalNetwork && item.Table.Columns.Contains("InternalUpdateAddress") && !string.IsNullOrEmpty(item["InternalUpdateAddress"] + "") ? item["InternalUpdateAddress"] + "" : Instance.UpdateAddress;
Instance.OAUrl = DBConfig.Instance.Internet && item.Table.Columns.Contains("localOAUrl") && !string.IsNullOrEmpty(item["localOAUrl"] + "") ? item["localOAUrl"] + "" : item["OAUrl"] + "";
@@ -330,6 +334,14 @@ namespace Lskj.Business
Instance.LoginUsername = item.Table.Columns.Contains("LoginUsername") && !string.IsNullOrEmpty(item["LoginUsername"] + "") ? item["LoginUsername"] + "" : "";
Instance.MainLeftShowMode = item.Table.Columns.Contains("MainLeftShowMode") && !string.IsNullOrEmpty(item["MainLeftShowMode"] + "") ? item["MainLeftShowMode"] + "" : "";
Instance.DeadlockPrompt = item.Table.Columns.Contains("DeadlockPrompt") && !string.IsNullOrEmpty(item["DeadlockPrompt"] + "") ? item["DeadlockPrompt"] + "" : "";
Instance.SpecialAttachmentBrowser = item.Table.Columns.Contains("SpecialAttachmentBrowser") && !string.IsNullOrEmpty(item["SpecialAttachmentBrowser"] + "") ? "1".Equals(item["SpecialAttachmentBrowser"] + "") : false;
if (Instance.SpecialAttachmentBrowser)
{
ResourceDynamic.PubBrower = System.Environment.OSVersion.Version.Major == 5 && (System.Environment.OSVersion.Version.Minor == 1 || System.Environment.OSVersion.Version.Minor == 2) ? "Lskj.PubBrowerXp.dll" : "Lskj.PubBrower2.dll";
}
Instance.IsSpecialAuditSave = item.Table.Columns.Contains("IsSpecialAuditSave") && !string.IsNullOrEmpty(item["IsSpecialAuditSave"] + "") ? "1".Equals(item["IsSpecialAuditSave"] + "") : false;
}
/// <summary>
/// 高拍仪AccessKey
@@ -1154,6 +1166,18 @@ namespace Lskj.Business
/// 死锁提示
/// </summary>
public string DeadlockPrompt;
/// <summary>
/// 附件按钮打开Lskj.PubBrower2.dll
/// </summary>
public bool SpecialAttachmentBrowser;
/// <summary>
/// 特殊审核保存模式(修改语句只拼接修改后的控件)
/// </summary>
public bool IsSpecialAuditSave;
/// <summary>
/// 默认权限模块
/// P_MessageToolLinkDllTab表中cardId=-99为通用模块(右侧快捷通道通用模块) 2023-12-4 徐成说的cardId=-99的配置
/// </summary>
//public DataTable DefaultPermissionTable;
}
}
+16 -1
View File
@@ -2016,7 +2016,7 @@ namespace Lskj.Control
}
//选中上一次选中行行号
if (SelectGridControlEx != null && oldRowHandle > 0)
if (SelectGridControlEx != null && oldRowHandle >= 0)
{
SelectGridControlEx.GridView.SelectRowHandler(oldRowHandle);
OnPcgridRowCellClick(SelectGridControlEx.GridView, null);
@@ -2057,10 +2057,25 @@ namespace Lskj.Control
string fieldValue = this.ControlObj.GetControlValue(model);
if (fieldValue == "****") continue;
if (SystemInfo.Instance.IsSpecialAuditSave &&
this._drBillInfoMsg != null &&
this._drBillInfoMsg.Table != null &&
this._drBillInfoMsg.Table.Columns.Contains(model.FieldName) &&
AuditChangeLog.IsSameValue(this._drBillInfoMsg[model.FieldName] + "", fieldValue))
{
continue;
}
//updateBuilder.AppendFormat("{0}='{1}',", model.FieldName, fieldValue);
updateBuilder.Append(string.IsNullOrEmpty(fieldValue) ? string.Format("{0}={1}", model.FieldName, this.ControlObj.GetNullValue(model)) : string.Format("{0}=N'{1}',", model.FieldName, fieldValue.Contains("'") ? fieldValue.Replace("'", "''") : fieldValue));
}
}
string updateFields = updateBuilder.ToString().TrimEnd(',');
if (string.IsNullOrEmpty(updateFields))
{
return string.Empty;
}
return string.Format("update {0} set {1} where {2}='{3}'", this.BillModelObj.MasterTable, updateBuilder.ToString().TrimEnd(','), BillModelObj.PrimaryKey, this.SysModel.BillDocumentId);
}
#endregion
+26 -16
View File
@@ -28,7 +28,6 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabMain = new DevExpress.XtraTab.XtraTabControl();
this.tabpage_finish = new DevExpress.XtraTab.XtraTabPage();
this.gridFinish = new Lskj.Control.GridControlEx();
@@ -51,8 +50,8 @@
this.btnReverseSelection = new DevExpress.XtraEditors.SimpleButton();
this.btnSelectAll = new DevExpress.XtraEditors.SimpleButton();
this.dpb_Tools = new DevExpress.XtraEditors.DropDownButton();
this.p_menu = new DevExpress.XtraBars.PopupMenu(this.components);
this.barManager1 = new DevExpress.XtraBars.BarManager(this.components);
this.p_menu = new DevExpress.XtraBars.PopupMenu();
this.barManager1 = new DevExpress.XtraBars.BarManager();
this.barDockControlTop = new DevExpress.XtraBars.BarDockControl();
this.barDockControlBottom = new DevExpress.XtraBars.BarDockControl();
this.barDockControlLeft = new DevExpress.XtraBars.BarDockControl();
@@ -85,7 +84,7 @@
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedTabPage = this.tabpage_finish;
this.tabMain.Size = new System.Drawing.Size(1051, 683);
this.tabMain.Size = new System.Drawing.Size(1051, 701);
this.tabMain.TabIndex = 20;
this.tabMain.TabPages.AddRange(new DevExpress.XtraTab.XtraTabPage[] {
this.tabpage_finish});
@@ -96,7 +95,7 @@
this.tabpage_finish.Controls.Add(this.splitBelow);
this.tabpage_finish.Controls.Add(this.pl_top);
this.tabpage_finish.Name = "tabpage_finish";
this.tabpage_finish.Size = new System.Drawing.Size(1045, 654);
this.tabpage_finish.Size = new System.Drawing.Size(1045, 672);
this.tabpage_finish.Text = "已完成单据";
//
// gridFinish
@@ -108,13 +107,14 @@
this.gridFinish.Margin = new System.Windows.Forms.Padding(4);
this.gridFinish.Name = "gridFinish";
this.gridFinish.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gridFinish.Size = new System.Drawing.Size(1045, 322);
this.gridFinish.Size = new System.Drawing.Size(1045, 340);
this.gridFinish.SysModel = null;
this.gridFinish.TabIndex = 29;
//
// splitBelow
//
this.splitBelow.Dock = System.Windows.Forms.DockStyle.Bottom;
this.splitBelow.Location = new System.Drawing.Point(0, 361);
this.splitBelow.Location = new System.Drawing.Point(0, 379);
this.splitBelow.Name = "splitBelow";
this.splitBelow.Panel1.Controls.Add(this.gridFlow);
this.splitBelow.Panel1.Text = "Panel1";
@@ -134,6 +134,7 @@
this.gridFlow.Name = "gridFlow";
this.gridFlow.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gridFlow.Size = new System.Drawing.Size(453, 293);
this.gridFlow.SysModel = null;
this.gridFlow.TabIndex = 19;
//
// gridDetail
@@ -145,6 +146,7 @@
this.gridDetail.Name = "gridDetail";
this.gridDetail.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gridDetail.Size = new System.Drawing.Size(587, 293);
this.gridDetail.SysModel = null;
this.gridDetail.TabIndex = 20;
//
// pl_top
@@ -174,6 +176,8 @@
// labeldate_start
//
this.labeldate_start.BackColor = System.Drawing.Color.Transparent;
this.labeldate_start.BackgroundColor = System.Drawing.Color.Empty;
this.labeldate_start.ContentBold = false;
this.labeldate_start.EditText = null;
this.labeldate_start.FontSize = 0F;
this.labeldate_start.LabelText = "终审时间起";
@@ -190,6 +194,8 @@
// labelcheck_finalAuditor
//
this.labelcheck_finalAuditor.BackColor = System.Drawing.Color.Transparent;
this.labelcheck_finalAuditor.BackgroundColor = System.Drawing.Color.Empty;
this.labelcheck_finalAuditor.ContentBold = false;
this.labelcheck_finalAuditor.EditText = null;
this.labelcheck_finalAuditor.FontSize = 0F;
this.labelcheck_finalAuditor.LabelText = "终审人";
@@ -206,6 +212,8 @@
// labeltxt_dataFlag
//
this.labeltxt_dataFlag.BackColor = System.Drawing.Color.Transparent;
this.labeltxt_dataFlag.BackgroundColor = System.Drawing.Color.Empty;
this.labeltxt_dataFlag.ContentBold = false;
this.labeltxt_dataFlag.EditText = "";
this.labeltxt_dataFlag.FontSize = 0F;
this.labeltxt_dataFlag.LabelText = "数据标识号";
@@ -233,6 +241,8 @@
// labeldate_end
//
this.labeldate_end.BackColor = System.Drawing.Color.Transparent;
this.labeldate_end.BackgroundColor = System.Drawing.Color.Empty;
this.labeldate_end.ContentBold = false;
this.labeldate_end.EditText = null;
this.labeldate_end.FontSize = 0F;
this.labeldate_end.LabelText = "终审时间止";
@@ -313,9 +323,9 @@
this.pl_bottom.Controls.Add(this.label_tips);
this.pl_bottom.Controls.Add(this.label_date);
this.pl_bottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pl_bottom.Location = new System.Drawing.Point(0, 683);
this.pl_bottom.Location = new System.Drawing.Point(0, 693);
this.pl_bottom.Name = "pl_bottom";
this.pl_bottom.Size = new System.Drawing.Size(1051, 32);
this.pl_bottom.Size = new System.Drawing.Size(1051, 21);
this.pl_bottom.TabIndex = 21;
//
// btnReverseSelection
@@ -323,7 +333,7 @@
this.btnReverseSelection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnReverseSelection.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.btnReverseSelection.Appearance.Options.UseFont = true;
this.btnReverseSelection.Location = new System.Drawing.Point(586, 3);
this.btnReverseSelection.Location = new System.Drawing.Point(586, -8);
this.btnReverseSelection.Name = "btnReverseSelection";
this.btnReverseSelection.Size = new System.Drawing.Size(55, 26);
this.btnReverseSelection.TabIndex = 13;
@@ -336,7 +346,7 @@
this.btnSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnSelectAll.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.btnSelectAll.Appearance.Options.UseFont = true;
this.btnSelectAll.Location = new System.Drawing.Point(647, 3);
this.btnSelectAll.Location = new System.Drawing.Point(647, -8);
this.btnSelectAll.Name = "btnSelectAll";
this.btnSelectAll.Size = new System.Drawing.Size(55, 26);
this.btnSelectAll.TabIndex = 12;
@@ -351,7 +361,7 @@
this.dpb_Tools.Appearance.Options.UseFont = true;
this.dpb_Tools.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
this.dpb_Tools.DropDownControl = this.p_menu;
this.dpb_Tools.Location = new System.Drawing.Point(888, 3);
this.dpb_Tools.Location = new System.Drawing.Point(888, -8);
this.dpb_Tools.Name = "dpb_Tools";
this.dpb_Tools.Size = new System.Drawing.Size(80, 26);
this.dpb_Tools.TabIndex = 11;
@@ -405,7 +415,7 @@
this.btnOkAudit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOkAudit.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.btnOkAudit.Appearance.Options.UseFont = true;
this.btnOkAudit.Location = new System.Drawing.Point(708, 3);
this.btnOkAudit.Location = new System.Drawing.Point(708, -8);
this.btnOkAudit.Name = "btnOkAudit";
this.btnOkAudit.Size = new System.Drawing.Size(82, 26);
this.btnOkAudit.TabIndex = 7;
@@ -418,7 +428,7 @@
this.btnBackAudit.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnBackAudit.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.btnBackAudit.Appearance.Options.UseFont = true;
this.btnBackAudit.Location = new System.Drawing.Point(796, 3);
this.btnBackAudit.Location = new System.Drawing.Point(796, -8);
this.btnBackAudit.Name = "btnBackAudit";
this.btnBackAudit.Size = new System.Drawing.Size(86, 26);
this.btnBackAudit.TabIndex = 6;
@@ -431,7 +441,7 @@
this.btnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnRefresh.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.btnRefresh.Appearance.Options.UseFont = true;
this.btnRefresh.Location = new System.Drawing.Point(974, 3);
this.btnRefresh.Location = new System.Drawing.Point(974, -8);
this.btnRefresh.Name = "btnRefresh";
this.btnRefresh.Size = new System.Drawing.Size(72, 26);
this.btnRefresh.TabIndex = 5;
@@ -448,7 +458,7 @@
this.Controls.Add(this.barDockControlBottom);
this.Controls.Add(this.barDockControlTop);
this.Name = "AuditPanelEx";
this.Size = new System.Drawing.Size(1051, 715);
this.Size = new System.Drawing.Size(1576, 1072);
((System.ComponentModel.ISupportInitialize)(this.tabMain)).EndInit();
this.tabMain.ResumeLayout(false);
this.tabpage_finish.ResumeLayout(false);
@@ -0,0 +1,49 @@
using Lskj.Control.MultiModelLookUp;
using System;
using System.Collections.Generic;
namespace Lskj.Control
{
/// <summary>
/// 按模块编号延迟读取模块数据源 SQL。只缓存 SQL 文本,不加载业务数据。
/// </summary>
internal sealed class ExtendedReturnModuleSourceResolver
{
private readonly object syncRoot = new object();
private readonly Dictionary<string, string> sourceSqlByModule =
new Dictionary<string, string>(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;
}
}
}
}
}
@@ -0,0 +1,331 @@
using DevExpress.XtraEditors;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.Utils;
using Lskj.Control.Model;
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace Lskj.Control
{
/// <summary>
/// 173/174 扩展搜索专用弹窗。查询文本只存在于本控件中,不参与业务列绑定。
/// </summary>
internal sealed class ExtendedReturnSearchPopup : UserControl
{
private sealed class SearchColumnOption
{
public SearchColumnOption(string fieldName, string caption)
{
FieldName = fieldName ?? string.Empty;
Caption = caption ?? string.Empty;
}
public string FieldName { get; private set; }
public string Caption { get; private set; }
public override string ToString()
{
return Caption;
}
}
private readonly TableLayoutPanel searchPanel;
private readonly ComboBoxEdit searchFieldEdit;
private readonly TextEdit searchEdit;
private readonly SimpleButton queryButton;
private readonly SimpleButton clearButton;
private readonly GridControl resultGrid;
private readonly GridView resultView;
private string selectedSearchField = string.Empty;
public event EventHandler SearchRequested;
public event EventHandler ClearRequested;
public event EventHandler ResultSelected;
public ExtendedReturnSearchPopup()
{
searchPanel = new TableLayoutPanel();
searchFieldEdit = new ComboBoxEdit();
searchEdit = new TextEdit();
queryButton = new SimpleButton();
clearButton = new SimpleButton();
resultGrid = new GridControl();
resultView = new GridView(resultGrid);
SuspendLayout();
searchPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(resultGrid)).BeginInit();
((System.ComponentModel.ISupportInitialize)(resultView)).BeginInit();
searchPanel.Dock = DockStyle.Top;
searchPanel.Height = 36;
searchPanel.Padding = new Padding(4);
searchPanel.ColumnCount = 4;
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 120F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
searchPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 72F));
searchPanel.RowCount = 1;
searchPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
searchPanel.GrowStyle = TableLayoutPanelGrowStyle.FixedSize;
queryButton.Dock = DockStyle.Fill;
queryButton.Margin = new Padding(4, 0, 0, 0);
queryButton.Text = "查询";
queryButton.TabIndex = 2;
queryButton.Click += QueryButton_Click;
clearButton.Dock = DockStyle.Fill;
clearButton.Margin = new Padding(4, 0, 0, 0);
clearButton.Text = "清空";
clearButton.TabIndex = 3;
clearButton.Click += ClearButton_Click;
searchFieldEdit.Dock = DockStyle.Fill;
searchFieldEdit.Margin = new Padding(0, 0, 4, 0);
searchFieldEdit.TabIndex = 0;
searchFieldEdit.Properties.AutoHeight = false;
searchFieldEdit.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
searchFieldEdit.SelectedIndexChanged += SearchFieldEdit_SelectedIndexChanged;
searchEdit.Dock = DockStyle.Fill;
searchEdit.Margin = new Padding(0);
searchEdit.TabIndex = 1;
searchEdit.Properties.AutoHeight = false;
searchEdit.Properties.NullValuePrompt = "输入查询内容后按回车";
searchEdit.Properties.NullValuePromptShowForEmptyValue = true;
searchEdit.KeyDown += SearchEdit_KeyDown;
searchPanel.Controls.Add(searchFieldEdit, 0, 0);
searchPanel.Controls.Add(searchEdit, 1, 0);
searchPanel.Controls.Add(queryButton, 2, 0);
searchPanel.Controls.Add(clearButton, 3, 0);
resultGrid.Dock = DockStyle.Fill;
resultGrid.MainView = resultView;
resultGrid.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] { resultView });
resultView.GridControl = resultGrid;
resultView.OptionsBehavior.Editable = false;
resultView.OptionsSelection.EnableAppearanceFocusedCell = false;
resultView.OptionsView.ShowGroupPanel = false;
resultView.OptionsView.ShowIndicator = true;
resultView.OptionsView.ShowAutoFilterRow = true;
resultView.OptionsView.ColumnAutoWidth = false;
resultView.IndicatorWidth = 40;
resultView.CustomDrawRowIndicator += ResultView_CustomDrawRowIndicator;
resultView.MouseDown += ResultView_MouseDown;
resultView.KeyDown += ResultView_KeyDown;
Controls.Add(resultGrid);
Controls.Add(searchPanel);
Name = "ExtendedReturnSearchPopup";
Size = new System.Drawing.Size(420, 240);
((System.ComponentModel.ISupportInitialize)(resultView)).EndInit();
((System.ComponentModel.ISupportInitialize)(resultGrid)).EndInit();
((System.ComponentModel.ISupportInitialize)(searchEdit.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(searchFieldEdit.Properties)).EndInit();
searchPanel.ResumeLayout(false);
ResumeLayout(false);
SetSearchColumns(null);
}
public GridControl ResultGrid
{
get { return resultGrid; }
}
public GridView ResultView
{
get { return resultView; }
}
public string SearchText
{
get { return (searchEdit.Text ?? string.Empty).Trim(); }
}
public string SelectedSearchField
{
get
{
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
return option == null ? string.Empty : option.FieldName;
}
}
public void SetSearchColumns(IEnumerable<KeyValuePair<string, string>> columns)
{
string preferredField = selectedSearchField;
SearchColumnOption all = new SearchColumnOption(string.Empty, "所有列");
SearchColumnOption selected = null;
HashSet<string> fields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
searchFieldEdit.Properties.BeginUpdate();
try
{
searchFieldEdit.Properties.Items.Clear();
searchFieldEdit.Properties.Items.Add(all);
if (columns != null)
{
foreach (KeyValuePair<string, string> column in columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.Key) || !fields.Add(column.Key))
{
continue;
}
string caption = string.IsNullOrWhiteSpace(column.Value) ? column.Key : column.Value;
SearchColumnOption option = new SearchColumnOption(column.Key, caption);
searchFieldEdit.Properties.Items.Add(option);
if (string.Equals(option.FieldName, preferredField, StringComparison.OrdinalIgnoreCase))
{
selected = option;
}
}
}
searchFieldEdit.SelectedItem = selected ?? all;
selectedSearchField = selected == null ? string.Empty : selected.FieldName;
}
finally
{
searchFieldEdit.Properties.EndUpdate();
}
}
public void PrepareForOpen()
{
searchEdit.Text = string.Empty;
ClearResultAndFilter();
}
public void ClearResultAndFilter()
{
resultView.ClearColumnsFilter();
resultGrid.DataSource = null;
}
public void FocusSearchEditor()
{
if (!searchEdit.CanFocus) return;
searchEdit.Focus();
searchEdit.SelectionStart = searchEdit.Text.Length;
searchEdit.SelectionLength = 0;
}
private void SearchEdit_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Down)
{
e.Handled = true;
e.SuppressKeyPress = true;
FocusResultRow(false);
return;
}
if (e.KeyCode == Keys.Up)
{
e.Handled = true;
e.SuppressKeyPress = true;
FocusResultRow(true);
return;
}
if (e.KeyCode != Keys.Enter) return;
e.Handled = true;
e.SuppressKeyPress = true;
RaiseSearchRequested();
}
private void SearchFieldEdit_SelectedIndexChanged(object sender, EventArgs e)
{
SearchColumnOption option = searchFieldEdit.SelectedItem as SearchColumnOption;
selectedSearchField = option == null ? string.Empty : option.FieldName;
}
private void FocusResultRow(bool focusLastRow)
{
if (resultView.DataRowCount <= 0) return;
int visibleIndex = focusLastRow ? resultView.DataRowCount - 1 : 0;
int rowHandle = resultView.GetVisibleRowHandle(visibleIndex);
if (rowHandle < 0) return;
resultGrid.Focus();
resultView.FocusedRowHandle = rowHandle;
resultView.SelectRow(rowHandle);
}
private void QueryButton_Click(object sender, EventArgs e)
{
RaiseSearchRequested();
}
private void RaiseSearchRequested()
{
if (SearchRequested != null)
{
SearchRequested(this, EventArgs.Empty);
}
}
private void ClearButton_Click(object sender, EventArgs e)
{
if (ClearRequested != null)
{
ClearRequested(this, EventArgs.Empty);
}
}
private void ResultView_CustomDrawRowIndicator(object sender, RowIndicatorCustomDrawEventArgs e)
{
if (e.Info == null || !e.Info.IsRowIndicator || e.RowHandle < 0) return;
e.Appearance.TextOptions.HAlignment = HorzAlignment.Center;
e.Info.DisplayText = (e.RowHandle + 1).ToString();
}
private void ResultView_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
GridHitInfo hitInfo = resultView.CalcHitInfo(e.Location);
if (!hitInfo.InRow && !hitInfo.InRowCell) return;
resultView.FocusedRowHandle = hitInfo.RowHandle;
if (ResultSelected != null)
{
ResultSelected(this, EventArgs.Empty);
}
}
private void ResultView_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up &&
resultView.FocusedRowHandle == resultView.GetVisibleRowHandle(0))
{
e.Handled = true;
e.SuppressKeyPress = true;
FocusSearchEditor();
return;
}
if (e.KeyCode != Keys.Enter) return;
e.Handled = true;
e.SuppressKeyPress = true;
if (ResultSelected != null)
{
ResultSelected(this, EventArgs.Empty);
}
}
}
}
@@ -0,0 +1,897 @@
using DevExpress.Utils;
using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraGrid.Columns;
using Lskj.Business.Impl;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Util;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
namespace Lskj.Control
{
/// <summary>
/// MyControl 中的 173/174 扩展搜索控件。业务实际值与界面显示文本相互独立,
/// 数据源仅在弹出框打开或用户执行查询时按需访问。
/// </summary>
public sealed class LabelExtendedReturnSearchEdit : BaseUserControl
{
private const int MaxRows = 100;
private const int DefaultPopupWidth = 520;
private const int DefaultPopupHeight = 300;
private const int MinimumPopupWidth = 360;
private readonly Panel labelPanel;
private readonly Label titleLabel;
private readonly Panel editorPanel;
private readonly PopupContainerEdit popupEdit;
private readonly PopupContainerControl popupControl;
private readonly ExtendedReturnSearchPopup popup;
private readonly object schemaSyncRoot = new object();
private readonly object querySyncRoot = new object();
private string actualValue = string.Empty;
private string schemaSql = string.Empty;
private DataTable schema;
private SearchRequest pendingSearch;
private bool queryWorkerRunning;
private int queryVersion;
private bool disposed;
private sealed class SearchRequest
{
public int Version;
public string SourceSql;
public string Keyword;
public string SearchField;
public string ConnectionString;
public bool SchemaOnly;
}
private sealed class QueryResult
{
public DataTable Schema;
public DataTable Table;
public Exception Error;
}
public LabelExtendedReturnSearchEdit()
{
labelPanel = new Panel();
titleLabel = new Label();
editorPanel = new Panel();
popupEdit = new PopupContainerEdit();
popupControl = new PopupContainerControl();
popup = new ExtendedReturnSearchPopup();
// MyControl 的坐标和尺寸均来自配置值,保持与现有 LabelTextEdit 一致,
// 禁止 UserControl 在高 DPI/大字体环境下再次缩放配置宽度。
AutoScaleMode = AutoScaleMode.None;
SuspendLayout();
labelPanel.SuspendLayout();
editorPanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(popupEdit.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(popupControl)).BeginInit();
popupControl.SuspendLayout();
labelPanel.BackColor = Color.Transparent;
labelPanel.Dock = DockStyle.Left;
labelPanel.Width = 40;
labelPanel.Controls.Add(titleLabel);
titleLabel.AutoSize = true;
titleLabel.BackColor = Color.Transparent;
titleLabel.Location = new Point(5, 4);
titleLabel.Text = "名称";
editorPanel.BackColor = Color.Transparent;
editorPanel.Dock = DockStyle.Fill;
editorPanel.Controls.Add(popupEdit);
popupEdit.Dock = DockStyle.Fill;
popupEdit.Properties.AutoHeight = false;
popupEdit.Properties.AllowNullInput = DefaultBoolean.True;
popupEdit.Properties.NullText = string.Empty;
popupEdit.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;
popupEdit.Properties.PopupSizeable = false;
popupEdit.Properties.PopupResizeMode = ResizeMode.Default;
popupEdit.Properties.PopupBorderStyle = PopupBorderStyles.Flat;
popupEdit.Properties.ShowPopupShadow = true;
popupEdit.Properties.PopupControl = popupControl;
popupEdit.Properties.Buttons.Clear();
popupEdit.Properties.Buttons.Add(new EditorButton(ButtonPredefines.Combo));
popupEdit.QueryPopUp += PopupEdit_QueryPopUp;
popupEdit.Popup += PopupEdit_Popup;
popupEdit.Closed += PopupEdit_Closed;
popup.Dock = DockStyle.Fill;
popupControl.Controls.Add(popup);
popup.SearchRequested += Popup_SearchRequested;
popup.ClearRequested += Popup_ClearRequested;
popup.ResultSelected += Popup_ResultSelected;
Controls.Add(editorPanel);
Controls.Add(labelPanel);
Name = "LabelExtendedReturnSearchEdit";
Size = new Size(249, 21);
Disposed += LabelExtendedReturnSearchEdit_Disposed;
popupControl.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(popupControl)).EndInit();
((System.ComponentModel.ISupportInitialize)(popupEdit.Properties)).EndInit();
editorPanel.ResumeLayout(false);
labelPanel.ResumeLayout(false);
labelPanel.PerformLayout();
ResumeLayout(false);
}
public Model.MyControl ControlObj { get; set; }
public PopupContainerEdit TextEdit
{
get { return popupEdit; }
}
/// <summary>
/// 保存到当前业务字段的实际 ID。
/// </summary>
public string EditValue
{
get { return actualValue ?? string.Empty; }
set
{
actualValue = value ?? string.Empty;
RefreshDisplayText();
}
}
/// <summary>
/// BaseUserControl 的 EditText 仍用于常规赋值入口;读取时返回界面显示文本,
/// MyControl.GetControlValue 对 173/174 会显式读取 EditValue。
/// </summary>
public override string EditText
{
get { return popupEdit.Text ?? string.Empty; }
set { EditValue = value; }
}
public override string LabelText
{
get { return titleLabel.Text; }
set
{
titleLabel.Text = value ?? string.Empty;
if (FontSize > 0)
{
labelPanel.AutoSize = false;
titleLabel.AutoSize = false;
titleLabel.Dock = DockStyle.Fill;
titleLabel.TextAlign = ContentAlignment.MiddleLeft;
labelPanel.Width = Math.Max(0, (value ?? string.Empty).Length * GetCharWidth());
GetCharWidthMultilingual(titleLabel, titleLabel.Text, labelPanel);
}
else
{
labelPanel.Width = titleLabel.Width + PaddingLeft;
}
}
}
public override float FontSize
{
get { return base.FontSize; }
set
{
base.FontSize = value;
if (value <= 0) return;
titleLabel.Font = new Font(titleLabel.Font.FontFamily, value);
popupEdit.Font = new Font(popupEdit.Font.FontFamily, value);
popup.ResultView.Appearance.Row.Font = new Font("微软雅黑", value);
}
}
public override string NullText
{
get { return popupEdit.Properties.NullValuePrompt; }
set
{
popupEdit.Properties.NullValuePromptShowForEmptyValue = !string.IsNullOrEmpty(value);
popupEdit.Properties.NullValuePrompt = value ?? string.Empty;
base.NullText = value;
}
}
public override bool ReadOnly
{
get { return base.ReadOnly; }
set
{
base.ReadOnly = value;
popupEdit.Properties.ReadOnly = value;
titleLabel.ForeColor = value
? ReadOnlyLabelForceColor
: Required ? RequiredLabelForceColor : DefaultLabelForceColor;
}
}
public override bool Required
{
get { return base.Required; }
set
{
base.Required = value;
if (value) titleLabel.ForeColor = RequiredLabelForceColor;
}
}
public override Color BackgroundColor
{
get { return popupEdit.Properties.Appearance.BackColor; }
set { popupEdit.Properties.Appearance.BackColor = value; }
}
public override Color ForeColor
{
get { return popupEdit.Properties.Appearance.ForeColor; }
set { popupEdit.Properties.Appearance.ForeColor = value; }
}
public override bool ContentBold
{
get { return popupEdit.Properties.Appearance.Font.Bold; }
set
{
Font oldFont = popupEdit.Properties.Appearance.Font;
popupEdit.Properties.Appearance.Font = new Font(
oldFont.FontFamily,
oldFont.Size,
value ? FontStyle.Bold : FontStyle.Regular);
}
}
public override bool IsEmpty()
{
return Model != null && Model.IsEmpty && string.IsNullOrWhiteSpace(EditValue);
}
public override bool IsUpdate()
{
return Model == null || Model.Text == null ||
!Model.Text.Equals(EditValue, StringComparison.OrdinalIgnoreCase);
}
/// <summary>
/// 从 ResultFields 中 TextMember 对应的业务控件读取预存显示文本。
/// </summary>
public void RefreshDisplayText()
{
string displayText = string.Empty;
try
{
string displayField = GetDisplayTargetField();
if (ControlObj != null && !string.IsNullOrWhiteSpace(displayField))
{
BaseUserControl displayControl = ControlObj.FindControl(displayField);
if (displayControl != null && !object.ReferenceEquals(displayControl, this))
{
displayText = displayControl.EditText ?? string.Empty;
}
}
}
catch
{
// 初始化配置尚未完整时保持为空,弹出时再给出明确配置错误。
}
popupEdit.EditValue = displayText;
}
private void PopupEdit_QueryPopUp(object sender, System.ComponentModel.CancelEventArgs e)
{
try
{
ValidateBusinessConfiguration();
Size popupSize = GetPopupSize();
popup.Size = popupSize;
popupControl.Size = popupSize;
popupEdit.Properties.PopupFormSize = popupSize;
popupEdit.Properties.PopupFormMinSize = popupSize;
popup.PrepareForOpen();
string sourceSql = BuildSourceSql();
DataTable cachedSchema = TryGetSchema(sourceSql);
if (cachedSchema != null)
{
ConfigureSearchColumns(cachedSchema);
}
if (!string.IsNullOrWhiteSpace(EditValue))
{
QueueSearch(sourceSql, EditValue, string.Empty, false);
}
else if (cachedSchema == null)
{
QueueSearch(sourceSql, string.Empty, string.Empty, true);
}
else
{
CancelSearch();
}
}
catch (Exception ex)
{
e.Cancel = true;
MessageUtil.Show("扩展搜索配置错误:" + ex.Message);
}
}
private void PopupEdit_Popup(object sender, EventArgs e)
{
try
{
popup.BeginInvoke(new MethodInvoker(popup.FocusSearchEditor));
}
catch (ObjectDisposedException)
{
}
catch (InvalidOperationException)
{
}
}
private void PopupEdit_Closed(object sender, ClosedEventArgs e)
{
CancelSearch();
popup.ClearResultAndFilter();
RefreshDisplayText();
}
private void Popup_SearchRequested(object sender, EventArgs e)
{
try
{
ValidateBusinessConfiguration();
string keyword = popup.SearchText;
string searchField = popup.SelectedSearchField;
popup.ClearResultAndFilter();
if (string.IsNullOrWhiteSpace(keyword))
{
CancelSearch();
return;
}
QueueSearch(BuildSourceSql(), keyword, searchField, false);
}
catch (Exception ex)
{
MessageUtil.Show("扩展搜索配置错误:" + ex.Message);
}
}
private void Popup_ClearRequested(object sender, EventArgs e)
{
try
{
IList<ExtendedReturnFieldMapping> mappings = ValidateClearConfiguration();
List<KeyValuePair<string, object>> values =
new List<KeyValuePair<string, object>>();
HashSet<string> targetFields =
new HashSet<string>(StringComparer.OrdinalIgnoreCase);
values.Add(new KeyValuePair<string, object>(Model.FieldName, string.Empty));
targetFields.Add(Model.FieldName);
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
if (targetFields.Add(mapping.TargetField))
{
values.Add(new KeyValuePair<string, object>(
mapping.TargetField,
string.Empty));
}
}
ControlObj.ApplyExtendedReturnValues(values);
popupEdit.ClosePopup();
}
catch (Exception ex)
{
MessageUtil.Show("扩展搜索清空失败:" + ex.Message);
}
}
private void Popup_ResultSelected(object sender, EventArgs e)
{
try
{
DataRow selectedRow = popup.ResultView.GetFocusedDataRow();
if (selectedRow == null) return;
IList<ExtendedReturnFieldMapping> mappings = ValidateBusinessConfiguration();
ValidateSourceColumns(selectedRow.Table.Columns, mappings);
List<KeyValuePair<string, object>> values = new List<KeyValuePair<string, object>>();
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
KeyValuePair<string, object> mappedValue = new KeyValuePair<string, object>(
mapping.TargetField,
selectedRow[mapping.SourceField]);
if (string.Equals(mapping.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase))
{
values.Insert(0, mappedValue);
}
else
{
values.Add(mappedValue);
}
}
bool containsActualField = mappings.Any(item =>
string.Equals(item.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase));
if (!containsActualField)
{
values.Insert(0, new KeyValuePair<string, object>(
Model.FieldName,
selectedRow[Model.ValueMember]));
}
ApplyValues(values);
RefreshDisplayText();
popupEdit.ClosePopup();
}
catch (Exception ex)
{
MessageUtil.Show("扩展搜索返回值失败:" + ex.Message);
}
}
private void ApplyValues(IList<KeyValuePair<string, object>> values)
{
ControlObj.ApplyExtendedReturnValues(values);
}
private IList<ExtendedReturnFieldMapping> ValidateClearConfiguration()
{
if (Model == null) throw new InvalidOperationException("扩展返回控件配置不存在。");
if (ControlObj == null) throw new InvalidOperationException("扩展返回控件未关联 MyControl。");
IList<ExtendedReturnFieldMapping> mappings =
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
if (mappings.Count == 0)
{
throw new InvalidOperationException("resultfields 不能为空。");
}
if (ControlObj.FindControl(Model.FieldName) == null)
{
throw new InvalidOperationException(
string.Format("MyControl 中不存在业务控件“{0}”。", Model.FieldName));
}
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
if (ControlObj.FindControl(mapping.TargetField) == null)
{
throw new InvalidOperationException(
string.Format("MyControl 中不存在业务控件“{0}”。", mapping.TargetField));
}
}
return mappings;
}
private IList<ExtendedReturnFieldMapping> ValidateBusinessConfiguration()
{
if (Model == null) throw new InvalidOperationException("扩展返回控件配置不存在。");
if (ControlObj == null) throw new InvalidOperationException("扩展返回控件未关联 MyControl。");
if (Model.FieldType == ControlType.LabModuleSelectReturnIdExtended)
{
if (string.IsNullOrWhiteSpace(Model.AddModuleId))
{
throw new InvalidOperationException("扩展模块搜索的模块编号不能为空。");
}
}
else if (string.IsNullOrWhiteSpace(Model.SourceSql))
{
throw new InvalidOperationException("搜索数据源 SQL 不能为空。");
}
if (string.IsNullOrWhiteSpace(Model.ValueMember))
{
throw new InvalidOperationException("fieldsqlid 不能为空。");
}
if (string.IsNullOrWhiteSpace(Model.TextMember))
{
throw new InvalidOperationException("fieldsqlname 不能为空。");
}
if (string.Equals(Model.ValueMember, Model.TextMember, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("fieldsqlid 与 fieldsqlname 必须配置为不同的返回列。");
}
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
if (mappings.Count == 0)
{
throw new InvalidOperationException("resultfields 不能为空。");
}
int displayMappingCount = mappings.Count(item =>
string.Equals(item.SourceField, Model.TextMember, StringComparison.OrdinalIgnoreCase));
if (displayMappingCount == 0)
{
throw new InvalidOperationException(
string.Format("resultfields 未配置显示字段“{0}”的业务控件映射。", Model.TextMember));
}
if (displayMappingCount > 1)
{
throw new InvalidOperationException(
string.Format("resultfields 中显示字段“{0}”只能映射到一个业务控件。", Model.TextMember));
}
ExtendedReturnFieldMapping actualMapping = mappings.FirstOrDefault(item =>
string.Equals(item.TargetField, Model.FieldName, StringComparison.OrdinalIgnoreCase));
if (actualMapping != null &&
!string.Equals(actualMapping.SourceField, Model.ValueMember, StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException(
string.Format("实际值控件“{0}”必须映射到 fieldsqlid 指定的返回列“{1}”。",
Model.FieldName,
Model.ValueMember));
}
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
if (ControlObj.FindControl(mapping.TargetField) == null)
{
throw new InvalidOperationException(
string.Format("MyControl 中不存在业务控件“{0}”。", mapping.TargetField));
}
}
return mappings;
}
private void ValidateSourceColumns(
DataColumnCollection columns,
IEnumerable<ExtendedReturnFieldMapping> mappings)
{
if (columns == null || columns.Count == 0)
{
throw new InvalidOperationException("扩展搜索数据源没有返回任何列。");
}
if (!columns.Contains(Model.ValueMember))
{
throw new InvalidOperationException(
string.Format("返回数据不存在值字段“{0}”。", Model.ValueMember));
}
if (!columns.Contains(Model.TextMember))
{
throw new InvalidOperationException(
string.Format("返回数据不存在显示字段“{0}”。", Model.TextMember));
}
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
if (!columns.Contains(mapping.SourceField))
{
throw new InvalidOperationException(
string.Format("返回数据不存在映射源字段“{0}”。", mapping.SourceField));
}
}
}
private string GetDisplayTargetField()
{
if (Model == null) return string.Empty;
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
return ExtendedReturnSupport.FindTargetField(mappings, Model.TextMember);
}
private Size GetPopupSize()
{
int width = Model != null && Model.LookUpWidth > 0
? Model.LookUpWidth
: DefaultPopupWidth;
width = Math.Max(width, MinimumPopupWidth);
return new Size(width, DefaultPopupHeight);
}
private string BuildSourceSql()
{
string sourceSql = GetBaseSourceSql();
if (ControlObj != null)
{
sourceSql = ControlObj.ReplaceControlValue(sourceSql);
}
sourceSql = BaseImpl.GetDefaultValue(sourceSql);
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 QueueSearch(string sourceSql, string keyword, string searchField, bool schemaOnly)
{
SearchRequest request = new SearchRequest();
request.Version = Interlocked.Increment(ref queryVersion);
request.SourceSql = sourceSql;
request.Keyword = keyword;
request.SearchField = searchField;
request.ConnectionString = SqlHelper._connection.ConnectionString;
request.SchemaOnly = schemaOnly;
bool startWorker = false;
lock (querySyncRoot)
{
pendingSearch = request;
if (!queryWorkerRunning)
{
queryWorkerRunning = true;
startWorker = true;
}
}
if (startWorker)
{
ThreadPool.QueueUserWorkItem(ProcessSearchQueue);
}
}
private void ProcessSearchQueue(object state)
{
while (true)
{
SearchRequest request;
lock (querySyncRoot)
{
request = pendingSearch;
pendingSearch = null;
if (request == null)
{
queryWorkerRunning = false;
return;
}
}
QueryResult result = Query(request);
DeliverResult(request, result);
}
}
private QueryResult Query(SearchRequest request)
{
QueryResult result = new QueryResult();
try
{
DataTable sourceSchema = GetSchema(request.SourceSql, request.ConnectionString);
result.Schema = sourceSchema;
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
ValidateSourceColumns(sourceSchema.Columns, mappings);
if (!request.SchemaOnly)
{
string searchSql = ExtendedReturnSupport.BuildSearchSql(
request.SourceSql, sourceSchema.Columns, MaxRows, request.SearchField);
result.Table = ExecuteQuery(
searchSql,
ExtendedReturnSupport.BuildLikeParameterValue(request.Keyword),
request.ConnectionString);
}
}
catch (Exception ex)
{
result.Error = ex;
}
return result;
}
private DataTable TryGetSchema(string sourceSql)
{
lock (schemaSyncRoot)
{
if (schema != null && string.Equals(schemaSql, sourceSql, StringComparison.Ordinal))
{
return schema;
}
return null;
}
}
private DataTable GetSchema(string sourceSql, string connectionString)
{
lock (schemaSyncRoot)
{
if (schema != null && string.Equals(schemaSql, sourceSql, StringComparison.Ordinal))
{
return schema;
}
schema = ExecuteQuery(ExtendedReturnSupport.BuildStructureSql(sourceSql), null, connectionString);
schemaSql = sourceSql;
return schema;
}
}
private static DataTable ExecuteQuery(
string commandText,
string keywordParameterValue,
string connectionString)
{
DataTable table = new DataTable();
using (DbConnection connection = SqlHelper.dbFactory.CreateConnection())
using (DbCommand command = SqlHelper.dbFactory.CreateCommand())
using (DbDataAdapter adapter = SqlHelper.dbFactory.CreateDataAdapter())
{
connection.ConnectionString = connectionString;
command.Connection = connection;
command.CommandText = commandText;
command.CommandType = CommandType.Text;
command.CommandTimeout = SqlHelper.CommandTimeout;
if (keywordParameterValue != null)
{
DbParameter parameter = SqlHelper.dbFactory.CreateParameter();
parameter.ParameterName = ExtendedReturnSupport.SearchParameterName;
parameter.DbType = DbType.String;
parameter.Size = 4000;
parameter.Value = keywordParameterValue;
command.Parameters.Add(parameter);
}
adapter.SelectCommand = command;
connection.Open();
adapter.Fill(table);
}
return table;
}
private void DeliverResult(SearchRequest request, QueryResult result)
{
if (disposed || !IsHandleCreated) return;
MethodInvoker deliver = new MethodInvoker(delegate
{
if (disposed || IsDisposed || request.Version != queryVersion || !popupEdit.IsPopupOpen) return;
ConfigureSearchColumns(result.Schema);
if (result.Error != null)
{
MessageUtil.Show("扩展搜索查询失败:" + result.Error.Message);
return;
}
if (result.Table != null)
{
popup.ResultGrid.DataSource = result.Table;
ConfigureResultColumns(result.Table);
}
});
try
{
BeginInvoke(deliver);
}
catch (ObjectDisposedException)
{
}
catch (InvalidOperationException)
{
}
}
private void ConfigureSearchColumns(DataTable sourceSchema)
{
if (sourceSchema == null) return;
List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>();
IList<ExtendedReturnFieldMapping> mappings =
ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
foreach (DataColumn column in sourceSchema.Columns)
{
if (!ExtendedReturnSupport.IsSearchableColumn(column.ColumnName)) continue;
options.Add(new KeyValuePair<string, string>(
column.ColumnName,
GetColumnCaption(column.ColumnName, mappings)));
}
popup.SetSearchColumns(options);
}
private void ConfigureResultColumns(DataTable table)
{
if (table == null) return;
IList<ExtendedReturnFieldMapping> mappings = ExtendedReturnSupport.ParseResultFields(Model.ResultFields);
popup.ResultView.Columns.Clear();
foreach (DataColumn dataColumn in table.Columns)
{
GridColumn column = new GridColumn();
column.Name = column.FieldName = dataColumn.ColumnName;
column.Caption = GetColumnCaption(dataColumn.ColumnName, mappings);
column.Visible = !dataColumn.ColumnName.StartsWith("_", StringComparison.Ordinal);
column.OptionsFilter.AutoFilterCondition = AutoFilterCondition.Contains;
popup.ResultView.Columns.Add(column);
}
string[] configuredWidths = string.IsNullOrWhiteSpace(Model.LookUpFieldsWidth)
? null
: Model.LookUpFieldsWidth.Trim().TrimEnd(',').Split(',');
int visibleIndex = 0;
foreach (GridColumn column in popup.ResultView.Columns)
{
if (!column.Visible) continue;
int width;
if (configuredWidths != null && visibleIndex < configuredWidths.Length &&
int.TryParse(configuredWidths[visibleIndex], out width))
{
column.Width = width;
}
else
{
int captionWidth = GraphicsText.GetTextWidth(column.Caption);
int valueWidth = CalcMaxColumnWidth(table, column.FieldName);
column.Width = Math.Max(captionWidth, valueWidth);
}
visibleIndex++;
}
}
private string GetColumnCaption(
string sourceField,
IEnumerable<ExtendedReturnFieldMapping> mappings)
{
string targetField = ExtendedReturnSupport.FindTargetField(mappings, sourceField);
if (string.IsNullOrWhiteSpace(targetField)) return sourceField;
BaseUserControl targetControl = ControlObj.FindControl(targetField);
if (targetControl != null && !string.IsNullOrWhiteSpace(targetControl.LabelText))
{
return targetControl.LabelText;
}
return targetField;
}
private static int CalcMaxColumnWidth(DataTable table, string fieldName)
{
int maxWidth = 0;
foreach (DataRow row in table.Rows)
{
object value = row[fieldName];
int width = GraphicsText.GetTextWidth(
value == null || value == DBNull.Value ? string.Empty : value + string.Empty);
if (width > maxWidth) maxWidth = width;
}
return maxWidth;
}
private void CancelSearch()
{
Interlocked.Increment(ref queryVersion);
lock (querySyncRoot)
{
pendingSearch = null;
}
}
private void LabelExtendedReturnSearchEdit_Disposed(object sender, EventArgs e)
{
disposed = true;
CancelSearch();
}
}
}
@@ -258,7 +258,8 @@ namespace Lskj.Control
DataRow gridRow = this.GridView.GetDataRow(e.RowHandle);
foreach (DataRow item in this.GridRowColorsTable.Rows)
{
string cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "");
//string cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "");
string cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(gridRow, item["condition"] + "");
try
{
if (!string.IsNullOrWhiteSpace(cond) && ReplaceHelper.EvalCond(cond))
@@ -360,7 +361,8 @@ namespace Lskj.Control
continue;
}
}
cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
//cond = ReplaceHelper.ReplaceRowParam(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(gridRow, item["condition"] + "").ReplaceColumnParam(e.Column.Name, e.Column.Caption, e.CellValue + "");
try
{
if (!string.IsNullOrWhiteSpace(cond) && ReplaceHelper.EvalCond(cond) && (!string.IsNullOrEmpty(e.CellValue + "") || isLaterDatePresent|| SystemInfo.Instance.isBlankCellColor))
@@ -1,5 +1,6 @@
using Lskj.Business;
using Lskj.Model;
using Lskj.Util;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -56,6 +57,19 @@ namespace Lskj.Control.BrowserSetting
return contextMenuHandler;
}
protected override bool OnProcessMessageReceived(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message)
{
try
{
return OnProcessMessageReceivedCore(browser, frame, sourceProcess, message);
}
catch (Exception exception)
{
ReportProcessMessageFailure(exception);
return true;
}
}
private bool OnProcessMessageReceivedCore(CefBrowser browser, CefFrame frame, CefProcessId sourceProcess, CefProcessMessage message)
{
if (message.Name.Equals("OpenModule"))
{
@@ -150,6 +164,46 @@ namespace Lskj.Control.BrowserSetting
return base.OnProcessMessageReceived(browser, frame, sourceProcess, message);
}
private static void ReportProcessMessageFailure(Exception exception)
{
try
{
LogHelper.Instance.WriteError(exception);
}
catch
{
// Logging must never rethrow across the native CEF callback.
}
Action showError = () =>
{
try
{
MessageUtil.Show(exception);
}
catch
{
// Error reporting must never terminate the browser callback.
}
};
try
{
System.Windows.Forms.Control mainControl = ERPInfo.Instance.MainControl;
if (mainControl == null || mainControl.IsDisposed || !mainControl.IsHandleCreated)
return;
if (mainControl.InvokeRequired)
mainControl.BeginInvoke(showError);
else
showError();
}
catch
{
// The main window may close while the CEF callback is reporting.
}
}
public void Created(CefBrowser cefBrowser)
{
if (OnCreated != null)
@@ -7,8 +7,6 @@ using Lskj.Control.Model;
using Lskj.Data;
using Lskj.Model;
using Lskj.Util;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
@@ -108,7 +106,7 @@ namespace Lskj.Control.BrowserSetting
menu.Model = new DynamicModel(new string[] { MenuName, ERPInfo.Instance.UserId, ERPInfo.Instance.UserName, "1", mMenuCode });
//DataRow[] dataRows = JsonHandler.ParseJsonArrayToDataRows(arrayItem);
//JArray jArray = (JArray)JsonConvert.DeserializeObject(arrayItem);
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(arrayItem);
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(arrayItem);
if (dataTable != null && dataTable.Rows.Count > 0)
{
menu.ExecRightMenu(menuModel, dataTable.Select());
@@ -323,10 +321,7 @@ namespace Lskj.Control.BrowserSetting
{
if (!string.IsNullOrWhiteSpace(rowdata) && StaticControl.RightMenuGridView != null)
{
JObject rowObject = JsonConvert.DeserializeObject<JObject>(rowdata);
JArray jArray = new JArray();
jArray.Add(rowObject);
DataTable dataTable = JsonConvert.DeserializeObject<DataTable>(JsonConvert.SerializeObject(jArray));
DataTable dataTable = JsonUtil.ToDataTablePreservingComplexValues(rowdata);
DataTable gridTable = (StaticControl.RightMenuGridView.GridControl.DataSource as DataTable).TrimDeleteRows();
+78 -2
View File
@@ -25,6 +25,7 @@ using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
@@ -36,6 +37,11 @@ namespace Lskj.Control
/// </summary>
public partial class FrmExport : Form
{
/// <summary>
/// 临时导出表无法执行原表的自定义汇总逻辑,保存原表已经计算完成的总计值。
/// </summary>
private readonly Dictionary<string, object> _exportCustomSummaryValues = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
public FrmExport()
{
InitializeComponent();
@@ -45,8 +51,57 @@ namespace Lskj.Control
gridView1.Appearance.Row.Font = new Font("宋体", 9);
gridView1.OptionsView.RowAutoHeight = true;
gridView1.RowCellStyle += new RowCellStyleEventHandler(OnGridViewRowCellStyle);
gridView1.CustomSummaryCalculate += OnExportCustomSummaryCalculate;
Lskj.Control.Model.AutoSizeChange.ControllInitializeSize(this);
}
/// <summary>
/// 将原表已经计算完成的自定义总计回填到临时导出表。
/// </summary>
private void OnExportCustomSummaryCalculate(object sender, DevExpress.Data.CustomSummaryEventArgs e)
{
if (!e.IsTotalSummary || e.SummaryProcess != DevExpress.Data.CustomSummaryProcess.Finalize)
{
return;
}
GridSummaryItem summaryItem = e.Item as GridSummaryItem;
object summaryValue;
if (summaryItem != null && !string.IsNullOrEmpty(summaryItem.FieldName) &&
_exportCustomSummaryValues.TryGetValue(summaryItem.FieldName, out summaryValue))
{
e.TotalValue = summaryValue;
e.TotalValueReady = true;
}
}
/// <summary>
/// 百分率自定义汇总在原表中可能已经格式化为字符串,导出前还原为数值。
/// </summary>
private static object GetExportSummaryValue(GridColumn column, GridSummaryItem summaryItem)
{
object summaryValue = summaryItem.SummaryValue;
string valueText = summaryValue as string;
string summaryFormat = summaryItem.DisplayFormat ?? string.Empty;
string columnFormat = column == null ? string.Empty : column.DisplayFormat.FormatString;
if (string.IsNullOrWhiteSpace(valueText) ||
(!summaryFormat.Contains("%") && !columnFormat.Contains("%")))
{
return summaryValue;
}
string percentSymbol = CultureInfo.CurrentCulture.NumberFormat.PercentSymbol;
string numericText = valueText.Replace(percentSymbol, string.Empty).Replace("%", string.Empty).Trim();
decimal percentageValue;
if (decimal.TryParse(numericText, NumberStyles.Any, CultureInfo.CurrentCulture, out percentageValue) ||
decimal.TryParse(numericText, NumberStyles.Any, CultureInfo.InvariantCulture, out percentageValue))
{
return percentageValue / 100m;
}
return summaryValue;
}
/// <summary>
/// DataTable转换成Excel文档流(导出数据量超出65535条,分sheet)
/// </summary>
@@ -105,10 +160,12 @@ namespace Lskj.Control
/// <returns>GridControl.</returns>
public BandedGridControlEx ReplaceBitColumn(BandedGridControlEx bandGridControlEx, bool IsCustomColumn = false)
{
_exportCustomSummaryValues.Clear();
bool hasBoolean = false;
BandedGridView gridView = bandGridControlEx.GridView as BandedGridView;
BandedGridControlEx NewBandedGridControlEx = new BandedGridControlEx();
BandedGridView gridView2 = NewBandedGridControlEx.GridView as BandedGridView;
gridView2.CustomSummaryCalculate += OnExportCustomSummaryCalculate;
gridView2.Columns.Clear();//默认有2个列
List<string> boolList = new List<string>();
List<string> datetimeList = new List<string>();
@@ -164,6 +221,8 @@ namespace Lskj.Control
newCol.Width = col.Width;
newCol.OptionsColumn.AllowEdit = col.OptionsColumn.AllowEdit;
newCol.ColumnEdit = boolList.Contains(col.FieldName) || datetimeList.Contains(col.FieldName) ? null : col.ColumnEdit;
newCol.DisplayFormat.FormatType = col.DisplayFormat.FormatType;
newCol.DisplayFormat.FormatString = col.DisplayFormat.FormatString;
//多表头默认都有1级标题(默认有空白表头)
if (col.OwnerBand != null)
@@ -377,6 +436,7 @@ namespace Lskj.Control
//底部汇总是否导出
if (SystemInfo.Instance.ExportSummary)
{
gridView.UpdateTotalSummary();
for (int i = 1; i < gridView2.Columns.Count; i++)
{
string columnName = gridView2.Columns[i].FieldName;
@@ -384,6 +444,11 @@ namespace Lskj.Control
GridSummaryItem gsi = gridView.Columns[columnName].SummaryItem;
if (gsi.SummaryType != DevExpress.Data.SummaryItemType.None) //gsi.SummaryValue!=null&& !string.IsNullOrEmpty(gsi.SummaryValue.ToString())
{
if (gsi.SummaryType == DevExpress.Data.SummaryItemType.Custom)
{
_exportCustomSummaryValues[columnName] = GetExportSummaryValue(gridView.Columns[columnName], gsi);
}
gridView2.Columns[i].Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(gsi.SummaryType, gridView2.Columns[i].FieldName.ToString(), gsi.DisplayFormat) });
if (SystemInfo.Instance.GroupSpecialMode)
@@ -422,6 +487,7 @@ namespace Lskj.Control
public GridControl ReplaceBitColumn(GridControl control, bool IsCustomColumn = false)
{
GridView gridView = control.FocusedView as GridView;
_exportCustomSummaryValues.Clear();
bool hasBoolean = false;
List<string> boolList = new List<string>();
List<string> datetimeList = new List<string>();
@@ -481,6 +547,8 @@ namespace Lskj.Control
newCol.Width = 100;
newCol.OptionsColumn.AllowEdit = col.OptionsColumn.AllowEdit;
newCol.ColumnEdit = boolList.Contains(col.FieldName) || datetimeList.Contains(col.FieldName) ? null : col.ColumnEdit;
newCol.DisplayFormat.FormatType = col.DisplayFormat.FormatType;
newCol.DisplayFormat.FormatString = col.DisplayFormat.FormatString;
this.gridView1.Columns.Add(newCol);
visibleList.Add(col.FieldName);
if (gridModel != null && !dictionary.ContainsKey(col.FieldName))
@@ -733,7 +801,9 @@ namespace Lskj.Control
if (firstColumn != null)
{
this.gridView1.OptionsView.ShowFooter = true;
firstColumn.Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Count, firstColumn.FieldName.ToString(), "合计: {0:#,###}行") });
string firstFieldName = firstColumn.FieldName.ToString();
_exportCustomSummaryValues[firstFieldName] = string.Format("合计: {0}行", dtTable.Rows.Count);
firstColumn.Summary.AddRange(new DevExpress.XtraGrid.GridSummaryItem[] { new DevExpress.XtraGrid.GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Custom, firstFieldName, "{0}") });
if (SystemInfo.Instance.GroupSpecialMode)
{
@@ -748,6 +818,7 @@ namespace Lskj.Control
//底部汇总是否导出
if (SystemInfo.Instance.ExportSummary)
{
gridView.UpdateTotalSummary();
for (int i = 1; i < this.gridView1.Columns.Count; i++)
{
string columnName = this.gridView1.Columns[i].FieldName;
@@ -755,6 +826,11 @@ namespace Lskj.Control
if (gsi.SummaryType != DevExpress.Data.SummaryItemType.None) //gsi.SummaryValue!=null&& !string.IsNullOrEmpty(gsi.SummaryValue.ToString())
{
if (gsi.SummaryType == DevExpress.Data.SummaryItemType.Custom)
{
_exportCustomSummaryValues[columnName] = GetExportSummaryValue(gridView.Columns[columnName], gsi);
}
string originalFormat = gsi.DisplayFormat;
// 匹配 {0:#.##}、{0:0.##} 等格式 避免出现没有小数但是还有小数点的情况,如 0.
try
@@ -763,7 +839,7 @@ namespace Lskj.Control
if (match.Success)
{
string innerFormat = match.Groups[1].Value;
if (innerFormat.Contains("."))
if (innerFormat.Contains(".") && innerFormat.Split(';').Length == 1)
{
// 生成条件格式:正数;负数;零(整数无小数点)
string newInnerFormat = $"{innerFormat};{innerFormat};{innerFormat.Split('.')[0]}";
+3 -4
View File
@@ -31,11 +31,10 @@ namespace Lskj.Control
{
this.SuspendLayout();
//
// FrmWebBrowser
// FrmWebBrowser2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FrmWebBrowser";
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FrmWebBrowser2";
this.Size = new System.Drawing.Size(800, 450);
this.ResumeLayout(false);
+16 -5
View File
@@ -64,24 +64,35 @@ namespace Lskj.Control
private void bsClient_OnCreated(object sender, EventArgs e)
{
cefBrowserSettings = (CefBrowser)sender;
var handle = cefBrowserSettings.GetHost().GetWindowHandle();
ResizeWindow(handle, this.Width, this.Height);
SyncBrowserBounds();
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
if (cefBrowserSettings != null)
SyncBrowserBounds();
}
/// <summary>
/// 将CEF原生子窗口同步到当前控件的客户区,修正高DPI或父容器布局变化造成的位置偏移。
/// </summary>
public void SyncBrowserBounds()
{
if (cefBrowserSettings == null || IsDisposed || Disposing ||
ClientSize.Width <= 0 || ClientSize.Height <= 0)
{
ResizeWindow(cefBrowserSettings.GetHost().GetWindowHandle(), Width, Height);
return;
}
ResizeWindow(cefBrowserSettings.GetHost().GetWindowHandle(), ClientSize.Width, ClientSize.Height);
}
public void ResizeWindow(IntPtr handle, int width, int height)
{
if (handle != IntPtr.Zero)
{
const uint SWP_NOZORDER = 0x0004;
const uint SWP_NOACTIVATE = 0x0010;
NativeMethod.SetWindowPos(handle, IntPtr.Zero,
0, 0, width, height,
0x0002 | 0x0004
SWP_NOZORDER | SWP_NOACTIVATE
);
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -75,6 +75,11 @@ namespace Lskj.Control
/// 初始赋值
/// </summary>
public string ControlValue = string.Empty;
/// <summary>
/// 保存表格属性用到的key
/// </summary>
public string CurrentOperColumnKey = string.Empty;
public LabelMultiAutoTextEdit()
@@ -380,6 +385,7 @@ namespace Lskj.Control
_lookUpForm.TextField = TextField;
_lookUpForm.SourceSQL = SourceSQL;
_lookUpForm.DataSource = dataSource;
_lookUpForm.CurrentOperColumnKey = CurrentOperColumnKey;
}
/// <summary>
/// <para>说明:清空选中的值</para>
@@ -419,6 +425,7 @@ namespace Lskj.Control
_lookUpForm.EditValue = this.EditValue;
_lookUpForm.IsType = Model.FieldType;
_lookUpForm.EditText = this.TextEdit.Text;
_lookUpForm.CurrentOperColumnKey = CurrentOperColumnKey;
string sqlValue = string.Empty;
if (this.ControlObj != null)
{
+13 -1
View File
@@ -708,6 +708,13 @@
<Compile Include="AutoGridLookUp\AutoGridPopup.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoGridLookUp\ExtendedReturnSearchPopup.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoGridLookUp\ExtendedReturnModuleSourceResolver.cs" />
<Compile Include="AutoGridLookUp\LabelExtendedReturnSearchEdit.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="AutoGridLookUp\AutoGridPopup.Designer.cs">
<DependentUpon>AutoGridPopup.cs</DependentUpon>
</Compile>
@@ -1161,6 +1168,10 @@
<Compile Include="GridControlEx.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="GridControlEx.ExtendedReturn.cs">
<DependentUpon>GridControlEx.cs</DependentUpon>
<SubType>UserControl</SubType>
</Compile>
<Compile Include="GridControlEx.Designer.cs">
<DependentUpon>GridControlEx.cs</DependentUpon>
</Compile>
@@ -1263,6 +1274,7 @@
<Compile Include="Model\ControlModel.cs" />
<Compile Include="Model\ControlType.cs" />
<Compile Include="Model\DateFormat.cs" />
<Compile Include="Model\ExtendedReturnSupport.cs" />
<Compile Include="Model\GridColumnModel.cs" />
<Compile Include="Model\GridRowColorModel.cs" />
<Compile Include="Model\MessageUtil.cs" />
@@ -1880,4 +1892,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
@@ -182,7 +182,10 @@ namespace Lskj.Control.Model
/// 判断两个值是否相同。
/// 优先按日期、数字进行值比较,最后再按普通字符串比较。
/// </summary>
private static bool IsSameValue(string oldValue, string newValue)
/// <param name="oldValue">原始值</param>
/// <param name="newValue">当前值</param>
/// <returns>两个值在统一格式后是否相同</returns>
public static bool IsSameValue(string oldValue, string newValue)
{
oldValue = NormalizeValue(oldValue);
newValue = NormalizeValue(newValue);
+51 -5
View File
@@ -22,6 +22,7 @@ using System.IO;
using System.Data.SqlClient;
using Lskj.Business;
using DevExpress.XtraGrid.Views.Grid;
using Lskj.Core;
namespace Lskj.Control.Model
{
@@ -38,6 +39,12 @@ namespace Lskj.Control.Model
/// </summary>
private MyControl _controlObj;
public bool issuccess = true;
/// <summary>
/// 最初账套版本
/// </summary>
public DataRow AccountItem;
/// <summary>
/// Occurs when [apply before].
/// </summary>
@@ -73,13 +80,12 @@ namespace Lskj.Control.Model
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
public bool Apply(DataRow rowItem)
{
bool resultValue = false;
if (rowItem == null || this._controlObj == null) return resultValue;
GridRightMenuModel model = new GridRightMenuModel(rowItem);
try
{
bool resultValue = false;
if (rowItem == null || this._controlObj == null) return resultValue;
GridRightMenuModel model = new GridRightMenuModel(rowItem);
//if (!string.IsNullOrWhiteSpace(model.MenuCond))
//{
// try
@@ -103,6 +109,18 @@ namespace Lskj.Control.Model
// }
//}
if (!string.IsNullOrEmpty(model.UnionZTid))
{
string UnionZTid = ReplaceHelper.ReplaceRowParam(BaseGridView.GetFocusedDataRow(), model.UnionZTid);
string condition = string.Format("where ShowName ='{0}'", ERPInfo.Instance.AccountBook);
DataTable dt = MainImpl.GetLedgerList(condition);
DataRow RT = BaseImpl.GetDataRowResult($"select * from p_sydbGroupTab where ID={UnionZTid}");
AccountItem = dt.Rows[0];
AccountItem["IP"] = DBConfig.Instance.ServerName;
ToDBatching(RT, AccountItem);
}
if (!string.IsNullOrWhiteSpace(model.BeforeMsg))
{
@@ -186,6 +204,10 @@ namespace Lskj.Control.Model
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
finally
{
if (!string.IsNullOrEmpty(model.UnionZTid)) ToDBatching(AccountItem, AccountItem);
}
return true;
}
/// <summary>
@@ -507,5 +529,29 @@ namespace Lskj.Control.Model
}
return false;
}
/// <summary>
/// 启动账套数据源刷新
/// </summary>
protected void ToDBatching(DataRow RT, DataRow firstrow)
{
string serverIP = RT["IP"] + "";
string dbName = RT["DBName"] + "";
string dataBook = RT["ShowName"] + "";
bool isInternal = RT.Table.Columns.Contains("IsInternalNetwork") && !string.IsNullOrEmpty(RT["IsInternalNetwork"] + "") ? "1".Equals(RT["IsInternalNetwork"] + "") : false;
DBConfig.Instance.DataBook = dataBook;
DBConfig.Instance.ServerName = serverIP;
DBConfig.Instance.DataBase = dbName;
DBConfig.Instance.IsInternalNetwork = isInternal;
if (!DBConfig.Instance.CreateConnection())
{
ToDBatching(firstrow, firstrow);
}
}
}
}
+9 -2
View File
@@ -139,6 +139,10 @@ namespace Lskj.Control.Model
/// <value>The text member.</value>
public string TextMember { get; set; }
/// <summary>
/// 扩展返回字段映射,格式为“业务控件字段=返回数据字段”。
/// </summary>
public string ResultFields { get; set; }
/// <summary>
/// Gets or sets the source SQL.
/// </summary>
/// <value>The source SQL.</value>
@@ -204,7 +208,7 @@ namespace Lskj.Control.Model
/// <value>The enable cond.</value>
public string RequiredCond { get; set; }
/// <summary>
/// 可以方式
/// 禁用方式(默认禁编,设置为1就禁显)
/// </summary>
/// <value>The type of the enable.</value>
public string DisableType { get; set; }
@@ -366,7 +370,10 @@ namespace Lskj.Control.Model
///记住上一次的值(关闭时记住上一次的条件值,下一次打开时输入上去。关闭程序后清空)
/// </summary>
public bool RememberValue { get; set; }
/// <summary>
/// 明细合计
/// </summary>
public string SumlistField { get; set; }
}
}
+23 -12
View File
@@ -493,21 +493,30 @@ namespace Lskj.Control.Model
/// <summary>
/// 快速搜索框返回id(字典模式)
/// 模块选择返回ID-扩展
/// </summary>
public const int DictionarySearchBoxToId = 181;
public const int LabModuleSelectReturnIdExtended = 173;
/// <summary>
/// 快速搜索返回text(字典模式)
/// 搜索返回ID-扩展
/// </summary>
public const int DictionarySearchBoxToText = 182;
/// <summary>
/// 快速搜索框返回id 带参数(字典模式)
/// </summary>
public const int DictionarySearchBoxToIdParam = 183;
/// <summary>
/// 快速搜索框返回text 带参数(字典模式)
/// </summary>
public const int DictionarySearchBoxToTextParam = 184;
public const int LabSearchReturnIdExtended = 174;
///// <summary>
///// 快速搜索框返回id(字典模式)
///// </summary>
//public const int DictionarySearchBoxToId = 181;
///// <summary>
///// 快速搜索框返回text(字典模式)
///// </summary>
//public const int DictionarySearchBoxToText = 182;
///// <summary>
///// 快速搜索框返回id 带参数(字典模式)
///// </summary>
//public const int DictionarySearchBoxToIdParam = 183;
///// <summary>
///// 快速搜索框返回text 带参数(字典模式)
///// </summary>
//public const int DictionarySearchBoxToTextParam = 184;
/// <summary>
/// <para>说明:是否为Value类型</para>
@@ -628,6 +637,8 @@ namespace Lskj.Control.Model
fieldType == LabPhone ||
fieldType == LabSelectReturnIdNew ||
fieldType == LabSelectReturnTextNew ||
fieldType == LabModuleSelectReturnIdExtended ||
fieldType == LabSearchReturnIdExtended ||
fieldType == LabApiBtuton||
fieldType == LabModuleAddRowsID ||
fieldType == LabModuleAddRowsText;
@@ -0,0 +1,195 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Text.RegularExpressions;
namespace Lskj.Control.Model
{
internal sealed class ExtendedReturnFieldMapping
{
public ExtendedReturnFieldMapping(string targetField, string sourceField)
{
TargetField = targetField;
SourceField = sourceField;
}
public string TargetField { get; private set; }
public string SourceField { get; private set; }
}
internal static class ExtendedReturnSupport
{
internal const string SearchAlias = "LS_ExtendedLookup";
internal const string SearchParameterName = "@lookupKeyword";
public static IList<ExtendedReturnFieldMapping> ParseResultFields(string resultFields)
{
List<ExtendedReturnFieldMapping> mappings = new List<ExtendedReturnFieldMapping>();
if (string.IsNullOrWhiteSpace(resultFields)) return mappings;
HashSet<string> targetFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
string[] items = resultFields.Split(new char[] { ';', '' });
foreach (string rawItem in items)
{
string item = (rawItem ?? string.Empty).Trim();
if (item.Length == 0) continue;
int separatorIndex = item.IndexOf('=');
if (separatorIndex <= 0 || separatorIndex == item.Length - 1 || item.IndexOf('=', separatorIndex + 1) >= 0)
{
throw new FormatException(string.Format("返回字段配置“{0}”格式错误,应为“业务表字段=返回数据字段”。", item));
}
string targetField = item.Substring(0, separatorIndex).Trim();
string sourceField = item.Substring(separatorIndex + 1).Trim();
if (targetField.Length == 0 || sourceField.Length == 0)
{
throw new FormatException(string.Format("返回字段配置“{0}”存在空字段名。", item));
}
if (!targetFields.Add(targetField))
{
throw new FormatException(string.Format("返回字段配置中的业务表字段“{0}”重复。", targetField));
}
mappings.Add(new ExtendedReturnFieldMapping(targetField, sourceField));
}
return mappings;
}
public static string FindTargetField(IEnumerable<ExtendedReturnFieldMapping> mappings, string sourceField)
{
if (mappings == null || string.IsNullOrWhiteSpace(sourceField)) return string.Empty;
foreach (ExtendedReturnFieldMapping mapping in mappings)
{
if (string.Equals(mapping.SourceField, sourceField, StringComparison.OrdinalIgnoreCase))
{
return mapping.TargetField;
}
}
return string.Empty;
}
public static string BuildStructureSql(string sourceSql)
{
return string.Format("select top 0 * from ({0}) as [{1}]", NormalizeSourceSql(sourceSql), SearchAlias);
}
public static string BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows)
{
return BuildSearchSql(sourceSql, columns, maxRows, string.Empty);
}
public static string BuildSearchSql(string sourceSql, DataColumnCollection columns, int maxRows, string searchField)
{
if (columns == null || columns.Count == 0)
{
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
}
if (maxRows <= 0)
{
throw new ArgumentOutOfRangeException("maxRows", "最大返回行数必须大于零。");
}
List<DataColumn> searchColumns = new List<DataColumn>();
string selectedField = (searchField ?? string.Empty).Trim();
if (selectedField.Length == 0)
{
foreach (DataColumn column in columns)
{
if (IsSearchableColumn(column.ColumnName))
{
searchColumns.Add(column);
}
}
}
else
{
foreach (DataColumn column in columns)
{
if (string.Equals(column.ColumnName, selectedField, StringComparison.OrdinalIgnoreCase) &&
IsSearchableColumn(column.ColumnName))
{
searchColumns.Add(column);
break;
}
}
}
if (searchColumns.Count == 0)
{
if (selectedField.Length > 0)
{
throw new InvalidOperationException(string.Format("搜索字段“{0}”不存在或不允许查询。", selectedField));
}
throw new InvalidOperationException("搜索 SQL 没有返回任何可查询列。");
}
string alias = QuoteIdentifier(SearchAlias);
StringBuilder builder = new StringBuilder();
builder.AppendFormat("select top ({0}) * from ({1}) as {2} where ", maxRows, NormalizeSourceSql(sourceSql), alias);
for (int i = 0; i < searchColumns.Count; i++)
{
if (i > 0) builder.Append(" or ");
builder.Append("convert(nvarchar(4000), ");
builder.Append(alias);
builder.Append('.');
builder.Append(QuoteIdentifier(searchColumns[i].ColumnName));
builder.Append(") like ");
builder.Append(SearchParameterName);
builder.Append(" escape N'\\'");
}
return builder.ToString();
}
public static bool IsSearchableColumn(string columnName)
{
return !string.IsNullOrWhiteSpace(columnName) &&
!columnName.StartsWith("_", StringComparison.Ordinal);
}
public static string BuildLikeParameterValue(string keyword)
{
string value = keyword ?? string.Empty;
value = value.Replace("\\", "\\\\");
value = value.Replace("%", "\\%");
value = value.Replace("_", "\\_");
value = value.Replace("[", "\\[");
return "%" + value + "%";
}
private static string NormalizeSourceSql(string sourceSql)
{
if (string.IsNullOrWhiteSpace(sourceSql))
{
throw new InvalidOperationException("搜索数据源 SQL 不能为空。");
}
string normalized = sourceSql.Trim();
if (normalized.EndsWith(";", StringComparison.Ordinal))
{
normalized = normalized.Substring(0, normalized.Length - 1).TrimEnd();
}
if (normalized.IndexOf(';') >= 0)
{
throw new InvalidOperationException("扩展搜索只支持一条可组合的 SELECT 语句。");
}
if (!Regex.IsMatch(normalized, @"^select\b", RegexOptions.IgnoreCase))
{
throw new InvalidOperationException("扩展搜索数据源必须是可作为派生表使用的 SELECT 语句。");
}
return normalized;
}
private static string QuoteIdentifier(string identifier)
{
if (string.IsNullOrWhiteSpace(identifier))
{
throw new InvalidOperationException("搜索 SQL 返回了空列名。");
}
return "[" + identifier.Replace("]", "]]") + "]";
}
}
}
@@ -57,6 +57,7 @@ namespace Lskj.Control.Model
private bool _frozenFlag;
private int _lookUpWidth;
private string _lookUpFieldsWidth;
private string _resultFields;
#endregion
@@ -326,6 +327,10 @@ namespace Lskj.Control.Model
/// </summary>
public string LookUpFieldsWidth { get { return this._lookUpFieldsWidth; } }
/// <summary>
/// 扩展选择结果映射,格式:业务表字段=返回数据字段;业务表字段1=返回数据字段1。
/// </summary>
public string ResultFields { get { return this._resultFields; } }
/// <summary>
/// 动态列
/// </summary>
public bool isDynamic;
@@ -459,6 +464,7 @@ namespace Lskj.Control.Model
}
this.addModuleResult = item.Table.Columns.Contains("addModuleResult") ? item["addModuleResult"] + "" : string.Empty;
this._resultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
this.addModuleld = item.Table.Columns.Contains("addModuleId") ? item["addModuleId"] + "" : string.Empty;
this.unionCompare = item.Table.Columns.Contains("UnionCompare") ? item["UnionCompare"] + "" : string.Empty;
this.isExportColumns = item.Table.Columns.Contains("isExportColumns") && !string.IsNullOrWhiteSpace(item["isExportColumns"] + "") ? "1".Equals(item["isExportColumns"] + "") : false;
@@ -307,6 +307,11 @@ namespace Lskj.Control.Model
/// </summary>
public bool AddHideBottomPanel;
/// <summary>
/// 禁用条件
/// </summary>
public string VisibleCond;
/// <summary>
/// 主模块编号
/// </summary>
@@ -379,6 +384,7 @@ namespace Lskj.Control.Model
this.IgnoreAssociatedFields = item.Table.Columns.Contains("IgnoreAssociatedFields") ? "1".Equals(item["IgnoreAssociatedFields"] + "") : false;
this.Library = item.Table.Columns.Contains("Library") ? item["Library"] + "" : "";
this.AddHideBottomPanel = item.Table.Columns.Contains("AddHideBottomPanel") ? "1".Equals(item["AddHideBottomPanel"] + "") : false;
this.VisibleCond = item.Table.Columns.Contains("VisibleCond") ? item["VisibleCond"] + "" : "";
}
}
}
+7 -3
View File
@@ -1110,6 +1110,7 @@ namespace Lskj.Control.Model
gridControl.gridViewRightMenu = rightMenu;
rightMenu.InitRightMenus(gridControl, table, model, control, menu);
rightMenu.SetRightCallback(handler);
gridControl.SetRightMenuButtonTable(table);
}
/// <summary>
/// <para>说明:设置表格右键菜单</para>
@@ -2801,7 +2802,9 @@ namespace Lskj.Control.Model
GridColumnModel model = col.Tag as GridColumnModel;
if (cell != null)
{
if (cell.CellType == CellType.Blank)
// DevExpress导出的xlsx空值可能是内容为空的String单元格,也应按空单元格处理。
if (cell.CellType == CellType.Blank ||
(cell.CellType == CellType.String && string.IsNullOrEmpty(cell.StringCellValue)))
{
//isImportRows = false;
continue;
@@ -3564,7 +3567,8 @@ namespace Lskj.Control.Model
{
string field = fields[i];
string value = rowResult.Table.Columns.Contains(field) ? rowResult[field] + "" : null;
rowItem[field] = value;
if(rowItem.Table.Columns.Contains(field)) rowItem[field] = value;
}
}
else
@@ -3573,7 +3577,7 @@ namespace Lskj.Control.Model
for (int i = 0; i < fields.Length; i++)
{
string field = fields[i];
rowItem[field] = DBNull.Value;
if (rowItem.Table.Columns.Contains(field)) rowItem[field] = DBNull.Value;
}
}
}
@@ -36,54 +36,62 @@ namespace Lskj.Control.Model.MenuStrip
}
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
{
int[] mSelectRows = this._gridView.GetSelectedRows();
if (mSelectRows == null || mSelectRows.Length == 0) return;
int[] mSelectRows = this._gridView.GetSelectedRows() ?? new int[0];
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
DataRow[] dataRows = new DataRow[mSelectRows.Length];
for (int i = 0; i < mSelectRows.Length; i++)
{
dataRows[i] = this._gridView.GetDataRow(mSelectRows[i]);
}
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
cmsMenu.Items.Clear();
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (GridColumn column in this._gridView.Columns)
if (mSelectRows.Length > 0)
{
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (GridColumn column in this._gridView.Columns)
{
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabQQ)
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabWWW ||
rowValue.StartsWith("www.") ||
rowValue.StartsWith("http://") ||
rowValue.StartsWith("https://") ||
rowValue.StartsWith("ftp://") ||
rowValue.StartsWith("file://"))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
if (model.FieldType == ControlType.LabQQ)
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
if (model.FieldType == ControlType.LabWWW ||
rowValue.StartsWith("www.") ||
rowValue.StartsWith("http://") ||
rowValue.StartsWith("https://") ||
rowValue.StartsWith("ftp://") ||
rowValue.StartsWith("file://"))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
}
}
}
}
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
}
// 判断右键菜单是否可用
foreach (ToolStripItem cms in cmsMenu.Items)
@@ -95,34 +103,83 @@ namespace Lskj.Control.Model.MenuStrip
{
try
{
string cond = string.Empty;
if (this._control != null)
cond = _control.ReplaceParentControlValue(model.MenuCond);
cond = ReplaceHelper.ReplaceRowParam(mSelectRow, model.MenuCond);
if (this._gridView != null)
bool condResult = false;
StringBuilder condBuilder = new StringBuilder();
StringBuilder sqlCondBuilder = new StringBuilder();
GridCell[] cells = this._gridView.GetSelectedCells();
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
DataRow[] conditionRows = dataRows;
if (model.AllowNullExec && conditionRows.Length == 0)
{
GridCell[] cells = this._gridView.GetSelectedCells();
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
foreach (DataRow selectRow in conditionRows)
{
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
if (this._control != null)
{
GridCell cell = cells[0];
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
cond = _control.ReplaceParentControlValue(cond);
}
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
if (model.Mergeexec && cond.StartsWith("@"))
{
//替换[],替换的是多选行中的数据
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
}
if (this._gridView != null)
{
if (cells != null && cells.Length > 0 && cond.Contains("{COLUMN_"))
{
GridCell cell = cells[0];
string colValue = focusedRow == null || !focusedRow.Table.Columns.Contains(cell.Column.Name) ? "" : focusedRow[cell.Column.Name] + "";
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
}
}
if (ControlObj != null)
{
cond = ControlObj.ReplaceParentControlValue(cond);
}
if (cond.StartsWith("@"))
{
sqlCondBuilder.Append($"({cond.TrimStart('@')}) = '1' and ");
}
else
{
condBuilder.Append($"({cond}) and ");
}
}
if (ControlObj != null)
cond = ControlObj.ReplaceParentControlValue(cond);
string condStr = model.MenuCond;
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
{
if (model.MenuCond.StartsWith("@"))
{
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
}
else
{
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
}
}
condResult = ValidateCond(condStr, null);
//cms.Enabled = ReplaceHelper.EvalCond(cond);
if (model.ForbiddenDisplay)
{
cms.Visible = ValidateCond(cond, null); ;
cms.Visible = condResult;
}
cms.Enabled = ValidateCond(cond, null); ;
cms.Enabled = condResult;
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(ResourceKeys.SetRightMenuCondFault + "\r\n" + Message);
e.Cancel = true;
break;
}
}
@@ -50,6 +50,7 @@ namespace Lskj.Control.Model
/// 最初账套版本
/// </summary>
public DataRow AccountItem;
public DataTable MenuTable;
public DynamicModel Model;
public MyControl ControlObj;
@@ -71,6 +72,23 @@ namespace Lskj.Control.Model
/// 替换参数前执行
/// </summary>
public event BeforeHandleParamsEventHandler OnBeforeHandleParamsCallback;
/// <summary>
/// 触发替换参数前事件,并返回事件处理后的参数值。
/// </summary>
protected string RaiseBeforeHandleParamsCallback(List<string> paramList, DataRow[] rowDatas, string paramItem, DataRow rowData, string fieldValue)
{
BeforeHandleParamsEventHandler handler = OnBeforeHandleParamsCallback;
if (handler == null)
return fieldValue;
HandleParamsArgs handleParamsArgs = new HandleParamsArgs(paramList, rowDatas, paramItem, rowData)
{
FieldValue = fieldValue
};
handler(this, handleParamsArgs);
return handleParamsArgs.FieldValue;
}
/// <summary>
/// 缓存右键菜单
/// </summary>
@@ -156,6 +174,11 @@ namespace Lskj.Control.Model
cmsMenu.Items.Add(menuItem);
RightMenuItems.Add(menuItem);
}
if (menuModel.FontSize != 0)
{
menuItem.Font = new Font(menuItem.Font.FontFamily, menuModel.FontSize);
}
}
if (!string.IsNullOrWhiteSpace(menuModel.ExecuteFirstCode))
{
@@ -245,7 +268,7 @@ namespace Lskj.Control.Model
public bool ValidateCond(string cond, DataRow dataRow)
{
bool result = false;
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
if (cond.StartsWith("@") || cond.StartsWith("!"))
{
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
@@ -287,7 +310,7 @@ namespace Lskj.Control.Model
return;
}
if (model.VerifyUpdate && BaseGridView!=null)
if (model.VerifyUpdate && BaseGridView != null)
{
for (int i = 0; i < BaseGridView.DataRowCount; i++)
{
@@ -485,7 +508,7 @@ namespace Lskj.Control.Model
{
tipOnlyOne = false;
string prompt = ReplaceHelper.ReplaceRowParam(rowData, model.BeforeMsg);
if (model.Mergeexec)
if (model.Mergeexec)
{
//替换[],替换的是多选行中的数据
prompt = ReplaceHelper.ReplaceRowParam(rows, prompt.Replace("[", "{").Replace("]", "}"), "", "");
@@ -960,7 +983,7 @@ namespace Lskj.Control.Model
case -1:
if (rValue == -1)
{
if (SqlHelper.ConnectionType == ConnectionType.SqlServer)
if (SqlHelper.ConnectionType == ConnectionType.SqlServer)
{
SqlStoredProcedurepPrompt.GenerateProcedureExecutionScript(procName, paramList, isFirstFlag, comfirmFlag);
}
@@ -1794,7 +1817,7 @@ namespace Lskj.Control.Model
paramList[2] = ReplaceHelper.ReplaceRowParam(rows, url) + "";
}
}
if (model.DllName.ToLower().Contains("p_PubPrint.lsp".ToLower())&& !model.CancelDefaultReplace)
if (model.DllName.ToLower().Contains("p_PubPrint.lsp".ToLower()) && !model.CancelDefaultReplace)
{
string paramsql1 = paramList[2];
paramList[2] = ReplaceHelper.ReplaceRowParam(rows, paramsql1, "'", "'");
@@ -1899,15 +1922,7 @@ namespace Lskj.Control.Model
if (!string.IsNullOrWhiteSpace(item))
{
string fieldValue = ReplaceHelper.ReplaceUserInfo(item);
if (OnBeforeHandleParamsCallback != null)
{
HandleParamsArgs handleParamsArgs = new HandleParamsArgs(paramList, rowDatas, item, rowData)
{
FieldValue = fieldValue
};
OnBeforeHandleParamsCallback(this, handleParamsArgs);
fieldValue = handleParamsArgs.FieldValue;
}
fieldValue = RaiseBeforeHandleParamsCallback(paramList, rowDatas, item, rowData, fieldValue);
if (!string.IsNullOrWhiteSpace(fieldValue) && fieldValue.TrimStart().StartsWith("MergeExec_", StringComparison.OrdinalIgnoreCase))
{
fieldValue = ReplaceHelper.ReplaceRowParam(rowDatas, fieldValue.Replace("MergeExec_", "", true));
@@ -2086,4 +2101,4 @@ namespace Lskj.Control.Model
}
}
}
}
}
@@ -40,8 +40,7 @@ namespace Lskj.Control.Model
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
{
int[] mSelectRows = this._gridView.GetSelectedRows();
if (mSelectRows == null || mSelectRows.Length == 0) return;
int[] mSelectRows = this._gridView.GetSelectedRows() ?? new int[0];
DataRow[] dataRows = new DataRow[mSelectRows.Length];
for (int i = 0; i < mSelectRows.Length; i++)
@@ -49,49 +48,53 @@ namespace Lskj.Control.Model
dataRows[i] = this._gridView.GetDataRow(mSelectRows[i]);
}
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
this._gridView.UpdateCurrentRow();
this._gridView.ShowEditor();
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
cmsMenu.Items.Clear();
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (GridColumn column in this._gridView.Columns)
if (mSelectRows.Length > 0)
{
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
DataRow mSelectRow = this._gridView.GetDataRow(mSelectRows[0]);
this._gridView.UpdateCurrentRow();
this._gridView.ShowEditor();
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (GridColumn column in this._gridView.Columns)
{
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabQQ)
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabWWW && !string.IsNullOrWhiteSpace(rowValue))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.www);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
if (model.FieldType == ControlType.LabQQ)
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
if (model.FieldType == ControlType.LabWWW && !string.IsNullOrWhiteSpace(rowValue))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.www);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
}
}
}
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
}
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
Dictionary<ToolStripItem, GridRightMenuModel> cmsModelDic = new Dictionary<ToolStripItem, GridRightMenuModel>();
List<string> roleNamesList = new List<string>();
@@ -103,6 +106,8 @@ namespace Lskj.Control.Model
roleNamesList.Add(model.PrivilegeOper);
}
}
// 判断右键菜单是否可用
foreach (ToolStripItem cms in cmsMenu.Items)
{
@@ -126,20 +131,28 @@ namespace Lskj.Control.Model
StringBuilder sqlCondBuilder = new StringBuilder();
GridCell[] cells = this._gridView.GetSelectedCells();
DataRow focusedRow = this.BaseGridView.GetFocusedDataRow();
foreach (int itemIndex in mSelectRows)
DataRow[] conditionRows = dataRows;
if (model.AllowNullExec && conditionRows.Length == 0)
{
DataRow selectRow = this._gridView.GetDataRow(itemIndex);
string cond = string.Empty;
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
foreach (DataRow selectRow in conditionRows)
{
//DataRow selectRow = this._gridView.GetDataRow(itemIndex);
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
if (this._control != null)
{
cond = _control.ReplaceParentControlValue(model.MenuCond);
cond = _control.ReplaceParentControlValue(cond);
}
cond = ReplaceHelper.ReplaceRowParam(selectRow, model.MenuCond);
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
if (model.Mergeexec&& cond.StartsWith("@"))
{
//替换[],替换的是多选行中的数据
cond = ReplaceHelper.ReplaceRowParam(dataRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
}
if (this._gridView != null)
@@ -151,6 +164,7 @@ namespace Lskj.Control.Model
cond = cond.ReplaceColumnParam(cell.Column.Name, cell.Column.Caption, colValue);
}
}
if (ControlObj != null)
{
cond = ControlObj.ReplaceParentControlValue(cond);
@@ -164,15 +178,19 @@ namespace Lskj.Control.Model
condBuilder.Append($"({cond}) and ");
}
}
string condStr = "";
if (model.MenuCond.StartsWith("@"))
string condStr = model.MenuCond;
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
{
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
}
else
{
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
if (model.MenuCond.StartsWith("@"))
{
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
}
else
{
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
}
}
condResult = ValidateCond(condStr, null);
//if (!condResult) break;
//cms.Enabled = ReplaceHelper.EvalCond(cond);
@@ -346,6 +346,10 @@ namespace Lskj.Control.Model
/// 右键多选合并不走默认替换(p_PubPrint.lsp
/// </summary>
public bool CancelDefaultReplace;
/// <summary>
/// 右键字体大小
/// </summary>
public int FontSize;
/// <summary>
@@ -485,6 +489,8 @@ namespace Lskj.Control.Model
this.VerifyUpdate = string.IsNullOrWhiteSpace(item["VerifyUpdate"] + "") ? false : "1".Equals(item["VerifyUpdate"] + "");
if (item.Table.Columns.Contains("CancelDefaultReplace"))
this.CancelDefaultReplace = string.IsNullOrWhiteSpace(item["CancelDefaultReplace"] + "") ? false : "1".Equals(item["CancelDefaultReplace"] + "");
this.FontSize = item.Table.Columns.Contains("FontSize") && !string.IsNullOrEmpty(item["FontSize"] + "") ? Convert.ToInt32(item["FontSize"] + "") : 0;
}
/// <summary>
@@ -73,56 +73,58 @@ namespace Lskj.Control.Model.MenuStrip
}
protected override void MenuStripOpening(object sender, System.ComponentModel.CancelEventArgs e)
{
DataRow[] mSelectRows = this.TreeGridControlObj.GetViewFocusedDataRows();
if (mSelectRows == null || mSelectRows.Length == 0) return;
DataRow mSelectRow = mSelectRows[0];
this._treeView.EndCurrentEdit();
this._treeView.ShowEditor();
DataRow[] mSelectRows = this.TreeGridControlObj.GetViewFocusedDataRows() ?? new DataRow[0];
ContextMenuStrip cmsMenu = (ContextMenuStrip)sender;
cmsMenu.Items.Clear();
cmsMenu.Items.AddRange(this.RightMenuItems.ToArray());
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (TreeListColumn column in this._treeView.Columns)
if (mSelectRows.Length > 0)
{
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
DataRow mSelectRow = mSelectRows[0];
this._treeView.EndCurrentEdit();
this._treeView.ShowEditor();
// 创建QQ、浏览器右键菜单
List<ToolStripMenuItem> mQQArray = new List<ToolStripMenuItem>();
List<ToolStripMenuItem> mBrowerArray = new List<ToolStripMenuItem>();
foreach (TreeListColumn column in this._treeView.Columns)
{
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabQQ)
if (!mSelectRow.Table.Columns.Contains(column.Name))
continue;
string rowValue = mSelectRow[column.Name] + "";
if (!string.IsNullOrWhiteSpace(rowValue))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
GridColumnModel model = column.Tag as GridColumnModel;
if (model == null) continue;
if (model.FieldType == ControlType.LabWWW &&
(rowValue.StartsWith("www.") ||
rowValue.StartsWith("http://") ||
rowValue.StartsWith("https://") ||
rowValue.StartsWith("ftp://") ||
rowValue.StartsWith("file://")))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
if (model.FieldType == ControlType.LabQQ)
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(QQItemClick);
mQQArray.Add(item);
}
if (model.FieldType == ControlType.LabWWW &&
(rowValue.StartsWith("www.") ||
rowValue.StartsWith("http://") ||
rowValue.StartsWith("https://") ||
rowValue.StartsWith("ftp://") ||
rowValue.StartsWith("file://")))
{
ToolStripMenuItem item = new ToolStripMenuItem("(" + column.Caption + ")" + rowValue, Resources.qq);
item.Tag = mSelectRow[column.Name] + "";
item.Click += new EventHandler(BrowerItemClick);
mBrowerArray.Add(item);
}
}
}
}
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
cmsMenu.Items.AddRange(mQQArray.ToArray());
cmsMenu.Items.AddRange(mBrowerArray.ToArray());
}
// 判断右键菜单是否可用
foreach (ToolStripItem cms in cmsMenu.Items)
@@ -139,19 +141,27 @@ namespace Lskj.Control.Model.MenuStrip
StringBuilder sqlCondBuilder = new StringBuilder();
List<TreeListCell> cells = this._treeView != null ? this._treeView.GetSelectedCells() : null;
DataRow focusedRow = this.TreeGridControlObj.GetViewFocusedDataRow();
foreach (DataRow selectRow in mSelectRows)
DataRow[] conditionRows = mSelectRows;
if (model.AllowNullExec && conditionRows.Length == 0)
{
conditionRows = new DataRow[] { new DataTable().NewRow() };
}
foreach (DataRow selectRow in conditionRows)
{
if (selectRow == null) continue;
string cond = string.Empty;
string cond = ReplaceHelper.ReplaceUserInfo(model.MenuCond);
cond = RaiseBeforeHandleParamsCallback(model.ParamList, conditionRows, model.MenuCond, selectRow, cond);
if (this._control != null)
cond = _control.ReplaceParentControlValue(model.MenuCond);
cond = ReplaceHelper.ReplaceRowParam(selectRow, model.MenuCond);
cond = _control.ReplaceParentControlValue(cond);
//cond = ReplaceHelper.ReplaceRowParam(selectRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(selectRow, cond);
if (model.Mergeexec && cond.StartsWith("@"))
{
//替换[],替换的是多选行中的数据
cond = ReplaceHelper.ReplaceRowParam(mSelectRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
cond = ReplaceHelper.ReplaceRowParam(conditionRows, cond.Replace("[", "{").Replace("]", "}"), "", "");
}
if (cells != null && cells.Count > 0 && cond.Contains("{COLUMN_"))
@@ -173,14 +183,17 @@ namespace Lskj.Control.Model.MenuStrip
condBuilder.Append($"({cond}) and ");
}
}
string condStr = "";
if (model.MenuCond.StartsWith("@"))
string condStr = model.MenuCond;
if (!string.IsNullOrWhiteSpace(sqlCondBuilder.ToString()) || !string.IsNullOrWhiteSpace(condBuilder.ToString()))
{
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
}
else
{
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
if (model.MenuCond.StartsWith("@"))
{
condStr = $"@if({sqlCondBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a')}) begin select '1' end else begin select '0' end";
}
else
{
condStr = condBuilder.ToString().TrimEnd().TrimEnd('d', 'n', 'a');
}
}
condResult = ValidateCond(condStr, null);
//cms.Enabled = ReplaceHelper.EvalCond(cond);
+49 -9
View File
@@ -27,7 +27,43 @@ namespace Lskj.Control
public sealed class MessageUtil
{
public static string Prompt = string.IsNullOrWhiteSpace(SystemInfo.Instance.DeadlockPrompt) ? "网络连接超时,请稍候再试!" : SystemInfo.Instance.DeadlockPrompt;
public static string Prompt = "网络连接超时,请稍候再试!";
/// <summary>
/// 系统配置尚未初始化时不主动访问数据库,读取失败则使用默认死锁提示。
/// </summary>
private static bool TryGetDeadlockPrompt(string message, out string deadlockPrompt)
{
deadlockPrompt = message;
if (string.IsNullOrEmpty(message) || !message.Contains("与另一个进程被死锁在"))
{
return false;
}
bool promptDeadlock = false;
string configuredPrompt = string.Empty;
try
{
SystemInfo systemInfo = SystemInfo.Instance;
if (systemInfo != null)
{
promptDeadlock = systemInfo.PromptDeadlock;
configuredPrompt = systemInfo.DeadlockPrompt;
}
}
catch
{
// 数据库连接失败或系统参数尚未初始化时,提示框仍使用安全默认值。
}
if (promptDeadlock)
{
return false;
}
deadlockPrompt = string.IsNullOrWhiteSpace(configuredPrompt) ? Prompt : configuredPrompt;
return true;
}
/// <summary>
@@ -54,8 +90,9 @@ namespace Lskj.Control
}
}
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在")&& !SystemInfo.Instance.PromptDeadlock)
msg = Prompt;
string deadlockPrompt;
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
msg = deadlockPrompt;
if (Business.Impl.LanguageTranslation.Translatable)
{
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
@@ -89,9 +126,10 @@ namespace Lskj.Control
}
}
if (!string.IsNullOrEmpty(errorMessage) && errorMessage.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
string deadlockPrompt;
if (TryGetDeadlockPrompt(errorMessage, out deadlockPrompt))
{
errorMessage = Prompt;
errorMessage = deadlockPrompt;
if (Business.Impl.LanguageTranslation.Translatable)
{
errorMessage = Business.Impl.LanguageTranslation.GetTranslatedText(errorMessage);
@@ -165,8 +203,9 @@ namespace Lskj.Control
if (Debugger.IsAttached)
{
string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.StackTrace;
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
msg = Prompt;
string deadlockPrompt;
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
msg = deadlockPrompt;
if (Business.Impl.LanguageTranslation.Translatable)
{
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
@@ -176,8 +215,9 @@ namespace Lskj.Control
else
{
string msg = ex == null ? ResourceKeys.UnKownErrorTip : ex.Message; //ResourceKeys.SystemErrorTip + "\r\n" + ex.Message + "\r\n" + ex.StackTrace;
if (!string.IsNullOrEmpty(msg) && msg.Contains("与另一个进程被死锁在") && !SystemInfo.Instance.PromptDeadlock)
msg = Prompt;
string deadlockPrompt;
if (TryGetDeadlockPrompt(msg, out deadlockPrompt))
msg = deadlockPrompt;
if (Business.Impl.LanguageTranslation.Translatable)
{
msg = Business.Impl.LanguageTranslation.GetTranslatedText(msg);
+217 -24
View File
@@ -136,6 +136,13 @@ namespace Lskj.Control.Model
/// 下拉框、搜索框控件对象
/// </summary>
public List<ControlModel> mControlList = new List<ControlModel>();
private readonly List<LabelExtendedReturnSearchEdit> mExtendedReturnSearchControls =
new List<LabelExtendedReturnSearchEdit>();
private readonly List<KeyValuePair<object, EventArgs>> mExtendedReturnPendingChanges =
new List<KeyValuePair<object, EventArgs>>();
private readonly ExtendedReturnModuleSourceResolver mExtendedReturnModuleSourceResolver =
new ExtendedReturnModuleSourceResolver();
private int mExtendedReturnBatchDepth;
/// <summary>
/// 数据源任务对象
/// </summary>
@@ -258,6 +265,12 @@ namespace Lskj.Control.Model
///特殊左侧表
/// </summary>
public GridControlEx SpecialLeftTable;
/// <summary>
///修改前的数据源
/// </summary>
public DataRow beforeData;
/// <summary>
/// 控件Panel对象
/// </summary>
@@ -1050,7 +1063,7 @@ namespace Lskj.Control.Model
DataTable rightDt = null;
if (dynamicModel != null)
{
if (!dataCaches.GetValue(parent, "RightDtGridRightMenus", out rightDt))
if (!dataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
{
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}
@@ -1210,7 +1223,7 @@ namespace Lskj.Control.Model
DataTable rightDt = null;
if (dynamicModel != null)
{
if (!dynamicModel.DataCaches.GetValue(parent, "RightDtGridRightMenus", out rightDt))
if (!dynamicModel.DataCaches.GetValue(this, "RightDtGridRightMenus", out rightDt))
{
rightDt = BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}
@@ -2253,6 +2266,11 @@ 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;
break;
case ControlType.DynamicallyGeneratedSql:
LabelMultiAutoTextEdit3 moduleSqlGenerated = ctr as LabelMultiAutoTextEdit3;
value = moduleSqlGenerated.EditText;
@@ -2679,6 +2697,7 @@ namespace Lskj.Control.Model
}
}
RefreshExtendedReturnDisplayControls();
foreach (ControlModel model in this.ControlModels)
{
BaseUserControl control = FindControl(model);
@@ -3035,6 +3054,8 @@ namespace Lskj.Control.Model
}
else
{
// 修改记录
foreach (ControlModel model in this.ControlModels)
{
@@ -3051,6 +3072,16 @@ namespace Lskj.Control.Model
if (userControl != null)
{
string fieldValue = this.GetControlValue(model);
if (beforeData != null &&
beforeData.Table != null &&
beforeData.Table.Columns.Contains(model.FieldName) &&
AuditChangeLog.IsSameValue(beforeData[model.FieldName] + "", fieldValue))
{
continue;
}
if (fieldValue == "****") continue;
if (model.FieldType == 7)
{
@@ -3710,6 +3741,14 @@ namespace Lskj.Control.Model
}
pictureEdit.TextEdit.Image = image;
}
else if (baseControl is LabelExtendedReturnSearchEdit)
{
LabelExtendedReturnSearchEdit extendedReturnSearch = baseControl as LabelExtendedReturnSearchEdit;
extendedReturnSearch.EditValue = controlValue == null || controlValue == DBNull.Value
? string.Empty
: controlValue + "";
baseControl.Model.Text = extendedReturnSearch.EditValue;
}
else if (baseControl.Model.FieldType == 7 && !"****".Equals(controlValue))
{
string dfmt = baseControl.Model.DataFormat;
@@ -3750,6 +3789,118 @@ namespace Lskj.Control.Model
//baseControl.Parent.Focus();
}
}
RefreshExtendedReturnDisplayControls();
}
/// <summary>
/// 用户从扩展搜索弹窗选择或清空时,批量写入所有映射字段。
/// 中间值改变事件会延迟到全部字段提交成功后执行,且不改变原始值基线。
/// </summary>
public void ApplyExtendedReturnValues(IList<KeyValuePair<string, object>> values)
{
if (values == null || values.Count == 0) return;
if (mExtendedReturnBatchDepth > 0)
{
throw new InvalidOperationException("扩展返回字段正在批量赋值,不能重复执行。");
}
List<KeyValuePair<string, object>> normalizedValues =
new List<KeyValuePair<string, object>>();
Dictionary<string, string> originalValues =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
Dictionary<BaseUserControl, string> originalModelTexts =
new Dictionary<BaseUserControl, string>();
HashSet<string> targetFields = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
foreach (KeyValuePair<string, object> value in values)
{
string targetField = (value.Key ?? string.Empty).Trim();
if (targetField.Length == 0)
{
throw new InvalidOperationException("扩展返回字段名称不能为空。");
}
if (!targetFields.Add(targetField))
{
throw new InvalidOperationException(
string.Format("扩展返回字段“{0}”重复。", targetField));
}
BaseUserControl targetControl = FindControl(targetField);
if (targetControl == null)
{
throw new InvalidOperationException(
string.Format("MyControl 中不存在业务控件“{0}”。", targetField));
}
object normalizedValue = value.Value == null || value.Value == DBNull.Value
? string.Empty
: value.Value;
normalizedValues.Add(new KeyValuePair<string, object>(targetField, normalizedValue));
originalValues[targetField] = GetControlValue(targetField);
originalModelTexts[targetControl] = targetControl.Model == null
? null
: targetControl.Model.Text;
}
bool success = false;
mExtendedReturnPendingChanges.Clear();
mExtendedReturnBatchDepth++;
try
{
foreach (KeyValuePair<string, object> value in normalizedValues)
{
SetControlValue(value.Key, value.Value);
}
RestoreExtendedReturnModelTexts(originalModelTexts);
RefreshExtendedReturnDisplayControls(true);
success = true;
}
catch
{
foreach (KeyValuePair<string, string> originalValue in originalValues)
{
SetControlValue(originalValue.Key, originalValue.Value);
}
RestoreExtendedReturnModelTexts(originalModelTexts);
RefreshExtendedReturnDisplayControls(true);
throw;
}
finally
{
mExtendedReturnBatchDepth--;
if (!success) mExtendedReturnPendingChanges.Clear();
}
FlushExtendedReturnPendingChanges();
}
private static void RestoreExtendedReturnModelTexts(
IDictionary<BaseUserControl, string> originalModelTexts)
{
foreach (KeyValuePair<BaseUserControl, string> item in originalModelTexts)
{
if (item.Key != null && item.Key.Model != null)
{
item.Key.Model.Text = item.Value;
}
}
}
private void RefreshExtendedReturnDisplayControls(bool force = false)
{
if (mExtendedReturnBatchDepth > 0 && !force) return;
foreach (LabelExtendedReturnSearchEdit control in mExtendedReturnSearchControls)
{
if (control != null && !control.IsDisposed && control.Model != null)
{
control.RefreshDisplayText();
}
}
}
public string ResolveExtendedReturnModuleSourceSql(string moduleCode)
{
return mExtendedReturnModuleSourceResolver.Resolve(moduleCode);
}
/// <summary>
@@ -4152,6 +4303,7 @@ namespace Lskj.Control.Model
model.Sign = item.Table.Columns.Contains("TM_tagID") && !string.IsNullOrEmpty(item["TM_tagID"] + "") ? Convert.ToInt32(item["TM_tagID"] + "") : 0;
model.TextMember = item["lookupResult"] + "";
model.ValueMember = item["lookupKeyField"] + "";
model.ResultFields = item.Table.Columns.Contains("resultfields") ? item["resultfields"] + "" : string.Empty;
if (!dataCaches.GetValue(item, "LookupSql", out string lookupSql))
{
@@ -4212,7 +4364,7 @@ namespace Lskj.Control.Model
model.ModuleFrameDisplayText = item.Table.Columns.Contains("ModuleFrameDisplayText") ? "1".Equals(item["ModuleFrameDisplayText"] + "") : false;
model.InputBoxFontSize = item.Table.Columns.Contains("InputBoxFontSize") && !string.IsNullOrEmpty(item["InputBoxFontSize"] + "") ? Convert.ToInt32(item["InputBoxFontSize"] + "") : 0;
model.RememberValue = item.Table.Columns.Contains("RememberValue") ? "1".Equals(item["RememberValue"] + "") : false;
model.SumlistField = item.Table.Columns.Contains("SumlistField") ? item["SumlistField"] + "" : "";
//为了和工具里和bs里统一
if (model.FieldType == 42)
@@ -4239,27 +4391,7 @@ namespace Lskj.Control.Model
model.FieldType = 161;
model.IsRadio = true;
}
//快速搜索框在控件中转成普通搜索框
if (model.FieldType == 181 || model.FieldType == 182 || model.FieldType == 183 || model.FieldType == 184)
{
switch (model.FieldType)
{
case ControlType.DictionarySearchBoxToId:
model.FieldType = 5;
break;
case ControlType.DictionarySearchBoxToText:
model.FieldType = 6;
break;
case ControlType.DictionarySearchBoxToIdParam:
model.FieldType = 15;
break;
case ControlType.DictionarySearchBoxToTextParam:
model.FieldType = 16;
break;
}
}
return model;
}
@@ -4615,6 +4747,11 @@ namespace Lskj.Control.Model
multiAutoEdit.ValueField = model.ValueMember;
multiAutoEdit.TextField = model.TextMember;
multiAutoEdit.ControlObj = this;
if (Model != null)
{
multiAutoEdit.CurrentOperColumnKey = Model.ModuleCode + "_" + model.FieldName;
}
//multiAutoEdit.SetDataSource(dataSource);
multiAutoEdit.TextBoxProhibition = model.TextBoxProhibition;
multiAutoEdit.TextEdit.KeyDown += new KeyEventHandler(OnTextEditKeyDown);
@@ -4829,6 +4966,19 @@ 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;
mExtendedReturnSearchControls.Add(extendedReturnSearch);
extendedReturnSearch.TextEdit.KeyDown += new KeyEventHandler(OnTextEditKeyDown);
extendedReturnSearch.TextEdit.TextChanged += new EventHandler(OnTextEditTextChanged);
if (!isLoadBorder)
{
extendedReturnSearch.TextEdit.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
}
baseControl = extendedReturnSearch;
break;
case ControlType.DynamicallyGeneratedSql:
LabelMultiAutoTextEdit3 moduleSqlGenerated = new LabelMultiAutoTextEdit3();
// moduleSqlGenerated.SetDataSource();
@@ -5883,6 +6033,49 @@ namespace Lskj.Control.Model
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void OnTextEditTextChanged(object sender, EventArgs e)
{
if (mExtendedReturnBatchDepth > 0)
{
QueueExtendedReturnPendingChange(sender, e);
return;
}
ProcessTextEditTextChanged(sender, e);
}
private void QueueExtendedReturnPendingChange(object sender, EventArgs e)
{
System.Windows.Forms.Control changedControl = sender as System.Windows.Forms.Control;
BaseUserControl baseControl = changedControl == null
? null
: changedControl.ToBaseUserControl();
foreach (KeyValuePair<object, EventArgs> pendingChange in mExtendedReturnPendingChanges)
{
System.Windows.Forms.Control pendingControl =
pendingChange.Key as System.Windows.Forms.Control;
BaseUserControl pendingBaseControl = pendingControl == null
? null
: pendingControl.ToBaseUserControl();
if (baseControl != null && object.ReferenceEquals(baseControl, pendingBaseControl))
{
return;
}
}
mExtendedReturnPendingChanges.Add(
new KeyValuePair<object, EventArgs>(sender, e ?? EventArgs.Empty));
}
private void FlushExtendedReturnPendingChanges()
{
KeyValuePair<object, EventArgs>[] pendingChanges =
mExtendedReturnPendingChanges.ToArray();
mExtendedReturnPendingChanges.Clear();
foreach (KeyValuePair<object, EventArgs> pendingChange in pendingChanges)
{
ProcessTextEditTextChanged(pendingChange.Key, pendingChange.Value);
}
}
private void ProcessTextEditTextChanged(object sender, EventArgs e)
{
BaseUserControl baseControl = (sender as System.Windows.Forms.Control).ToBaseUserControl();
this.SetUnionAncCalcControl(baseControl);
+101 -10
View File
@@ -31,7 +31,6 @@ using FastReport;
using DevExpress.XtraGrid.Views.BandedGrid;
using System.Diagnostics;
using Lskj.Core;
using System.Text.RegularExpressions;
using Lskj.Business;
using DevExpress.XtraTreeList.Nodes;
using DevExpress.XtraTreeList;
@@ -680,8 +679,35 @@ namespace Lskj.Control
// this.ModuleGridObj.InitlizeSpiltLocation();
//}
this.ModuleGridObj.SearchObj.SearchGrid(sqlValue);
if (!this.IsDragDetail)
this.ModuleGridDetailObj.SetDetailGridDataSource();
if (!this.IsDragDetail)
{
bool enter = false;
try
{
if (this.ModuleGridObj != null)
{
DataRow rowItem = this.ModuleGridObj.GridControlObj.GetViewFocusedDataRow();
if (this.ModuleGridObj.GridControlObj.CustomGroupSelectedRow != null)
{
rowItem = this.ModuleGridObj.GridControlObj.CustomGroupSelectedRow;
}
if (rowItem != null&& !this.SysModel.DoubleClickDetail) enter = true;
}
}
catch (Exception ex)
{
}
//enter判断 2026-7-24 添加 因为主表有行改版后事件,主表赋值后会刷新一次,这里是重复刷新(方法里有判断,主表有值执行的逻辑是相同的)
//如果是主表有数据,并且绑定了行改变事件,就执行了(重复执行)
//如果主表没有数据,就执行(清空明细) 或者绑定的是双击加载明细事件也执行(节点改变后刷新主表,顺便刷新明细)
if (!enter)
{
this.ModuleGridDetailObj.SetDetailGridDataSource();
}
}
if (this.treeGridLeft.Visible && ModuleGridDetailObj.GridDetailList != null && ModuleGridDetailObj.GridDetailList.Count > 0)
{
this.ModuleGridDetailObj.scc_container.PanelVisibility = this.ModuleGridObj.GridControlObj.DataRowCount() == 0 ? SplitPanelVisibility.Panel1 : SplitPanelVisibility.Both;
@@ -1851,16 +1877,81 @@ namespace Lskj.Control
}
/// <summary>
/// 判断是否selete开头(可以处理sql前方有注释和空格的情况
/// 判断有效SQL是否select开头(忽略前方空格、BOM和注释
/// </summary>
/// <param name="sqlText"></param>
/// <returns></returns>
public static bool IsSelectAtStart(string sqlText)
{
// Remove comments and whitespace at the start of the text
string cleanedText = Regex.Replace(sqlText, @"^(\s*--.*?(\r\n|\n)|\s*)*", "");
// Check if the remaining text starts with 'select'
return cleanedText.StartsWith("select", StringComparison.OrdinalIgnoreCase);
if (string.IsNullOrEmpty(sqlText))
{
return false;
}
int index = 0;
while (index < sqlText.Length)
{
while (index < sqlText.Length &&
(char.IsWhiteSpace(sqlText[index]) || sqlText[index] == '\uFEFF'))
{
index++;
}
// 跳过SQL开头连续出现的单行注释。
if (index + 1 < sqlText.Length && sqlText[index] == '-' && sqlText[index + 1] == '-')
{
index += 2;
while (index < sqlText.Length && sqlText[index] != '\r' && sqlText[index] != '\n')
{
index++;
}
continue;
}
// 跳过块注释,同时兼容SQL Server支持的嵌套块注释。
if (index + 1 < sqlText.Length && sqlText[index] == '/' && sqlText[index + 1] == '*')
{
index += 2;
int commentDepth = 1;
while (index < sqlText.Length && commentDepth > 0)
{
if (index + 1 < sqlText.Length && sqlText[index] == '/' && sqlText[index + 1] == '*')
{
commentDepth++;
index += 2;
}
else if (index + 1 < sqlText.Length && sqlText[index] == '*' && sqlText[index + 1] == '/')
{
commentDepth--;
index += 2;
}
else
{
index++;
}
}
if (commentDepth > 0)
{
return false;
}
continue;
}
break;
}
const string selectKeyword = "select";
if (index + selectKeyword.Length > sqlText.Length ||
string.Compare(sqlText, index, selectKeyword, 0, selectKeyword.Length,
StringComparison.OrdinalIgnoreCase) != 0)
{
return false;
}
int nextIndex = index + selectKeyword.Length;
return nextIndex == sqlText.Length ||
(!char.IsLetterOrDigit(sqlText[nextIndex]) && sqlText[nextIndex] != '_');
}
@@ -1990,7 +2081,7 @@ namespace Lskj.Control
{
if (this.gridLeft.Visible) this.OnGridViewRowClick(null, null);
if (this.treeGridLeft.Visible) this.TreeListObj_Click(null, null);
if (this.treeLeft.Visible)
if (this.treeLeft.Visible&& this.treeLeft.TreeView.SelectedNode!=null)
{
TreeViewEventArgs treeViewEventArgs = new TreeViewEventArgs(this.treeLeft.TreeView.SelectedNode);
this.OnTreeLeftTreeNodeSelected(null, treeViewEventArgs);
@@ -2000,4 +2091,4 @@ namespace Lskj.Control
}
}
}
}
@@ -707,6 +707,13 @@ namespace Lskj.Control
}
}
if (model!=null&& !string.IsNullOrWhiteSpace(model.VisibleCond))
{
tabPage.PageVisible = !ValidateCond(model.VisibleCond, rowItem);
if (!tabPage.PageVisible) return;
}
if (IsDynamicDetailType)
{
@@ -1464,7 +1471,46 @@ namespace Lskj.Control
}
/// <summary>
/// <para>说明:检查可用条件</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-11-09 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="cond">The cond.</param>
/// <param name="dataRow">The data row.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
private bool ValidateCond(string cond, DataRow dataRow)
{
bool result = false;
string condition = cond;
try
{
if (string.IsNullOrWhiteSpace(cond)) return true;//如果值是空格或者空行,默认正确
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
if (cond.StartsWith("@") || cond.StartsWith("!"))
{
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
}
else if (dataRow == null)
{
result = ReplaceHelper.EvalCond(cond);
}
else
{
result = ReplaceHelper.ReplaceRowParamCond(dataRow, cond);
}
return result;
}
catch (Exception ex)
{
}
return result;
}
+18 -11
View File
@@ -538,6 +538,14 @@ namespace Lskj.Control
if (fixedQuery)
{
//固定条件不显示,隐藏上方。(只显示表格)
if (SystemInfo.Instance.HideFixedConditions)
{
this.pl_top.Visible = false;
return;
}
this.pl_top_fix_search.Visible = true;
// 加载固定查询条件
@@ -560,11 +568,7 @@ namespace Lskj.Control
this.SearchObj.InitDefaultSearchControl(table, this.pl_top_fix_search, false);
else
this.SearchObj.InitDefaultSearchControl(table, this.pl_top_fix_search);
//固定条件不显示,隐藏上方。(只显示表格)
if (SystemInfo.Instance.HideFixedConditions)
{
this.pl_top.Visible = false;
}
}
else
{
@@ -1603,6 +1607,8 @@ namespace Lskj.Control
this.bbi_export.Enabled = this.SysModel.ExportEnable;
this.pl_top_fix_search.Enabled = this.pl_top_search.Enabled = this.SysModel.SearchEnable;
this.pl_buttom.Visible = this.VisibleOperPanel && (this.SysModel.AddEnable || this.SysModel.DeleteEnable || (this.SysModel.ModifyEnable && this.SysModel.CanEdit));
this.btnUpdate.Enabled = this.SysModel.ModifyEnable && this.SysModel.CanEdit;
this.gcMain.GridView.FocusedRowObjectChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventHandler(OnGridViewFocusedRowObjectChanged);
if (this.LeftGridEx != null) this.LeftGridEx.GridView.FocusedRowObjectChanged += new DevExpress.XtraGrid.Views.Base.FocusedRowObjectChangedEventHandler(OnGridViewFocusedRowObjectChanged);
@@ -1611,7 +1617,7 @@ namespace Lskj.Control
}
else
{
this.btnAdd.Enabled = this.btnDel.Enabled = this.btnSave.Enabled = this.bbi_import.Enabled = false;
this.btnUpdate.Enabled=this.btnAdd.Enabled = this.btnDel.Enabled = this.btnSave.Enabled = this.bbi_import.Enabled = false;
this.gcMain.GridView.OptionsBehavior.Editable = false;
this.pl_buttom.Visible = false;
}
@@ -1678,7 +1684,8 @@ namespace Lskj.Control
}
else
{
cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
//cond = ReplaceHelper.ReplaceRowParam(dataRow, cond);
cond = ReplaceHelper.ReplaceRowParamEmptyWrapQuote(dataRow, cond);
if (cond.StartsWith("@") || cond.StartsWith("!"))
{
result = "1".Equals(BaseImpl.GetDefaultValue(cond));
@@ -3978,10 +3985,10 @@ namespace Lskj.Control
{
return new ModuleModel(MainImpl.GetSystemdllTab(dynamicModel.ModuleCode));
}));
Task<DataTable> searchBaseGridRightMenusTask = cachesDic.AddTask(pl_top_search, "BaseGridRightMenus", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
}));
//Task<DataTable> searchBaseGridRightMenusTask = cachesDic.AddTask(pl_top_search, "BaseGridRightMenus", new Task<DataTable>(() =>
//{
// return BaseModuleImpl.GetBaseGridRightMenus(dynamicModel.ModuleCode, ModuleType.MrpClickBtn);
//}));
Task<DataTable> fixedQueryFieldsTask = cachesDic.AddTask(this, "FixedQueryFields", new Task<DataTable>(() =>
{
return BaseModuleImpl.GetFixedQueryFields(dynamicModel.ModuleCode);//加载固定查询条件
+5 -1
View File
@@ -1814,7 +1814,11 @@ namespace Lskj.Control
{
// 提交数据
this.PrimaryValue = this.SysModel.NewVer == 0 ? this.ControlObj.GetControlValue(this.PrimaryKey) : this.PrimaryValue;
if (string.IsNullOrEmpty(PrimaryValue) || SavaState) this.AddControlRecord(true, false);
if (string.IsNullOrEmpty(PrimaryValue) || SavaState)
{
isApply=this.AddControlRecord(true, false);
if (!isApply) return;//保存失败不执行提交
}
DialogResult result = MessageUtil.Show(ResourceKeys.BillApply, MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
@@ -186,6 +186,8 @@ namespace Lskj.Control.MultiGridLookUp
this.Location = new Point((SystemInformation.PrimaryMonitorSize.Width - this.Width) / 2,
(SystemInformation.PrimaryMonitorSize.Height - this.Height) / 2);
}
// 自动列宽和弹窗尺寸计算完成后,最后应用个性化列配置,避免配置被覆盖。
this.SetCustomColumns();
}
/// <summary>
/// <para>说明:计算控件Size,只计算一次</para>
@@ -374,7 +376,6 @@ namespace Lskj.Control.MultiGridLookUp
}
}
}
SetCustomColumns();
this.gcDetail.GridControl.DataSource = this.gridControl1.DataSourceTable().Clone();
this.gcMain.BestFitColumns();
//this.gcDetail.SelectAll();
@@ -397,28 +398,53 @@ namespace Lskj.Control.MultiGridLookUp
DataTable customTable = this.gcMain.GetCustomColumnByDatabase(this.CurrentOperColumnKey);
if (customTable != null && customTable.Rows.Count > 0)
{
foreach (DataRow rowItem in customTable.Rows)
this.gcMain.BeginUpdate();
this.gcDetail.BeginUpdate();
try
{
string fieldName = rowItem["fieldName"] + "";
int fieldWidth = Convert.ToInt32(rowItem["fieldWidth"]);
int index = Convert.ToInt32(rowItem["orderid"]);
bool visible = "1".Equals(rowItem["isVisible"] + "") && fieldWidth > 0;
bool isFix = "True".Equals(rowItem["IfFixColumn"] + "", StringComparison.OrdinalIgnoreCase);
GridColumn gridColumn = this.gcMain.Columns.ColumnByName(fieldName);
if (gridColumn != null && gridColumn.Visible && gridColumn.Width > 0)
foreach (DataRow rowItem in customTable.Rows)
{
GridColumn colObj = this.gcMain.Columns[fieldName];
colObj.VisibleIndex = index;
colObj.Width = fieldWidth;
colObj.Visible = visible;
colObj.Fixed = isFix ? FixedStyle.Left : FixedStyle.None;
colObj.OptionsFilter.FilterPopupMode = FilterPopupMode.CheckedList;
string fieldName = rowItem["fieldName"] + "";
int fieldWidth = Convert.ToInt32(rowItem["fieldWidth"]);
int index = Convert.ToInt32(rowItem["orderid"]);
bool visible = "1".Equals(rowItem["isVisible"] + "") && fieldWidth > 0;
bool isFix = "True".Equals(rowItem["IfFixColumn"] + "", StringComparison.OrdinalIgnoreCase);
SetCustomColumn(this.gcMain.Columns.ColumnByName(fieldName), fieldWidth, index, visible, isFix);
SetCustomColumn(this.gcDetail.Columns.ColumnByName(fieldName), fieldWidth, index, visible, isFix);
}
}
finally
{
this.gcDetail.EndUpdate();
this.gcMain.EndUpdate();
}
}
}
/// <summary>
/// 应用单列的个性化布局。
/// </summary>
private static void SetCustomColumn(GridColumn column, int width, int visibleIndex, bool visible, bool isFix)
{
if (column == null)
{
return;
}
column.Visible = visible;
if (visible)
{
column.VisibleIndex = visibleIndex;
}
if (width > 0)
{
column.Width = width;
}
column.Fixed = isFix ? FixedStyle.Left : FixedStyle.None;
column.OptionsFilter.FilterPopupMode = FilterPopupMode.CheckedList;
}
/// <summary>
/// <para>说明:设置默认选中</para>
/// <para>创建人:龚宇超</para>
@@ -247,11 +247,10 @@ namespace Lskj.Control.MultiModelLookUp
{
try
{
string width = IniHelper.Read(string.Format("base_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
string width = IniHelper.Read(string.Format("FrmModelLookUp_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
if (!string.IsNullOrEmpty(width))
{
this.splitMain.SplitterPosition = Convert.ToInt32(width);
}
}
catch (Exception ex)
@@ -777,6 +776,7 @@ namespace Lskj.Control.MultiModelLookUp
private void PositionChange(object sender, EventArgs e)
{
PositionSplitter = this.splitMain_Right.SplitterPosition;
IniHelper.Write(string.Format("FrmModelLookUp_height_{0}", this.UnionModuleCodel), PositionSplitter + "");
}
#endregion
#region
@@ -1028,6 +1028,21 @@ namespace Lskj.Control.MultiModelLookUp
this.SysModel = new ModuleModel(modelRow);// 系统模块实体对象
if (this.SysModel != null)
{
if (this.SysModel.ModuleFrameHeight > 0 && this.SysModel.ModuleFrameWidth > 0)
{
this.Height = this.SysModel.ModuleFrameHeight;
this.Width = this.SysModel.ModuleFrameWidth;
}
string height = IniHelper.Read(string.Format("FrmModelLookUp_height_{0}", this.UnionModuleCodel));//通过Key获取Value值
if (!string.IsNullOrEmpty(height))
{
this.splitMain_Right.SplitterPosition = Convert.ToInt32(height);
}
else if (this.SysModel.BottomHeight > 0)
{
this.splitMain_Right.SplitterPosition = Convert.ToInt32(this.splitMain_Right.Height - this.SysModel.BottomHeight);
}
switch (this.SysModel.MenuType)
@@ -1053,7 +1068,7 @@ namespace Lskj.Control.MultiModelLookUp
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
break;
}
this.splitMain.SplitterPositionChanged += SplitMain_SplitterPositionChanged;
}
else
{
@@ -1063,6 +1078,12 @@ namespace Lskj.Control.MultiModelLookUp
}
return false;
}
private void SplitMain_SplitterPositionChanged(object sender, EventArgs e)
{
IniHelper.Write(string.Format("FrmModelLookUp_width_{0}", this.UnionModuleCodel), this.splitMain.SplitterPosition + "");
}
#endregion
@@ -28,11 +28,11 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.splitMain = new DevExpress.XtraEditors.SplitContainerControl();
this.pl_left = new DevExpress.XtraEditors.PanelControl();
this.pl_left_main = new System.Windows.Forms.Panel();
this.pl_gridandtree_container = new DevExpress.XtraEditors.PanelControl();
this.treeLeft = new Lskj.Control.TreeViewEx();
this.gridLeft = new Lskj.Control.GridControlEx();
this.pl_left_top = new DevExpress.XtraEditors.PanelControl();
this.splitMain_Right = new DevExpress.XtraEditors.SplitContainerControl();
@@ -44,12 +44,11 @@
this.btn_selectAll = new DevExpress.XtraEditors.SimpleButton();
this.btn_cancelAll = new DevExpress.XtraEditors.SimpleButton();
this.btnOk = new DevExpress.XtraEditors.SimpleButton();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip();
this.tsmi_all = new System.Windows.Forms.ToolStripMenuItem();
this.tsmi_reserve = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.tsmi_cancel = new System.Windows.Forms.ToolStripMenuItem();
this.treeLeft = new Lskj.Control.TreeViewEx();
((System.ComponentModel.ISupportInitialize)(this.splitMain)).BeginInit();
this.splitMain.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_left)).BeginInit();
@@ -118,6 +117,16 @@
this.pl_gridandtree_container.Size = new System.Drawing.Size(260, 454);
this.pl_gridandtree_container.TabIndex = 9;
//
// treeLeft
//
this.treeLeft.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeLeft.Location = new System.Drawing.Point(0, 0);
this.treeLeft.Margin = new System.Windows.Forms.Padding(4);
this.treeLeft.Name = "treeLeft";
this.treeLeft.Size = new System.Drawing.Size(260, 454);
this.treeLeft.TabIndex = 7;
this.treeLeft.Visible = false;
//
// gridLeft
//
this.gridLeft.AdapterObj = null;
@@ -218,7 +227,7 @@
this.btnCancel.Location = new System.Drawing.Point(772, 5);
this.btnCancel.Margin = new System.Windows.Forms.Padding(4);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(79, 35);
this.btnCancel.Size = new System.Drawing.Size(76, 35);
this.btnCancel.TabIndex = 24;
this.btnCancel.Text = "取消(&C)";
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
@@ -297,16 +306,6 @@
this.tsmi_cancel.Size = new System.Drawing.Size(100, 22);
this.tsmi_cancel.Text = "取消";
//
// treeLeft
//
this.treeLeft.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeLeft.Location = new System.Drawing.Point(0, 0);
this.treeLeft.Margin = new System.Windows.Forms.Padding(4);
this.treeLeft.Name = "treeLeft";
this.treeLeft.Size = new System.Drawing.Size(260, 454);
this.treeLeft.TabIndex = 7;
this.treeLeft.Visible = false;
//
// FrmModelLookUp2
//
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
@@ -156,6 +156,14 @@ namespace Lskj.Control.MultiModelLookUp
/// </summary>
public Dictionary<string, string> ModuleResultDic = new Dictionary<string, string>();
/// <summary>
/// 单选模式最后选中的原始数据行,供需要按动态列名返回多字段的调用方使用。
/// </summary>
public DataRow SelectedResultRow { get; private set; }
public DataRow GetSelectedResultRow()
{
return SelectedResultRow ?? this.gcMain.GridView.GetFocusedDataRow();
}
/// <summary>
/// 返回多行的集合(模块返回添加行 167 168)
/// </summary>
public List<string> EditValueList = new List<string>();
@@ -258,12 +266,12 @@ namespace Lskj.Control.MultiModelLookUp
{
try
{
string width = IniHelper.Read(string.Format("base_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
string width = IniHelper.Read(string.Format("FrmModelLookUp2_width_{0}", this.UnionModuleCodel));//通过Key获取Value值
if (!string.IsNullOrEmpty(width))
{
this.splitMain.SplitterPosition = Convert.ToInt32(width);
}
}
catch (Exception ex)
{
@@ -797,6 +805,7 @@ namespace Lskj.Control.MultiModelLookUp
private void PositionChange(object sender, EventArgs e)
{
PositionSplitter = this.splitMain_Right.SplitterPosition;
IniHelper.Write(string.Format("FrmModelLookUp2_height_{0}", this.UnionModuleCodel), PositionSplitter + "");
}
#endregion
#region
@@ -855,10 +864,12 @@ namespace Lskj.Control.MultiModelLookUp
{
EditValue = string.Empty;
EditText = string.Empty;
SelectedResultRow = null;
ModuleResultDic.Clear();
DataRow dr = this.gcMain.GridView.GetFocusedDataRow();
if (dr != null)
{
SelectedResultRow = dr;
this.EditValue = dr[ValueMember] + "";
this.EditText = dr[TextField] + "";
@@ -1121,7 +1132,21 @@ namespace Lskj.Control.MultiModelLookUp
this.SysModel = new ModuleModel(modelRow);// 系统模块实体对象
if (this.SysModel != null)
{
if (this.SysModel.ModuleFrameHeight > 0 && this.SysModel.ModuleFrameWidth > 0)
{
this.Height = this.SysModel.ModuleFrameHeight;
this.Width = this.SysModel.ModuleFrameWidth;
}
string height = IniHelper.Read(string.Format("FrmModelLookUp2_height_{0}", this.UnionModuleCodel));//通过Key获取Value值
if (!string.IsNullOrEmpty(height))
{
this.splitMain_Right.SplitterPosition = Convert.ToInt32(height);
}
else if (this.SysModel.BottomHeight > 0)
{
this.splitMain_Right.SplitterPosition = Convert.ToInt32(this.splitMain_Right.Height - this.SysModel.BottomHeight);
}
switch (this.SysModel.MenuType)
{
@@ -1146,7 +1171,7 @@ namespace Lskj.Control.MultiModelLookUp
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
break;
}
this.splitMain.SplitterPositionChanged += SplitMain_SplitterPositionChanged;
}
else
{
@@ -1156,6 +1181,11 @@ namespace Lskj.Control.MultiModelLookUp
}
return false;
}
private void SplitMain_SplitterPositionChanged(object sender, EventArgs e)
{
IniHelper.Write(string.Format("FrmModelLookUp2_width_{0}", this.UnionModuleCodel), this.splitMain.SplitterPosition + "");
}
#endregion
//设置选中框的值
File diff suppressed because it is too large Load Diff
+8 -5
View File
@@ -7,7 +7,7 @@ using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Lskj.Core
{
@@ -148,15 +148,18 @@ namespace Lskj.Core
apiHandlerModels = new List<ApiHandlerModel>();
apiHandler._dataImpl = new Data.Api.DataImpl();
apiHandler._dataImpl.dbOperator = new Lskj.Data.ADO.Template.DbTemplate(SqlHelper._connection.ConnectionString, "system.data.sqlclient");
apiHandler._dataImpl = new Lskj.Data.Api.DataImpl()//新建数据库连接
{
dbOperator = new Lskj.Data.ADO.Template.DbTemplate(SqlHelper._connection.ConnectionString, "system.data.sqlclient")
};
if (isSend)//是否发送数据
{
apiHandler.GetEventApiSendData(mep, apiHandlerModels);
apiHandler.SendEventApiData(apiHandlerModels);
apiHandler.GetEventApiSendData(mep, apiHandlerModels, apiHandler._dataImpl);
apiHandler.SendEventApiData(apiHandlerModels, apiHandler._dataImpl);
}
else
{
apiHandler.GetEventApiSendData(mep, apiHandlerModels);
apiHandler.GetEventApiSendData(mep, apiHandlerModels, apiHandler._dataImpl);
}
this.apiResutMsg = apiHandler.GetApiReturnMsg(apiHandlerModels);
}
+13
View File
@@ -381,6 +381,15 @@ namespace Lskj.Core
{
return Internet ? AESUtil.Decrypt(Connection3) : AESUtil.Decrypt(Connection4);
}
private static string EnableSqlServerIdleConnectionResilience(string connectionString)
{
SqlConnectionStringBuilder builder =
new SqlConnectionStringBuilder(connectionString);
builder["ConnectRetryCount"] = 1;
return builder.ConnectionString;
}
/// <summary>
/// <para>说明:创建数据库连接</para>
/// <para>创建人:龚宇超</para>
@@ -420,6 +429,10 @@ namespace Lskj.Core
providerName = "Dm";
SqlHelper.ConnectionType = ConnectionType.DmServer;
}
if (connectionType == ConnectionType.SqlServer)
{
connStr = EnableSqlServerIdleConnectionResilience(connStr);
}
SqlHelper.dbFactory = DbProviderFactories.GetFactory(providerName);
if (SqlHelper._connection != null)
{
+14
View File
@@ -271,6 +271,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lskj.PubCodeDesign", "..\Ls
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lskj.PubBillManagement", "..\Lskj.PubBillManagement\Lskj.PubBillManagement.csproj", "{6CE319BA-1253-41F2-8B59-8173FD7BE3F3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lskj.PubUpdatePwd", "..\Lskj.PubUpdatePwd\Lskj.PubUpdatePwd.csproj", "{91470E21-B8FB-4A16-967A-912F9E4807E1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -1741,6 +1743,18 @@ Global
{6CE319BA-1253-41F2-8B59-8173FD7BE3F3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6CE319BA-1253-41F2-8B59-8173FD7BE3F3}.Release|x86.ActiveCfg = Release|Any CPU
{6CE319BA-1253-41F2-8B59-8173FD7BE3F3}.Release|x86.Build.0 = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|x86.ActiveCfg = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Debug|x86.Build.0 = Debug|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|Any CPU.Build.0 = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|x86.ActiveCfg = Release|Any CPU
{91470E21-B8FB-4A16-967A-912F9E4807E1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -4836,6 +4836,14 @@ namespace Lskj.Main.Control
tabPage.Controls.Add(this.FirstMain);
this.webBrowser.Show();
this.webBrowser.BringToFront();
// 等待页签和FirstMain完成布局后,再同步CEF原生子窗口的位置和尺寸。
this.webBrowser.BeginInvoke(new MethodInvoker(delegate
{
if (!this.webBrowser.IsDisposed && !this.webBrowser.Disposing)
{
this.webBrowser.SyncBrowserBounds();
}
}));
//if (this.webBrowser.cefBrowserSettings != null) this.webBrowser.cefBrowserSettings.Reload();
int MemuEventType = 1;
//左侧二级目录菜单设置为单击切换模式
+5 -2
View File
@@ -681,6 +681,9 @@ namespace Lskj.Main
ERPInfo.Instance.LoginAccount = LoginAccount;
ERPInfo.Instance.InPassWord = password;
ERPInfo.Instance.PrimitiveBrowser = SystemInfo.Instance.PrimitiveBrowser;
if (BaseImpl.HasExistsColumn("p_formmenuconfigtab", "SingleOpenMode")) ERPInfo.Instance.SingleOpenMode = true;
DBConfig.Instance.LoginName = isLoginByAd ? lueUserName.Text.Trim() : lueUserName.Text;
DBConfig.Instance.NoticeUserID = userId;
DBConfig.Instance.NoticeUserName = userName;
@@ -1284,7 +1287,7 @@ namespace Lskj.Main
DialogResult result = MessageUtil.Show(ResourceKeys.IsExit, MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
Process[] p = Process.GetProcessesByName("Ls_ERP");
Process[] p = Manager.GetApplicationProcesses();
foreach (Process item in p)
{
try
@@ -1920,4 +1923,4 @@ namespace Lskj.Main
isPlaintextPwd = !isPlaintextPwd;
}
}
}
}
+2 -2
View File
@@ -546,7 +546,7 @@ namespace Lskj.Main
//记录登出日志
LogUtil.WriteDebug("", "退出软件", "软件退出", "系统登录");
Process[] p = Process.GetProcessesByName("Ls_ERP");
Process[] p = Manager.GetApplicationProcesses();
foreach (Process item in p)
{
try
@@ -716,4 +716,4 @@ namespace Lskj.Main
}
#endregion
}
}
}
+12 -3
View File
@@ -428,10 +428,19 @@ namespace Lskj.Main
ERPInfo.Instance.UserId = userId;
ERPInfo.Instance.UserName = userName;
this.Close();
IniHelper.Write("isRefresh", "1");
Manager.ReStartMain(true);
//this.DialogResult = System.Windows.Forms.DialogResult.OK;
if (Manager.ExternalMainShell == null)
{
this.Close();
Manager.ReStartMain(true);
}
else
{
// WPF 已接管主窗口生命周期:只返回切换成功,
// 由 WPF 在当前模态窗体关闭后重建主框架。
this.DialogResult = System.Windows.Forms.DialogResult.OK;
this.Close();
}
break;
case 1: // 密码不正确
MessageUtil.Show(ResourceKeys.NameOrPasswordError);
@@ -0,0 +1,25 @@
using System.Windows.Forms;
namespace Lskj.Main.Hosting
{
/// <summary>
/// 旧启动流程与可选新主界面之间的中立扩展点。
/// 此接口只使用 .NET Framework 4.0/WinForms 基础类型,不引用 WPF 或 DevExpress 25.2。
/// </summary>
public interface IExternalMainShell
{
bool IsOpen { get; }
DialogResult ShowLoginDialog(object loginRuntime);
DialogResult ShowDialog();
void RequestRelogin();
void RequestLock();
void RequestSubscriptRefresh();
void RequestExit(string message);
}
}
@@ -0,0 +1,735 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using DevExpress.LookAndFeel;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Data;
using Lskj.Main.Model;
using Lskj.Model;
using Lskj.Util;
namespace Lskj.Main.Hosting
{
public sealed class LegacyProcessStartResult
{
internal LegacyProcessStartResult(
bool shouldRunApplication,
int exitCode)
{
ShouldRunApplication = shouldRunApplication;
ExitCode = exitCode;
}
public bool ShouldRunApplication { get; private set; }
public int ExitCode { get; private set; }
}
/// <summary>
/// 为独立的新启动程序公开原 Ls_ERP 初始化和登录流程。
/// </summary>
public static class LegacyApplicationHost
{
private static readonly object ProcessSync = new object();
private static bool _mainProcessInitializationStarted;
private static bool _mainProcessInitialized;
private static bool _mainProcessShutdown;
public static LegacyProcessStartResult PrepareProcess(string[] args)
{
int code = Program.PrepareProcess(args ?? new string[0]);
return new LegacyProcessStartResult(code == -1, code);
}
public static void InitializeMainProcess(IExternalMainShell externalMainShell)
{
lock (ProcessSync)
{
if (_mainProcessInitialized)
throw new InvalidOperationException(
"旧主进程运行时已经初始化。");
if (_mainProcessShutdown)
throw new InvalidOperationException(
"旧主进程运行时已经关闭。");
_mainProcessInitializationStarted = true;
Manager.ExternalMainShell = externalMainShell;
try
{
Program.InitializeMainProcess();
_mainProcessInitialized = true;
}
catch
{
try
{
Program.ShutdownMainProcess();
}
finally
{
_mainProcessShutdown = true;
Manager.ExternalMainShell = null;
}
throw;
}
}
}
public static void ShutdownMainProcess()
{
lock (ProcessSync)
{
if (!_mainProcessInitializationStarted ||
_mainProcessShutdown)
{
return;
}
try
{
Manager.EndExternalSessionServices();
Manager.ExitSystem();
}
finally
{
try
{
Program.ShutdownMainProcess();
}
finally
{
_mainProcessInitialized = false;
_mainProcessShutdown = true;
Manager.ExternalMainShell = null;
}
}
}
}
public static object CreateLoginRuntime()
{
return new LegacyLoginRuntime();
}
public static string PrepareAuthenticatedSession()
{
if (!ERPInfo.Instance.LoginResult)
return ResourceKeys.LoginFault;
DataTable enabled = MainImpl.EnableSubSystem();
ERPInfo.Instance.SubMenuCount = enabled == null
? 0
: enabled.Rows.Count;
if (!Manager.TrySelectExternalMainShellSubSystem())
return ResourceKeys.SubSystemUnEnabled;
LegacyLoginRuntime.RefreshDelphiParameters();
Manager.BeginExternalSessionServices();
return string.Empty;
}
public static void CompleteAuthenticatedSession()
{
Manager.EndExternalSessionServices();
}
public static void ActivateSubSystem(string id, string caption)
{
ERPInfo.Instance.SubSysId = id ?? string.Empty;
ERPInfo.Instance.SubSysName = caption ?? string.Empty;
LegacyLoginRuntime.RefreshDelphiParameters();
}
}
/// <summary>
/// 向外部 WPF 登录页提供旧账套、用户、认证和会话状态写入能力。
/// 该类型不创建 WinForms 控件,也不引用 WPF。
/// </summary>
public sealed partial class LegacyLoginRuntime
{
private DataTable _ledgerTable;
private bool _connectionInitialized;
public LegacyLoginRuntime()
{
ERPInfo.Instance.LoginResult = false;
}
public string SelectedLedgerName { get; private set; }
public string LoginName
{
get { return DBConfig.Instance.LoginName ?? string.Empty; }
}
public bool RememberPasswordEnabled
{
get { return !SystemInfo.Instance.DisableRememberPassword; }
}
public bool AutoUpdate
{
get
{
return SystemInfo.Instance.AutomaticUpdates ||
DBConfig.Instance.UpdateSet;
}
}
public bool AutoUpdateEnabled
{
get { return !SystemInfo.Instance.AutomaticUpdates; }
}
public bool SmartClient
{
get { return DBConfig.Instance.SmallClient; }
}
public bool SmartClientEnabled
{
get { return !SystemInfo.Instance.HiddenIntelligentClient; }
}
public bool SmartClientVisible
{
get { return !SystemInfo.Instance.HiddenIntelligentClient; }
}
public bool Notice
{
get
{
return SystemInfo.Instance.AutoCheckedNotice ||
SystemInfo.Instance.StartMessageBox ||
DBConfig.Instance.NoticeClient;
}
}
public bool NoticeEnabled
{
get { return !SystemInfo.Instance.StartMessageBox; }
}
public DataTable LoadLedgers()
{
EnsureInitialConnection();
_ledgerTable = MainImpl.GetLedgerList() ?? new DataTable("Ledgers");
SelectedLedgerName = ResolveSelectedLedgerName(_ledgerTable);
return _ledgerTable;
}
private void EnsureInitialConnection()
{
if (_connectionInitialized)
return;
if (string.Equals(
IniHelper.Read(SystemResourcesIniName, ConnectionModeKey),
"1",
StringComparison.Ordinal))
{
int port;
string host = IniHelper.Read(
SystemResourcesIniName,
DirectLastHostKey);
string name = IniHelper.Read(
SystemResourcesIniName,
DirectLastNameKey);
if (!int.TryParse(
IniHelper.Read(
SystemResourcesIniName,
DirectLastPortKey),
out port))
{
throw new InvalidOperationException(
"保存的直连端口无效,请重新设置连接。");
}
string error = ApplyDirectConnection(host, port, name);
if (!string.IsNullOrWhiteSpace(error))
throw new InvalidOperationException(error);
}
else
{
if (!DBConfig.Instance.CreateConnection(
DBConfig.Instance.Connection))
{
throw new InvalidOperationException(
ResourceKeys.UnConnectServer);
}
if (!string.Equals(
DBConfig.Instance.ServerType,
"达梦数据库",
StringComparison.Ordinal) &&
DelphiHelper.Delphi_Init(new StringBuilder(
DBConfig.Instance.GetDelphiConnection(
DBConfig.Instance.dephiConnection))) == 0)
{
throw new InvalidOperationException(
ResourceKeys.UnConnectServer + "[By Delphi]");
}
SystemInfo.RefreshSystemParam();
}
BaseResources.Localization(LocalizationType.CHS);
_connectionInitialized = true;
}
public DataTable LoadUsers()
{
DataTable users = SystemInfo.Instance.DisplayUserCode
? MainImpl.GetEmployeeListNew()
: MainImpl.GetEmployeeList();
return NormalizeUsersForLogin(
users ?? new DataTable("Users"),
SystemInfo.Instance.LoginUsername,
SystemInfo.Instance.DisplayUserCode);
}
public DataTable SelectLedger(string ledgerName)
{
if (string.IsNullOrWhiteSpace(ledgerName))
throw new InvalidOperationException("请选择账套。");
if (_ledgerTable == null)
LoadLedgers();
DataRow ledger = _ledgerTable.Rows.Cast<DataRow>().FirstOrDefault(
row => string.Equals(
Value(row, "ShowName"),
ledgerName,
StringComparison.OrdinalIgnoreCase));
if (ledger == null)
throw new InvalidOperationException("未找到所选账套,请重新选择。");
string serverName = Value(ledger, "IP");
string database = Value(ledger, "DBName");
string dataBook = Value(ledger, "ShowName");
if (string.IsNullOrWhiteSpace(serverName) ||
string.IsNullOrWhiteSpace(database))
{
throw new InvalidOperationException(ResourceKeys.UnSetServerAddress);
}
string oldServerName = DBConfig.Instance.ServerName;
string oldDatabase = DBConfig.Instance.DataBase;
string oldDataBook = DBConfig.Instance.DataBook;
string oldSelectedLedgerName = SelectedLedgerName;
string oldAccountBook = ERPInfo.Instance.AccountBook;
bool oldConnectionInitialized = _connectionInitialized;
try
{
DBConfig.Instance.ServerName = serverName;
DBConfig.Instance.DataBase = database;
DBConfig.Instance.DataBook = dataBook;
if (!DBConfig.Instance.CreateConnection(DBConfig.Instance.Connection))
throw new InvalidOperationException(ResourceKeys.ServerAddressFault);
if (!DBConfig.Instance.ServerType.Equals("达梦数据库") &&
DelphiHelper.Delphi_Init(new StringBuilder(
DBConfig.Instance.GetDelphiConnection(
DBConfig.Instance.dephiConnection))) == 0)
{
throw new InvalidOperationException(
ResourceKeys.UnConnectServer + "[By Delphi]");
}
SystemInfo.RefreshSystemParam();
BaseResources.Localization(LocalizationType.CHS);
DataTable users = LoadUsers();
SelectedLedgerName = dataBook;
ERPInfo.Instance.AccountBook = dataBook;
_connectionInitialized = true;
return users;
}
catch (Exception switchException)
{
DBConfig.Instance.ServerName = oldServerName;
DBConfig.Instance.DataBase = oldDatabase;
DBConfig.Instance.DataBook = oldDataBook;
SelectedLedgerName = oldSelectedLedgerName;
ERPInfo.Instance.AccountBook = oldAccountBook;
_connectionInitialized = oldConnectionInitialized;
try
{
DBConfig.Instance.CreateConnection(DBConfig.Instance.Connection);
if (!DBConfig.Instance.ServerType.Equals("达梦数据库"))
{
DelphiHelper.Delphi_Init(new StringBuilder(
DBConfig.Instance.GetDelphiConnection(
DBConfig.Instance.dephiConnection)));
}
SystemInfo.RefreshSystemParam();
}
catch (Exception restoreException)
{
LogHelper.Instance.WriteError(restoreException);
}
LogHelper.Instance.WriteError(switchException);
throw;
}
}
public string LoadRememberedPassword(string loginName)
{
if (!RememberPasswordEnabled || string.IsNullOrWhiteSpace(loginName))
return null;
try
{
string encrypted = IniHelper.Read(
DBConfig.Instance.ServerName + loginName);
if (string.IsNullOrWhiteSpace(encrypted))
return null;
string[] parts = AESUtil.Decrypt(encrypted).Split('^');
bool remember;
if (parts.Length < 2 ||
!bool.TryParse(parts[0], out remember) ||
!remember)
{
return null;
}
return string.Join("^", parts.Skip(1).ToArray());
}
catch
{
return null;
}
}
public string Login(
string loginName,
string password,
bool rememberPassword,
bool forceLogin,
bool autoUpdate,
bool smartClient,
bool notice)
{
ERPInfo.Instance.LoginResult = false;
if (string.IsNullOrWhiteSpace(loginName))
return ResourceKeys.UserNameNotNull;
password = NormalizePassword(password);
try
{
DataTable users = MainImpl.GetEmployeeList();
string displayColumn = ResolveDisplayColumn(users);
List<DataRow> matches = users.Rows.Cast<DataRow>()
.Where(row =>
string.Equals(
Value(row, displayColumn),
loginName,
StringComparison.OrdinalIgnoreCase) ||
string.Equals(
Value(row, "UserCode"),
loginName,
StringComparison.OrdinalIgnoreCase))
.ToList();
if (matches.Count == 0)
return ResourceKeys.NameOrPasswordError;
if (matches.Count > 1)
return ResourceKeys.DuplicatedNameError;
DataRow user = matches[0];
string userId = Value(user, "UserId");
string userName = Value(user, "UserName");
string loginAccount = Value(user, "UserCode");
if (string.IsNullOrWhiteSpace(userId))
return ResourceKeys.UserNotFound;
ERPInfo.Instance.LoginResult = false;
if (SystemInfo.Instance.MacEnabled)
{
int macResult = MainImpl.CheckMacAddress(
ERPInfo.Instance.MacAddress,
userId);
MainImpl.LoginAfterRegister(
ERPInfo.Instance.MacAddress,
userId);
if (macResult == 0)
return ResourceKeys.LoginFault + ResourceKeys.UnKownMacAddress;
if (macResult == -1)
return ResourceKeys.LoginFault + ResourceKeys.UnKownMacAddressTable;
}
string keyError = VerifyEncryptionKey();
if (!string.IsNullOrEmpty(keyError))
return keyError;
if (!MainImpl.CheckingMacAddress(userId))
return ResourceKeys.MacAddressError +
",当前地址:" + ERPInfo.Instance.MacAddress;
int loginResult = MainImpl.Login(
userId,
password,
forceLogin);
if (loginResult != 0)
return LoginError(loginResult);
CompleteLogin(
userId,
userName,
loginAccount,
loginName,
password,
rememberPassword,
autoUpdate,
smartClient,
notice);
ERPInfo.Instance.LoginResult = true;
LogUtil.WriteDebug("", "登录软件", "进入操作", "系统登录");
return string.Empty;
}
catch (Exception exception)
{
ERPInfo.Instance.LoginResult = false;
LogUtil.WriteError(ResourceKeys.UserLogin, exception);
return ResourceKeys.LoginFault;
}
}
private static string VerifyEncryptionKey()
{
if (!SystemInfo.Instance.IsEncrypt)
return string.Empty;
int[] keyHandles = ERPInfo.Instance.keyHandles = new int[8];
int[] keyNumbers = ERPInfo.Instance.keyNumber = new int[8];
SmartX1Api.SmartX1Find(DBConfig.Instance.ServerName, keyHandles, keyNumbers);
int keyHandle = keyHandles[0];
int pin1 = Convert.ToInt32("0x987F6BCD", 16);
int pin2 = Convert.ToInt32("0xE193C5B2", 16);
int pin3 = Convert.ToInt32("0xD507CC28", 16);
int pin4 = Convert.ToInt32("0x4B125AF6", 16);
return SmartX1Api.SmartX1Open(keyHandle, pin1, pin2, pin3, pin4) == 0
? string.Empty
: "U盾数据获取失败,请重试或联系管理员";
}
private void CompleteLogin(
string userId,
string userName,
string loginAccount,
string enteredLoginName,
string password,
bool rememberPassword,
bool autoUpdate,
bool smartClient,
bool notice)
{
if (!MainImpl.HasExistsColumn("p_employeetab", "MacAdress"))
BaseImpl.ExecSqlValue("alter table p_employeetab add MacAdress varchar(100)");
BaseImpl.ExecSqlValue(string.Format(
"update p_employeetab set MacAdress = '{0}' where employeeid='{1}'",
(ERPInfo.Instance.MacAddress ?? string.Empty).Replace("'", "''"),
userId.Replace("'", "''")));
if (!MainImpl.HasExistsColumn("p_employeetab", "ClientIp"))
BaseImpl.ExecSqlValue("alter table p_employeetab add ClientIp varchar(100)");
BaseImpl.ExecSqlValue(string.Format(
"update p_employeetab set ClientIp = '{0}' where employeeid='{1}'",
(ERPInfo.Instance.LoginIPV4 ?? string.Empty).Replace("'", "''"),
userId.Replace("'", "''")));
if (SystemInfo.Instance.AutoSystemDataFormat)
{
FormatSystemDatetime formatter = new FormatSystemDatetime();
formatter.SetDateTimeFormat();
}
string skinName = MainImpl.GetUserSkin(userId);
skinName = string.IsNullOrEmpty(skinName)
? ERPInfo.Instance.SkinName
: skinName;
UserLookAndFeel.Default.SetSkinStyle(skinName);
IniHelper.Write(
DBConfig.Instance.ServerName + enteredLoginName,
AESUtil.Encrypt(rememberPassword + "^" + password));
ERPInfo.Instance.SeriesId = SystemInfo.Instance.seriesid;
ERPInfo.Instance.UserLinkPhone = MainImpl.GetUserPhone(userId);
ERPInfo.Instance.UserId = userId;
ERPInfo.Instance.UserName = userName;
ERPInfo.Instance.Password = SHAHelper.EncryptPassword(password);
ERPInfo.Instance.SkinName = skinName;
string accountBook = string.IsNullOrWhiteSpace(SelectedLedgerName)
? DBConfig.Instance.DataBook
: SelectedLedgerName;
ERPInfo.Instance.AccountBook = accountBook;
ERPInfo.Instance.LoginAccount = loginAccount;
ERPInfo.Instance.InPassWord = password;
ERPInfo.Instance.PrimitiveBrowser = SystemInfo.Instance.PrimitiveBrowser;
DBConfig.Instance.LoginName = enteredLoginName;
DBConfig.Instance.NoticeUserID = userId;
DBConfig.Instance.NoticeUserName = userName;
DBConfig.Instance.UpdateSet = autoUpdate;
DBConfig.Instance.SmallClient = smartClient;
DBConfig.Instance.NoticeClient = notice;
DBConfig.Instance.DataBook = accountBook;
DBConfig.Instance.WriteConfig();
if (userName.Equals("管理员") &&
!string.IsNullOrWhiteSpace(loginAccount))
{
ERPInfo.Instance.Password = SqlHelper.ExecuteString(
"Password",
"select Password from P_EmployeeTab where LoginAccount='" +
loginAccount.Replace("'", "''") + "'");
}
ERPInfo.Instance.LanguageName = "中文";
LanguageTranslation.GetLanguageComparisonTable();
RefreshDelphiParameters();
PubUtil.ClearFilesInDirectory(PubUtil.ImageDownloadPath);
}
internal static void RefreshDelphiParameters()
{
try
{
DelphiHelper.Delphi_SetParams(
Convert.ToInt32(ERPInfo.Instance.UserId),
string.IsNullOrWhiteSpace(ERPInfo.Instance.SubSysId)
? 0
: Convert.ToInt32(ERPInfo.Instance.SubSysId),
new StringBuilder(ERPInfo.Instance.UserName),
new StringBuilder(ERPInfo.Instance.WindowName),
new StringBuilder(ERPInfo.Instance.SkinName));
}
catch (Exception exception)
{
LogHelper.Instance.WriteError(exception);
}
}
private static string LoginError(int loginResult)
{
switch (loginResult)
{
case 1:
return ResourceKeys.NameOrPasswordError;
case 2:
return ResourceKeys.AlreadyLogin;
case -2:
return ResourceKeys.MultiFailedLogin;
default:
return ResourceKeys.LoginFault;
}
}
private static string ResolveSelectedLedgerName(DataTable ledgers)
{
DataRow selected = ledgers.Rows.Cast<DataRow>().FirstOrDefault(
row => string.Equals(
Value(row, "DBName"),
DBConfig.Instance.DataBase,
StringComparison.OrdinalIgnoreCase));
if (selected == null && !string.IsNullOrWhiteSpace(DBConfig.Instance.DataBook))
{
selected = ledgers.Rows.Cast<DataRow>().FirstOrDefault(
row => string.Equals(
Value(row, "ShowName"),
DBConfig.Instance.DataBook,
StringComparison.OrdinalIgnoreCase));
}
if (selected == null)
selected = ledgers.Rows.Cast<DataRow>().FirstOrDefault();
return selected == null ? string.Empty : Value(selected, "ShowName");
}
private static DataTable NormalizeUsersForLogin(
DataTable users,
string configuredLoginColumn,
bool displayUserCode)
{
DataTable normalized = new DataTable("Users");
normalized.Columns.Add("UserId", typeof(string));
normalized.Columns.Add("LoginName", typeof(string));
normalized.Columns.Add("DisplayName", typeof(string));
if (users == null)
return normalized;
string loginColumn = ResolveLoginColumn(
users,
configuredLoginColumn);
foreach (DataRow row in users.Rows)
{
string loginName = Value(row, loginColumn).Trim();
string userCode = Value(row, "UserCode").Trim();
if (string.IsNullOrWhiteSpace(loginName))
loginName = userCode;
if (string.IsNullOrWhiteSpace(loginName))
continue;
string displayName = loginName;
if (displayUserCode &&
!string.IsNullOrWhiteSpace(userCode) &&
!string.Equals(
loginName,
userCode,
StringComparison.OrdinalIgnoreCase))
{
displayName = loginName + "" + userCode + "";
}
normalized.Rows.Add(
Value(row, "UserId"),
loginName,
displayName);
}
return normalized;
}
private static string NormalizePassword(string password)
{
return (password ?? string.Empty).Trim();
}
private static string ResolveDisplayColumn(DataTable users)
{
return ResolveLoginColumn(
users,
SystemInfo.Instance.LoginUsername);
}
private static string ResolveLoginColumn(
DataTable users,
string configuredLoginColumn)
{
if (users != null &&
!string.IsNullOrWhiteSpace(configuredLoginColumn) &&
users.Columns.Contains(configuredLoginColumn))
{
return configuredLoginColumn;
}
return users != null && users.Columns.Contains("UserName")
? "UserName"
: "UserCode";
}
private static string Value(DataRow row, string columnName)
{
return row != null && row.Table.Columns.Contains(columnName)
? row[columnName] + string.Empty
: string.Empty;
}
}
}
@@ -0,0 +1,601 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Net;
using System.Text;
using Microsoft.Win32;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Data;
using Lskj.Main.Model;
using Lskj.Model;
using Lskj.Util;
namespace Lskj.Main.Hosting
{
public sealed partial class LegacyLoginRuntime
{
private const string RegistryFilePath = @"AA_LS_Erp V2.0\File";
private const string SystemResourcesIniName = "SystemResources.ini";
private const string SystemResourcesSection = "SystemResources";
private const string DirectHistoryPrefix = "DownloadAESStr_";
private const string DirectLastHostKey = "LocalLastIP";
private const string DirectLastPortKey = "LocalLastPort";
private const string DirectLastNameKey = "LocalLastPortName";
private const string ConnectionModeKey = "FrmConfigFlag";
private const int DirectRequestTimeoutMilliseconds = 5000;
public DataSet LoadConnectionSettings()
{
var result = new DataSet("LoginConnectionSettings");
DataTable settings = CreateSettingsTable();
DataTable savedConnections = CreateSavedConnectionsTable();
string directHost = IniHelper.Read(
SystemResourcesIniName,
DirectLastHostKey);
string directPort = IniHelper.Read(
SystemResourcesIniName,
DirectLastPortKey);
string directName = IniHelper.Read(
SystemResourcesIniName,
DirectLastNameKey);
bool directMode = string.Equals(
IniHelper.Read(SystemResourcesIniName, ConnectionModeKey),
"1",
StringComparison.Ordinal);
settings.Rows.Add(
directMode ? "Direct" : "Database",
ReadRegistryValue("ServerName"),
ReadRegistryValue("datastr"),
directHost,
directPort,
directName);
Dictionary<string, string> entries = IniHelper.GetSectionKeys(
SystemResourcesIniName,
SystemResourcesSection);
foreach (KeyValuePair<string, string> entry in entries)
{
if (!entry.Key.StartsWith(
DirectHistoryPrefix,
StringComparison.OrdinalIgnoreCase))
{
continue;
}
string endpoint = entry.Key.Substring(
DirectHistoryPrefix.Length);
string host;
int port;
if (!TrySplitEndpoint(endpoint, out host, out port))
continue;
string displayName = ReadHistoryDisplayName(entry.Value);
if (string.IsNullOrWhiteSpace(displayName))
continue;
savedConnections.Rows.Add(
entry.Key,
displayName,
host,
port);
}
result.Tables.Add(settings);
result.Tables.Add(savedConnections);
return result;
}
public string ApplyDatabaseConnection(
string serverName,
string databaseName)
{
try
{
ConnectionCandidate candidate = CreateDatabaseCandidate(
serverName,
databaseName);
return ApplyConnection(
candidate,
delegate { CommitDatabaseConnection(); });
}
catch (Exception exception)
{
LogSanitized(exception);
return ToSafeConnectionError(exception);
}
}
public string ApplyDirectConnection(
string host,
int port,
string accountBookName)
{
try
{
Uri resourceUri = BuildDirectResourceUri(host, port);
string encryptedPayload = DownloadDirectPayload(resourceUri);
string decryptedPayload = AESUtil.Decrypt(encryptedPayload);
string[] parts = ParseDirectPayload(decryptedPayload);
ConnectionCandidate candidate = CreateDirectCandidate(
parts,
host,
port,
accountBookName,
encryptedPayload);
return ApplyConnection(
candidate,
delegate { CommitDirectConnection(candidate); });
}
catch (Exception exception)
{
LogSanitized(exception);
return ToSafeConnectionError(exception);
}
}
private string ApplyConnection(
ConnectionCandidate candidate,
Action commit)
{
LegacyConnectionStateSnapshot snapshot =
LegacyConnectionStateSnapshot.Capture(this);
try
{
ApplyCandidate(candidate);
ValidateDatabase(candidate);
ValidateDelphi(candidate);
SystemInfo.RefreshSystemParam();
BaseResources.Localization(LocalizationType.CHS);
commit();
_ledgerTable = null;
SelectedLedgerName = candidate.AccountBookName;
ERPInfo.Instance.AccountBook = candidate.AccountBookName;
_connectionInitialized = true;
return string.Empty;
}
catch (Exception exception)
{
snapshot.Restore(this);
LogSanitized(exception);
return ToSafeConnectionError(exception);
}
}
private static ConnectionCandidate CreateDatabaseCandidate(
string serverName,
string databaseName)
{
serverName = (serverName ?? string.Empty).Trim();
databaseName = (databaseName ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(serverName))
throw new ArgumentException("请输入数据库服务器地址。");
if (string.IsNullOrWhiteSpace(databaseName))
throw new ArgumentException("请输入数据库名称。");
return new ConnectionCandidate
{
ServerName = serverName,
DatabaseName = databaseName,
AccountBookName = DBConfig.Instance.DataBook ?? string.Empty,
ServerType = DBConfig.Instance.ServerType ?? "SqlServer",
ConnectionTemplate = string.Empty,
DelphiConnectionTemplate = string.Empty
};
}
private static ConnectionCandidate CreateDirectCandidate(
string[] parts,
string host,
int port,
string accountBookName,
string encryptedPayload)
{
accountBookName = (accountBookName ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(accountBookName))
throw new ArgumentException("请输入直连账套名称。");
string connectionTemplate =
"Server={0};Database={1};Persist Security Info=True;" +
"User ID=" + parts[2] + ";Password=" + parts[3] + ";" +
"Connection Timeout=5;MultipleActiveResultSets=true";
string delphiTemplate =
"Provider=SQLOLEDB.1;Server={0};Database={1};" +
"Persist Security Info=True;User ID=" + parts[2] +
";Password=" + parts[3] + ";Connection Timeout=5";
return new ConnectionCandidate
{
ServerName = parts[0],
DatabaseName = parts[1],
AccountBookName = accountBookName,
ServerType = DBConfig.Instance.ServerType ?? "SqlServer",
ConnectionTemplate = AESUtil.Encrypt(connectionTemplate),
DelphiConnectionTemplate = AESUtil.Encrypt(delphiTemplate),
DirectHost = (host ?? string.Empty).Trim().TrimEnd('/'),
DirectPort = port,
DirectEncryptedPayload = encryptedPayload
};
}
private static void ApplyCandidate(ConnectionCandidate candidate)
{
DBConfig.Instance.ServerName = candidate.ServerName;
DBConfig.Instance.DataBase = candidate.DatabaseName;
DBConfig.Instance.DataBook = candidate.AccountBookName;
DBConfig.Instance.ServerType = candidate.ServerType;
DBConfig.Instance.Connection = candidate.ConnectionTemplate;
DBConfig.Instance.dephiConnection =
candidate.DelphiConnectionTemplate;
}
private static void ValidateDatabase(ConnectionCandidate candidate)
{
if (!DBConfig.Instance.CreateConnection(
candidate.ConnectionTemplate))
{
throw new LegacyConnectionSettingsException(
"无法连接数据库,请检查服务器和数据库配置。");
}
}
private static void ValidateDelphi(ConnectionCandidate candidate)
{
if (string.Equals(
candidate.ServerType,
"达梦数据库",
StringComparison.Ordinal))
{
return;
}
string connection = DBConfig.Instance.GetDelphiConnection(
candidate.DelphiConnectionTemplate);
if (DelphiHelper.Delphi_Init(new StringBuilder(connection)) == 0)
{
throw new LegacyConnectionSettingsException(
"数据库已连接,但 Delphi 组件初始化失败。");
}
}
private static void CommitDatabaseConnection()
{
DBConfig.Instance.WriteConfig();
IniHelper.Write(
SystemResourcesIniName,
ConnectionModeKey,
"0");
}
private static void CommitDirectConnection(
ConnectionCandidate candidate)
{
string endpoint = candidate.DirectHost + ":" +
candidate.DirectPort;
string historyValue = candidate.AccountBookName + "^" +
candidate.DirectEncryptedPayload;
IniHelper.Write(
SystemResourcesIniName,
DirectHistoryPrefix + endpoint,
historyValue);
IniHelper.Write(
SystemResourcesIniName,
DirectLastHostKey,
candidate.DirectHost);
IniHelper.Write(
SystemResourcesIniName,
DirectLastPortKey,
candidate.DirectPort.ToString());
IniHelper.Write(
SystemResourcesIniName,
DirectLastNameKey,
candidate.AccountBookName);
IniHelper.Write(
SystemResourcesIniName,
ConnectionModeKey,
"1");
DBConfig.Instance.WriteConfig(
DirectLastHostKey,
candidate.DirectHost);
DBConfig.Instance.WriteConfig(
DirectLastPortKey,
candidate.DirectPort.ToString());
DBConfig.Instance.WriteConfig(
DirectLastNameKey,
candidate.AccountBookName);
}
private static Uri BuildDirectResourceUri(string host, int port)
{
host = (host ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(host))
throw new ArgumentException("请输入直连服务器地址。");
if (port < 1 || port > 65535)
throw new ArgumentOutOfRangeException(
"port",
"直连端口必须介于 1 和 65535 之间。");
if (!host.StartsWith("http://", StringComparison.OrdinalIgnoreCase) &&
!host.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
host = "http://" + host;
}
Uri baseUri;
if (!Uri.TryCreate(host, UriKind.Absolute, out baseUri) ||
(baseUri.Scheme != Uri.UriSchemeHttp &&
baseUri.Scheme != Uri.UriSchemeHttps))
{
throw new ArgumentException("直连服务器地址格式无效。");
}
var builder = new UriBuilder(baseUri)
{
Port = port,
Path = "/SystemResources.txt",
Query = string.Empty,
Fragment = string.Empty
};
return builder.Uri;
}
private static string DownloadDirectPayload(Uri resourceUri)
{
var request = (HttpWebRequest)WebRequest.Create(resourceUri);
request.Method = "GET";
request.Timeout = DirectRequestTimeoutMilliseconds;
request.ReadWriteTimeout = DirectRequestTimeoutMilliseconds;
using (var response = (HttpWebResponse)request.GetResponse())
using (Stream stream = response.GetResponseStream())
{
if (stream == null)
{
throw new InvalidDataException(
"直连服务器未返回连接配置。");
}
using (var reader = new StreamReader(
stream,
Encoding.UTF8,
true))
{
string payload = reader.ReadToEnd().Trim();
if (string.IsNullOrWhiteSpace(payload))
{
throw new InvalidDataException(
"直连服务器返回的连接配置为空。");
}
return payload;
}
}
}
private static string[] ParseDirectPayload(string decryptedPayload)
{
string[] parts = (decryptedPayload ?? string.Empty).Split('^');
if (parts.Length != 5)
{
throw new InvalidDataException(
"直连服务器返回的连接配置格式无效。");
}
for (int index = 0; index < parts.Length; index++)
{
parts[index] = (parts[index] ?? string.Empty).Trim();
if (string.IsNullOrWhiteSpace(parts[index]))
{
throw new InvalidDataException(
"直连服务器返回的连接配置不完整。");
}
}
return parts;
}
private static string ToSafeConnectionError(Exception exception)
{
if (exception is ArgumentException ||
exception is InvalidDataException ||
exception is LegacyConnectionSettingsException)
{
return exception.Message;
}
if (exception is WebException)
{
return "无法读取直连配置,请检查地址、端口和网络连接。";
}
return "连接设置失败,请检查配置和网络连接。";
}
private static void LogSanitized(Exception exception)
{
string exceptionType = exception == null
? "Unknown"
: exception.GetType().FullName;
LogHelper.Instance.WriteLog(
"WPF 登录连接设置失败。异常类型:" + exceptionType);
}
private static DataTable CreateSettingsTable()
{
var table = new DataTable("Settings");
table.Columns.Add("Mode", typeof(string));
table.Columns.Add("ServerName", typeof(string));
table.Columns.Add("DatabaseName", typeof(string));
table.Columns.Add("DirectHost", typeof(string));
table.Columns.Add("DirectPort", typeof(string));
table.Columns.Add("DirectAccountBookName", typeof(string));
return table;
}
private static DataTable CreateSavedConnectionsTable()
{
var table = new DataTable("SavedDirectConnections");
table.Columns.Add("Key", typeof(string));
table.Columns.Add("DisplayName", typeof(string));
table.Columns.Add("Host", typeof(string));
table.Columns.Add("Port", typeof(int));
return table;
}
private static string ReadRegistryValue(string valueName)
{
try
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(
RegistryFilePath,
false))
{
object value = key == null
? null
: key.GetValue(valueName, string.Empty);
return value == null ? string.Empty : value.ToString();
}
}
catch
{
return string.Empty;
}
}
private static bool TrySplitEndpoint(
string endpoint,
out string host,
out int port)
{
host = string.Empty;
port = 0;
if (string.IsNullOrWhiteSpace(endpoint))
return false;
int separatorIndex = endpoint.LastIndexOf(':');
if (separatorIndex <= 0 ||
separatorIndex >= endpoint.Length - 1)
{
return false;
}
host = endpoint.Substring(0, separatorIndex).Trim();
return !string.IsNullOrWhiteSpace(host) &&
int.TryParse(endpoint.Substring(separatorIndex + 1), out port) &&
port >= 1 &&
port <= 65535;
}
private static string ReadHistoryDisplayName(string value)
{
if (string.IsNullOrWhiteSpace(value))
return string.Empty;
int separatorIndex = value.IndexOf('^');
return separatorIndex < 0
? string.Empty
: value.Substring(0, separatorIndex).Trim();
}
private sealed class ConnectionCandidate
{
public string ServerName;
public string DatabaseName;
public string AccountBookName;
public string ServerType;
public string ConnectionTemplate;
public string DelphiConnectionTemplate;
public string DirectHost;
public int DirectPort;
public string DirectEncryptedPayload;
}
private sealed class LegacyConnectionStateSnapshot
{
private string _serverName;
private string _databaseName;
private string _dataBook;
private string _loginName;
private string _serverType;
private string _connectionTemplate;
private string _delphiConnectionTemplate;
private string _selectedLedgerName;
private string _accountBook;
private bool _connectionInitialized;
public static LegacyConnectionStateSnapshot Capture(
LegacyLoginRuntime runtime)
{
return new LegacyConnectionStateSnapshot
{
_serverName = DBConfig.Instance.ServerName,
_databaseName = DBConfig.Instance.DataBase,
_dataBook = DBConfig.Instance.DataBook,
_loginName = DBConfig.Instance.LoginName,
_serverType = DBConfig.Instance.ServerType,
_connectionTemplate = DBConfig.Instance.Connection,
_delphiConnectionTemplate =
DBConfig.Instance.dephiConnection,
_selectedLedgerName = runtime.SelectedLedgerName,
_accountBook = ERPInfo.Instance.AccountBook,
_connectionInitialized = runtime._connectionInitialized
};
}
public void Restore(LegacyLoginRuntime runtime)
{
DBConfig.Instance.ServerName = _serverName;
DBConfig.Instance.DataBase = _databaseName;
DBConfig.Instance.DataBook = _dataBook;
DBConfig.Instance.LoginName = _loginName;
DBConfig.Instance.ServerType = _serverType;
DBConfig.Instance.Connection = _connectionTemplate;
DBConfig.Instance.dephiConnection =
_delphiConnectionTemplate;
runtime.SelectedLedgerName = _selectedLedgerName;
runtime._ledgerTable = null;
runtime._connectionInitialized = _connectionInitialized;
ERPInfo.Instance.AccountBook = _accountBook;
try
{
if (!string.IsNullOrWhiteSpace(_serverName) &&
!string.IsNullOrWhiteSpace(_databaseName))
{
DBConfig.Instance.CreateConnection(
_connectionTemplate);
if (!string.Equals(
_serverType,
"达梦数据库",
StringComparison.Ordinal))
{
DelphiHelper.Delphi_Init(new StringBuilder(
DBConfig.Instance.GetDelphiConnection(
_delphiConnectionTemplate)));
}
SystemInfo.RefreshSystemParam();
}
}
catch (Exception restoreException)
{
LogSanitized(restoreException);
}
}
}
private sealed class LegacyConnectionSettingsException : Exception
{
public LegacyConnectionSettingsException(string message)
: base(message)
{
}
}
}
}
+37
View File
@@ -0,0 +1,37 @@
# 外部主界面兼容层
这个目录只为旧 `.NET Framework 4.0` 启动流程提供一个可选扩展点,不引用 WPF 或 DevExpress 25.2。
## 默认路线
直接运行 `Ls_ERP.exe` 时,`Manager.ExternalMainShell``null`
```text
Program.Main
-> Manager.StartForm
-> FrmLogin
-> Manager.RunMainForm
-> FrmMain
```
这条路线不加载任何 WPF 程序集,并保持 DevExpress WinForms 15.2。
## 外部宿主路线
`.NET Framework 4.8` 的独立启动程序通过 `LegacyApplicationHost.Run` 注入 `IExternalMainShell`。旧程序仍负责 CEF、全局异常、配置、数据库和登录;登录成功后自动保留当前有效子系统,或选择第一个有权限且启用的子系统,不再显示 `FrmSubSystem`,随后在 `RunMainForm` 位置回调外部主界面。
该跳过逻辑只在 `Manager.ExternalMainShell != null` 时生效。直接运行 `Ls_ERP.exe` 时仍保留原子系统选择页和原有循环。
`IExternalMainShell` 当前承担:
- 同步显示外部主窗口;
- 返回普通关闭或重新登录结果;
- 处理旧插件发起的重新登录;
- 在强制下线时通知外部主窗口退出。
## 修改规则
- 此层必须继续可以在 .NET Framework 4.0 下编译。
- 禁止引用 `Lserp.Wpf.*`、WPF 类型或 DevExpress 25.2。
- 新界面特有实现放在独立 WPF 解决方案的 `Lserp.Wpf.Legacy.WinForms`
- 新增兼容能力时优先扩展中立接口,不要在旧工程中直接调用 WPF。
+3
View File
@@ -276,6 +276,9 @@
<Compile Include="Model\BitMapHelper.cs" />
<Compile Include="Model\Manager.cs" />
<Compile Include="Model\winApi.cs" />
<Compile Include="Hosting\IExternalMainShell.cs" />
<Compile Include="Hosting\LegacyApplicationHost.cs" />
<Compile Include="Hosting\LegacyLoginRuntime.ConnectionSettings.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Control\AwaitScreenControl.resx">
+356 -192
View File
@@ -15,6 +15,7 @@ using Lskj.Control;
using Lskj.Control.Model;
using Lskj.Core;
using Lskj.Data;
using Lskj.Main.Hosting;
using Lskj.Model;
using Lskj.Util;
using Lskj.Web.Core.Util;
@@ -55,6 +56,14 @@ namespace Lskj.Main.Model
public static int isAwaitTime = 10;
public static int RefreshTime = 0;
/// <summary>
/// 由外部启动程序提供的可选主界面。默认为 null,旧 Ls_ERP.exe 仍打开 FrmMain。
/// </summary>
public static IExternalMainShell ExternalMainShell { get; internal set; }
private static readonly object SessionMonitorSync = new object();
private static CancellationTokenSource _sessionMonitorCancellation;
private static readonly List<Thread> SessionMonitorThreads =
new List<Thread>();
/// <summary>
/// 默认下载地址
/// </summary>
private static string filePath = string.Empty;
@@ -82,8 +91,12 @@ namespace Lskj.Main.Model
public static void StartForm()
{
bool isStart = true;
bool useLegacySplash = ExternalMainShell == null;
// 加载Splash动画界面
SplashForm.ShowForm();
if (useLegacySplash)
{
SplashForm.ShowForm();
}
//CheckLocalConfig();
// C#数据库连接检查
bool isLocalConnect = false;
@@ -103,27 +116,36 @@ namespace Lskj.Main.Model
if (!DBConfig.Instance.CreateConnection(DBConfig.Instance.Connection))
{
MessageUtil.Show(ResourceKeys.UnConnectServer);
SplashForm.HideForm();
if (useLegacySplash)
{
SplashForm.HideForm();
}
DialogResult result = RunConfigForm();
isStart = result == DialogResult.OK;
}
if (isStart)
{
// Delphi数据库连接检查
if (!DBConfig.Instance.ServerType.Equals("达梦数据库"))
if (!DBConfig.Instance.ServerType.Equals("达梦数据库"))
{
if (DelphiHelper.Delphi_Init(new StringBuilder(DBConfig.Instance.GetDelphiConnection(DBConfig.Instance.dephiConnection))) == 0)
{
MessageUtil.Show(ResourceKeys.UnConnectServer + "[By Delphi]");
SplashForm.HideForm();
if (useLegacySplash)
{
SplashForm.HideForm();
}
RunConfigForm();
return;
}
}
SplashForm.HideForm();
if (useLegacySplash)
{
SplashForm.HideForm();
}
// 汉化dev控件
BaseResources.Localization(LocalizationType.CHS);
// 启动登录页面
@@ -145,7 +167,10 @@ namespace Lskj.Main.Model
}
else
{
SplashForm.HideForm();
if (useLegacySplash)
{
SplashForm.HideForm();
}
}
}
@@ -161,9 +186,7 @@ namespace Lskj.Main.Model
/// <param name="skipMenu">是否跳过子系统选择(适用于切换用户).</param>
public static void ReStartMain(bool skipMenu = false)
{
WhenConstraintLogin();
LockApplication();
if (SystemInfo.Instance.SubscriptRefreshTime > 0 && !SystemInfo.Instance.RefreshNotify) RefreshSubscript();
StartSessionMonitors();
if (_frmMain != null)
{
if (ERPInfo.Instance.WatermarkForm != null)
@@ -180,7 +203,13 @@ namespace Lskj.Main.Model
bool isOpenBs = false;
DialogResult result;
if (ERPInfo.Instance.SubMenuCount > 1 && !skipMenu)
if (ExternalMainShell != null)
{
// WPF 主框架已经提供顶部子系统导航,不再打开旧 FrmSubSystem。
// 优先保留当前仍有权限的子系统,否则选择第一个可用子系统。
isStart = TrySelectExternalMainShellSubSystem();
}
else if (ERPInfo.Instance.SubMenuCount > 1 && !skipMenu)
{
// 进入子系统界面
result = RunSubSystemForm();
@@ -190,8 +219,19 @@ namespace Lskj.Main.Model
if (isStart)
{
// 直接进入主界面
RunMainForm();
if (ERPInfo.Instance.SubMenuCount > 1)
result = RunMainForm();
if (result == DialogResult.Retry)
{
StartForm();
return;
}
if (ExternalMainShell != null)
{
// 外部主界面关闭即结束本次 WPF 入口,不返回旧子系统选择页。
ExitSystem();
return;
}
else if (ERPInfo.Instance.SubMenuCount > 1)
{
ReStartMain();
}
@@ -531,22 +571,23 @@ namespace Lskj.Main.Model
form.Show();
if (args != null && !string.IsNullOrEmpty(args[4] + ""))
{
ModuleModel moduleModel = new ModuleModel(MainImpl.GetSystemdllTab(args[4] + ""));
if (!string.IsNullOrEmpty(moduleModel.SearchCondFormModuleCode))
{
ModuleConditionsPanelEx mcpex = new ModuleConditionsPanelEx();
mcpex.InitializeControl(new ModuleModel(MainImpl.GetSystemdllTab(moduleModel.SearchCondFormModuleCode)), null, null, true);
if (StaticControl.ConditionsPanelDic.ContainsKey(args[4] + ""))
{
StaticControl.ConditionsPanelDic[args[4] + ""].Dispose();
StaticControl.ConditionsPanelDic[args[4] + ""] = mcpex;
}
else
{
StaticControl.ConditionsPanelDic.Add(args[4] + "", mcpex);
}
DialogResult dialogResult = mcpex.ShowDialog();
}
//2026-08-08 pz说把SearchCondFormModuleCode判断去掉,不要这个功能
//ModuleModel moduleModel = new ModuleModel(MainImpl.GetSystemdllTab(args[4] + ""));
//if (!string.IsNullOrEmpty(moduleModel.SearchCondFormModuleCode))
//{
// ModuleConditionsPanelEx mcpex = new ModuleConditionsPanelEx();
// mcpex.InitializeControl(new ModuleModel(MainImpl.GetSystemdllTab(moduleModel.SearchCondFormModuleCode)), null, null, true);
// if (StaticControl.ConditionsPanelDic.ContainsKey(args[4] + ""))
// {
// StaticControl.ConditionsPanelDic[args[4] + ""].Dispose();
// StaticControl.ConditionsPanelDic[args[4] + ""] = mcpex;
// }
// else
// {
// StaticControl.ConditionsPanelDic.Add(args[4] + "", mcpex);
// }
// DialogResult dialogResult = mcpex.ShowDialog();
//}
}
TabMain.TabPages.Add(tp);
@@ -596,8 +637,9 @@ namespace Lskj.Main.Model
}
return dllName;
}
private static void ExitSystem()
internal static void ExitSystem()
{
StopSessionMonitors();
try
{
// 退出系统
@@ -653,6 +695,9 @@ namespace Lskj.Main.Model
/// <returns>DialogResult.</returns>
private static DialogResult RunLoginForm()
{
if (ExternalMainShell != null)
return ExternalMainShell.ShowLoginDialog(new LegacyLoginRuntime());
FrmLogin frmLogin = new FrmLogin();
return frmLogin.ShowDialog();
}
@@ -674,6 +719,44 @@ namespace Lskj.Main.Model
BsUrl = _frmSubSystem.BsUrl;
return dialogResult;
}
/// <summary>
/// 为外部 WPF 主框架选择登录后的初始子系统。
/// 旧 WinForms 入口仍由 FrmSubSystem 完成人工选择。
/// </summary>
internal static bool TrySelectExternalMainShellSubSystem()
{
string where = string.IsNullOrEmpty(ERPInfo.Instance.SeriesId)
? string.Empty
: string.Format("and SeriesId={0}", ERPInfo.Instance.SeriesId);
DataTable subSystems = MainImpl.GetSubSystems(where);
if (subSystems == null || subSystems.Rows.Count == 0)
return false;
DataRow selectedRow = subSystems.AsEnumerable().FirstOrDefault(row =>
IsEnabledSubSystem(row) &&
string.Equals(
row["SubSysId"] + string.Empty,
ERPInfo.Instance.SubSysId,
StringComparison.OrdinalIgnoreCase));
if (selectedRow == null)
selectedRow = subSystems.AsEnumerable().FirstOrDefault(IsEnabledSubSystem);
if (selectedRow == null)
return false;
ERPInfo.Instance.SubMenuCount = subSystems.AsEnumerable().Count(IsEnabledSubSystem);
ERPInfo.Instance.SubSysId = selectedRow["SubSysId"] + string.Empty;
ERPInfo.Instance.SubSysName = selectedRow["SubSysName"] + string.Empty;
return true;
}
private static bool IsEnabledSubSystem(DataRow row)
{
return row != null &&
row.Table.Columns.Contains("UseEd") &&
row["UseEd"] != DBNull.Value &&
Convert.ToBoolean(row["UseEd"]);
}
/// <summary>
/// <para>说明:打开主程序</para>
/// <para>创建人:龚宇超</para>
@@ -686,6 +769,10 @@ namespace Lskj.Main.Model
/// <returns>DialogResult.</returns>
private static DialogResult RunMainForm()
{
IExternalMainShell externalMainShell = ExternalMainShell;
if (externalMainShell != null)
return externalMainShell.ShowDialog();
_frmMain = new FrmMain();
return _frmMain.ShowDialog();
}
@@ -862,187 +949,247 @@ namespace Lskj.Main.Model
return isSuccess;
}
#endregion
/// <summary>
/// <para>说明:强制登录下线</para>
/// <para>创建人:唐德馨</para>
/// <para>创建日期:2023-10-16 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
private static void WhenConstraintLogin()
internal static void BeginExternalSessionServices()
{
Thread thread = new Thread(() =>
StartSessionMonitors();
}
internal static void EndExternalSessionServices()
{
StopSessionMonitors();
}
private static void StartSessionMonitors()
{
StopSessionMonitors();
CancellationTokenSource cancellation =
new CancellationTokenSource();
var threads = new List<Thread>();
if (SystemInfo.Instance.IsConstraintExit)
{
bool isClose = false;
while (SystemInfo.Instance.IsConstraintExit)
threads.Add(CreateSessionMonitor(
"ConstraintLoginMonitor",
delegate { MonitorConstraintLogin(cancellation.Token); }));
}
if (SystemInfo.Instance.AwaitTime > 10)
{
threads.Add(CreateSessionMonitor(
"ApplicationLockMonitor",
delegate { MonitorApplicationLock(cancellation.Token); }));
}
if (SystemInfo.Instance.SubscriptRefreshTime > 0 &&
!SystemInfo.Instance.RefreshNotify)
{
threads.Add(CreateSessionMonitor(
"SubscriptRefreshMonitor",
delegate { MonitorSubscriptRefresh(cancellation.Token); }));
}
lock (SessionMonitorSync)
{
_sessionMonitorCancellation = cancellation;
SessionMonitorThreads.AddRange(threads);
isAwaitTime = 10;
RefreshTime = 0;
}
foreach (Thread thread in threads)
thread.Start();
}
internal static void StopSessionMonitors()
{
CancellationTokenSource cancellation;
Thread[] threads;
lock (SessionMonitorSync)
{
cancellation = _sessionMonitorCancellation;
_sessionMonitorCancellation = null;
threads = SessionMonitorThreads.ToArray();
SessionMonitorThreads.Clear();
}
if (cancellation == null)
return;
cancellation.Cancel();
bool allStopped = true;
foreach (Thread thread in threads)
{
if (thread != null &&
thread != Thread.CurrentThread &&
thread.IsAlive)
{
string hostName = "";
string clientip = "";
string loginMacAdress = "";
DataTable loginTable = new DataTable();
if (!thread.Join(2000))
allStopped = false;
}
}
if (allStopped)
cancellation.Dispose();
}
private static Thread CreateSessionMonitor(
string name,
ThreadStart monitor)
{
return new Thread(monitor)
{
Name = name,
IsBackground = true
};
}
private static void MonitorConstraintLogin(CancellationToken token)
{
while (SystemInfo.Instance.IsConstraintExit &&
!token.IsCancellationRequested)
{
string clientip = string.Empty;
string loginMacAdress = string.Empty;
try
{
clientip = SqlHelper.ExecuteScalar(string.Format(
"select clientip from p_employeetab where employeeid = '{0}'",
ERPInfo.Instance.UserId)) + string.Empty;
loginMacAdress = SqlHelper.ExecuteScalar(string.Format(
"select macAdress from p_employeetab where employeeid = '{0}'",
ERPInfo.Instance.UserId)) + string.Empty;
}
catch (Exception)
{
}
if (!string.IsNullOrWhiteSpace(loginMacAdress) &&
!loginMacAdress.Equals(ERPInfo.Instance.MacAddress))
{
string message = string.Format(
"当前用户在另一电脑登录\r\nClientIp:{0}\r\nMacAdress:{1}\r\n当前系统即将关闭",
clientip,
loginMacAdress);
try
{
loginTable = SqlHelper.ExecuteDataTable("select rtrim(ltrim(substring(hostname,1,100))) as hostname from master.dbo.sysprocesses where loginame = 'lserpAdmin' and (program_name = '' or program_name = '.Net SqlClient Data Provider')");
hostName = SqlHelper.ExecuteScalar(string.Format("select hostname from p_LoginHostInfotab where OperatorId = '{0}' and Tagid = 1", ERPInfo.Instance.UserId)) + "";
clientip = SqlHelper.ExecuteScalar(string.Format("select clientip from p_employeetab where employeeid = '{0}'", ERPInfo.Instance.UserId)) + "";
loginMacAdress = SqlHelper.ExecuteScalar(string.Format("select macAdress from p_employeetab where employeeid = '{0}'", ERPInfo.Instance.UserId)) + "";
IExternalMainShell externalMainShell = ExternalMainShell;
if (externalMainShell != null &&
externalMainShell.IsOpen)
{
externalMainShell.RequestExit(message);
return;
}
bool isClose = false;
if (_frmSubSystem != null && _frmSubSystem.Visible)
{
_frmSubSystem.Invoke(new Action(delegate
{
_frmSubSystem.Opacity = 0;
MessageUtil.Show(message);
isClose = true;
}));
}
else if (_frmMain != null && _frmMain.Visible)
{
_frmMain.Invoke(new Action(delegate
{
_frmMain.Opacity = 0;
MessageUtil.Show(message);
isClose = true;
}));
}
if (isClose)
{
ExitSystem();
LogUtil.WriteDebug(
string.Empty,
"退出软件",
"软件退出",
"系统登录");
foreach (Process item in GetApplicationProcesses())
{
try
{
item.Kill();
}
catch (Exception)
{
}
}
Application.Exit();
return;
}
}
catch (Exception)
{
}
//!string.IsNullOrEmpty(hostName) && loginTable.Select().Where(n => n["hostname"].Equals(hostName)).Count() > 0 && !loginMacAdress.Equals(ERPInfo.Instance.MacAddress)
if (!loginMacAdress.Equals(ERPInfo.Instance.MacAddress))
{
try
{
if (_frmSubSystem != null && _frmSubSystem.Visible == true)
{
_frmSubSystem.Invoke(new Action(() =>
{
if (!isClose)
{
_frmSubSystem.Opacity = 0;
MessageUtil.Show($"当前用户在另一电脑登录\r\nClientIp:{clientip}\r\nMacAdress:{loginMacAdress}\r\n当前系统即将关闭");
isClose = true;
}
}));
}
else if (_frmMain != null && _frmMain.Visible == true)
{
_frmMain.Invoke(new Action(() =>
{
if (!isClose)
{
_frmMain.Opacity = 0;
MessageUtil.Show($"当前用户在另一电脑登录\r\nClientIp:{clientip}\r\nMacAdress:{loginMacAdress}\r\n当前系统即将关闭");
isClose = true;
}
}));
}
if (isClose)
{
if (DBConfig.Instance.NoticeExit)
{
Process[] p1 = Process.GetProcessesByName("Ls_Notice");
foreach (Process item in p1)
{
try
{
item.Kill();
}
catch (Exception)
{
}
}
if (!string.IsNullOrWhiteSpace(SystemInfo.Instance.QuickMenuId))
{
Process[] p2 = Process.GetProcessesByName("Lskj.QuickModule");
foreach (Process item in p2)
{
try
{
item.Kill();
}
catch (Exception)
{
}
}
}
}
//记录登出日志
LogUtil.WriteDebug("", "退出软件", "软件退出", "系统登录");
Process[] p = Process.GetProcessesByName("Ls_ERP");
foreach (Process item in p)
{
try
{
item.Kill();
}
catch (Exception)
{
}
}
//Environment.Exit(0);
Application.Exit();
break;
}
}
catch (Exception)
{
}
}
Thread.Sleep(1000);
}
});
thread.Start();
}
/// <summary>
/// 锁定程序
/// </summary>
private static void LockApplication()
{
Thread thread = new Thread(() =>
{
while (SystemInfo.Instance.AwaitTime > 10)
{
if (isAwaitTime == SystemInfo.Instance.AwaitTime)
{
isAwaitTime = 0;
if (_frmMain != null && _frmMain.Visible == true)
{
_frmMain.Invoke(new Action(() =>
{
_frmMain.mainPanelControlEx.AwaitControl.BringToFront();
_frmMain.mainPanelControlEx.AwaitControl.Visible = true;
_frmMain.mainPanelControlEx.AwaitControl.OnFrmAwaitScreenLoad();
}));
}
}
isAwaitTime += 1;
Thread.Sleep(1000);
}
});
thread.Start();
if (token.WaitHandle.WaitOne(1000))
return;
}
}
/// <summary>
/// 刷新数量角标
/// </summary>
private static void RefreshSubscript()
private static void MonitorApplicationLock(CancellationToken token)
{
Thread thread = new Thread(() =>
while (SystemInfo.Instance.AwaitTime > 10 &&
!token.IsCancellationRequested)
{
while (SystemInfo.Instance.SubscriptRefreshTime > 0)
if (isAwaitTime >= SystemInfo.Instance.AwaitTime)
{
if (RefreshTime >= SystemInfo.Instance.SubscriptRefreshTime)
isAwaitTime = 0;
IExternalMainShell externalMainShell = ExternalMainShell;
if (externalMainShell != null && externalMainShell.IsOpen)
{
RefreshTime = 0;
if (_frmMain != null && _frmMain.Visible == true)
externalMainShell.RequestLock();
return;
}
if (_frmMain != null && _frmMain.Visible)
{
_frmMain.Invoke(new Action(delegate
{
XtraTabPage tabPage = _frmMain.mainPanelControlEx.tabMain.SelectedTabPage;
if (tabPage.TabIndex == 0)
{
if (!SystemInfo.Instance.RefreshNotify)
{
Thread threadnew = new Thread(_frmMain.mainPanelControlEx.RefreshSubscript);
threadnew.IsBackground = true;
threadnew.Start();
}
}
_frmMain.mainPanelControlEx.AwaitControl.BringToFront();
_frmMain.mainPanelControlEx.AwaitControl.Visible = true;
_frmMain.mainPanelControlEx.AwaitControl.OnFrmAwaitScreenLoad();
}));
}
}
isAwaitTime += 1;
if (token.WaitHandle.WaitOne(1000))
return;
}
}
private static void MonitorSubscriptRefresh(CancellationToken token)
{
while (SystemInfo.Instance.SubscriptRefreshTime > 0 &&
!token.IsCancellationRequested)
{
if (RefreshTime >= SystemInfo.Instance.SubscriptRefreshTime)
{
RefreshTime = 0;
IExternalMainShell externalMainShell = ExternalMainShell;
if (externalMainShell != null && externalMainShell.IsOpen)
{
externalMainShell.RequestSubscriptRefresh();
}
else if (_frmMain != null && _frmMain.Visible)
{
XtraTabPage tabPage =
_frmMain.mainPanelControlEx.tabMain.SelectedTabPage;
if (tabPage != null &&
tabPage.TabIndex == 0 &&
!SystemInfo.Instance.RefreshNotify)
{
Thread refreshThread = new Thread(
_frmMain.mainPanelControlEx.RefreshSubscript);
refreshThread.IsBackground = true;
refreshThread.Start();
}
}
RefreshTime += 1;
Thread.Sleep(60000);
}
});
thread.Start();
RefreshTime += 1;
if (token.WaitHandle.WaitOne(60000))
return;
}
}
@@ -1107,6 +1254,12 @@ namespace Lskj.Main.Model
/// </summary>
public static void ReLogin()
{
IExternalMainShell externalMainShell = ExternalMainShell;
if (externalMainShell != null && externalMainShell.IsOpen)
{
externalMainShell.RequestRelogin();
return;
}
if (_frmMain != null)
{
if (ERPInfo.Instance.WatermarkForm != null)
@@ -1121,5 +1274,16 @@ namespace Lskj.Main.Model
StartForm();
}
/// <summary>
/// 返回当前启动路线需要退出的主进程。
/// 旧入口保持原有 Ls_ERP 进程名语义,外部宿主只退出当前 WPF 进程。
/// </summary>
internal static Process[] GetApplicationProcesses()
{
return ExternalMainShell == null
? Process.GetProcessesByName("Ls_ERP")
: new[] { Process.GetCurrentProcess() };
}
}
}
}
+172 -50
View File
@@ -21,11 +21,22 @@ using System.Resources;
using System.Runtime.InteropServices;
using System.Resources;
using System.Diagnostics;
using Lskj.Main.Hosting;
namespace Lskj.Main
{
static class Program
{
private static CefMainArgs _mainArgs;
private static DemoCefApp _cefApp;
private static CefSettings _cefSettings;
private static Messager _messageFilter;
private static EventHandler _cefIdleHandler;
private static AboutDevCompanion _devCompanion;
private static bool _cefInitialized;
private static bool _mainProcessInitialized;
private static bool _mainProcessShutdown;
//[DllImport("user32.dll")]
//private static extern bool SetProcessDpiAwarenessContext(IntPtr dpiContext);
@@ -36,61 +47,160 @@ namespace Lskj.Main
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
static int Main(string[] args)
{
//SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
CefRuntime.Load();//cef浏览器模块设置加载
var mainArgs = new CefMainArgs(args);
var app = new DemoCefApp();
var settings = new CefSettings
LegacyProcessStartResult processResult;
try
{
processResult = LegacyApplicationHost.PrepareProcess(args);
}
catch (Exception exception)
{
LogHelper.Instance.WriteError(exception);
return -1;
}
if (!processResult.ShouldRunApplication)
return processResult.ExitCode;
try
{
LegacyApplicationHost.InitializeMainProcess(null);
Manager.StartForm();
return 0;
}
catch (Exception exception)
{
MessageUtil.Show(exception);
LogHelper.Instance.WriteError(exception);
return -1;
}
finally
{
LegacyApplicationHost.ShutdownMainProcess();
}
}
internal static int PrepareProcess(string[] args)
{
if (_mainArgs != null)
throw new InvalidOperationException("CEF 进程分流已经执行。");
CefRuntime.Load();
_mainArgs = new CefMainArgs(args ?? new string[0]);
_cefApp = new DemoCefApp();
_cefSettings = CreateCefSettings();
int code = CefRuntime.ExecuteProcess(
_mainArgs,
_cefApp,
IntPtr.Zero);
Console.WriteLine(
"CefRuntime.ExecuteProcess() returns {0}",
code);
return code;
}
internal static void InitializeMainProcess()
{
if (_mainProcessInitialized)
throw new InvalidOperationException("旧主进程环境已经初始化。");
if (_mainProcessShutdown)
throw new InvalidOperationException("旧主进程环境已经关闭。");
if (_mainArgs == null || _cefApp == null || _cefSettings == null)
throw new InvalidOperationException("尚未执行 CEF 进程分流。");
try
{
CefRuntime.Initialize(
_mainArgs,
_cefSettings,
_cefApp,
IntPtr.Zero);
_cefInitialized = true;
Thread.CurrentThread.CurrentUICulture =
new CultureInfo("zh-CN");
BonusSkins.Register();
SkinManager.EnableFormSkins();
Application.SetUnhandledExceptionMode(
UnhandledExceptionMode.CatchException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
_messageFilter = new Messager();
Application.AddMessageFilter(_messageFilter);
Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException +=
CurrentDomain_UnhandledException;
if (!_cefSettings.MultiThreadedMessageLoop)
{
_cefIdleHandler = delegate
{
CefRuntime.DoMessageLoopWork();
};
Application.Idle += _cefIdleHandler;
}
_devCompanion = new AboutDevCompanion(1, false);
_devCompanion.Run();
Register();
_mainProcessInitialized = true;
}
catch
{
ShutdownMainProcess();
throw;
}
}
internal static void ShutdownMainProcess()
{
if (_mainProcessShutdown)
return;
_mainProcessShutdown = true;
try
{
if (_cefIdleHandler != null)
{
Application.Idle -= _cefIdleHandler;
_cefIdleHandler = null;
}
Application.ThreadException -= Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException -=
CurrentDomain_UnhandledException;
if (_messageFilter != null)
{
Application.RemoveMessageFilter(_messageFilter);
_messageFilter = null;
}
if (_devCompanion != null)
{
_devCompanion.Stop();
_devCompanion = null;
}
}
finally
{
if (_cefInitialized)
{
CefRuntime.Shutdown();
_cefInitialized = false;
}
_mainProcessInitialized = false;
}
}
private static CefSettings CreateCefSettings()
{
return new CefSettings
{
MultiThreadedMessageLoop = true,
LogSeverity = CefLogSeverity.Disable,
LogFile = "CefGlue.log",
Locale = "zh-CN"
};
try
{
var Code = CefRuntime.ExecuteProcess(mainArgs, app, IntPtr.Zero);
Console.WriteLine("CefRuntime.ExecuteProcess() returns {0}", Code);
}
catch (Exception ex)
{
}
CefRuntime.Initialize(mainArgs, settings, app, IntPtr.Zero);
try
{
// 汉化DevExpress界面
Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN");
// 设置皮肤
BonusSkins.Register();
SkinManager.EnableFormSkins();
//处理未捕获的异常
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.AddMessageFilter(new Messager());
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
if (!settings.MultiThreadedMessageLoop)//消息循环
{
Application.Idle += (sender, e) => { CefRuntime.DoMessageLoopWork(); };
}
AboutDevCompanion DC = new AboutDevCompanion(1, false);
DC.Run();
Register();
// 启动程序
Manager.StartForm();
CefRuntime.Shutdown();
DC.Stop();
}
catch (Exception ex)
{
MessageUtil.Show(ex);
LogHelper.Instance.WriteError(ex);
}
}
#region
/// <summary>
@@ -174,8 +284,20 @@ namespace Lskj.Main
/// <param name="e">The <see cref="ThreadExceptionEventArgs"/> instance containing the event data.</param>
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Console.WriteLine(e.ExceptionObject.ToString());
MessageUtil.Show(e.ExceptionObject.ToString());
Exception exception = e == null
? null
: e.ExceptionObject as Exception;
if (exception == null)
{
exception = new Exception(
e == null || e.ExceptionObject == null
? "AppDomain 未处理异常对象为空。"
: e.ExceptionObject.ToString());
}
Console.WriteLine(exception);
LogHelper.Instance.WriteError(exception);
MessageUtil.Show(exception);
}
+11 -1
View File
@@ -467,6 +467,14 @@ namespace Lskj.Model
/// 单据横向模式
/// </summary>
public bool HorizontalMode;
/// <summary>
/// 树表格新版节点号模式
/// </summary>
public bool NewNodeRules;
/// <summary>
/// 新版树节点位数(默认2位,最小2位)
/// </summary>
public int TreeNumberNodes;
/// <summary>
@@ -575,6 +583,8 @@ namespace Lskj.Model
this.SourceMainPushPullHide = rowItem.Table.Columns.Contains("SourceMainPushPullHide") ? "1".Equals(rowItem["SourceMainPushPullHide"] + "") : false;
this.SelectSourceColor = rowItem.Table.Columns.Contains("SelectSourceColor") ? rowItem["SelectSourceColor"] + "" : "";
this.HorizontalMode = rowItem.Table.Columns.Contains("HorizontalMode") ? "1".Equals(rowItem["HorizontalMode"] + "") : false;
this.NewNodeRules = rowItem.Table.Columns.Contains("NewNodeRules") ? "1".Equals(rowItem["NewNodeRules"] + "") : false;
this.TreeNumberNodes = rowItem.Table.Columns.Contains("TreeNumberNodes") && !string.IsNullOrEmpty(rowItem["TreeNumberNodes"] + "") ? Convert.ToInt32(rowItem["TreeNumberNodes"] + "")>2? Convert.ToInt32(rowItem["TreeNumberNodes"] + ""):2 : 2;
}
}
}
}
+5 -1
View File
@@ -108,7 +108,11 @@ namespace Lskj.Model
/// 是否阻止回车事件
/// </summary>
public bool IsExecute = false;
/// <summary>
/// 是否根据模块id判断是否设置不能同时打开多个相同模块
/// </summary>
public bool SingleOpenMode = false;
/// <summary>
/// 登录IP
+18 -2
View File
@@ -585,7 +585,7 @@ namespace Lskj.Model
/// </summary>
public int AccordingNameSelected;
/// <summary>
/// 基础档案关闭时候触发存储过程
/// 基础档案关闭时候触发存储过程(扫码模块关闭时)
/// </summary>
public string FrmCloseStored;
/// <summary>
@@ -1050,7 +1050,18 @@ namespace Lskj.Model
///隐藏审核按钮(lskj.pubadd.dll
/// </summary>
public bool HideReviewBut;
/// <summary>
/// 模块弹出框高度
/// </summary>
public int ModuleFrameHeight;
/// <summary>
/// 模块弹出框宽度
/// </summary>
public int ModuleFrameWidth;
/// <summary>
/// 下方高
/// </summary>
public int BottomHeight;
#endregion
/// <summary>
@@ -1243,6 +1254,11 @@ namespace Lskj.Model
this.TotalQuantity = rowItem.Table.Columns.Contains("TotalQuantity") ? "1".Equals(rowItem["TotalQuantity"] + "") : false;
this.HeaderSortCriteria = rowItem.Table.Columns.Contains("HeaderSortCriteria") ? rowItem["HeaderSortCriteria"] + "" : "";
this.HideReviewBut = rowItem.Table.Columns.Contains("HideReviewBut") ? "1".Equals(rowItem["HideReviewBut"] + "") : false;
this.ModuleFrameHeight = rowItem.Table.Columns.Contains("ModuleFrameHeight") && !string.IsNullOrEmpty(rowItem["ModuleFrameHeight"] + "") ? Convert.ToInt32(rowItem["ModuleFrameHeight"] + "") : 0;
this.ModuleFrameWidth = rowItem.Table.Columns.Contains("ModuleFrameWidth") && !string.IsNullOrEmpty(rowItem["ModuleFrameWidth"] + "") ? Convert.ToInt32(rowItem["ModuleFrameWidth"] + "") : 0;
this.BottomHeight = rowItem.Table.Columns.Contains("BottomHeight") && !string.IsNullOrEmpty(rowItem["BottomHeight"] + "") ? Convert.ToInt32(rowItem["BottomHeight"] + "") : 0;
}
}
}
@@ -3665,6 +3665,15 @@ namespace Lskj.PubAccraditation
string newfieldValue = fieldValue;
if (fieldValue == "****") continue;
if (SystemInfo.Instance.IsSpecialAuditSave &&
this._drBillInfoMsg != null &&
this._drBillInfoMsg.Table != null &&
this._drBillInfoMsg.Table.Columns.Contains(model.FieldName) &&
AuditChangeLog.IsSameValue(this._drBillInfoMsg[model.FieldName] + "", fieldValue))
{
continue;
}
if ((model.FieldType == ControlType.LabDate ||
model.FieldType == ControlType.LabDate ||
model.FieldType == ControlType.LabDate ||
@@ -3683,7 +3692,12 @@ namespace Lskj.PubAccraditation
}
}
SaveErrorMessage = errorMessage;
return string.Format("update {0} set {1} where {2}='{3}'", this.BillModelObj.MasterTable, updateBuilder.ToString().TrimEnd(','), BillModelObj.PrimaryKey, this.SysModel.BillDocumentId);
string updateFields = updateBuilder.ToString().TrimEnd(',');
if (string.IsNullOrEmpty(updateFields))
{
return string.Empty;
}
return string.Format("update {0} set {1} where {2}='{3}'", this.BillModelObj.MasterTable, updateFields, BillModelObj.PrimaryKey, this.SysModel.BillDocumentId);
}
#endregion
+5 -2
View File
@@ -439,7 +439,10 @@ namespace Lskj.PubApiSetModule
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 3, Text = "URL地址加密" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 4, Text = "URL文件Base64" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 5, Text = "RSA" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 103, Text = "道宏发票接口特殊加密" });//道宏发票接口特殊加密
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 101, Text = "航天凯特特殊加密" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 102, Text = "SHA256ToBase64" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 103, Text = "道宏发票接口特殊加密" });
valueEncryptTypeComboBox.Items.Add(new ComBoxModel() { Value = 104, Text = "SHA256ToBit" });
#endregion
#region
getIdColumn.OptionsColumn.AllowEdit = false;
@@ -607,7 +610,7 @@ namespace Lskj.PubApiSetModule
colDic.Add("valueDataType", "int");
colDic.Add("unionPmsId", "int");
colDic.Add("valueEncryptType", "int");
colDic.Add("encryptKey", "int");
colDic.Add("encryptKey", "varchar(100)");
colDic.Add("allowNull", "int");
string isExitApiTab = "select top 1 * from sysObjects where Id=OBJECT_ID(N'P_systemEventApiPmsTab') and xtype='U'";
DataTable apiTab = SqlHelper.ExecuteDataTable(isExitApiTab);
+6 -7
View File
@@ -28,17 +28,16 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.barManager1 = new DevExpress.XtraBars.BarManager(this.components);
this.barManager1 = new DevExpress.XtraBars.BarManager();
this.barDockControl1 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl2 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl3 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl5 = new DevExpress.XtraBars.BarDockControl();
this.pmFP = new DevExpress.XtraBars.PopupMenu(this.components);
this.pmBillExp = new DevExpress.XtraBars.PopupMenu(this.components);
this.pmBill = new DevExpress.XtraBars.PopupMenu(this.components);
this.pMprint = new DevExpress.XtraBars.PopupMenu(this.components);
this.pMenu = new DevExpress.XtraBars.PopupMenu(this.components);
this.pmFP = new DevExpress.XtraBars.PopupMenu();
this.pmBillExp = new DevExpress.XtraBars.PopupMenu();
this.pmBill = new DevExpress.XtraBars.PopupMenu();
this.pMprint = new DevExpress.XtraBars.PopupMenu();
this.pMenu = new DevExpress.XtraBars.PopupMenu();
this.tb_buttom = new Lskj.Control.TabControlEx();
this.ssc_main_top = new DevExpress.XtraEditors.SplitContainerControl();
this.pl_left = new DevExpress.XtraEditors.PanelControl();
File diff suppressed because it is too large Load Diff
@@ -61,9 +61,11 @@ namespace Lskj.PubBill.Model
public string Orderid;// 来源页签序号
public string DetailMenuCode;// 来源模块号
public string SourceModeCode;// 来源模块号
public string DetailModeCode;// 来源明细模块号
public BillSourceModel(DataRow item)
{
@@ -110,7 +112,8 @@ namespace Lskj.PubBill.Model
this.DragAndSave = item.Table.Columns.Contains("DragAndSave") && "1".Equals(item["DragAndSave"] + "") ? true : false;
this.TreeInhibitSort = item.Table.Columns.Contains("TreeInhibitSort") && "1".Equals(item["TreeInhibitSort"] + "") ? true : false;
this.Orderid = item.Table.Columns.Contains("Orderid") ? item["Orderid"] + "" : "";
this.DetailMenuCode = item.Table.Columns.Contains("DetailMenuCode") ? item["DetailMenuCode"] + "" : "";
this.SourceModeCode = item.Table.Columns.Contains("SourceModeCode") ? item["SourceModeCode"] + "" : "";
this.DetailModeCode = item.Table.Columns.Contains("DetailModeCode") ? item["DetailModeCode"] + "" : "";
}
/// <summary>
/// 改变来源类型
@@ -129,5 +132,24 @@ namespace Lskj.PubBill.Model
{
this.sourceDetailType = sourceDetailType;
}
/// <summary>
/// 改变来源主表sql
/// </summary>
/// <param name="sourceType"></param>
public void ChangeSourceSql(string Sql)
{
this.SourceSql = Sql;
}
/// <summary>
/// 改变来源明细sql
/// </summary>
/// <param name="sourceType"></param>
public void ChangeSourceDetailSql(string Sql)
{
this.DetailSql = Sql;
}
}
}
@@ -54,10 +54,7 @@ namespace Lskj.PubBill.Model
/// 单据来源明细表格的明细
/// </summary>
public GridControlEx GridDetailDetailControlObj;
/// <summary>
/// 单据来源明细模块
/// </summary>
public ModuleGridEx GridDetailModuleGridEx;
public bool IsChange = false;
@@ -72,5 +69,18 @@ namespace Lskj.PubBill.Model
public string AddDataCondition;
/// <summary>
/// 单据来源明细模块
/// </summary>
public ModuleGridEx GridDetailModuleGridEx;
/// <summary>
/// 主表配置模块号的情况下,对应的明细选项
/// </summary>
public GridDetailModel GridDetailModel;
/// <summary>
/// 来源主表主键
/// </summary>
public string ParmaryKey;
}
}
+215
View File
@@ -0,0 +1,215 @@
namespace Lskj.PubBillManagement
{
partial class BillModule
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.barManager1 = new DevExpress.XtraBars.BarManager();
this.barDockControl1 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl2 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl3 = new DevExpress.XtraBars.BarDockControl();
this.barDockControl5 = new DevExpress.XtraBars.BarDockControl();
this.pmFP = new DevExpress.XtraBars.PopupMenu();
this.pmBillExp = new DevExpress.XtraBars.PopupMenu();
this.pmBill = new DevExpress.XtraBars.PopupMenu();
this.pMprint = new DevExpress.XtraBars.PopupMenu();
this.pMenu = new DevExpress.XtraBars.PopupMenu();
this.tb_buttom = new Lskj.Control.TabControlEx();
this.pl_Main = new DevExpress.XtraEditors.PanelControl();
this.xtc_main_container = new DevExpress.XtraTab.XtraTabControl();
this.ssc_main = new DevExpress.XtraEditors.SplitContainerControl();
((System.ComponentModel.ISupportInitialize)(this.barManager1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pmFP)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pmBillExp)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pmBill)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pMprint)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pMenu)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pl_Main)).BeginInit();
this.pl_Main.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.xtc_main_container)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ssc_main)).BeginInit();
this.ssc_main.SuspendLayout();
this.SuspendLayout();
//
// barManager1
//
this.barManager1.DockControls.Add(this.barDockControl1);
this.barManager1.DockControls.Add(this.barDockControl2);
this.barManager1.DockControls.Add(this.barDockControl3);
this.barManager1.DockControls.Add(this.barDockControl5);
this.barManager1.Form = this;
this.barManager1.MaxItemId = 0;
//
// barDockControl1
//
this.barDockControl1.CausesValidation = false;
this.barDockControl1.Dock = System.Windows.Forms.DockStyle.Top;
this.barDockControl1.Location = new System.Drawing.Point(0, 0);
this.barDockControl1.Size = new System.Drawing.Size(1511, 0);
//
// barDockControl2
//
this.barDockControl2.CausesValidation = false;
this.barDockControl2.Dock = System.Windows.Forms.DockStyle.Bottom;
this.barDockControl2.Location = new System.Drawing.Point(0, 730);
this.barDockControl2.Size = new System.Drawing.Size(1511, 0);
//
// barDockControl3
//
this.barDockControl3.CausesValidation = false;
this.barDockControl3.Dock = System.Windows.Forms.DockStyle.Left;
this.barDockControl3.Location = new System.Drawing.Point(0, 0);
this.barDockControl3.Size = new System.Drawing.Size(0, 730);
//
// barDockControl5
//
this.barDockControl5.CausesValidation = false;
this.barDockControl5.Dock = System.Windows.Forms.DockStyle.Right;
this.barDockControl5.Location = new System.Drawing.Point(1511, 0);
this.barDockControl5.Size = new System.Drawing.Size(0, 730);
//
// pmFP
//
this.pmFP.Manager = this.barManager1;
this.pmFP.Name = "pmFP";
//
// pmBillExp
//
this.pmBillExp.Manager = this.barManager1;
this.pmBillExp.Name = "pmBillExp";
//
// pmBill
//
this.pmBill.Manager = this.barManager1;
this.pmBill.Name = "pmBill";
//
// pMprint
//
this.pMprint.Manager = this.barManager1;
this.pMprint.Name = "pMprint";
//
// pMenu
//
this.pMenu.Manager = this.barManager1;
this.pMenu.Name = "pMenu";
//
// tb_buttom
//
this.tb_buttom.Dock = System.Windows.Forms.DockStyle.Fill;
this.tb_buttom.Location = new System.Drawing.Point(0, 0);
this.tb_buttom.Name = "tb_buttom";
this.tb_buttom.Size = new System.Drawing.Size(1511, 280);
this.tb_buttom.TabIndex = 25;
this.tb_buttom.Load += new System.EventHandler(this.tb_buttom_Load);
//
// pl_Main
//
this.pl_Main.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_Main.Appearance.Options.UseBackColor = true;
this.pl_Main.Controls.Add(this.xtc_main_container);
this.pl_Main.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_Main.Location = new System.Drawing.Point(0, 0);
this.pl_Main.Name = "pl_Main";
this.pl_Main.Size = new System.Drawing.Size(1511, 445);
this.pl_Main.TabIndex = 5;
//
// xtc_main_container
//
this.xtc_main_container.Appearance.BackColor = System.Drawing.Color.Transparent;
this.xtc_main_container.Appearance.Options.UseBackColor = true;
this.xtc_main_container.Dock = System.Windows.Forms.DockStyle.Fill;
this.xtc_main_container.HeaderLocation = DevExpress.XtraTab.TabHeaderLocation.Bottom;
this.xtc_main_container.Location = new System.Drawing.Point(2, 2);
this.xtc_main_container.Name = "xtc_main_container";
this.xtc_main_container.Size = new System.Drawing.Size(1507, 441);
this.xtc_main_container.TabIndex = 0;
this.xtc_main_container.SelectedPageChanged += new DevExpress.XtraTab.TabPageChangedEventHandler(this.OnTabSelectedPageChanged);
//
// ssc_main
//
this.ssc_main.Appearance.BackColor = System.Drawing.Color.Transparent;
this.ssc_main.Appearance.Options.UseBackColor = true;
this.ssc_main.CollapsePanel = DevExpress.XtraEditors.SplitCollapsePanel.Panel2;
this.ssc_main.Dock = System.Windows.Forms.DockStyle.Fill;
this.ssc_main.Horizontal = false;
this.ssc_main.Location = new System.Drawing.Point(0, 0);
this.ssc_main.Name = "ssc_main";
this.ssc_main.Panel1.Controls.Add(this.pl_Main);
this.ssc_main.Panel1.Text = "Panel1";
this.ssc_main.Panel2.Controls.Add(this.tb_buttom);
this.ssc_main.Panel2.Text = "Panel2";
this.ssc_main.Size = new System.Drawing.Size(1511, 730);
this.ssc_main.SplitterPosition = 445;
this.ssc_main.TabIndex = 0;
this.ssc_main.Text = "splitContainerControl1";
this.ssc_main.SplitterMoved += new System.EventHandler(this.OnMainSplitterMoved);
//
// BillModule
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Controls.Add(this.ssc_main);
this.Controls.Add(this.barDockControl3);
this.Controls.Add(this.barDockControl5);
this.Controls.Add(this.barDockControl2);
this.Controls.Add(this.barDockControl1);
this.Name = "BillModule";
this.Size = new System.Drawing.Size(1511, 730);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnFrmMainKeyDown);
((System.ComponentModel.ISupportInitialize)(this.barManager1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pmFP)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pmBillExp)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pmBill)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pMprint)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pMenu)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pl_Main)).EndInit();
this.pl_Main.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.xtc_main_container)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ssc_main)).EndInit();
this.ssc_main.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private DevExpress.XtraBars.PopupMenu pMenu;
private DevExpress.XtraBars.BarManager barManager1;
private DevExpress.XtraBars.BarDockControl barDockControl1;
private DevExpress.XtraBars.BarDockControl barDockControl2;
private DevExpress.XtraBars.BarDockControl barDockControl3;
private DevExpress.XtraBars.BarDockControl barDockControl5;
private DevExpress.XtraBars.PopupMenu pmBillExp;
private DevExpress.XtraBars.PopupMenu pmBill;
private DevExpress.XtraBars.PopupMenu pMprint;
private DevExpress.XtraBars.PopupMenu pmFP;
private DevExpress.XtraEditors.SplitContainerControl ssc_main;
private DevExpress.XtraEditors.PanelControl pl_Main;
private DevExpress.XtraTab.XtraTabControl xtc_main_container;
private Control.TabControlEx tb_buttom;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="barManager1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>642, 21</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>59</value>
</metadata>
<metadata name="pmFP.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1078, 23</value>
</metadata>
<metadata name="pmBillExp.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>873, 21</value>
</metadata>
<metadata name="pmBill.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>983, 21</value>
</metadata>
<metadata name="pMprint.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>773, 21</value>
</metadata>
<metadata name="pMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>548, 21</value>
</metadata>
</root>
@@ -0,0 +1,64 @@
/******************************
*
*
* 2017-11-23
*
*
*
* 1.0.0.0
******************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lskj.Util;
using System.Windows.Forms;
using Lskj.Model;
using Lskj.Business;
using Lskj.Business.Impl;
using System.Collections;
namespace Lskj.PubBillManagement
{
/// <summary>
/// 单据模版入口
/// </summary>
public class DllBaseClass : IForm
{
public DllBaseClass()
{
}
public DllBaseClass(string[] obj)
{
try
{
FrmMain main = new FrmMain();
DynamicBillModel moduleModel = new DynamicBillModel(obj);
main.SysModel = moduleModel;
moduleModel.DataCaches = new Dictionary<object, Hashtable>();
if (SystemInfo.Instance.OptimizationSpeed) main.GetDataCaches(moduleModel.DataCaches);
GridEnum gridEnum = GridEnum.GridView;
if (!moduleModel.DataCaches.GetValue(main, "FormType", out int formType))
{
formType = BaseImpl.GetBillDetailType(moduleModel.ModuleCode);
}
if (formType == 1)
{
gridEnum = GridEnum.BandedGridView;
}
main.SysModel.GridEnumObj = gridEnum;
this.SubForm = main;
}
catch (Exception ex)
{
LogUtil.WriteError("Lskj.PubBillManagement.dll--参数错误-->" + obj.ToString(), ex);
}
}
public Form SubForm { get; set; }
}
}
+81
View File
@@ -0,0 +1,81 @@

namespace Lskj.PubBillManagement
{
partial class FrmAdd
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.txtEdit = new DevExpress.XtraEditors.TextEdit();
this.label1 = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.txtEdit.Properties)).BeginInit();
this.SuspendLayout();
//
// txtEdit
//
this.txtEdit.EditValue = "1";
this.txtEdit.Location = new System.Drawing.Point(12, 39);
this.txtEdit.Name = "txtEdit";
this.txtEdit.Properties.Appearance.Font = new System.Drawing.Font("微软雅黑", 12F);
this.txtEdit.Properties.Appearance.Options.UseFont = true;
this.txtEdit.Size = new System.Drawing.Size(198, 28);
this.txtEdit.TabIndex = 25;
this.txtEdit.KeyDown += new System.Windows.Forms.KeyEventHandler(this.txtEdit_KeyDown);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(10, 14);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(77, 12);
this.label1.TabIndex = 22;
this.label1.Text = "请输入数量:";
//
// FrmAddRole
//
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.Appearance.Options.UseBackColor = true;
this.Appearance.Options.UseFont = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(219, 96);
this.Controls.Add(this.txtEdit);
this.Controls.Add(this.label1);
this.Margin = new System.Windows.Forms.Padding(2);
this.Name = "FrmAddRole";
this.Text = "";
((System.ComponentModel.ISupportInitialize)(this.txtEdit.Properties)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private DevExpress.XtraEditors.TextEdit txtEdit;
private System.Windows.Forms.Label label1;
}
}
+112
View File
@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lskj.Control;
using Lskj.Business;
using Lskj.Business.Impl;
namespace Lskj.PubBillManagement
{
public partial class FrmAdd : BaseForm
{
public int Quantity;
public Label LabelObj { get { return label1; } }
public FrmAdd()
{
InitializeComponent();
}
/// <summary>
/// <para>说明:确定事件</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2019-06-21 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnBtnOKClick(object sender, EventArgs e)
{
try
{
string text=this.txtEdit.Text;
if (string.IsNullOrWhiteSpace(text)) text = "0";
if (!this.IsDigitsOnly(text))
{
MessageUtil.Show("请输入数字");
}
this.Quantity = int.Parse(text);
this.Close();
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
catch (Exception ex)
{
LogUtil.WriteError("确定事件出错!", ex);
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
/// <summary>
/// <para>说明:取消事件</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2019-06-21 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnBtnCancelClick(object sender, EventArgs e)
{
this.Close();
}
bool IsDigitsOnly(string input)
{
foreach (char c in input)
{
if (!char.IsDigit(c))
return false;
}
return true;
}
private void txtEdit_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
string text = this.txtEdit.Text;
if (string.IsNullOrWhiteSpace(text)) return;
if (!this.IsDigitsOnly(text))
{
MessageUtil.Show("请输入数字");
}
if (int.Parse(text) > 0)
{
this.Quantity = int.Parse(text);
this.Close();
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
else
{
MessageUtil.Show("请检查输入数量");
}
}
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+639
View File
@@ -0,0 +1,639 @@

namespace Lskj.PubBillManagement
{
partial class FrmBill
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pl_main = new DevExpress.XtraEditors.PanelControl();
this.pl_main_center = new DevExpress.XtraEditors.PanelControl();
this.pl_main_center_detail = new DevExpress.XtraEditors.PanelControl();
this.gcMain = new Lskj.Control.GridControlEx();
this.pl_main_center_master = new DevExpress.XtraEditors.XtraScrollableControl();
this.pl_main_bottom = new DevExpress.XtraEditors.PanelControl();
this.dbpFP = new DevExpress.XtraEditors.DropDownButton();
this.btnRefresh = new DevExpress.XtraEditors.SimpleButton();
this.btnHiding = new DevExpress.XtraEditors.SimpleButton();
this.btnHelp = new DevExpress.XtraEditors.SimpleButton();
this.pl_templete = new DevExpress.XtraEditors.PanelControl();
this.cb_templete = new DevExpress.XtraEditors.ComboBoxEdit();
this.lbl_templete = new DevExpress.XtraEditors.LabelControl();
this.pl_input = new DevExpress.XtraEditors.PanelControl();
this.cb_input = new DevExpress.XtraEditors.ComboBoxEdit();
this.txt_input = new DevExpress.XtraEditors.TextEdit();
this.labelControl2 = new DevExpress.XtraEditors.LabelControl();
this.btn_input = new DevExpress.XtraEditors.SimpleButton();
this.dpbImport = new DevExpress.XtraEditors.DropDownButton();
this.btnBillAdd = new DevExpress.XtraEditors.SimpleButton();
this.btnBillApply = new DevExpress.XtraEditors.SimpleButton();
this.dpCopyBill = new DevExpress.XtraEditors.DropDownButton();
this.btnPrint = new DevExpress.XtraEditors.DropDownButton();
this.dpbTools = new DevExpress.XtraEditors.DropDownButton();
this.btnDelete = new DevExpress.XtraEditors.SimpleButton();
this.btnBillSave = new DevExpress.XtraEditors.SimpleButton();
this.pl_main_top = new DevExpress.XtraEditors.PanelControl();
this.pl_main_top_center = new DevExpress.XtraEditors.PanelControl();
this.lbTitle = new System.Windows.Forms.Label();
this.pl_main_top_right = new DevExpress.XtraEditors.PanelControl();
this.lblOrderNo = new DevExpress.XtraEditors.LabelControl();
this.labelControl1 = new DevExpress.XtraEditors.LabelControl();
this.pl_main_top_left = new DevExpress.XtraEditors.PanelControl();
this.pl_red = new DevExpress.XtraEditors.PanelControl();
this.rdRed = new System.Windows.Forms.RadioButton();
this.pl_blue = new DevExpress.XtraEditors.PanelControl();
this.rdBlue = new System.Windows.Forms.RadioButton();
((System.ComponentModel.ISupportInitialize)(this.pl_main)).BeginInit();
this.pl_main.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_center)).BeginInit();
this.pl_main_center.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_center_detail)).BeginInit();
this.pl_main_center_detail.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_bottom)).BeginInit();
this.pl_main_bottom.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_templete)).BeginInit();
this.pl_templete.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.cb_templete.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pl_input)).BeginInit();
this.pl_input.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.cb_input.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.txt_input.Properties)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top)).BeginInit();
this.pl_main_top.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_center)).BeginInit();
this.pl_main_top_center.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_right)).BeginInit();
this.pl_main_top_right.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_left)).BeginInit();
this.pl_main_top_left.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_red)).BeginInit();
this.pl_red.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_blue)).BeginInit();
this.pl_blue.SuspendLayout();
this.SuspendLayout();
//
// pl_main
//
this.pl_main.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main.Appearance.Options.UseBackColor = true;
this.pl_main.Controls.Add(this.pl_main_center);
this.pl_main.Controls.Add(this.pl_main_bottom);
this.pl_main.Controls.Add(this.pl_main_top);
this.pl_main.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_main.Location = new System.Drawing.Point(0, 0);
this.pl_main.Name = "pl_main";
this.pl_main.Size = new System.Drawing.Size(1260, 613);
this.pl_main.TabIndex = 2;
//
// pl_main_center
//
this.pl_main_center.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_center.Appearance.Options.UseBackColor = true;
this.pl_main_center.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_center.Controls.Add(this.pl_main_center_detail);
this.pl_main_center.Controls.Add(this.pl_main_center_master);
this.pl_main_center.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_main_center.Location = new System.Drawing.Point(2, 40);
this.pl_main_center.Name = "pl_main_center";
this.pl_main_center.Size = new System.Drawing.Size(1256, 534);
this.pl_main_center.TabIndex = 2;
//
// pl_main_center_detail
//
this.pl_main_center_detail.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_center_detail.Appearance.Options.UseBackColor = true;
this.pl_main_center_detail.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_center_detail.Controls.Add(this.gcMain);
this.pl_main_center_detail.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_main_center_detail.Location = new System.Drawing.Point(0, 164);
this.pl_main_center_detail.Name = "pl_main_center_detail";
this.pl_main_center_detail.Size = new System.Drawing.Size(1256, 370);
this.pl_main_center_detail.TabIndex = 5;
//
// gcMain
//
this.gcMain.AdapterObj = null;
this.gcMain.BackColor = System.Drawing.Color.Transparent;
this.gcMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.gcMain.Location = new System.Drawing.Point(0, 0);
this.gcMain.Margin = new System.Windows.Forms.Padding(5);
this.gcMain.Name = "gcMain";
this.gcMain.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gcMain.Size = new System.Drawing.Size(1256, 370);
this.gcMain.SysModel = null;
this.gcMain.TabIndex = 0;
//
// pl_main_center_master
//
this.pl_main_center_master.AutoScroll = false;
this.pl_main_center_master.Dock = System.Windows.Forms.DockStyle.Top;
this.pl_main_center_master.Location = new System.Drawing.Point(0, 0);
this.pl_main_center_master.Name = "pl_main_center_master";
this.pl_main_center_master.Size = new System.Drawing.Size(1256, 164);
this.pl_main_center_master.TabIndex = 6;
//
// pl_main_bottom
//
this.pl_main_bottom.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_bottom.Appearance.Options.UseBackColor = true;
this.pl_main_bottom.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_bottom.Controls.Add(this.dbpFP);
this.pl_main_bottom.Controls.Add(this.btnRefresh);
this.pl_main_bottom.Controls.Add(this.btnHiding);
this.pl_main_bottom.Controls.Add(this.btnHelp);
this.pl_main_bottom.Controls.Add(this.pl_templete);
this.pl_main_bottom.Controls.Add(this.pl_input);
this.pl_main_bottom.Controls.Add(this.dpbImport);
this.pl_main_bottom.Controls.Add(this.btnBillAdd);
this.pl_main_bottom.Controls.Add(this.btnBillApply);
this.pl_main_bottom.Controls.Add(this.dpCopyBill);
this.pl_main_bottom.Controls.Add(this.btnPrint);
this.pl_main_bottom.Controls.Add(this.dpbTools);
this.pl_main_bottom.Controls.Add(this.btnDelete);
this.pl_main_bottom.Controls.Add(this.btnBillSave);
this.pl_main_bottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pl_main_bottom.Location = new System.Drawing.Point(2, 574);
this.pl_main_bottom.Name = "pl_main_bottom";
this.pl_main_bottom.Size = new System.Drawing.Size(1256, 37);
this.pl_main_bottom.TabIndex = 1;
//
// dbpFP
//
this.dbpFP.AllowFocus = false;
this.dbpFP.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.dbpFP.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dbpFP.Appearance.Options.UseFont = true;
this.dbpFP.Location = new System.Drawing.Point(395, 7);
this.dbpFP.Name = "dbpFP";
this.dbpFP.Size = new System.Drawing.Size(58, 26);
this.dbpFP.TabIndex = 34;
this.dbpFP.Text = "分配";
//
// btnRefresh
//
this.btnRefresh.AllowFocus = false;
this.btnRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnRefresh.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnRefresh.Appearance.Options.UseFont = true;
this.btnRefresh.Location = new System.Drawing.Point(459, 7);
this.btnRefresh.Name = "btnRefresh";
this.btnRefresh.Size = new System.Drawing.Size(74, 26);
this.btnRefresh.TabIndex = 33;
this.btnRefresh.Text = "刷新列数据";
//
// btnHiding
//
this.btnHiding.AllowFocus = false;
this.btnHiding.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnHiding.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnHiding.Appearance.Options.UseFont = true;
this.btnHiding.Location = new System.Drawing.Point(535, 7);
this.btnHiding.Name = "btnHiding";
this.btnHiding.Size = new System.Drawing.Size(67, 26);
this.btnHiding.TabIndex = 32;
this.btnHiding.Text = "隐藏主表";
this.btnHiding.Visible = false;
//
// btnHelp
//
this.btnHelp.AllowFocus = false;
this.btnHelp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnHelp.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnHelp.Appearance.Options.UseFont = true;
this.btnHelp.Location = new System.Drawing.Point(604, 7);
this.btnHelp.Name = "btnHelp";
this.btnHelp.Size = new System.Drawing.Size(67, 26);
this.btnHelp.TabIndex = 30;
this.btnHelp.Text = "帮助文档";
//
// pl_templete
//
this.pl_templete.Controls.Add(this.cb_templete);
this.pl_templete.Controls.Add(this.lbl_templete);
this.pl_templete.Location = new System.Drawing.Point(3, 3);
this.pl_templete.LookAndFeel.SkinName = "VS2010";
this.pl_templete.LookAndFeel.Style = DevExpress.LookAndFeel.LookAndFeelStyle.Style3D;
this.pl_templete.Name = "pl_templete";
this.pl_templete.Size = new System.Drawing.Size(195, 29);
this.pl_templete.TabIndex = 29;
this.pl_templete.Visible = false;
//
// cb_templete
//
this.cb_templete.Location = new System.Drawing.Point(58, 4);
this.cb_templete.Name = "cb_templete";
this.cb_templete.Properties.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
this.cb_templete.Properties.DropDownRows = 8;
this.cb_templete.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
this.cb_templete.Size = new System.Drawing.Size(133, 20);
this.cb_templete.TabIndex = 19;
//
// lbl_templete
//
this.lbl_templete.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lbl_templete.Location = new System.Drawing.Point(5, 8);
this.lbl_templete.Name = "lbl_templete";
this.lbl_templete.Size = new System.Drawing.Size(48, 12);
this.lbl_templete.TabIndex = 16;
this.lbl_templete.Text = "选择模版";
//
// pl_input
//
this.pl_input.Controls.Add(this.cb_input);
this.pl_input.Controls.Add(this.txt_input);
this.pl_input.Controls.Add(this.labelControl2);
this.pl_input.Controls.Add(this.btn_input);
this.pl_input.Location = new System.Drawing.Point(3, 3);
this.pl_input.LookAndFeel.SkinName = "VS2010";
this.pl_input.LookAndFeel.Style = DevExpress.LookAndFeel.LookAndFeelStyle.Style3D;
this.pl_input.Name = "pl_input";
this.pl_input.Size = new System.Drawing.Size(280, 29);
this.pl_input.TabIndex = 27;
this.pl_input.Visible = false;
//
// cb_input
//
this.cb_input.Location = new System.Drawing.Point(58, 4);
this.cb_input.Name = "cb_input";
this.cb_input.Properties.Buttons.AddRange(new DevExpress.XtraEditors.Controls.EditorButton[] {
new DevExpress.XtraEditors.Controls.EditorButton(DevExpress.XtraEditors.Controls.ButtonPredefines.Combo)});
this.cb_input.Properties.DropDownRows = 8;
this.cb_input.Properties.TextEditStyle = DevExpress.XtraEditors.Controls.TextEditStyles.DisableTextEditor;
this.cb_input.Size = new System.Drawing.Size(79, 20);
this.cb_input.TabIndex = 19;
//
// txt_input
//
this.txt_input.Location = new System.Drawing.Point(149, 4);
this.txt_input.Name = "txt_input";
this.txt_input.Properties.Appearance.Font = new System.Drawing.Font("宋体", 10.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.txt_input.Properties.Appearance.Options.UseFont = true;
this.txt_input.Size = new System.Drawing.Size(98, 20);
this.txt_input.TabIndex = 18;
//
// labelControl2
//
this.labelControl2.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelControl2.Location = new System.Drawing.Point(5, 8);
this.labelControl2.Name = "labelControl2";
this.labelControl2.Size = new System.Drawing.Size(48, 12);
this.labelControl2.TabIndex = 16;
this.labelControl2.Text = "快速录入";
//
// btn_input
//
this.btn_input.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btn_input.Appearance.Options.UseFont = true;
this.btn_input.Location = new System.Drawing.Point(249, 4);
this.btn_input.Name = "btn_input";
this.btn_input.Size = new System.Drawing.Size(27, 21);
this.btn_input.TabIndex = 13;
this.btn_input.Text = ">>";
//
// dpbImport
//
this.dpbImport.AllowFocus = false;
this.dpbImport.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.dpbImport.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dpbImport.Appearance.Options.UseFont = true;
this.dpbImport.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
this.dpbImport.Location = new System.Drawing.Point(749, 7);
this.dpbImport.Name = "dpbImport";
this.dpbImport.Size = new System.Drawing.Size(74, 26);
this.dpbImport.TabIndex = 26;
this.dpbImport.Text = "导入导出";
//
// btnBillAdd
//
this.btnBillAdd.AllowFocus = false;
this.btnBillAdd.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnBillAdd.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnBillAdd.Appearance.Options.UseFont = true;
this.btnBillAdd.Location = new System.Drawing.Point(901, 7);
this.btnBillAdd.Name = "btnBillAdd";
this.btnBillAdd.Size = new System.Drawing.Size(67, 26);
this.btnBillAdd.TabIndex = 19;
this.btnBillAdd.Text = "新建单据";
//
// btnBillApply
//
this.btnBillApply.AllowFocus = false;
this.btnBillApply.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnBillApply.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnBillApply.Appearance.Options.UseFont = true;
this.btnBillApply.Location = new System.Drawing.Point(1108, 7);
this.btnBillApply.Name = "btnBillApply";
this.btnBillApply.Size = new System.Drawing.Size(67, 26);
this.btnBillApply.TabIndex = 25;
this.btnBillApply.Text = "保存提交";
//
// dpCopyBill
//
this.dpCopyBill.AllowFocus = false;
this.dpCopyBill.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.dpCopyBill.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dpCopyBill.Appearance.Options.UseFont = true;
this.dpCopyBill.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
this.dpCopyBill.Location = new System.Drawing.Point(825, 7);
this.dpCopyBill.Name = "dpCopyBill";
this.dpCopyBill.Size = new System.Drawing.Size(74, 26);
this.dpCopyBill.TabIndex = 24;
this.dpCopyBill.Text = "复制单据";
//
// btnPrint
//
this.btnPrint.AllowFocus = false;
this.btnPrint.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnPrint.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnPrint.Appearance.Options.UseFont = true;
this.btnPrint.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
this.btnPrint.Location = new System.Drawing.Point(1177, 7);
this.btnPrint.Name = "btnPrint";
this.btnPrint.Size = new System.Drawing.Size(74, 26);
this.btnPrint.TabIndex = 23;
this.btnPrint.Text = "打印单据";
//
// dpbTools
//
this.dpbTools.AllowFocus = false;
this.dpbTools.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.dpbTools.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.dpbTools.Appearance.Options.UseFont = true;
this.dpbTools.DropDownArrowStyle = DevExpress.XtraEditors.DropDownArrowStyle.Show;
this.dpbTools.Location = new System.Drawing.Point(673, 7);
this.dpbTools.Name = "dpbTools";
this.dpbTools.Size = new System.Drawing.Size(74, 26);
this.dpbTools.TabIndex = 22;
this.dpbTools.Text = "常用工具";
//
// btnDelete
//
this.btnDelete.AllowFocus = false;
this.btnDelete.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnDelete.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnDelete.Appearance.Options.UseFont = true;
this.btnDelete.Location = new System.Drawing.Point(970, 7);
this.btnDelete.Name = "btnDelete";
this.btnDelete.Size = new System.Drawing.Size(67, 26);
this.btnDelete.TabIndex = 20;
this.btnDelete.Text = "删除记录";
//
// btnBillSave
//
this.btnBillSave.AllowFocus = false;
this.btnBillSave.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnBillSave.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnBillSave.Appearance.Options.UseFont = true;
this.btnBillSave.Location = new System.Drawing.Point(1039, 7);
this.btnBillSave.Name = "btnBillSave";
this.btnBillSave.Size = new System.Drawing.Size(67, 26);
this.btnBillSave.TabIndex = 21;
this.btnBillSave.Text = "保存单据";
//
// pl_main_top
//
this.pl_main_top.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.pl_main_top.Appearance.Options.UseBackColor = true;
this.pl_main_top.Controls.Add(this.pl_main_top_center);
this.pl_main_top.Controls.Add(this.pl_main_top_right);
this.pl_main_top.Controls.Add(this.pl_main_top_left);
this.pl_main_top.Dock = System.Windows.Forms.DockStyle.Top;
this.pl_main_top.Location = new System.Drawing.Point(2, 2);
this.pl_main_top.Name = "pl_main_top";
this.pl_main_top.Size = new System.Drawing.Size(1256, 38);
this.pl_main_top.TabIndex = 0;
//
// pl_main_top_center
//
this.pl_main_top_center.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_top_center.Appearance.Options.UseBackColor = true;
this.pl_main_top_center.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_top_center.Controls.Add(this.lbTitle);
this.pl_main_top_center.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_main_top_center.Location = new System.Drawing.Point(162, 2);
this.pl_main_top_center.Name = "pl_main_top_center";
this.pl_main_top_center.Size = new System.Drawing.Size(902, 34);
this.pl_main_top_center.TabIndex = 3;
//
// lbTitle
//
this.lbTitle.BackColor = System.Drawing.Color.Transparent;
this.lbTitle.Dock = System.Windows.Forms.DockStyle.Fill;
this.lbTitle.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.lbTitle.ForeColor = System.Drawing.Color.Blue;
this.lbTitle.Location = new System.Drawing.Point(0, 0);
this.lbTitle.Name = "lbTitle";
this.lbTitle.Size = new System.Drawing.Size(902, 34);
this.lbTitle.TabIndex = 1;
this.lbTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// pl_main_top_right
//
this.pl_main_top_right.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_top_right.Appearance.Options.UseBackColor = true;
this.pl_main_top_right.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_top_right.Controls.Add(this.lblOrderNo);
this.pl_main_top_right.Controls.Add(this.labelControl1);
this.pl_main_top_right.Dock = System.Windows.Forms.DockStyle.Right;
this.pl_main_top_right.Location = new System.Drawing.Point(1064, 2);
this.pl_main_top_right.Name = "pl_main_top_right";
this.pl_main_top_right.Size = new System.Drawing.Size(190, 34);
this.pl_main_top_right.TabIndex = 2;
//
// lblOrderNo
//
this.lblOrderNo.Appearance.BackColor = System.Drawing.Color.Transparent;
this.lblOrderNo.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Underline);
this.lblOrderNo.Appearance.ForeColor = System.Drawing.Color.Blue;
this.lblOrderNo.Location = new System.Drawing.Point(67, 19);
this.lblOrderNo.Name = "lblOrderNo";
this.lblOrderNo.Size = new System.Drawing.Size(90, 12);
this.lblOrderNo.TabIndex = 1;
this.lblOrderNo.Text = "XTC170112010001";
//
// labelControl1
//
this.labelControl1.Appearance.BackColor = System.Drawing.Color.Transparent;
this.labelControl1.Appearance.Font = new System.Drawing.Font("宋体", 9F);
this.labelControl1.Appearance.ForeColor = System.Drawing.Color.Blue;
this.labelControl1.Location = new System.Drawing.Point(7, 19);
this.labelControl1.Name = "labelControl1";
this.labelControl1.Size = new System.Drawing.Size(54, 12);
this.labelControl1.TabIndex = 0;
this.labelControl1.Text = "单据编号:";
//
// pl_main_top_left
//
this.pl_main_top_left.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main_top_left.Appearance.Options.UseBackColor = true;
this.pl_main_top_left.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main_top_left.Controls.Add(this.pl_red);
this.pl_main_top_left.Controls.Add(this.pl_blue);
this.pl_main_top_left.Dock = System.Windows.Forms.DockStyle.Left;
this.pl_main_top_left.Location = new System.Drawing.Point(2, 2);
this.pl_main_top_left.Name = "pl_main_top_left";
this.pl_main_top_left.Size = new System.Drawing.Size(160, 34);
this.pl_main_top_left.TabIndex = 1;
//
// pl_red
//
this.pl_red.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_red.Appearance.Options.UseBackColor = true;
this.pl_red.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_red.Controls.Add(this.rdRed);
this.pl_red.Dock = System.Windows.Forms.DockStyle.Left;
this.pl_red.Location = new System.Drawing.Point(80, 0);
this.pl_red.Name = "pl_red";
this.pl_red.Size = new System.Drawing.Size(80, 34);
this.pl_red.TabIndex = 3;
//
// rdRed
//
this.rdRed.AutoSize = true;
this.rdRed.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.rdRed.ForeColor = System.Drawing.Color.Red;
this.rdRed.Location = new System.Drawing.Point(6, 12);
this.rdRed.Name = "rdRed";
this.rdRed.Size = new System.Drawing.Size(71, 16);
this.rdRed.TabIndex = 3;
this.rdRed.Text = "红字单据";
this.rdRed.UseVisualStyleBackColor = true;
//
// pl_blue
//
this.pl_blue.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_blue.Appearance.Options.UseBackColor = true;
this.pl_blue.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_blue.Controls.Add(this.rdBlue);
this.pl_blue.Dock = System.Windows.Forms.DockStyle.Left;
this.pl_blue.Location = new System.Drawing.Point(0, 0);
this.pl_blue.Name = "pl_blue";
this.pl_blue.Size = new System.Drawing.Size(80, 34);
this.pl_blue.TabIndex = 2;
//
// rdBlue
//
this.rdBlue.AutoSize = true;
this.rdBlue.Checked = true;
this.rdBlue.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.rdBlue.ForeColor = System.Drawing.Color.Blue;
this.rdBlue.Location = new System.Drawing.Point(7, 12);
this.rdBlue.Name = "rdBlue";
this.rdBlue.Size = new System.Drawing.Size(71, 16);
this.rdBlue.TabIndex = 2;
this.rdBlue.TabStop = true;
this.rdBlue.Text = "蓝字单据";
this.rdBlue.UseVisualStyleBackColor = true;
//
// FrmBill
//
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.Appearance.Options.UseBackColor = true;
this.Appearance.Options.UseFont = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1260, 613);
this.Controls.Add(this.pl_main);
this.Name = "FrmBill";
this.Text = "FrmBill";
((System.ComponentModel.ISupportInitialize)(this.pl_main)).EndInit();
this.pl_main.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main_center)).EndInit();
this.pl_main_center.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main_center_detail)).EndInit();
this.pl_main_center_detail.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main_bottom)).EndInit();
this.pl_main_bottom.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_templete)).EndInit();
this.pl_templete.ResumeLayout(false);
this.pl_templete.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.cb_templete.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pl_input)).EndInit();
this.pl_input.ResumeLayout(false);
this.pl_input.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.cb_input.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.txt_input.Properties)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top)).EndInit();
this.pl_main_top.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_center)).EndInit();
this.pl_main_top_center.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_right)).EndInit();
this.pl_main_top_right.ResumeLayout(false);
this.pl_main_top_right.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main_top_left)).EndInit();
this.pl_main_top_left.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_red)).EndInit();
this.pl_red.ResumeLayout(false);
this.pl_red.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_blue)).EndInit();
this.pl_blue.ResumeLayout(false);
this.pl_blue.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private DevExpress.XtraEditors.PanelControl pl_main;
private DevExpress.XtraEditors.PanelControl pl_main_center;
private DevExpress.XtraEditors.PanelControl pl_main_center_detail;
private Control.GridControlEx gcMain;
private DevExpress.XtraEditors.XtraScrollableControl pl_main_center_master;
public DevExpress.XtraEditors.PanelControl pl_main_bottom;
private DevExpress.XtraEditors.DropDownButton dbpFP;
private DevExpress.XtraEditors.SimpleButton btnRefresh;
private DevExpress.XtraEditors.SimpleButton btnHiding;
private DevExpress.XtraEditors.SimpleButton btnHelp;
private DevExpress.XtraEditors.PanelControl pl_templete;
private DevExpress.XtraEditors.ComboBoxEdit cb_templete;
private DevExpress.XtraEditors.LabelControl lbl_templete;
private DevExpress.XtraEditors.PanelControl pl_input;
private DevExpress.XtraEditors.ComboBoxEdit cb_input;
private DevExpress.XtraEditors.TextEdit txt_input;
private DevExpress.XtraEditors.LabelControl labelControl2;
private DevExpress.XtraEditors.SimpleButton btn_input;
private DevExpress.XtraEditors.DropDownButton dpbImport;
private DevExpress.XtraEditors.SimpleButton btnBillAdd;
private DevExpress.XtraEditors.SimpleButton btnBillApply;
private DevExpress.XtraEditors.DropDownButton dpCopyBill;
private DevExpress.XtraEditors.DropDownButton btnPrint;
private DevExpress.XtraEditors.DropDownButton dpbTools;
private DevExpress.XtraEditors.SimpleButton btnDelete;
private DevExpress.XtraEditors.SimpleButton btnBillSave;
private DevExpress.XtraEditors.PanelControl pl_main_top;
private DevExpress.XtraEditors.PanelControl pl_main_top_center;
private System.Windows.Forms.Label lbTitle;
private DevExpress.XtraEditors.PanelControl pl_main_top_right;
private DevExpress.XtraEditors.LabelControl lblOrderNo;
private DevExpress.XtraEditors.LabelControl labelControl1;
private DevExpress.XtraEditors.PanelControl pl_main_top_left;
private DevExpress.XtraEditors.PanelControl pl_red;
private System.Windows.Forms.RadioButton rdRed;
private DevExpress.XtraEditors.PanelControl pl_blue;
private System.Windows.Forms.RadioButton rdBlue;
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+196
View File
@@ -0,0 +1,196 @@
namespace Lskj.PubBillManagement
{
partial class FrmBomSelect
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panelControl1 = new DevExpress.XtraEditors.PanelControl();
this.pl_main = new DevExpress.XtraEditors.PanelControl();
this.gcMain = new Lskj.Control.GridControlEx();
this.pl_bottom = new DevExpress.XtraEditors.PanelControl();
this.chkOperate = new DevExpress.XtraEditors.CheckEdit();
this.btnClearSelectAll = new DevExpress.XtraEditors.SimpleButton();
this.btnCancel = new DevExpress.XtraEditors.SimpleButton();
this.btnSelectAll = new DevExpress.XtraEditors.SimpleButton();
this.btnOk = new DevExpress.XtraEditors.SimpleButton();
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).BeginInit();
this.panelControl1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_main)).BeginInit();
this.pl_main.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).BeginInit();
this.pl_bottom.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.chkOperate.Properties)).BeginInit();
this.SuspendLayout();
//
// panelControl1
//
this.panelControl1.Controls.Add(this.pl_main);
this.panelControl1.Controls.Add(this.pl_bottom);
this.panelControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelControl1.Location = new System.Drawing.Point(0, 0);
this.panelControl1.Name = "panelControl1";
this.panelControl1.Size = new System.Drawing.Size(515, 341);
this.panelControl1.TabIndex = 0;
//
// pl_main
//
this.pl_main.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_main.Appearance.Options.UseBackColor = true;
this.pl_main.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_main.Controls.Add(this.gcMain);
this.pl_main.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_main.Location = new System.Drawing.Point(2, 2);
this.pl_main.Name = "pl_main";
this.pl_main.Size = new System.Drawing.Size(511, 303);
this.pl_main.TabIndex = 1;
//
// gcMain
//
this.gcMain.AdapterObj = null;
this.gcMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.gcMain.Location = new System.Drawing.Point(0, 0);
this.gcMain.Name = "gcMain";
this.gcMain.Size = new System.Drawing.Size(511, 303);
this.gcMain.TabIndex = 0;
//
// pl_bottom
//
this.pl_bottom.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_bottom.Appearance.Options.UseBackColor = true;
this.pl_bottom.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_bottom.Controls.Add(this.chkOperate);
this.pl_bottom.Controls.Add(this.btnClearSelectAll);
this.pl_bottom.Controls.Add(this.btnCancel);
this.pl_bottom.Controls.Add(this.btnSelectAll);
this.pl_bottom.Controls.Add(this.btnOk);
this.pl_bottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.pl_bottom.Location = new System.Drawing.Point(2, 305);
this.pl_bottom.Name = "pl_bottom";
this.pl_bottom.Size = new System.Drawing.Size(511, 34);
this.pl_bottom.TabIndex = 0;
//
// chkOperate
//
this.chkOperate.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.chkOperate.Location = new System.Drawing.Point(250, 8);
this.chkOperate.Name = "chkOperate";
this.chkOperate.Properties.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.chkOperate.Properties.Appearance.Options.UseFont = true;
this.chkOperate.Properties.Caption = "应用到所有操作";
this.chkOperate.Size = new System.Drawing.Size(115, 19);
this.chkOperate.TabIndex = 28;
//
// btnClearSelectAll
//
this.btnClearSelectAll.AllowFocus = false;
this.btnClearSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnClearSelectAll.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnClearSelectAll.Appearance.Options.UseFont = true;
this.btnClearSelectAll.Location = new System.Drawing.Point(73, 4);
this.btnClearSelectAll.Name = "btnClearSelectAll";
this.btnClearSelectAll.Size = new System.Drawing.Size(67, 26);
this.btnClearSelectAll.TabIndex = 27;
this.btnClearSelectAll.Text = "反选(&N)";
this.btnClearSelectAll.Click += new System.EventHandler(this.OnClearSelectAllClick);
//
// btnCancel
//
this.btnCancel.AllowFocus = false;
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnCancel.Appearance.Options.UseFont = true;
this.btnCancel.Location = new System.Drawing.Point(440, 4);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(67, 26);
this.btnCancel.TabIndex = 27;
this.btnCancel.Text = "取消(&C)";
this.btnCancel.Click += new System.EventHandler(this.OnCancelButtonClick);
//
// btnSelectAll
//
this.btnSelectAll.AllowFocus = false;
this.btnSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.btnSelectAll.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnSelectAll.Appearance.Options.UseFont = true;
this.btnSelectAll.Location = new System.Drawing.Point(4, 4);
this.btnSelectAll.Name = "btnSelectAll";
this.btnSelectAll.Size = new System.Drawing.Size(67, 26);
this.btnSelectAll.TabIndex = 26;
this.btnSelectAll.Text = "全选(&Y)";
this.btnSelectAll.Click += new System.EventHandler(this.OnSelectAllClick);
//
// btnOk
//
this.btnOk.AllowFocus = false;
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnOk.Appearance.Options.UseFont = true;
this.btnOk.Location = new System.Drawing.Point(371, 4);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(67, 26);
this.btnOk.TabIndex = 26;
this.btnOk.Text = "确定(&S)";
this.btnOk.Click += new System.EventHandler(this.OnOkButtonClick);
//
// FrmBomSelect
//
this.Appearance.BackColor = System.Drawing.Color.Transparent;
this.Appearance.Options.UseBackColor = true;
this.Appearance.Options.UseFont = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(515, 341);
this.Controls.Add(this.panelControl1);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FrmBomSelect";
this.Text = "Bom选择";
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).EndInit();
this.panelControl1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_main)).EndInit();
this.pl_main.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_bottom)).EndInit();
this.pl_bottom.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.chkOperate.Properties)).EndInit();
this.ResumeLayout(false);
}
#endregion
private DevExpress.XtraEditors.PanelControl panelControl1;
private DevExpress.XtraEditors.PanelControl pl_main;
private DevExpress.XtraEditors.PanelControl pl_bottom;
private Control.GridControlEx gcMain;
private DevExpress.XtraEditors.SimpleButton btnCancel;
private DevExpress.XtraEditors.SimpleButton btnOk;
private DevExpress.XtraEditors.SimpleButton btnClearSelectAll;
private DevExpress.XtraEditors.SimpleButton btnSelectAll;
private DevExpress.XtraEditors.CheckEdit chkOperate;
}
}
@@ -0,0 +1,260 @@
/******************************
* Bom选择
*
* 2018-02-06
*
*
*
* 1.0.0.0
******************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lskj.Control;
using Lskj.Control.Model;
using Lskj.PubBillManagement.Model;
using Lskj.Business.Impl;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid;
using Lskj.Data;
namespace Lskj.PubBillManagement
{
/// <summary>
/// Bom选择
/// </summary>
public partial class FrmBomSelect : BaseForm
{
/// <summary>
/// 是否记住操作,后续不在弹出界面
/// </summary>
public bool OnlyPopup;
/// <summary>
/// 标题
/// </summary>
public string Caption;
/// <summary>
/// 选中的bom数据
/// </summary>
public DataRow[] SelectBomRows;
/// <summary>
/// The bom data table
/// </summary>
public DataTable BomDataTable;
/// <summary>
/// 单据明细表格列
/// </summary>
public GridColumnCollection GridColumns;
public FrmBomSelect()
{
InitializeComponent();
}
/// <summary>
/// <para>说明:窗口加载</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-06 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected override void OnLoad(EventArgs e)
{
try
{
base.OnLoad(e);
if (BomDataTable != null)
{
this.Text = string.IsNullOrEmpty(Caption) ? this.Text : this.Caption;
DataColumn dataColumn = new DataColumn("Id", typeof(bool));
dataColumn.DefaultValue = true;
this.BomDataTable.Columns.Add(dataColumn);
this.InitGridView();
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message,ex.Message);
}
}
/// <summary>
/// <para>说明:初始化表格控件</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="table">The table.</param>
private void InitGridView()
{
// 增加选择列
GridColumn gridColumn = new GridColumn();
gridColumn.FieldName = gridColumn.Name = "Id";
gridColumn.Caption = "选择";
gridColumn.Width = 50;
gridColumn.VisibleIndex = 1;
gridColumn.AppearanceHeader.TextOptions.HAlignment = DevExpress.Utils.HorzAlignment.Center;
gridColumn.Visible = true;
gcMain.GridView.Columns.Add(gridColumn);
// 添加其他列
foreach (GridColumn item in GridColumns)
{
GridColumn column = new GridColumn();
column.Caption = item.Caption;
column.FieldName = item.FieldName;
column.OptionsColumn.AllowEdit = false;
column.OptionsColumn.ReadOnly = true;
column.Width = item.Width;
column.VisibleIndex = item.VisibleIndex;
column.Visible = item.Visible;
gcMain.GridView.Columns.Add(column);
}
gcMain.SetGridViewDataSource(BomDataTable);
}
/// <summary>
/// <para>说明:获取选中数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <returns>DataRow[].</returns>
private DataRow[] GetSelectRows()
{
DataTable table = gcMain.GridControl.DataSourceTable();
return table.Select("Id = true").ToArray();
}
/// <summary>
/// <para>说明:全选</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnSelectAllClick(object sender, EventArgs e)
{
try
{
DataTable table = gcMain.GridControl.DataSourceTable();
foreach (DataRow item in table.Rows)
{
item["Id"] = true;
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message,ex.Message);
}
}
/// <summary>
/// <para>说明:反选</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnClearSelectAllClick(object sender, EventArgs e)
{
try
{
DataTable table = gcMain.GridControl.DataSourceTable();
foreach (DataRow item in table.Rows)
{
item["Id"] = false;
}
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message,ex.Message);
}
}
/// <summary>
/// <para>说明:确定</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnOkButtonClick(object sender, EventArgs e)
{
try
{
DataRow[] rows = GetSelectRows();
if (rows == null || rows.Length == 0)
{
MessageUtil.Show(ResourceKeys.SelectRowIsNull);
return;
}
this.SelectBomRows = rows;
this.OnlyPopup = chkOperate.Checked;
this.DialogResult = DialogResult.OK;
}
catch (Exception ex)
{
//MessageUtil.Show("确定事件出错!" + ex);
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message,ex.Message);
}
}
/// <summary>
/// <para>说明:取消</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-02-07 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void OnCancelButtonClick(object sender, EventArgs e)
{
try
{
this.DialogResult = DialogResult.Cancel;
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message,ex.Message);
}
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,245 @@

namespace Lskj.PubBillManagement
{
partial class FrmDocumentSource
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.splitMain = new DevExpress.XtraEditors.SplitContainerControl();
this.pl_left = new DevExpress.XtraEditors.PanelControl();
this.pl_left_main = new System.Windows.Forms.Panel();
this.pl_gridandtree_container = new DevExpress.XtraEditors.PanelControl();
this.treeLeft = new Lskj.Control.TreeViewEx();
this.gridLeft = new Lskj.Control.GridControlEx();
this.pl_left_top = new DevExpress.XtraEditors.PanelControl();
this.pl_top = new DevExpress.XtraEditors.PanelControl();
this.panelControl1 = new DevExpress.XtraEditors.PanelControl();
this.btnCancel = new DevExpress.XtraEditors.SimpleButton();
this.btnOk = new DevExpress.XtraEditors.SimpleButton();
this.gcMain = new Lskj.Control.GridControlEx();
((System.ComponentModel.ISupportInitialize)(this.splitMain)).BeginInit();
this.splitMain.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_left)).BeginInit();
this.pl_left.SuspendLayout();
this.pl_left_main.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_gridandtree_container)).BeginInit();
this.pl_gridandtree_container.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pl_left_top)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.pl_top)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).BeginInit();
this.panelControl1.SuspendLayout();
this.SuspendLayout();
//
// splitMain
//
this.splitMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitMain.Location = new System.Drawing.Point(0, 0);
this.splitMain.Margin = new System.Windows.Forms.Padding(4);
this.splitMain.Name = "splitMain";
this.splitMain.Panel1.Controls.Add(this.pl_left);
this.splitMain.Panel1.Text = "Panel1";
this.splitMain.Panel2.Controls.Add(this.gcMain);
this.splitMain.Panel2.Controls.Add(this.panelControl1);
this.splitMain.Panel2.Controls.Add(this.pl_top);
this.splitMain.Panel2.Text = "Panel2";
this.splitMain.Size = new System.Drawing.Size(800, 450);
this.splitMain.SplitterPosition = 260;
this.splitMain.TabIndex = 1;
this.splitMain.Text = "splitContainerControl1";
//
// pl_left
//
this.pl_left.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_left.Appearance.Options.UseBackColor = true;
this.pl_left.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_left.Controls.Add(this.pl_left_main);
this.pl_left.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_left.Location = new System.Drawing.Point(0, 0);
this.pl_left.Margin = new System.Windows.Forms.Padding(4);
this.pl_left.Name = "pl_left";
this.pl_left.Size = new System.Drawing.Size(260, 450);
this.pl_left.TabIndex = 1;
//
// pl_left_main
//
this.pl_left_main.BackColor = System.Drawing.Color.Transparent;
this.pl_left_main.Controls.Add(this.pl_gridandtree_container);
this.pl_left_main.Controls.Add(this.pl_left_top);
this.pl_left_main.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_left_main.Location = new System.Drawing.Point(0, 0);
this.pl_left_main.Margin = new System.Windows.Forms.Padding(4);
this.pl_left_main.Name = "pl_left_main";
this.pl_left_main.Size = new System.Drawing.Size(260, 450);
this.pl_left_main.TabIndex = 6;
//
// pl_gridandtree_container
//
this.pl_gridandtree_container.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_gridandtree_container.Controls.Add(this.treeLeft);
this.pl_gridandtree_container.Controls.Add(this.gridLeft);
this.pl_gridandtree_container.Dock = System.Windows.Forms.DockStyle.Fill;
this.pl_gridandtree_container.Location = new System.Drawing.Point(0, 45);
this.pl_gridandtree_container.Margin = new System.Windows.Forms.Padding(4);
this.pl_gridandtree_container.Name = "pl_gridandtree_container";
this.pl_gridandtree_container.Size = new System.Drawing.Size(260, 405);
this.pl_gridandtree_container.TabIndex = 9;
//
// treeLeft
//
this.treeLeft.Dock = System.Windows.Forms.DockStyle.Fill;
this.treeLeft.Location = new System.Drawing.Point(0, 0);
this.treeLeft.Margin = new System.Windows.Forms.Padding(4);
this.treeLeft.Name = "treeLeft";
this.treeLeft.Size = new System.Drawing.Size(260, 405);
this.treeLeft.TabIndex = 7;
this.treeLeft.Visible = false;
//
// gridLeft
//
this.gridLeft.AdapterObj = null;
this.gridLeft.BackColor = System.Drawing.SystemColors.Control;
this.gridLeft.Dock = System.Windows.Forms.DockStyle.Fill;
this.gridLeft.Location = new System.Drawing.Point(0, 0);
this.gridLeft.Margin = new System.Windows.Forms.Padding(5);
this.gridLeft.Name = "gridLeft";
this.gridLeft.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gridLeft.Size = new System.Drawing.Size(260, 405);
this.gridLeft.SysModel = null;
this.gridLeft.TabIndex = 6;
//
// pl_left_top
//
this.pl_left_top.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.pl_left_top.Appearance.Options.UseBackColor = true;
this.pl_left_top.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_left_top.Dock = System.Windows.Forms.DockStyle.Top;
this.pl_left_top.Location = new System.Drawing.Point(0, 0);
this.pl_left_top.Margin = new System.Windows.Forms.Padding(4);
this.pl_left_top.Name = "pl_left_top";
this.pl_left_top.Size = new System.Drawing.Size(260, 45);
this.pl_left_top.TabIndex = 8;
//
// pl_top
//
this.pl_top.Appearance.BackColor = System.Drawing.Color.Transparent;
this.pl_top.Appearance.Options.UseBackColor = true;
this.pl_top.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
this.pl_top.Dock = System.Windows.Forms.DockStyle.Top;
this.pl_top.Location = new System.Drawing.Point(0, 0);
this.pl_top.Name = "pl_top";
this.pl_top.Size = new System.Drawing.Size(535, 34);
this.pl_top.TabIndex = 13;
//
// panelControl1
//
this.panelControl1.Controls.Add(this.btnCancel);
this.panelControl1.Controls.Add(this.btnOk);
this.panelControl1.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelControl1.Location = new System.Drawing.Point(0, 403);
this.panelControl1.Margin = new System.Windows.Forms.Padding(4);
this.panelControl1.Name = "panelControl1";
this.panelControl1.Size = new System.Drawing.Size(535, 47);
this.panelControl1.TabIndex = 15;
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.Location = new System.Drawing.Point(441, 5);
this.btnCancel.Margin = new System.Windows.Forms.Padding(4);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(79, 35);
this.btnCancel.TabIndex = 24;
this.btnCancel.Text = "取消(&C)";
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Appearance.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.btnOk.Appearance.Options.UseFont = true;
this.btnOk.Location = new System.Drawing.Point(357, 5);
this.btnOk.Margin = new System.Windows.Forms.Padding(4);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(76, 35);
this.btnOk.TabIndex = 23;
this.btnOk.TabStop = false;
this.btnOk.Text = "确定(&O)";
//
// gcMain
//
this.gcMain.AdapterObj = null;
this.gcMain.BackColor = System.Drawing.Color.Transparent;
this.gcMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.gcMain.Location = new System.Drawing.Point(0, 34);
this.gcMain.Margin = new System.Windows.Forms.Padding(5);
this.gcMain.Name = "gcMain";
this.gcMain.SiftEnumObj = Lskj.Control.GridControlEx.HeaderSiftEnum.Sum;
this.gcMain.Size = new System.Drawing.Size(535, 369);
this.gcMain.SysModel = null;
this.gcMain.TabIndex = 16;
//
// FrmDocumentSource
//
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.Appearance.Options.UseBackColor = true;
this.Appearance.Options.UseFont = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.splitMain);
this.Name = "FrmDocumentSource";
this.Text = "FrmDocumentSource";
((System.ComponentModel.ISupportInitialize)(this.splitMain)).EndInit();
this.splitMain.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_left)).EndInit();
this.pl_left.ResumeLayout(false);
this.pl_left_main.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_gridandtree_container)).EndInit();
this.pl_gridandtree_container.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.pl_left_top)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.pl_top)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.panelControl1)).EndInit();
this.panelControl1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private DevExpress.XtraEditors.SplitContainerControl splitMain;
private DevExpress.XtraEditors.PanelControl pl_left;
private System.Windows.Forms.Panel pl_left_main;
private DevExpress.XtraEditors.PanelControl pl_gridandtree_container;
private Control.TreeViewEx treeLeft;
private Control.GridControlEx gridLeft;
private DevExpress.XtraEditors.PanelControl pl_left_top;
private Control.GridControlEx gcMain;
private DevExpress.XtraEditors.PanelControl panelControl1;
private DevExpress.XtraEditors.SimpleButton btnCancel;
private DevExpress.XtraEditors.SimpleButton btnOk;
private DevExpress.XtraEditors.PanelControl pl_top;
}
}
@@ -0,0 +1,601 @@
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Grid;
using Lskj.Business;
using Lskj.Business.Impl;
using Lskj.Control;
using Lskj.Control.Model;
using Lskj.Data;
using Lskj.Model;
using Lskj.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Lskj.PubBillManagement
{
public partial class FrmDocumentSource : BaseForm
{
/// <summary>
/// 配置的关联ModuleCodel值
/// </summary>
/// <value>The Union ModuleCodel.</value>
public string UnionModuleCodel;
/// <summary>
/// 左侧树数据
/// </summary>
public DataRow LeftRowObj;
/// <summary>
/// 系统模块实体对象
/// </summary>
/// <value>The system model.</value>
public ModuleModel SysModel { get; private set; }
/// <summary>
/// 自定义查询条件
/// </summary>
public MyControl SearchObj { get; private set; }
/// <summary>
/// 第一次进入
/// </summary>
private bool isFirst = true;
/// <summary>
/// 第一次进入
/// </summary>
private bool isFirstSearch = true;
/// <summary>
/// 左侧树结构
/// </summary>
public TreeViewEx LeftTreeViewEx;
/// <summary>
/// 左侧表格
/// </summary>
public GridControlEx LeftGridEx;
/// <summary>
/// 左侧结构关联字段
/// </summary>
public string ParentUnionField;
/// <summary>
/// 左侧树结构、表格主键
/// </summary>
public string ParentKeyField;
/// <summary>
/// CurrentOperColumnKey值(保存表格属性会用)
/// </summary>
/// <value>The data source.</value>
public string CurrentOperColumnKey = string.Empty;
/// <summary>
/// 左侧表格查询条件
/// </summary>
private MyControl _leftGridSearchObj;
/// <summary>
/// 返回行
/// </summary>
public DataRow[] DataRows = null;
public FrmDocumentSource(string ModuleCodel)
{
InitializeComponent();
this.UnionModuleCodel = ModuleCodel;
this.Disposed += new EventHandler(OnFrmModelLookUp_Disposed);
this.gcMain.GridView.OptionsBehavior.EditorShowMode = DevExpress.Utils.EditorShowMode.MouseDown;
DataRow modelRow = MainImpl.GetSystemdllTab(this.UnionModuleCodel);//获取单个模块信息
if (modelRow == null)
{
MessageUtil.Show("模块编号[" + UnionModuleCodel + "],配置错误!\r\n该模块信息未找到!");
return;
}
this.SysModel = new ModuleModel(modelRow);// 系统模块实体对象
//设置关联模块(左侧)
this.InitLeftControls();
//设置主表
this.InitMainControls();
this.btnCancel.Click += btnCancel_Click;
this.btnOk.Click += btnOk_Click;
}
/// <summary>
/// 初始化左侧表
/// </summary>
public void InitLeftControls()
{
if (this.SysModel != null)
{
switch (this.SysModel.MenuType)
{
case 1: // 左侧为树节点
this.pl_left_top.Visible = false;
this.gridLeft.Visible = false;
this.treeLeft.Visible = true;
this.InitlizeSpiltLocation();//设置分割条位置
this.SetLeftTreeView();//设置左侧树数据
this.LeftTreeViewEx = this.treeLeft;
break;
case 2: // 左侧为表格
this.gridLeft.Visible = true;
this.treeLeft.Visible = false;
this.InitlizeSpiltLocation();
this.SetLeftGridView();
this.LeftGridEx = this.gridLeft;
break;
case 3: // 左侧为空
default:
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
break;
}
}
else
{
this.splitMain.PanelVisibility = SplitPanelVisibility.Panel2;
}
}
/// <summary>
/// 初始化主表
/// </summary>
public void InitMainControls()
{
//设置上方条件
this.pl_top.Controls.Clear();
DataTable queryTable = BaseModuleImpl.GetCustomQueryFields(this.SysModel.CondKey);//加载自定义配置字段
this.SearchObj = new MyControl(this.SysModel.MenuSql, this.gcMain, LeftTreeViewEx, LeftGridEx);
this.SearchObj.ParentKeyField = this.ParentKeyField;
this.SearchObj.ParentUnionField = this.ParentUnionField;
this.SearchObj.OnDataSourceBindCallBack += new EventHandler(OnFirstPageDataSourceBindCallBack);
this.SearchObj.OnSearchAfterCallBack += new EventHandler(OnSearchAfterd);
this.pl_top.Height = 0;
this.pl_top.Height = this.SearchObj.InitSearchControl(queryTable, this.pl_top);
//创建表格列
DataTable _gridColumns = BaseModuleImpl.GetBaseGridColumns(this.UnionModuleCodel);
this.gcMain.SetReadOnlyColumns(_gridColumns, GridCustomColumnStruct.BaseMainGridView + this.SysModel.FormKey);
//this.SetCustomColumns();
//设置复选框
GridDragGrid.GridAddCheckBox(gcMain.GridView);
//右键
DataTable dt = BaseModuleImpl.GetBaseGridRightMenus(this.UnionModuleCodel);
string[] obj = new string[]{
"",
ERPInfo.Instance.UserId,
ERPInfo.Instance.UserName,
"3",
this.UnionModuleCodel,
}; ;
DynamicModel dynamicModel = new DynamicModel(obj);
this.gcMain.SetGridRightMenus(dt, dynamicModel, this.OnGridViewRightCallBack, this.SearchObj, null);
//this.gcMain.GridView.OptionsView.ColumnAutoWidth = true;
}
/// <summary>
/// 查询后清空复选框勾选
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnSearchAfterd(object sender, EventArgs e)
{
this.gcMain.GridView.ClearSelection();
}
/// <summary>
/// 初始化后默认查询
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnFirstPageDataSourceBindCallBack(object sender, EventArgs e)
{
//打开时默认选中第一条
if (LeftTreeViewEx != null && LeftTreeViewEx.TreeView.Nodes.Count > 0)
{
LeftTreeViewEx.TreeView.SelectedNode = LeftTreeViewEx.TreeView.Nodes[0];
LeftTreeViewEx.TreeView.Nodes[0].Expand();
}
else if (LeftGridEx != null)
{
LeftGridEx.GridView.SelectRow(0);
}
this.SearchObj.SearchGrid();
}
#region
/// <summary>
/// <para>说明:设置分割条位置</para>
/// <para>创建人:王一帆</para>
/// <para>创建日期:2021-07-21 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
protected void InitlizeSpiltLocation()
{
try
{
string width = IniHelper.Read(string.Format("bill_Special_Width_{0}", this.UnionModuleCodel));//通过Key获取Value值
if (!string.IsNullOrEmpty(width))
{
this.splitMain.SplitterPosition = Convert.ToInt32(width);
}
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
MessageUtil.Show(ex);
}
}
#endregion
#region
/// <summary>
/// <para>说明:保存表格属性</para>
/// <para>创建人:王一帆</para>
/// <para>创建日期:2021-07-20 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected virtual void SaveItemClick(object sender, EventArgs e)
{
DataRow rowItem = null;
bool success = BaseImpl.HasExistsDataRow(ResourceKeys.SettingTableName, "formKey", CurrentOperColumnKey, string.Format(" and OperatorId='{0}' ", ERPInfo.Instance.UserId), out rowItem);
if (!success)
{
MessageUtil.Show(ResourceKeys.NotFoundSettingColumnTable);
return;
}
if (MessageUtil.Show(ResourceKeys.IsSaveColumn, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
try
{
if (rowItem == null)
{
success = this.gcMain.GridView.SaveCustomColumnToDatabase(this.CurrentOperColumnKey);
}
else
{
success = this.gcMain.GridView.UpdateCustomColumnToDatabase(this.CurrentOperColumnKey);
}
MessageUtil.Show(success ? ResourceKeys.SaveSuccess : ResourceKeys.SaveFault);
}
catch (SqlException sex)
{
if (sex.Message.Contains(ResourceKeys.FieldLenIsShort) &&
MessageUtil.Show(ResourceKeys.SaveFault + "\r\n" + ResourceKeys.CanUpgradeTable, MessageBoxButtons.YesNo) == DialogResult.Yes &&
BaseImpl.UpdateTableField(ResourceKeys.SettingTableName, "formKey", "varchar(200)"))
{
MessageUtil.Show(ResourceKeys.UpdateSuccess);
}
}
catch (Exception ex)
{
LogHelper.Instance.WriteError(ex);
LogUtil.WriteError("保存表格属性出错", ex);
MessageUtil.Show(ex);
}
}
}
#endregion
#region
/// <summary>
/// <para>说明:加载自定义列</para>
/// <para>创建人:王一帆</para>
/// <para>创建日期:2019-9-16 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
private void SetCustomColumns()
{
if (string.IsNullOrEmpty(this.CurrentOperColumnKey) || !BaseImpl.HasExistsTable(ResourceKeys.SettingTableName)) return;
DataTable customTable = this.gcMain.GridView.GetCustomColumnByDatabase(this.CurrentOperColumnKey);
if (customTable != null && customTable.Rows.Count > 0)
{
foreach (DataRow rowItem in customTable.Rows)
{
string fieldName = rowItem["fieldName"] + "";
int fieldWidth = Convert.ToInt32(rowItem["fieldWidth"]);
int index = Convert.ToInt32(rowItem["orderid"]);
bool visible = "1".Equals(rowItem["isVisible"] + "") && fieldWidth > 0;
bool isFix = "True".Equals(rowItem["IfFixColumn"] + "", StringComparison.OrdinalIgnoreCase);
GridColumn gridColumn = this.gcMain.GridView.Columns.ColumnByName(fieldName);
if (gridColumn != null && gridColumn.Visible && gridColumn.Width > 0)
{
GridColumn colObj = this.gcMain.GridView.Columns[fieldName];
colObj.VisibleIndex = index;
colObj.Width = fieldWidth;
colObj.Visible = visible;
colObj.Fixed = isFix ? FixedStyle.Left : FixedStyle.None;
}
}
}
}
#endregion
#region
/// <summary>
/// <para>说明:设置左侧树数据</para>
/// <para>创建人:王一帆</para>
/// <para>创建日期:2021-07-21 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
protected void SetLeftTreeView()
{
this.LeftRowObj = BaseModuleImpl.GetBaseLeftTreeField(this.UnionModuleCodel);//获取表格左侧树字段
if (this.LeftRowObj != null)
{
//this.ModuleGridObj.ParentUnionField = this.LeftRowObj["fieldname"] + "";
this.ParentUnionField = this.LeftRowObj["fieldname"] + "";
this.ParentKeyField = this.LeftRowObj["fieldsqlid"] + "";
this.treeLeft.TreeNodeKeyField = this.LeftRowObj["fieldsqlid"] + "";
this.treeLeft.TreeNodeTextField = this.LeftRowObj["fieldsqlname"] + "";
this.treeLeft.TreeNodeSelectAfter += new TreeViewEventHandler(OnTreeLeftTreeNodeSelected);
this.treeLeft.BindTreeView(BaseImpl.GetDataTableResult(this.LeftRowObj["fieldsql"] + ""));
}
else
{
// 根据模块上配置的sql加载树
if (this.SysModel != null && !string.IsNullOrEmpty(this.SysModel.TreeSQL))
{
this.ParentUnionField = "SpeciesNo";
this.ParentKeyField = "SpeciesNo";
this.treeLeft.TreeNodeKeyField = "SpeciesNo";
this.treeLeft.TreeNodeTextField = "SpeciesName";
this.treeLeft.TreeNodeSelectAfter += new TreeViewEventHandler(OnTreeLeftTreeNodeSelected);
this.treeLeft.BindTreeView(BaseImpl.GetDataTableResult(this.SysModel.TreeSQL));
}
}
}
/// <summary>
/// <para>说明:树节点点击后刷新数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-10-26 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="TreeViewEventArgs"/> instance containing the event data.</param>
protected void OnTreeLeftTreeNodeSelected(object sender, TreeViewEventArgs e)
{
string where = string.Format(" and {0} like '{1}%' ", this.treeLeft.TreeNodeKeyField, e.Node.Name);
string sqlValue = ReplaceHelper.IsProcedure(this.SysModel.MenuSql) ?
ReplaceHelper.ReplaceTreeViewParentKeyCond(this.SysModel.MenuSql, treeLeft.GetSelectNodeValue()) :
ReplaceHelper.ReplaceWhereCond(this.SysModel.MenuSql) + where;
//this.gcMain.gridControl.DataSource = MainImpl.GetDataTableResult(sqlValue);
this.SearchObj.SearchGrid(sqlValue);
this.gcMain.GridView.ClearSelection();
}
#region
/// <summary>
/// <para>说明:设置左侧表格数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-10-25 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
protected void SetLeftGridView()
{
this.LeftRowObj = BaseModuleImpl.GetBaseLeftTreeField(UnionModuleCodel);//获取表格左侧树字段
if (this.LeftRowObj != null)
{
DataTable dtTable = BaseModuleImpl.GetBaseLeftGridField(UnionModuleCodel);
DataTable dtColorTable = BaseModuleImpl.GetBaseGridRowColors(this.LeftRowObj["fieldKey"] + "");
this.gridLeft.GridView.RowClick += new DevExpress.XtraGrid.Views.Grid.RowClickEventHandler(OnGridViewRowClick);
this.gridLeft.SetGridRowColors(dtColorTable);
this.gridLeft.SetReadOnlyColumns(dtTable, GridCustomColumnStruct.BaseLeftGridView + UnionModuleCodel);
this.ParentUnionField = this.LeftRowObj["fieldname"] + "";
this.ParentKeyField = this.LeftRowObj["fieldsqlid"] + "";
//this.ModuleGridObj.ParentKeyField = this.LeftRowObj["fieldsqlid"] + "";
//this.ModuleGridObj.ParentUnionField = this.LeftRowObj["fieldname"] + "";
DataTable table = BaseModuleImpl.GetCustomQueryFields(this.LeftRowObj["fieldKey"] + "");
string searchSql = this.LeftRowObj["fieldsql"] + "";
if (table != null && table.Rows.Count > 0)
{
// 自定义查询条件
this._leftGridSearchObj = new MyControl(searchSql, this.gridLeft);
this.pl_left_top.Height = this._leftGridSearchObj.InitSearchControl(table, this.pl_left_top);
this._leftGridSearchObj.OnDataSourceBindCallBack += new EventHandler(OnLeftControlObjDataSourceBindCallBack);
}
else
{
DataTable leftGridCondtionTable = BaseImpl.GetDataTableResult(searchSql);
this.pl_left_top.Visible = false;
this.gridLeft.GridControl.DataSource = leftGridCondtionTable;
}
}
}
#endregion
#region
/// <summary>
/// <para>说明:刷新右侧表格数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-03-19 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="DevExpress.Data.SelectionChangedEventArgs"/> instance containing the event data.</param>
protected void OnGridViewRowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e)
{
try
{
string sqlValue = ReplaceHelper.ReplaceWhereCond(this.SysModel.MenuSql);
if (this.gridLeft.Visible)
{
DataRow rowitem = this.gridLeft.GridView.GetFocusedDataRow();
sqlValue = this._leftGridSearchObj != null ? this._leftGridSearchObj.ReplaceParentControlValue(sqlValue) : sqlValue;
sqlValue = ReplaceHelper.ReplaceRowParam(rowitem, sqlValue);
}
this.SearchObj.SearchGrid(sqlValue);
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
#endregion
#endregion
#region
/// <summary>
/// <para>说明:数据绑定完成后加载数据</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期: </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void OnLeftControlObjDataSourceBindCallBack(object sender, EventArgs e)
{
try
{
this._leftGridSearchObj.SearchGrid();
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
#region
/// <summary>
/// <para>说明:确定</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-03-20 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnOk_Click(object sender, EventArgs e)
{
this.DataRows = gcMain.GetViewFocusedDataRows();
if (DataRows.Length > 0)
{
this.DialogResult = System.Windows.Forms.DialogResult.OK;
}
this.Close();
}
#endregion
#region
/// <summary>
/// <para>说明:取消</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-03-20 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
#endregion
#region
/// <summary>
/// <para>说明:释放时清理数据源</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2018-03-16 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
private void OnFrmModelLookUp_Disposed(object sender, EventArgs e)
{
GC.Collect();
}
#endregion
#endregion
/// <summary>
/// <para>说明:右键菜单执行后刷新数据,刷新规则按照上一次查询条件刷新</para>
/// <para>创建人:龚宇超</para>
/// <para>创建日期:2017-11-02 </para>
/// <para>修改人:</para>
/// <para>修改日期:</para>
/// <para>修改备注:</para>
/// <para>版本:1.0</para>
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
protected void OnGridViewRightCallBack(object sender, EventArgs e)
{
try
{
this.SearchObj.SearchLastGrid();
}
catch (Exception ex)
{
string Message = ErrorMessage.PromptErrorMessage(ex);
MessageUtil.Show(Message, ex.Message);
}
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
+64
View File
@@ -0,0 +1,64 @@
namespace Lskj.PubBillManagement
{
partial class FrmMain
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.billModule1 = new Lskj.PubBillManagement.BillModule();
this.SuspendLayout();
//
// billModule1
//
this.billModule1.Dock = System.Windows.Forms.DockStyle.Fill;
this.billModule1.Location = new System.Drawing.Point(0, 0);
this.billModule1.Margin = new System.Windows.Forms.Padding(4);
this.billModule1.Name = "billModule1";
this.billModule1.Size = new System.Drawing.Size(1579, 912);
this.billModule1.TabIndex = 0;
//
// FrmMain
//
this.Appearance.BackColor = System.Drawing.SystemColors.Control;
this.Appearance.Options.UseBackColor = true;
this.Appearance.Options.UseFont = true;
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(1579, 912);
this.Controls.Add(this.billModule1);
this.Margin = new System.Windows.Forms.Padding(5);
this.Name = "FrmMain";
this.Text = "单据模版";
this.ResumeLayout(false);
}
#endregion
private BillModule billModule1;
}
}

Some files were not shown because too many files have changed in this diff Show More