服务插件如何抛出交互信息

需求背景:

服务插件中,需要弹出消息界面,供用户确认是否继续,或者录入数据后继续;
因为这样的信息,需要用户确认,称之为交互信息。

简单一点的交互信息,由平台标准消息显示界面显示,包括了提示内容,是、否两个按钮:如果选择是,则继续操作;
复杂一点的交互信息,可以由二开自行定制消息显示界面,显示非常复杂的信息,并要求用户录入内容后继续:如录入密码进行二次验权等。

本帖的示例代码,在一个操作中,依次弹出这两种交互信息。

案例说明:

本案例,需要一个单据A、一个动态表单B:

在单据A的保存操作上,挂上示例代码中的操作插件:
用于制造交互信息;单据上有什么字段不做要求;

动态表单B,挂上示例代码中的界面插件:
用于显示定制消息,上面放两个标签控件,两个按钮;其他不做要求;

运行效果:

1. 新建单据A,保存;
2. 弹出第一条交互信息:用K/3 Cloud标准的消息显示界面显示;
3. 点击"是",确认继续;
4. 弹出第二条交互信息:用自定义的消息显示界面;
5. 点击“继续”,继续保存;
6. 保存完毕,给出操作成功提示;

图一:标准交互消息显示界面
20160426 00交互信息1.png 


图二:定制交互消息显示界面
20160426 00交互信息2.png 


需掌握的技术难点:
1. 如何显示标准的交互信息?
2. 如何显示定制的交互信息?
3. 一个操作需要显示两条交互信息,即需要多次重新执行操作,如何避免重复显示?
4. 如何把定制消息输出到定制界面,并接收定制界面传回的用户录入结果?

示例代码(本地验证通过)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;
using Kingdee.BOS.Core.Interaction;
namespace JDSample.ServicePlugIn.Operation
{
    [Description("如何显示交互信息:操作插件,给出交互信息内容")]
    public class S160425ShowInteractionOpPlug : AbstractOperationServicePlugIn
    {
        /// <summary>
        /// 操作事务开始事件
        /// </summary>
        /// <param name="e"></param>
        /// <remarks>
        /// 只有BeginOperationTransaction、EndOperationTransaction这两个事件,才能够按照本示例代码弹出交互信息
        /// </remarks>
        public override void BeginOperationTransaction(BeginOperationTransactionArgs e)
        {
            // 利用K3标准消息显示界面,显示交互消息
            this.ShowK3DisplayMessage();
            // 利用自定义消息显示界面,显示交互消息
            this.ShowCustomMsgForm();
        }
        /// <summary>
        /// 利用K/3 Cloud标准的交互消息界面,显示消息:通常用于给用户选择是、否
        /// </summary>
        /// <remarks>
        /// 本案例,向用户提示负库存,如果用户选择是,则继续操作;否则中断操作
        /// </remarks>
        private void ShowK3DisplayMessage()
        {
            // 判断操作校验是否通过 : 如果通过了校验,则不用给出提示
            if (this.OperationCheck1())
            {
                return;
            }
            // 定义交互消息标识,以与其他交互消息区分开
            string spensorKey = "JDSample.ServicePlugIn.Operation.S160425ShowInteractionOpPlug.ShowK3DisplayMessage";
            
            // 判断用户是否已经确认过本交互信息
            if (this.Option.HasInteractionFlag(spensorKey))
            {
                // this.Option.HasInteractionFlag()在如下两种情况下,返回true:
                // 1. 用户已经确认过本交互信息,并选择了继续
                // 2. 外围代码,在调用本操作前,通过如下代码,强制要求不显示交互消息:
                // this.Option.SetIgnoreInteractionFlag(true);
                // 因此,如果 this.Option.HasInteractionFlag() == true, 表示需要忽略本交互
                return;
            }
            // 提示信息的列标题,以“~|~”分开两列
            string titleMsg = "行号~|~物料编码~|~物料名称~|~单据数量~|~序列号数量~|~错误消息";
            // 对应的提示信息格式,以"~|~"分开两列,以{n}进行占位
            string errMsg = "{0}~|~{1}~|~{2}~|~{3}~|~{4}~|~{5}";
            // 构建消息模型K3DisplayerModel,在此对象中,添加消息内容
            K3DisplayerModel model = K3DisplayerModel.Create(Context, titleMsg);
            // 消息内容:可以添加多行
            string rowMsg = string.Format(errMsg, "1", "1.01.001", "50KW柴油机", "10 Pcs", "10 Pcs", "库存不够,继续操作,会引起负库存,是否继续?");
            ((K3DisplayerModel)model).AddMessage(rowMsg);
            // 消息抬头
            model.Option.SetVariableValue(K3DisplayerModel.CST_FormTitle, "有多条信息需要您确认,是否继续?");
            // 是否继续按钮
            model.OKButton.Visible = true;
            model.OKButton.Caption = new LocaleValue("是", Context.UserLocale.LCID);
            model.CancelButton.Visible = true;
            model.CancelButton.Caption = new LocaleValue("否", Context.UserLocale.LCID);
            // 创建一个交互提示错误对象KDInteractionException:
            // 通过throw new KDInteractionException()的方式,向操作调用者,输出交互信息
            KDInteractionException ie = new KDInteractionException(this.Option, spensorKey);
            // 提示信息显示界面
            ie.InteractionContext.InteractionFormId = FormIdConst.BOS_K3Displayer;
            // 提示内容
            ie.InteractionContext.K3DisplayerModel = model;
            // 是否需要交互
            ie.InteractionContext.IsInteractive = true;
            // 抛出错误,终止流程
            throw ie; 
        }
        /// <summary>
        /// 利用自定义消息显示界面,显示交互消息:通常用于给用户输入数值、密码等
        /// </summary>
        /// <remarks>
        /// 这种消息显示模式,需要自定义界面显示消息;
        /// 自定义消息界面插件示例代码为S160425ShowInteractionEdit
        /// </remarks>
        private void ShowCustomMsgForm()
        {
            // 定义交互消息标识,以与其他交互消息区分开
            string spensorKey = "JDSample.ServicePlugIn.Operation.S160425ShowInteractionOpPlug.ShowCustomMsgForm";
            // 判断用户是否已经确认过本交互信息
            if (this.Option.HasInteractionFlag(spensorKey))
            {
                // this.Option.HasInteractionFlag()在如下两种情况下,返回true:
                // 1. 用户已经确认过本交互信息,并选择了继续
                // 2. 外围代码,在调用本操作前,通过如下代码,强制要求不显示交互消息:
                // this.Option.SetIgnoreInteractionFlag(true);
                // 因此,如果 this.Option.HasInteractionFlag() == true, 表示需要忽略本交互
                return;
            }
            // 如果已经交互过,获取交互时用户录入的数据:如果没有交互过,获得的结果为null
            RespondDataContext respondData = this.Option.GetInteractionFlag(spensorKey);
            var interactionFormResult = respondData.FormResult;
            // 判断操作校验是否通过 : 如果通过了校验,则不用给出提示
            if (this.OperationCheck2(interactionFormResult))
            {
                return;
            }
            // 自定义任意的消息模型,以传递消息内容;
            // 本演示代码,仅供参考:现场可以自行创建各种对象向外传递
            dynamic customMessageModel = new System.Dynamic.ExpandoObject();
            customMessageModel.MessageTitle = "属性1的值(仅供演示)";
            customMessageModel.MessageContent = "属性2的值(仅供演示)";
            // 创建自定义消息界面ShowParameter参数 : 把自定义消息数据,附加到参数中
            DynamicFormShowParameter showParameter = new DynamicFormShowParameter();
            showParameter.CustomComplexParams.Add("CustomMessageModel", customMessageModel);
            // 创建一个交互提示错误对象KDInteractionException:
            // 通过throw new KDInteractionException()的方式,向操作调用者,输出交互信息
            KDInteractionException ie = new KDInteractionException(this.Option, spensorKey);
            // 提示信息显示界面 :自定义消息界面FormId
            ie.InteractionContext.InteractionFormId = "ec1e91f227f443ff869b48a5de6f1db4";
            // 自定义消息界面ShowParameter参数
            ie.InteractionContext.FormShowParameter = showParameter; 
            // 是否需要交互
            ie.InteractionContext.IsInteractive = true;
            // 抛出错误,终止流程
            throw ie; 
        }
        /// <summary>
        /// 操作校验:如果校验不通过,则需要给出交互提示。
        /// </summary>
        /// <returns></returns>
        /// <remarks>
        /// 本案例,强制返回校验不通过,以演示交互信息显示效果
        /// </remarks>
        private bool OperationCheck1()
        {
            return false;
        }
        /// <summary>
        /// 操作校验:如果校验不通过,则需要给出交互提示。
        /// </summary>
        /// <param name="interactionFormResult">用户在交互界面上录入的内容</param>
        /// <returns></returns>
        /// <remarks>
        /// 本案例,强制返回校验不通过,以演示交互信息显示效果
        /// </remarks>
        private bool OperationCheck2(InteractionFormResult interactionFormResult)
        {
            if (interactionFormResult == null)
            {
                return false;
            }
            else
            {
                // TODO: 进一步判断用户录入的内容是否合法
                // 示例代码略过判断,直接返回true
                return true;
            }
        }
    }
    /// <summary>
    /// 消息界面插件
    /// </summary>
    /// <remarks>
    /// 界面上,包括两个标签,显示消息标题与正文;
    /// 两个按钮:继续,取消
    /// </remarks>
    [Description("如何显示交互信息:定制消息界面插件,显示出交互信息内容")]
    public class S160425ShowInteractionEdit : AbstractDynamicFormPlugIn
    {
        private dynamic _customMessageModel;
        /// <summary>
        /// 接收操作给出的自定义消息对象
        /// </summary>
        /// <param name="e"></param>
        public override void OnInitialize(InitializeEventArgs e)
        {
            // 取到操作插件传出的自定义消息对象:后面需要把消息对象中的内容,显示到界面上
            this._customMessageModel = e.Paramter.GetCustomParameter("CustomMessageModel");
        }
        /// <summary>
        /// 在界面上显示消息内容
        /// </summary>
        /// <param name="e"></param>
        public override void AfterBindData(EventArgs e)
        {
            if (this._customMessageModel != null)
            {
                this.View.GetControl("F_JD_MessageTitle").Text = this._customMessageModel.MessageTitle;
                this.View.GetControl("F_JD_MessageContent").Text = this._customMessageModel.MessageContent;
            }
        }
        /// <summary>
        /// 用户选择完毕,系统继续
        /// </summary>
        /// <param name="e"></param>
        public override void ButtonClick(ButtonClickEventArgs e)
        {
            if (e.Key.EqualsIgnoreCase("F_JD_Yes"))
            {// 用户选择了继续
                
                // 是否继续
                bool redo = true;
                // 在此执行操作时,需要传递给服务端插件的内容,如用户选择的选项,录入的数值等:
                // 服务端插件,需要据此进行后续处理
                dynamic redoParameter = new System.Dynamic.ExpandoObject();
                redoParameter.Field1 = "用户录入的值(仅供演示)";
                // 把需要传递给服务操作插件的数据,包在InteractionFormResult对象中,返回给父界面
                this.View.ReturnToParentWindow(new InteractionFormResult(redo, redoParameter));
                // 关闭消息显示界面
                this.View.Close();
            }
            else if (e.Key.EqualsIgnoreCase("F_JD_No"))
            {
                // 不需继续,直接关闭界面即可
                this.View.Close();
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的Unity VR拾取和物品的示例代码。该代码使用SteamVR件和Oculus Touch手柄进行交互。 ``` using UnityEngine; using Valve.VR; using System.Collections; public class VRPickupThrow : MonoBehaviour { private SteamVR_TrackedObject trackedObject; private SteamVR_Controller.Device device; private Rigidbody rigidbody; private Transform originalParent; private bool isHolding = false; private void Awake() { trackedObject = GetComponent<SteamVR_TrackedObject>(); rigidbody = GetComponent<Rigidbody>(); originalParent = transform.parent; } private void FixedUpdate() { device = SteamVR_Controller.Input((int)trackedObject.index); if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)) { Pickup(); } else if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger)) { Throw(); } } private void Pickup() { if (!isHolding) { RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit)) { if (hit.collider.gameObject.GetComponent<Rigidbody>()) { rigidbody = hit.collider.gameObject.GetComponent<Rigidbody>(); rigidbody.isKinematic = true; transform.SetParent(hit.collider.gameObject.transform); isHolding = true; } } } } private void Throw() { if (isHolding) { rigidbody.isKinematic = false; transform.SetParent(originalParent); rigidbody.velocity = device.velocity; rigidbody.angularVelocity = device.angularVelocity; isHolding = false; } } } ``` 在这个代码中,我们创建了一个名为VRPickupThrow的脚本。它有以下功能: - 跟踪SteamVR手柄的输入 - 检测手柄是否按下或松开扳机按钮 - 在按下触发器时,拾取附近的刚体物体并将其作为子对象附加到手柄上 - 在松开触发器时,将物体并恢复其自由运动 要使用这个脚本,将其添加到您想要交互的物体上。确保该物体具有刚体组件和碰撞器。还需要安装SteamVR件并连接Oculus Touch手柄。最后,您需要将此脚本附加到SteamVR手柄上。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值