Initial commit - Delphi MES client project
This commit is contained in:
@@ -0,0 +1,569 @@
|
||||
# Delphi 代码框架文档
|
||||
|
||||
## 概述
|
||||
|
||||
本文档描述了为 MES 客户端应用创建的代码框架,包括配置管理、业务服务、异常处理、日志管理和单元测试等模块。
|
||||
|
||||
---
|
||||
|
||||
## 1. 配置管理框架 (uConfigManager.pas)
|
||||
|
||||
### 1.1 主要组件
|
||||
|
||||
| 组件 | 说明 |
|
||||
|-----|------|
|
||||
| `TConfigManager` | 通用配置管理器,支持INI和JSON格式 |
|
||||
| `TAppConfig` | 应用配置单例,提供预定义的配置项 |
|
||||
|
||||
### 1.2 TConfigManager 核心方法
|
||||
|
||||
```pascal
|
||||
// 读取配置
|
||||
function GetString(const Section, Key, Default: string): string;
|
||||
function GetInteger(const Section, Key: string; Default: Integer): Integer;
|
||||
function GetBoolean(const Section, Key: string; Default: Boolean): Boolean;
|
||||
function GetFloat(const Section, Key: string; Default: Double): Double;
|
||||
|
||||
// 写入配置
|
||||
procedure SetString(const Section, Key, Value: string);
|
||||
procedure SetInteger(const Section, Key: string; Value: Integer);
|
||||
procedure SetBoolean(const Section, Key: string; Value: Boolean);
|
||||
procedure SetFloat(const Section, Key: string; Value: Double);
|
||||
```
|
||||
|
||||
### 1.3 TAppConfig 预定义配置
|
||||
|
||||
```pascal
|
||||
// 网络配置
|
||||
Config.GetServerURL: string; // 服务器地址
|
||||
Config.GetServerPort: Integer; // 服务器端口
|
||||
Config.GetTimeout: Integer; // 超时时间(ms)
|
||||
Config.GetRetryCount: Integer; // 重试次数
|
||||
Config.GetCORSOrigin: string; // CORS允许源
|
||||
Config.GetAPIPath: string; // API路径
|
||||
Config.GetAdminAPIPath: string; // 管理API路径
|
||||
|
||||
// 设备配置
|
||||
Config.GetPLCHost: string; // PLC主机地址
|
||||
Config.GetPLCPort: Integer; // PLC端口
|
||||
Config.GetSerialPort: string; // 串口号
|
||||
Config.GetBaudRate: Integer; // 波特率
|
||||
|
||||
// 文件服务器配置
|
||||
Config.GetFileServerPath: string; // 文件服务器路径
|
||||
Config.GetBackupServerPath: string; // 备份服务器路径
|
||||
|
||||
// 数据同步配置
|
||||
Config.GetSyncInterval: Integer; // 同步间隔(ms)
|
||||
Config.GetMaxRetryCount: Integer; // 最大重试次数
|
||||
|
||||
// 日志配置
|
||||
Config.GetLogFileDir: string; // 日志文件目录
|
||||
Config.GetLogFileMaxSize: Integer; // 日志文件最大大小(bytes)
|
||||
Config.GetLogLevel: Integer; // 日志级别(0-5)
|
||||
```
|
||||
|
||||
### 1.4 使用示例
|
||||
|
||||
```pascal
|
||||
// 读取配置
|
||||
ServerURL := Config.GetServerURL;
|
||||
Timeout := Config.GetTimeout;
|
||||
|
||||
// 修改配置
|
||||
Config.System.SetString('Network', 'ServerURL', 'http://new-server:8080');
|
||||
Config.Save; // 保存配置
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 业务服务框架 (uBusinessServices.pas)
|
||||
|
||||
### 2.1 服务工厂
|
||||
|
||||
```pascal
|
||||
class function TBusinessServiceFactory.GetAuthService(): TAuthService;
|
||||
class function TBusinessServiceFactory.GetWorkOrderService(const Token: string): TWorkOrderService;
|
||||
class function TBusinessServiceFactory.GetDeviceService(): TDeviceService;
|
||||
class function TBusinessServiceFactory.GetSyncService(const Token: string): TSyncService;
|
||||
class function TBusinessServiceFactory.GetDeviceConfigService(): TDeviceConfigService;
|
||||
class function TBusinessServiceFactory.GetProductionReportingService(const Token: string): TProductionReportingService;
|
||||
class function TBusinessServiceFactory.GetDataAccessService(): TDataAccessService;
|
||||
```
|
||||
|
||||
### 2.2 认证服务 (TAuthService)
|
||||
|
||||
```pascal
|
||||
// 登录
|
||||
function Login(const UserID, Password: string): TAuthResult;
|
||||
|
||||
// 注销
|
||||
function Logout(const Token: string): Boolean;
|
||||
|
||||
// 刷新令牌
|
||||
function RefreshToken(const Token: string): string;
|
||||
|
||||
// 验证令牌
|
||||
function ValidateToken(const Token: string): Boolean;
|
||||
```
|
||||
|
||||
### 2.3 工单服务 (TWorkOrderService)
|
||||
|
||||
```pascal
|
||||
// 获取工单列表
|
||||
function GetWorkOrderList(const Status: string = ''): TArray<TWorkOrderInfo>;
|
||||
|
||||
// 获取工单详情
|
||||
function GetWorkOrderDetail(const OrderID: string): TWorkOrderInfo;
|
||||
|
||||
// 获取工单工序
|
||||
function GetWorkOrderEntries(const OrderID: string): TArray<TWorkOrderEntry>;
|
||||
|
||||
// 创建工单
|
||||
function CreateWorkOrder(const OrderInfo: TWorkOrderInfo): string;
|
||||
|
||||
// 更新工单状态
|
||||
function UpdateWorkOrderStatus(const OrderID, Status: string): Boolean;
|
||||
|
||||
// 生产报工
|
||||
function ReportProduction(const OrderID, ProcessID, Quantity: string): Boolean;
|
||||
```
|
||||
|
||||
### 2.4 设备服务 (TDeviceService)
|
||||
|
||||
```pascal
|
||||
// 获取设备状态
|
||||
function GetDeviceStatus(const DeviceID: string): TDeviceStatus;
|
||||
|
||||
// 获取所有设备
|
||||
function GetAllDevices(): TArray<TDeviceStatus>;
|
||||
|
||||
// 连接设备
|
||||
function ConnectDevice(const DeviceID: string): Boolean;
|
||||
|
||||
// 断开设备
|
||||
function DisconnectDevice(const DeviceID: string): Boolean;
|
||||
|
||||
// 发送命令
|
||||
function SendCommand(const DeviceID, Command: string): string;
|
||||
```
|
||||
|
||||
### 2.5 同步服务 (TSyncService)
|
||||
|
||||
```pascal
|
||||
// 同步数据
|
||||
function SyncData(const Data: TJSONObject): Boolean;
|
||||
|
||||
// 批量同步
|
||||
function SyncBatchData(const DataArray: TJSONArray): Boolean;
|
||||
|
||||
// 获取同步状态
|
||||
function GetSyncStatus(): TJSONObject;
|
||||
|
||||
// 重试失败同步
|
||||
function RetryFailedSyncs(): Integer;
|
||||
```
|
||||
|
||||
### 2.6 设备配置服务 (TDeviceConfigService)
|
||||
|
||||
```pascal
|
||||
// 加载设备配置
|
||||
function LoadDeviceConfig(): Boolean;
|
||||
|
||||
// 保存设备配置
|
||||
function SaveDeviceConfig(): Boolean;
|
||||
|
||||
// 验证配置
|
||||
function ValidateConfig(): TValidationResult;
|
||||
|
||||
// 获取服务器URL
|
||||
function GetServerURL(): string;
|
||||
|
||||
// 获取工厂代码
|
||||
function GetFactoryCode(): string;
|
||||
|
||||
// 获取生产线
|
||||
function GetProductionLine(): string;
|
||||
|
||||
// 获取操作工位
|
||||
function GetOperatorStation(): string;
|
||||
```
|
||||
|
||||
### 2.7 生产报工服务 (TProductionReportingService)
|
||||
|
||||
```pascal
|
||||
// 报工
|
||||
function ReportProduction(const OrderID, ProcessID, Quantity, LotNo: string): Boolean;
|
||||
|
||||
// 报不良
|
||||
function ReportDefective(const OrderID, ProcessID, DefectType, Quantity: string): Boolean;
|
||||
|
||||
// 查询生产状态
|
||||
function QueryProductionStatus(const OrderID: string): TJSONObject;
|
||||
|
||||
// 验证用户
|
||||
function ValidateUser(const UserID: string): Boolean;
|
||||
|
||||
// 获取工单信息
|
||||
function GetWorkOrderInfo(const LotNo: string): TJSONObject;
|
||||
|
||||
// 获取工序列表
|
||||
function GetProcessList(const LotNo: string): TJSONArray;
|
||||
|
||||
// 验证二维码
|
||||
function ValidateGoodsNo(const ItemCode, ProcessCode, WorkOrderNumber: string): Boolean;
|
||||
|
||||
// 提交生产数据
|
||||
function SubmitProductionData(const UserID, LotNo, ProcessID, GoodsNo: string): Boolean;
|
||||
```
|
||||
|
||||
### 2.8 数据访问服务 (TDataAccessService)
|
||||
|
||||
```pascal
|
||||
// 读取配置值
|
||||
function ReadConfigValue(const ASection, AKey: string; const ADefault: string = ''): string;
|
||||
|
||||
// 写入配置值
|
||||
procedure WriteConfigValue(const ASection, AKey, AValue: string);
|
||||
|
||||
// 读取设备信息
|
||||
function ReadDeviceInfo(const AKey: string): string;
|
||||
|
||||
// 读取生产参数
|
||||
function ReadProductionParams(const AKey: string): string;
|
||||
|
||||
// 读取报警配置
|
||||
function ReadAlarmConfig(const AKey: string): string;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 异常处理框架 (uExceptionHandler.pas)
|
||||
|
||||
### 3.1 异常类型层次
|
||||
|
||||
```
|
||||
EBaseException
|
||||
├── ENetworkException (网络错误)
|
||||
├── EDataException (数据错误)
|
||||
├── EBusinessException (业务错误)
|
||||
├── EDeviceException (设备错误)
|
||||
└── EValidationException (验证错误)
|
||||
```
|
||||
|
||||
### 3.2 EBaseException 属性
|
||||
|
||||
```pascal
|
||||
property ErrorCode: Integer; // 错误码
|
||||
property ErrorType: string; // 错误类型
|
||||
property Cause: string; // 错误原因
|
||||
property Context: TStrings; // 错误上下文
|
||||
property Timestamp: TDateTime; // 时间戳
|
||||
```
|
||||
|
||||
### 3.3 快捷抛出函数
|
||||
|
||||
```pascal
|
||||
procedure RaiseNetworkException(const AMsg: string; AErrorCode: Integer = 0);
|
||||
procedure RaiseDataException(const AMsg: string; AErrorCode: Integer = 0);
|
||||
procedure RaiseBusinessException(const AMsg: string; AErrorCode: Integer = 0);
|
||||
procedure RaiseDeviceException(const AMsg: string; AErrorCode: Integer = 0);
|
||||
procedure RaiseValidationException(const AFieldName, AFieldValue, AMsg: string);
|
||||
```
|
||||
|
||||
### 3.4 使用示例
|
||||
|
||||
```pascal
|
||||
// 抛出特定类型异常
|
||||
RaiseNetworkException('连接失败: %s', [E.Message], 1001);
|
||||
RaiseBusinessException('工单不存在', 2001);
|
||||
|
||||
// 全局异常处理
|
||||
TExceptionHandler.Instance.HandleException(E);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 日志管理框架 (uLogManager.pas)
|
||||
|
||||
### 4.1 日志级别
|
||||
|
||||
| 级别 | 值 | 说明 |
|
||||
|-----|---|------|
|
||||
| `llTrace` | 0 | 跟踪信息 |
|
||||
| `llDebug` | 1 | 调试信息 |
|
||||
| `llInfo` | 2 | 一般信息 |
|
||||
| `llWarn` | 3 | 警告信息 |
|
||||
| `llError` | 4 | 错误信息 |
|
||||
| `llFatal` | 5 | 致命错误 |
|
||||
|
||||
### 4.2 日志分类
|
||||
|
||||
| 分类 | 说明 |
|
||||
|-----|------|
|
||||
| `lcSystem` | 系统日志 |
|
||||
| `lcNetwork` | 网络日志 |
|
||||
| `lcDatabase` | 数据库日志 |
|
||||
| `lcBusiness` | 业务日志 |
|
||||
| `lcDevice` | 设备日志 |
|
||||
| `lcUI` | 界面日志 |
|
||||
| `lcSecurity` | 安全日志 |
|
||||
| `lcPerformance` | 性能日志 |
|
||||
|
||||
### 4.3 日志方法
|
||||
|
||||
```pascal
|
||||
// 基础日志
|
||||
procedure Log(Level: TLogLevel; Category: TLogCategory; const Message: string; const Args: array of const);
|
||||
|
||||
// 分级日志
|
||||
procedure Trace(const Message: string; const Args: array of const = []);
|
||||
procedure Debug(const Message: string; const Args: array of const = []);
|
||||
procedure Info(const Message: string; const Args: array of const = []);
|
||||
procedure Warn(const Message: string; const Args: array of const = []);
|
||||
procedure Error(const Message: string; const Args: array of const = []);
|
||||
procedure Fatal(const Message: string; const Args: array of const = []);
|
||||
|
||||
// 分类日志
|
||||
procedure InfoCategory(Category: TLogCategory; const Message: string; const Args: array of const = []);
|
||||
procedure ErrorCategory(Category: TLogCategory; const Message: string; const Args: array of const = []);
|
||||
```
|
||||
|
||||
### 4.4 性能日志
|
||||
|
||||
```pascal
|
||||
// 方式1: 使用TPerformanceLogger
|
||||
var Logger := TPerformanceLogger.Create('数据查询');
|
||||
try
|
||||
// 执行操作
|
||||
finally
|
||||
Logger.Free;
|
||||
end;
|
||||
|
||||
// 方式2: 使用静态方法
|
||||
TPerformanceLogger.Measure<T>(
|
||||
'数据查询',
|
||||
function: T begin
|
||||
// 执行操作
|
||||
Result := ...;
|
||||
end,
|
||||
'Tag信息'
|
||||
);
|
||||
```
|
||||
|
||||
### 4.5 使用示例
|
||||
|
||||
```pascal
|
||||
// 记录日志
|
||||
LogManager.InfoCategory(lcNetwork, '连接成功: %s', ['192.168.1.100']);
|
||||
LogManager.ErrorCategory(lcDevice, 'PLC通信失败: %s', [E.Message]);
|
||||
|
||||
// 记录异常
|
||||
LogManager.LogException(E, lcNetwork, '额外的上下文信息');
|
||||
|
||||
// 性能监控
|
||||
var PerfLogger := TPerformanceLogger.Create('耗时操作');
|
||||
// ... 执行代码 ...
|
||||
PerfLogger.Finish;
|
||||
```
|
||||
|
||||
### 4.6 UI操作和网络请求监控
|
||||
|
||||
```pascal
|
||||
// UI操作监控
|
||||
LogManager.LogUIOperation('Click', 'Button1', 50);
|
||||
LogManager.LogUIOperation('Select', 'ComboBox1', -1);
|
||||
|
||||
// 网络请求监控
|
||||
LogManager.LogNetworkRequest('http://example.com/api', 'GET', 200, 150);
|
||||
LogManager.LogNetworkRequest('http://example.com/api', 'POST', 500, 300);
|
||||
|
||||
// 表单监控
|
||||
LogManager.LogFormShow('MainForm', 100);
|
||||
LogManager.LogFormClose('MainForm', 50);
|
||||
|
||||
// 数据操作监控
|
||||
LogManager.LogDataOperation('INSERT', 10, 25);
|
||||
LogManager.LogDataOperation('UPDATE', 5, -1);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 通用工具 (uCommonUtils.pas)
|
||||
|
||||
### 5.1 数据验证 (TValidator)
|
||||
|
||||
```pascal
|
||||
class function TValidator.IsEmpty(const AValue: string): Boolean;
|
||||
class function TValidator.IsInteger(const AValue: string): Boolean;
|
||||
class function TValidator.IsFloat(const AValue: string): Boolean;
|
||||
class function TValidator.IsEmail(const AValue: string): Boolean;
|
||||
class function TValidator.IsPhone(const AValue: string): Boolean;
|
||||
class function TValidator.IsIPAddress(const AValue: string): Boolean;
|
||||
class function TValidator.ValidateBarcode(const ABarcode: string): TValidationResult;
|
||||
```
|
||||
|
||||
### 5.2 字符串扩展 (TStringHelperEx)
|
||||
|
||||
```pascal
|
||||
function IsInteger: Boolean;
|
||||
function IsFloat: Boolean;
|
||||
function ToIntegerDef(ADefault: Integer): Integer;
|
||||
function ToFloatDef(ADefault: Double): Double;
|
||||
function Contains(const ASubStr: string): Boolean;
|
||||
function StartsWith(const AStr: string): Boolean;
|
||||
function EndsWith(const AStr: string): Boolean;
|
||||
function ReplaceAll(const AFrom, ATo: string): string;
|
||||
```
|
||||
|
||||
### 5.3 日期时间工具 (TDateTimeHelper)
|
||||
|
||||
```pascal
|
||||
class function TDateTimeHelper.FormatDateTime(const AFormat: string; ADateTime: TDateTime): string;
|
||||
class function TDateTimeHelper.ParseDateTime(const AValue: string): TDateTime;
|
||||
class function TDateTimeHelper.IsToday(ADateTime: TDateTime): Boolean;
|
||||
class function TDateTimeHelper.IsSameDay(ADate1, ADate2: TDateTime): Boolean;
|
||||
```
|
||||
|
||||
### 5.4 JSON工具 (TJSONHelper)
|
||||
|
||||
```pascal
|
||||
class function TJSONHelper.GetString(AJSON: TJSONObject; const AKey: string; const ADefault: string = ''): string;
|
||||
class function TJSONHelper.GetInteger(AJSON: TJSONObject; const AKey: string; const ADefault: Integer = 0): Integer;
|
||||
class function TJSONHelper.TryGetString(AJSON: TJSONObject; const AKey: string; out AValue: string): Boolean;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 单元测试 (uUnitTests.pas)
|
||||
|
||||
### 6.1 测试套件
|
||||
|
||||
| 测试套件 | 测试内容 |
|
||||
|---------|---------|
|
||||
| `ExceptionHandler` | 异常处理框架测试 |
|
||||
| `LogManager` | 日志管理框架测试 |
|
||||
| `ConfigManager` | 配置管理框架测试 |
|
||||
| `BusinessServices` | 业务服务框架测试 |
|
||||
| `CommonUtils` | 通用工具测试 |
|
||||
|
||||
### 6.2 运行测试
|
||||
|
||||
```bash
|
||||
# GUI模式
|
||||
TestRunner.exe
|
||||
|
||||
# 控制台模式
|
||||
TestRunner.exe -console
|
||||
```
|
||||
|
||||
### 6.3 测试示例
|
||||
|
||||
```pascal
|
||||
procedure TTestConfigManager.TestConfigTypes;
|
||||
var
|
||||
Config: TConfigManager;
|
||||
begin
|
||||
Config := TConfigManager.Create('test_config.ini');
|
||||
try
|
||||
Config.SetString('Test', 'String', 'Hello');
|
||||
Config.SetInteger('Test', 'Integer', 123);
|
||||
Config.SetBoolean('Test', 'Boolean', True);
|
||||
Config.SetFloat('Test', 'Float', 123.45);
|
||||
|
||||
CheckEquals('Hello', Config.GetString('Test', 'String', ''));
|
||||
CheckEquals(123, Config.GetInteger('Test', 'Integer', 0));
|
||||
CheckEquals(True, Config.GetBoolean('Test', 'Boolean', False));
|
||||
CheckEquals(123.45, Config.GetFloat('Test', 'Float', 0.0), 0.01);
|
||||
finally
|
||||
Config.Free;
|
||||
end;
|
||||
end;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 文件结构
|
||||
|
||||
```
|
||||
pas\
|
||||
├── uConfigManager.pas # 配置管理框架
|
||||
├── uBusinessServices.pas # 业务服务框架
|
||||
├── uExceptionHandler.pas # 异常处理框架
|
||||
├── uLogManager.pas # 日志管理框架
|
||||
├── uCommonUtils.pas # 通用工具
|
||||
├── uUnitTests.pas # 单元测试
|
||||
├── uSafeLog.pas # 安全日志(已集成新框架)
|
||||
├── uDM.pas # 数据模块(已集成新框架)
|
||||
├── uFrameBase.pas # 框架基类(已添加文档)
|
||||
└── 其他业务框架文件...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 迁移指南
|
||||
|
||||
### 8.1 使用配置管理器替代硬编码
|
||||
|
||||
**Before:**
|
||||
```pascal
|
||||
PLCHost := '192.168.1.100';
|
||||
PLCPort := 502;
|
||||
```
|
||||
|
||||
**After:**
|
||||
```pascal
|
||||
PLCHost := Config.GetPLCHost;
|
||||
PLCPort := Config.GetPLCPort;
|
||||
```
|
||||
|
||||
### 8.2 使用新的异常处理
|
||||
|
||||
**Before:**
|
||||
```pascal
|
||||
raise Exception.Create('错误信息');
|
||||
```
|
||||
|
||||
**After:**
|
||||
```pascal
|
||||
RaiseBusinessException('错误信息', 1001);
|
||||
// 或
|
||||
RaiseDeviceException('PLC连接失败: %s', [E.Message], 5001);
|
||||
```
|
||||
|
||||
### 8.3 使用新的日志框架
|
||||
|
||||
**Before:**
|
||||
```pascal
|
||||
WorkLog.MessageInfo('操作成功');
|
||||
WorkLog.Error('操作失败: %s', [E.Message]);
|
||||
```
|
||||
|
||||
**After:**
|
||||
```pascal
|
||||
LogManager.InfoCategory(lcBusiness, '操作成功');
|
||||
LogManager.ErrorCategory(lcBusiness, '操作失败: %s', [E.Message]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 最佳实践
|
||||
|
||||
1. **配置管理**: 所有硬编码的配置值都应迁移到配置管理器
|
||||
2. **异常处理**: 使用特定的异常类型,便于分类处理
|
||||
3. **日志记录**: 在关键业务操作中添加日志和性能监控
|
||||
4. **单元测试**: 新增功能应同步添加单元测试
|
||||
5. **代码文档**: 复杂函数应添加文档注释
|
||||
|
||||
---
|
||||
|
||||
## 10. 版本信息
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|-----|------|-----
|
||||
| 1.1 | 2026-04-26 | 扩展生产报工服务,添加用户验证、工单查询、二维码验证等功能 |
|
||||
| 1.0 | 2026-04-26 | 初始版本,包含核心框架 |
|
||||
|
||||
---
|
||||
|
||||
*文档最后更新: 2026-04-26*
|
||||
Reference in New Issue
Block a user