二开案例.单据插件.元数据缓存刷新之创建人创建日期丢失

【应用场景】
因不明原因的元数据损坏,导致某些字段的数据丢失。
【注意】
此方案用于元数据被损坏,且无法找到损坏源的特殊场景,属于不得已而为之。仍然建议您尽最大可能找到元数据被损坏的真实原因,只有找到了问题源头,才能根治元数据异常引发的各种灾难性问题。
【案例演示】
销售订单,元数据丢失了创建人,创建日期字段,导致新建订单没有创建人,创建日期,如果有编码规则引用了创建日期字段,还会导致跟根据此编码规则生成的单据编号也有异常。

【实现步骤】
<1> 注册表单插件,模拟采购订单元数据被人为破坏的场景。
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Util;
using System.ComponentModel;
using System.Linq;
namespace Jac.XkDemo.BOS.Business.PlugIn
{
/// <summary>
/// 【表单插件】创建人创建日期元数据损坏模拟测试
/// </summary>
[Description("【表单插件】创建人创建日期元数据损坏模拟测试"), HotUpdate]
public class CreateInfoLostTestFormPlugIn : AbstractDynamicFormPlugIn
{
public override void BarItemClick(BarItemClickEventArgs e)
{
base.BarItemClick(e);
if (e.BarItemKey.Contains("test"))
{
// 创建人字段
//var field1 = this.View.BillBusinessInfo.GetField("FCreatorId");
//if (field1 != null)
//{
// this.View.BillBusinessInfo.Remove(field1);
//}
var field1_Entity = this.View.BillBusinessInfo.GetEntity(0).Fields.FirstOrDefault(o => o.Key.EqualsIgnoreCase("FCreatorId"));
if (field1_Entity != null)
{
this.View.BillBusinessInfo.GetEntity(0).Fields.Remove(field1_Entity);
}
//var field1_FieldList = this.View.BillBusinessInfo.GetFieldList().FirstOrDefault(o => o.Key.EqualsIgnoreCase("FCreatorId"));
//if (field1_FieldList != null)
//{
// this.View.BillBusinessInfo.GetFieldList().Remove(field1_FieldList);
//}
// 创建日期字段
//var field2 = this.View.BillBusinessInfo.GetField("FCreateDate");
//if (field2 != null)
//{
// this.View.BillBusinessInfo.Remove(field2);
//}
var field2_Entity = this.View.BillBusinessInfo.GetEntity(0).Fields.FirstOrDefault(o => o.Key.EqualsIgnoreCase("FCreateDate"));
if (field2_Entity != null)
{
this.View.BillBusinessInfo.GetEntity(0).Fields.Remove(field2_Entity);
}
//var field2_FieldList = this.View.BillBusinessInfo.GetFieldList().FirstOrDefault(o => o.Key.EqualsIgnoreCase("FCreateDate"));
//if (field2_FieldList != null)
//{
// this.View.BillBusinessInfo.GetFieldList().Remove(field2_FieldList);
//}
}
}
}
}<2>注册单据插件,用于检测元数据是否有损坏,如果损坏了,清空缓存,重建元数据。
using Kingdee.BOS;
using Kingdee.BOS.Cache;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Bill.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.ServiceHelper;
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 ReloadMetadataForCreateInfoLostBillPlugIn : AbstractBillPlugIn
{
/// <summary>
/// 创建人字段标识
/// </summary>
private const string CreatorIdFieldKey = "FCreatorId";
/// <summary>
/// 创建人字段属性名
/// </summary>
private const string CreatorIdPropertyName = "CreatorId";
/// <summary>
/// 创建日期字段标识
/// </summary>
private const string CreateDateFieldKey = "FCreateDate";
/// <summary>
/// 创建日期字段属性名
/// </summary>
private const string CreateDatePropertyName = "CreateDate";
public override void AfterCreateModelData(EventArgs e)
{
base.AfterCreateModelData(e);
if (!CheckMetadata(this.View))
{
GetNewMetadata(this.View);
throw new Exception("创建新数据包后检测到元数据异常,请关闭当前界面后重试!");
}
}
public override void LoadData(LoadDataEventArgs e)
{
base.LoadData(e);
if (!CheckMetadata(this.View))
{
GetNewMetadata(this.View);
throw new Exception("加载数据前检测到元数据异常,请关闭当前界面后重试!");
}
}
public override void AfterLoadData(EventArgs e)
{
base.AfterLoadData(e);
if (!CheckMetadata(this.View))
{
GetNewMetadata(this.View);
throw new Exception("加载数据后检测到元数据异常,请关闭当前界面后重试!");
}
}
public override void BeforeDoOperation(BeforeDoOperationEventArgs e)
{
base.BeforeDoOperation(e);
if (!new long[] { 8, 40 }.Contains(e.Operation.FormOperation.OperationId))
{
// 只处理暂存和保存
return;
}
if (!CheckMetadata(this.View))
{
GetNewMetadata(this.View);
throw new Exception(string.Format("执行操作[{0}]前检测到元数据异常,请关闭当前界面后重试!", e.Operation.FormOperation.OperationName));
}
}
/// <summary>
/// 清除元数据缓存,返回新的元数据
/// </summary>
/// <param name="view"></param>
/// <returns></returns>
private FormMetadata GetNewMetadata(IBillView view)
{
var ctx = view.Context;
var businessInfo = view.BusinessInfo;
var formId = businessInfo.GetForm().Id;
var layoutId = view.OpenParameter.LayoutId;
// 清除元数据缓存
ClearMetaCache(ctx, formId);
// 重新加载元数据
var meta = FormMetaDataCache.GetCachedFormMetaData(ctx, formId, layoutId);
return meta;
}
/// <summary>
/// 清除元数据(清内存缓存和数据库缓存)
/// </summary>
/// <param name="ctx"></param>
/// <param name="formId"></param>
private void ClearMetaCache(Context ctx, string formId)
{
var ids = new List<string>();
// 获取与当前表单有关系的所有表单Id
var sql = string.Format(@"SELECT FID FROM T_META_OBJECTTYPE WHERE FMODELTYPEID<600 AND (FID='{0}' OR FINHERITPATH LIKE '%{0}%')", formId);
var objs = DBServiceHelper.ExecuteDynamicObject(ctx, sql);
if (objs != null && objs.Count > 0)
{
ids.AddRange(objs.Select(obj => obj[0].ToString()));
}
// 获取视图,视图的缓存也要清理
sql = string.Format(@"SELECT b.FID FROM T_META_OBJECTTYPE a
JOIN T_META_OBJECTTYPEVIEW b ON a.FID=b.FDEPENDENCYOBJECTID
WHERE a.FMODELTYPEID<600 AND (a.FID='{0}' OR a.FINHERITPATH LIKE '%{0}%')", formId);
objs = DBServiceHelper.ExecuteDynamicObject(ctx, sql);
if (objs != null && objs.Count > 0)
{
ids.AddRange(objs.Select(obj => obj[0].ToString()));
}
// 先更新版本号
sql = string.Format("UPDATE T_META_OBJECTTYPE SET FMAINVERSION='{0}' WHERE FID IN ({1})", DateTime.Now.Ticks.ToString(), string.Join(",", ids.Select(o => "'" + o + "'")));
DBServiceHelper.Execute(ctx, sql);
// 再删除数据库缓存
sql = string.Format("DELETE FROM T_META_OBJECTTYPECACHE WHERE FID IN ({0})", string.Join(",", ids.Select(o => "'" + o + "'")));
DBServiceHelper.Execute(ctx, sql);
// 再删除内存缓存
var kcmgr = KCacheManagerFactory.Instance.GetMetadataCacheManager(ctx);
if (kcmgr != null)
{
foreach (var id in ids)
{
kcmgr.Remove(id);
}
}
}
/// <summary>
/// 检查元数据是否正常
/// </summary>
/// <param name="view"></param>
/// <returns>返回false表示元数据异常</returns>
private bool CheckMet二开案例.单据插件.元数据缓存刷新之创建人创建日期丢失
【应用场景】因不明原因的元数据损坏,导致某些字段的数据丢失。【注意】此方案用于元数据被损坏,且无法找到损坏源的特殊场景,属于不得已...
点击下载文档文档为doc格式
声明:除非特别标注,否则均为本站原创文章,转载时请以链接形式注明文章出处。如若本站内容侵犯了原著者的合法权益,可联系本站删除。
上一篇
已经是第一篇



