二开案例.表单服务.服务端表单服务

栏目:云星空知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

二开案例.表单服务.服务端表单服务

【应用场景】

将服务端的通用功能封装成表单服务,当操作在服务端执行时,连带执行此服务。



【案例演示】

封装一个发送消息的表单服务,绑定在采购订单的保存操作上,每次保存时,就给指定用户发送一条消息。



【实现步骤】

编写表单服务自定义参数界面->编写表单服务类->注册表单服务->在单据上使用表单服务

<1>打开BOS设计器,设计表单服务自定义参数界面。


<2>编写自定义参数类,用于包装表单服务的自定义参数。

using Kingdee.BOS.Orm.DataEntity;

using System;


namespace Jac.XkDemo.BOS.Core.AppBusinessService

{

    /// <summary>

    /// 发送消息服务的配置参数

    /// </summary>

    [Serializable]

    public class SendMessageParameter

    {

        /// <summary>

        /// 接收人字段Key

        /// </summary>

        [SimpleProperty]

        public string ReceiverKey { get; set; }


        /// <summary>

        /// 组织字段Key

        /// </summary>

        [SimpleProperty]

        public string OrgKey { get; set; }

    }

}


<3>编写表单服务在BOS设计器中的自定义参数界面的控制代码,实现设计时功能。

using DevExpress.XtraEditors.Controls;

using Kingdee.BOS.Core.Designer;

using Kingdee.BOS.Core.Metadata;

using Kingdee.BOS.Core.Metadata.FieldElement;

using Kingdee.BOS.Core.Metadata.FormElement;

using Kingdee.BOS.DomainModelDesigner.PropertyEditor;

using Kingdee.BOS.DomainModelDesigner.ServiceDesigner;

using Kingdee.BOS.Resource;

using Kingdee.BOS.Util;

using Kingdee.BOS.WinForm;

using Kingdee.BOS.WinForm.Ctrl;

using Newtonsoft.Json;

using System.Collections.Generic;

using System.Linq;

using System.Windows.Forms;


namespace Jac.XkDemo.BOS.Core.AppBusinessService

{

    /// <summary>

    /// 发送消息服务配置界面

    /// </summary>

    public class SendMessageDesigner : KDDynamicUserControl, IFormBusinessServiceDesigner

    {

        #region 私有变量、控件


        /// <summary>

        /// 接收人字段(必录)

        /// </summary>

        private KDComboBox cbbReceiverKey;


        /// <summary>

        /// 组织字段

        /// </summary>

        private KDComboBox cbbOrgKey;


        /// <summary>

        /// 界面配置成果

        /// </summary>

        private FormBusinessService businessService;


        #endregion


        #region ctor


        /// <summary>

        /// 构造函数,传入本界面对应的动态表单编码,基类自动完成界面的加载

        /// </summary>

        /// <remarks>

        /// 本界面与特定下推、特定选单共用一个界面,界面改动时,要注意影响

        /// </remarks>

        public SendMessageDesigner()

            : base("Jac_SendMessage")

        {

            // TODO

        }


        #endregion


        #region IFormBusinessServiceDesigner


        /// <summary>

        /// 初始化控件

        /// </summary>

        protected override void InitializeComponent()

        {

            base.InitializeComponent();

            this.cbbReceiverKey = (KDComboBox)(this.GetControl<KDItemContainer>("F_Jac_ReceiverKey").Control);

            this.cbbReceiverKey.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;

            this.cbbOrgKey = (KDComboBox)(this.GetControl<KDItemContainer>("F_Jac_OrgKey").Control);

            this.cbbOrgKey.Properties.TextEditStyle = TextEditStyles.DisableTextEditor;

        }



        /// <summary>

        /// 表单服务编辑控件

        /// </summary>

        public System.Windows.Forms.Control ActionDesignerCtl

        {

            get { return this; }

        }


        /// <summary>

        /// 表单服务实例、描述信息

        /// </summary>

        public FormBusinessService Service { get; set; }


        /// <summary>

        /// 表单服务所在的元素实例

        /// </summary>

        public AbstractElement SourceElement { get; set; }


        /// <summary>

        /// 领域模型设计Model对象,管理元数据信息

        /// </summary>

        public IMetaDataDesignerModel Model { get; set; }


        /// <summary>

        /// 表单服务确定后,返回检查结果

        /// </summary>

        private bool actionValidated;


        /// <summary>

        /// 表单服务确定后,返回检查结果

        /// </summary>

        public bool ActionValidated

        {

            get

            {

                this.actionValidated = true; // 默认为通过

                // 校验

                var errorMessage = string.Empty;

                if (!ValidateOperateParameter(ref errorMessage))

                {

                    KDMessageBox.Show(errorMessage, "金蝶提示", MessageBoxButtons.OK);

                    this.actionValidated = false;

                    return this.actionValidated;

                }


                return this.actionValidated;

            }

            set { this.actionValidated = value; }

        }


        /// <summary>

        /// 表单服务类型

        /// </summary>

        public string ActionType { get; set; }


        /// <summary>

        /// 开始解析、展示实例数据

        /// </summary>

        public new void Load()

        {

            this.businessService = this.Service;

            if (this.businessService == null)

            {

                this.businessService = new FormBusinessService(this.Service);

            }


            var businessInfo = this.Model.FormMetaData.BusinessInfo;

            // 把已经配置的服务参数,展示到界面上

            SendMessageParameter sendMessageParameter = null;

            if (!string.IsNullOrWhiteSpace(businessService.Setting))

            {

                sendMessageParameter = JsonConvert.DeserializeObject<SendMessageParameter>(businessService.Setting);

            }


            if (sendMessageParameter == null)

            {

                sendMessageParameter = new SendMessageParameter();

            }


            BindReceiver(businessInfo, sendMessageParameter);

            BindOrg(businessInfo, sendMessageParameter);

        }


        /// <summary>

        /// 打包、提交表单服务实例

        /// </summary>

        public void Commit()

        {

            var sendMessageParameter = new SendMessageParameter();

            var receiverKey = this.cbbReceiverKey.EditValue as ListItem;

            if (receiverKey != null)

            {

                sendMessageParameter.ReceiverKey = receiverKey.Value.ToString();

            }


            var orgKey = this.cbbOrgKey.EditValue as ListItem;

            if (orgKey != null)

            {

                sendMessageParameter.OrgKey = orgKey.Value.ToString();

            }


            businessService.Setting = JsonConvert.SerializeObject(sendMessageParameter);

            this.Service = this.businessService;

        }


        #endregion


        #region 私有函数


        /// <summary>

        /// 绑定接收人字段

        /// </summary>

        private void BindReceiver(BusinessInfo businessInfo, SendMessageParameter parameter)

        {

            this.cbbReceiverKey.Properties.Items.Clear();

            var userFields = businessInfo.GetFieldList().Where(o => o is UserField).ToList();

            var list = new List<ListItem>();

            list.Add(new ListItem("", ""));

            ListItem defaultItem = null;

            var hasDefaultItem = !string.IsNullOrWhiteSpace(parameter.ReceiverKey);

            foreach (var field in userFields)

            {

                var item = new ListItem(field.Key, field.Name.ToString());

                list.Add(item);

                if (hasDefaultItem && field.Key.EqualsIgnoreCase(parameter.ReceiverKey))

                {

                    defaultItem = item;

                }

            }


            this.cbbReceiverKey.Properties.Items.AddRange(list);

            if (defaultItem != null)

            {

                this.cbbReceiverKey.EditValue = defaultItem;

            }

            else

            {

                this.cbbReceiverKey.EditValue = list[0];

            }

        }


        /// <summary>

        /// 绑定组织字段

        /// </summary>

        private void BindOrg(BusinessInfo businessInfo, SendMessageParameter parameter)

        {

            this.cbbOrgKey.Properties.Items.Clear();

            var orgFields = businessInfo.GetFieldList().Where(o => o is OrgField).ToList();

            var list = new List<ListItem>();

            list.Add(new ListItem("", ""));

            ListItem defaultItem = null;

            var hasDefaultItem = !string.IsNullOrWhiteSpace(parameter.OrgKey);

            foreach (var field in orgFields)

            {

                var item = new ListItem(field.Key, field.Name.ToString());

                list.Add(item);

                if (hasDefaultItem && field.Key.EqualsIgnoreCase(parameter.OrgKey))

                {

                    defaultItem = item;

                }

            }


            this.cbbOrgKey.Properties.Items.AddRange(list);

            if (defaultItem != null)

            {

                this.cbbOrgKey.EditValue = defaultItem;

            }

            else

            {

                this.cbbOrgKey.EditValue = list[0];

            }

        }


        /// <summary>

        /// 校验参数对象

        /// </summary>

        /// <param name="errorMessage"></param>

        /// <returns></returns>

        private bool ValidateOperateParameter(ref string errorMessage)

        {

            SendMessageParameter sendMessageParameter = null;

            if (!string.IsNullOrWhiteSpace(businessService.Setting))

            {

                sendMessageParameter = JsonConvert.DeserializeObject<SendMessageParameter>(businessService.Setting);

            }


            if (sendMessageParameter == null || string.IsNullOrWhiteSpace(sendMessageParameter.ReceiverKey))

            {

                errorMessage = "请设置接收人字段";

                return false;

            }


            return true;

        }


        #endregion 配置校验

    }

}


<4>编写服务端表单服务,实现运行时功能。

using Kingdee.BOS;

using Kingdee.BOS.App.Data;

using Kingdee.BOS.Core.DynamicForm;

using Kingdee.BOS.Core.Enums;

using Kingdee.BOS.Core.Metadata.FormElement;

using Kingdee.BOS.Core.Msg;

using Kingdee.BOS.Msg;

using Kingdee.BOS.Orm;

using Kingdee.BOS.Orm.DataEntity;

using Kingdee.BOS.Util;

using Newtonsoft.Json;

using System;

using System.Collections.Generic;


namespace Jac.XkDemo.BOS.Core.AppBusinessService

{

    /// <summary>

    /// 【服务层表单服务】发送消息

    /// </summary>

    public class SendMessageService : AbstractAppBusinessService

    {

        #region var


        /// <summary>

        /// 服务端表单服务执行参数

        /// </summary>

        private AppBusinessServiceArgs appBusinessServiceArgs;


        /// <summary>

        /// 服务配置

        /// </summary>

        private FormBusinessService serviceConfig;


        #endregion


        #region IAppFormBusinessService


        /// <summary>

        /// 重载是否允许在IDE中设定执行时机:本服务不允许在IDE设定时间点,服务要求必须在操作后执行

        /// </summary>

        public override bool SupportActionPoint

        {

            get { return false; }

        }


        /// <summary>

        /// 重载执行时间点:设定本服务仅在操作后执行

        /// </summary>

        public override int ActionPoint

        {

            get { return (int)BOSEnums.Enu_ServiceActionPoint.AfterOperation; }

        }


        /// <summary>

        /// 是否允许批量执行?本服务允许批量执行;

        /// </summary>

        public override bool RequestBatchProcess

        {

            get { return true; }

        }


        /// <summary>

        /// 添加本服务必须加载的字段

        /// </summary>

        /// <param name="fieldKeys"></param>

        public override void PreparePropertys(List<string> fieldKeys)

        {

            // TODO:服务中要用到的字段,需提前注册

            //fieldKeys.Add("FXXX");

        }


        /// <summary>

        /// 服务执行函数:在允许批量执行时,本函数不会被调用

        /// </summary>

        /// <param name="e"></param>

        public override void DoAction(AppBusinessServiceArgs e)

        {

            // TODO: 本服务允许批量执行,本函数不会被调用,无需实现

        }


        /// <summary>

        /// 服务执行函数:在允许批量执行时,本函数被调用

        /// </summary>

        /// <param name="e"></param>

        public override void DoActionBatch(AppBusinessServiceArgs e)

        {

            this.appBusinessServiceArgs = e;

            this.serviceConfig = e.FormBusinessService;

            this.SendMessage();

        }


        #endregion


        #region 辅助函数


        private void SendMessage()

        {

            if (string.IsNullOrWhiteSpace(serviceConfig.Setting))

            {

                return;

            }


            var sendMessageParameter = JsonConvert.DeserializeObject<SendMessageParameter>(serviceConfig.Setting);

            if (string.IsNullOrWhiteSpace(sendMessageParameter.ReceiverKey))

            {

                return;

            }


            var userField = appBusinessServiceArgs.FullBusinessInfo.GetField(sendMessageParameter.ReceiverKey);

            if (userField == null)

            {

                return;

            }


            var value = userField.GetFieldValue(appBusinessServiceArgs.DataEntity) as DynamicObject;

            if (value == null)

            {

                return;

            }


            var receiverId = Convert.ToInt64(value[0]);

            var title = string.Format("【{0}】操作执行通知", appBusinessServiceArgs.FullBusinessInfo.GetForm().Name);

            var billNo = appBusinessServiceArgs.FullBusinessInfo.GetBillNoField().GetFieldValue(appBusinessServiceArgs.DataEntity);

            var msg = string.Format("单据编号为【{0}】的【{1}】执行了【{2}】操作", billNo, appBusinessServiceArgs.FullBusinessInfo.GetForm().Name, appBusinessServiceArgs.FormOperation.OperationName);

            SendMessage(Context, appBusinessServiceArgs.FullBusinessInfo.GetForm().Id, appBusinessServiceArgs.DataEntity[0].ToString()

                , title, msg, Context.UserId, receiverId);

        }


        /// <summary>

        /// 发送消息(精简版,仅支持一个收件人,不写发件箱)

        /// </summary>

        /// <param name="ctx"></param>

        /// <param name="formId"></param>

        /// <param name="pkId"></param>

        /// <param name="title"></param>

        /// <param name="content"></param>

        /// <param name="senderId"></param>

        /// <param name="receiverId"></param>

        private static void SendMessage(Context ctx, string formId, string pkId, string title, string content, long senderId, long receiverId)

        {

            Message msg = new DynamicObject(Message.MessageDynamicObjectType);

            msg.MessageId = SequentialGuid.NewGuid().ToString();

            msg.MsgType = MsgType.CommonMessage;

            msg.SenderId = senderId;

            msg.ReceiverId = receiverId;

            msg.Title = title;

            msg.Content = content;

            msg.ObjectTypeId = formId;

            msg.KeyValue = pkId;

            msg.CreateTime = DateTime.Now;

            // 保存消息

            var dataManager = DataManagerUtils.GetDataManager(Message.MessageDynamicObjectType, new OLEDbDriver(ctx));

            dataManager.Save(msg.DataEntity);

        }


        #endregion

    }

}


<5>将表单服务注册到BOS平台。

-- 数据库执行以下脚本,注册表单服务

-- 注册服务层表单服务

DELETE FROM T_MDL_FORMBUSINESS WHERE FACTIONID=88801

INSERT INTO T_MDL_FORMBUSINESS

        ( FACTIONID ,

          FNAME ,

          FTYPE ,

          FSETCOMPONENT ,

          FRUNCOMPONENT ,

          FDESIGNERVISIBLE ,

          FREVERSEACTIONCLASS ,

          FPUSHCOMPONENT ,

          FDEFAULTRAISETYPE ,

          FAPPSCENARIOTYPE

        )

VALUES  ( 88801 , -- FACTIONID - int

          'SendMessage' , -- FNAME - varchar(50)

          8 , -- FTYPE - int

          'Jac.XkDemo.BOS.Core.AppBusinessService.SendMessageDesigner, Jac.XkDemo.BOS.Core' , -- FSETCOMPONENT - varchar(150)

          'Jac.XkDemo.BOS.Core.AppBusinessService.SendMessageService, Jac.XkDemo.BOS.Core' , -- FRUNCOMPONENT - varchar(150)

          1 , -- FDESIGNERVISIBLE - int

          '' , -- FREVERSEACTIONCLASS - varchar(150)

          '' , -- FPUSHCOMPONENT - varchar(150)

          41 , -- FDEFAULTRAISETYPE - int

          1  -- FAPPSCENARIOTYPE - int

        )

DELETE FROM T_MDL_FORMBUSINESS_L WHERE FACTIONID=88801

INSERT INTO T_MDL_FORMBUSINESS_L

        ( FPKID ,

          FACTIONID ,

          FLOCALEID ,

          FDESC ,

          FSYNTAX ,

          FPARAMETER

        )

VALUES  ( (SELECT ISNULL(MAX(FPKID),0)+1 FROM T_MDL_FORMBUSINESS_L) , -- FPKID - int

          88801 , -- FACTIONID - int

          2052 , -- FLOCALEID - int

          N'发送消息' , -- FDESC - nvarchar(255)

          N'SendMessage()' , -- FSYNTAX - nvarchar(255)

          N'发送消息'  -- FPARAMETER - nvarchar(1000)

        )

---------------------------------------------------------------------------------------------------------


<6>拷贝当前组件到应用站点的WebSite\Bin目录下,重启IIS。


<7>拷贝当前组件到BOS设计器运行目录下,重新登录BOS设计器。

BOS设计器通常安装在目录:C:\Program Files (x86)\Kingdee\K3Cloud\DeskClient\K3CloudClient


<8>BOS设计器扩展采购订单,保存操作注册发送消息的表单服务,保存元数据,至此,开发完毕。



【功能验证】

<1>登录业务站点,打开采购订单列表,进入某个采购订单的编辑界面,执行保存操作,此时,对应操作人会收到一条普通消息。

执行保存操作:

收到普通消息:

---------------------------------------------------------------------------------------------------------



【知识点】

<1>表单服务对应的元数据:

<2>如果表单服务在BOS设计器中使用了自定义参数,那么对应组件需要同步更新到BOS设计器运行目录,如果是本地测试,直接拷贝一下就可以快速测试了,如果是生产环境,建议将组件统一打包到部署包中,打包方式可参考教程:https://vip.kingdee.com/school/97996311328065024

---------------------------------------------------------------------------------------------------------











【金蝶云星空BOS二次开发案例演示】https://vip.kingdee.com/article/94751030918525696

二开案例.表单服务.服务端表单服务

【应用场景】将服务端的通用功能封装成表单服务,当操作在服务端执行时,连带执行此服务。【案例演示】封装一个发送消息的表单服务,绑定在...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息