二开案例.元模型.日志单据
【应用场景】日志单据专门用于存储和展示日志数据,与单据不同,单据数据存储在业务数据库,而日志单据数据存储在日志数据库,日志单据最大限度的减小了日志功能及日志数据对业务系统的入侵。
【使用限制】日志单据需要启用日志库,公有云不支持日志库,无法使用日志单据功能。
【实现原理】
Context指向业务数据库,Context.LogDBContext指向日志数据库,如果未启用日志库,那么LogDBContext等于null,将无法使用日志单据。往日志单据的日志表中写数据时,需要显示指定使用LogDBContext。
【案例演示】本文演示如何从零开发一张日志单据,用于存储采购订单的操作日志。
<1>环境准备,登录管理中心,启用日志库,一个业务库有且仅有一个日志库。
<2>打开BOSIDE,新建日志单据(元数据见文末附件),如下图所示。
<3>在日志库创建日志单据对应的日志表,对应建表脚本如下。
-------------------------------------------------------------------------------------------------
CREATE TABLE Jac_Log_OperateLog(
FID varchar(36) NOT NULL,
F_JAC_OBJECTTYPEID nvarchar(50) NOT NULL DEFAULT (''),
F_JAC_OBJECTTYPENAME nvarchar(50) NOT NULL DEFAULT (''),
F_JAC_OPERATIONNAME nvarchar(50) NOT NULL DEFAULT (''),
F_JAC_CREATORID int NOT NULL DEFAULT (0),
F_JAC_CREATORNAME nvarchar(50) NOT NULL DEFAULT (''),
F_JAC_CREATETIME datetime NULL DEFAULT (getdate()),
F_JAC_LOG nvarchar(2000) NOT NULL DEFAULT (''),
)
GO
ALTER TABLE Jac_Log_OperateLog ADD CONSTRAINT PK_Jac_Log_OperateLog PRIMARY KEY CLUSTERED (FID ASC)
GO
-------------------------------------------------------------------------------------------------
<4>发布日志单据。
/*
-- 发布菜单
DELETE T_META_CONSOLEDETAIL WHERE FDetailFuncId='5fc5efc2d14e01'
INSERT INTO T_META_CONSOLEDETAIL(FDETAILFUNCID,FSUBFUNCID,FNUMBER,FOBJECTID,FTYPE,FSTATUS,FPERMISSIONITEMID,FSEQ,FPARAM,FCUSTOMPARAMS,FTHUMB,FLEVEL,FVISIBLE,FFUNCTIONGROUP,FAUTHPMOBJECTTYPEID,FHTMLSTATUS,FEXCELSTATUS,FH5OBJECTID) VALUES ('5fc5efc2d14e01','068cff00618e48f4b22623a826bca1ba',N'CZRZ','Jac_OperateLog','1','1',' ',6,N'{"FormId":"Jac_OperateLog","ShowType":"1","formType":"list"}',N' ',' ',null,29,0,' ','1','0',null)
DELETE T_META_CONSOLEDETAIL_L WHERE FDetailFuncId = '5fc5efc2d14e01' AND FLOCALEID = 2052
INSERT INTO T_META_CONSOLEDETAIL_L(FPKID, FDETAILFUNCID, FLOCALEID, FNAME, FDESCRIPTION) VALUES('5fc5efc2d14e02','5fc5efc2d14e01',2052, N'操作日志(日志库)', N' ')
*/
<5>编写表单插件,用于操作后写日志库日志,代码如下。
using Kingdee.BOS;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace Jac.XkDemo.BOS.Business.PlugIn
{
/// <summary>
/// 【表单插件】将日志写入日志库
/// </summary>
[Description("【表单插件】将日志写入日志库"), HotUpdate]
public class WriteLogToLogDbFormPlugIn : AbstractDynamicFormPlugIn
{
public override void AfterDoOperation(AfterDoOperationEventArgs e)
{
base.AfterDoOperation(e);
var log = string.Empty;
if (e.OperationResult != null)
{
log = e.OperationResult.IsSuccess ? "成功" : "失败";
if (e.OperationResult.OperateResult != null && e.OperationResult.OperateResult.Count > 0)
{
log += "\r\n操作结果:" + string.Join("\r\n", e.OperationResult.OperateResult.Select(o => o.Message));
}
if (e.OperationResult.ValidationErrors != null && e.OperationResult.ValidationErrors.Count > 0)
{
log += "\r\n校验错误:" + string.Join("\r\n", e.OperationResult.ValidationErrors.Select(o => o.Message));
}
}
DbLogger.AddOperateLog(this.Context, this.View.BillBusinessInfo, e.Operation.OperationName, log);
}
}
/// <summary>
/// 日志库日志管理器
/// </summary>
public class DbLogger
{
/// <summary>
/// 写操作日志
/// </summary>
/// <param name="ctx">上下文</param>
/// <param name="businessInfo">业务对象</param>
/// <param name="operationName"></param>
/// <param name="log"></param>
/// <returns></returns>
public static bool AddOperateLog(Context ctx, BusinessInfo businessInfo, string operationName, string log)
{
var sql = @"INSERT INTO Jac_Log_OperateLog (FID,F_JAC_OBJECTTYPEID,F_JAC_OBJECTTYPENAME,F_JAC_OPERATIONNAME,F_JAC_CREATORID,F_JAC_CREATORNAME,F_JAC_CREATETIME,F_JAC_LOG)
VALUES(@FID, @F_JAC_OBJECTTYPEID, @F_JAC_OBJECTTYPENAME, @F_JAC_OPERATIONNAME, @F_JAC_CREATORID, @F_JAC_CREATORNAME, @F_JAC_CREATETIME, @F_JAC_LOG)";
var sqlParameterList = new List<SqlParam>();
sqlParameterList.Add(new SqlParam("@FID", KDDbType.AnsiString, SequentialGuid.NewGuid().ToString().Replace("-", "")));
sqlParameterList.Add(new SqlParam("@F_JAC_OBJECTTYPEID", KDDbType.AnsiString, businessInfo.GetForm().Id));
sqlParameterList.Add(new SqlParam("@F_JAC_OBJECTTYPENAME", KDDbType.AnsiString, businessInfo.GetForm().Name.ToString()));
sqlParameterList.Add(new SqlParam("@F_JAC_OPERATIONNAME", KDDbType.AnsiString, operationName));
sqlParameterList.Add(new SqlParam("@F_JAC_CREATORID", KDDbType.Int64, ctx.UserId));
sqlParameterList.Add(new SqlParam("@F_JAC_CREATORNAME", KDDbType.AnsiString, ctx.UserName));
sqlParameterList.Add(new SqlParam("@F_JAC_CREATETIME", KDDbType.DateTime, DateTime.Now));
sqlParameterList.Add(new SqlParam("@F_JAC_LOG", KDDbType.AnsiString, log));
var returnValue = DBUtils.Execute(ctx.LogDBContext, sql, sqlParameterList);
return returnValue > 0;
}
}
}
<6>拷贝插件组件到应用站点的WebSite\Bin目录下,重启IIS。
<7>BOSIDE扩展采购订单,注册表单插件,保存元数据,开发完毕。
现在可以登录业务站点,打开采购订单新增界面,保存新的采购订单,此操作过程会记录操作日志到日志库。
然后就可以前往操作日志单据上查询日志数据啦。
【参考资料】
以下是一些BOS平台基于日志单据开发的针对一些通用功能的日志追踪和管理功能,感兴趣的同学可以继续学习了解。
【金蝶云星空日志管理汇总贴】https://vip.kingdee.com/article/8747
【日志库创建与注册说明】https://vip.kingdee.com/article/14863
【金蝶云星空日志管理-WebAPI日志】https://vip.kingdee.com/article/8744
【金蝶云星空日志管理-插件监控日志】https://vip.kingdee.com/article/8746
【金蝶云星空日志管理-执行计划日志】https://vip.kingdee.com/article/8745
【金蝶云星空BOS二次开发案例演示】https://vip.kingdee.com/article/94751030918525696
二开案例.元模型.日志单据
本文2024-09-23 04:21:02发表“云星空知识”栏目。
本文链接:https://wenku.my7c.com/article/kingdee-k3cloud-164737.html