BOS 创建面板组件 表单构建插件 表单插件 设置网页

在单据内通过 BOS 创建面板组件、编写表单构建插件与表单插件,即可把外部网页嵌入金蝶单据,并通过 pageid 实现网页与单据的双向数据交互。

核心机制:pageid
页面与单据的交互正是通过 pageid 完成——单据端把 this.View.PageId 拼进网页 URL,网页端解析 pageid 后通过 postMessage 把数据传回单据。
1
单据上拖一个面板作为存放展示网页的区域
2
给面板所在单据设置「表单构建插件」把面板控件类型改成 kdwebbrowser
C# · 表单构建插件showUrl.cs
public class showUrl : AbstractDynamicWebFormBuilderPlugIn
{
    public override void CreateControl(CreateControlEventArgs e)
    {
        base.CreateControl(e);
        // F_XRRX_Panel1 是你拖入的面板的标识
        if (e.ControlAppearance.Key.EqualsIgnoreCase("F_XRRX_Panel1"))
        {
            // 主要是为了设置类型
            e.Control["xtype"] = "kdwebbrowser";
        }
    }
}
3
设置「表单插件」页面加载后设置嵌套网页地址,并接收网页回传数据
C# · 表单插件GetMessageData.cs
public class GetMessageData : AbstractBillPlugIn
{
    // 页面加载后就要展示,所以在 afterBind 中设置
    public override void AfterBindData(EventArgs e)
    {
        string sourceUrl = string.Format(
            "http://换成你要访问的页面地址/?pageid={0}&content={1}",
            this.View.PageId, "传给页面的参数");

        // 拿到面板控件,设置需要展示的嵌套网页地址,参数通过 url 传参。
        Control webBrowse = this.View.GetControl("F_XRRX_Panel1");
        webBrowse.SetCustomPropertyValue("Source", sourceUrl);
        webBrowse.SetCustomPropertyValue("IsSetBrowseVisible", true);
        // webBrowse.SetCustomPropertyValue("Allowfullscreen", true);

        // 兼容 GUI。
        if (this.View.Context.ClientType != ClientType.Silverlight
            && this.View.Context.ClientType != ClientType.Html)
        {
            webBrowse.InvokeControlMethod("StartTime", 1);
        }
        // this.View.AddAction("notShowMainFormHolder", true);
    }

    // 页面传递过来的值时,通过这个事件接收
    public override void CustomEvents(CustomEventsArgs e)
    {
        // 判断是嵌套网页发起的自定义事件,才执行相关逻辑。
        if (e.EventName.EqualsIgnoreCase("$$MessageCustomerEvent"))
        {
            // 拿到嵌套网页传递过来的 JSON 数据。
            JSONObject data = JSONObject.Parse(e.EventArgs);
            string content = data.GetValue("content", string.Empty);
            this.View.ShowMessage(content);

            // 消息提示完隐藏 WebBrowse,兼容 WPF。
            // Control webBrowse = this.View.GetControl("F_XRRX_Panel1");
            // webBrowse.SetCustomPropertyValue("IsBrowserVisible", false);
        }
    }
}
4
设置网页网页端解析 pageid / content,并通过 postMessage 回传数据
💡 网页端通过 postMessage 把数据发回单据;单据端在 CustomEvents 中监听 $$MessageCustomerEvent 事件接收,实现完整的双向交互闭环。
HTML · 嵌套网页index.html
<!DOCTYPE html>
<html>
<head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
        (function () {
            var formatOrigin = (function () {
                var reg = /^([\w]+?:\/\/.*?(?=\/|$))/i;
                return function (origin) {
                    origin = origin || '';
                    if (reg.test(origin)) {
                        return RegExp.$1;
                    }
                    return '*';
                };
            })();
            var $postMessage = function (r, data) {
                var t = { _top: window.top, _self: window, _parent: window.parent };
                r = t[r];
                if (!r) return;
                r.postMessage(JSON.stringify(data), formatOrigin("*"));
            };
            window._$postMessage = $postMessage;
        })();
    </script>
</head>
<body>
    <div>
        <h1>这是嵌套网页</h1>
        <input id="Text1" type="text" />
        <input id="Button1" type="button" value="提交" />
    </div>
    <script>
        // 定义解析地址参数的方法,用以拿到动态表单传递的地址参数值。
        var getQueryString = function (name) {
            var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
            var r = window.location.search.substr(1).match(reg);
            if (r != null)
                return decodeURIComponent(r[2]);
            return "";
        };

        // 拿到动态表单传递过来的内容参数,并赋值到文本框上。
        $("#Text1").attr("value", getQueryString("content"));

        // 注册按钮点击事件。
        $(document).ready(function () {
            $("#Button1").bind('click', function () {
                var n = {};
                n.pageid = getQueryString("pageid"); // 赋值动态表单传递过来的 pageid 值。
                n.putdata = {}; // 构建传递给动态表单插件的 JSON 参数对象。
                n.putdata.content = $("#Text1").val(); // 将文本框内容传递回动态表单。
                window._$postmessageargs = JSON.stringify(n);
                window._$postMessage("_top", n);
            });
        });
    </script>
</body>
</html>
小结
通过「面板 + 表单构建插件 + 表单插件 + 嵌套网页」四步即可实现单据嵌入网页。核心是借助 pageid 建立单据与网页的绑定关系,再靠 postMessage 完成双向数据传递,适合在单据中集成报表、地图、审批看板等外部页面。