15 KiB
15 KiB
Delphi 代码框架文档
概述
本文档描述了为 MES 客户端应用创建的代码框架,包括配置管理、业务服务、异常处理、日志管理和单元测试等模块。
1. 配置管理框架 (uConfigManager.pas)
1.1 主要组件
| 组件 | 说明 |
|---|---|
TConfigManager |
通用配置管理器,支持INI和JSON格式 |
TAppConfig |
应用配置单例,提供预定义的配置项 |
1.2 TConfigManager 核心方法
// 读取配置
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 预定义配置
// 网络配置
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 使用示例
// 读取配置
ServerURL := Config.GetServerURL;
Timeout := Config.GetTimeout;
// 修改配置
Config.System.SetString('Network', 'ServerURL', 'http://new-server:8080');
Config.Save; // 保存配置
2. 业务服务框架 (uBusinessServices.pas)
2.1 服务工厂
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)
// 登录
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)
// 获取工单列表
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)
// 获取设备状态
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)
// 同步数据
function SyncData(const Data: TJSONObject): Boolean;
// 批量同步
function SyncBatchData(const DataArray: TJSONArray): Boolean;
// 获取同步状态
function GetSyncStatus(): TJSONObject;
// 重试失败同步
function RetryFailedSyncs(): Integer;
2.6 设备配置服务 (TDeviceConfigService)
// 加载设备配置
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)
// 报工
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)
// 读取配置值
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 属性
property ErrorCode: Integer; // 错误码
property ErrorType: string; // 错误类型
property Cause: string; // 错误原因
property Context: TStrings; // 错误上下文
property Timestamp: TDateTime; // 时间戳
3.3 快捷抛出函数
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 使用示例
// 抛出特定类型异常
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 日志方法
// 基础日志
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 性能日志
// 方式1: 使用TPerformanceLogger
var Logger := TPerformanceLogger.Create('数据查询');
try
// 执行操作
finally
Logger.Free;
end;
// 方式2: 使用静态方法
TPerformanceLogger.Measure<T>(
'数据查询',
function: T begin
// 执行操作
Result := ...;
end,
'Tag信息'
);
4.5 使用示例
// 记录日志
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操作和网络请求监控
// 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)
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)
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)
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)
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 运行测试
# GUI模式
TestRunner.exe
# 控制台模式
TestRunner.exe -console
6.3 测试示例
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:
PLCHost := '192.168.1.100';
PLCPort := 502;
After:
PLCHost := Config.GetPLCHost;
PLCPort := Config.GetPLCPort;
8.2 使用新的异常处理
Before:
raise Exception.Create('错误信息');
After:
RaiseBusinessException('错误信息', 1001);
// 或
RaiseDeviceException('PLC连接失败: %s', [E.Message], 5001);
8.3 使用新的日志框架
Before:
WorkLog.MessageInfo('操作成功');
WorkLog.Error('操作失败: %s', [E.Message]);
After:
LogManager.InfoCategory(lcBusiness, '操作成功');
LogManager.ErrorCategory(lcBusiness, '操作失败: %s', [E.Message]);
9. 最佳实践
- 配置管理: 所有硬编码的配置值都应迁移到配置管理器
- 异常处理: 使用特定的异常类型,便于分类处理
- 日志记录: 在关键业务操作中添加日志和性能监控
- 单元测试: 新增功能应同步添加单元测试
- 代码文档: 复杂函数应添加文档注释
10. 版本信息
| 版本 | 日期 | 说明 |
|---|---|---|
| 1.1 | 2026-04-26 | 扩展生产报工服务,添加用户验证、工单查询、二维码验证等功能 |
| 1.0 | 2026-04-26 | 初始版本,包含核心框架 |
文档最后更新: 2026-04-26