增加功能:定制GUI登录界面插件 (目前仅支持到WPF的GUI客户端程序)
金蝶云社区-端端
端端
6人赞赏了该文章 1616次浏览 未经作者许可,禁止转载编辑于2018年05月13日 14:42:28

增加功能:定制GUI登录界面插件 (目前仅支持到WPF的GUI客户端程序) 版本:K/3 CLoud V6.0

一、应用背景

    在特殊行业应用中,对登录需求有特定业务场景,需要定制一些登录特定逻辑,例如医疗系统,POS系统,B2C后台系统等等。这时候通用界面可能信息太多,需要做 适当简化,就需要用到定制登录界面UI来满足需求。

 

二、部署二次开发组件

1、在K/3 Cloud服务器安装目录的【WebSite/ClientBin/CustomControl/WPF】目录下部署二次开发组件,这个目录安装包会创建。自定义组件可以用Zip压缩文件压缩为Zip格式,后修改后缀名为.kdz。

 

2、配置组件下载列表MainDownloadList.xml

 

2.1、运行记事本编辑器,打开安装目录【WebSite/ClientBin/CustomControl/WPF/MainDownloadList.xml】的文件。

1.jpg


手工拷贝一个节点(一个文件需要一个节点进行注册如下图)。然后修改绿色的文件名为你的组件名就好了

2.jpg

2.2、如果有组件需要更新,请拷贝相关组件到【WebSite/ClientBin/CustomControl/WPF】目录下,并执行上面2.1的步骤,注意更新组件的动作仅在客户端启动时运行一次。同时需要修改注册文件的版本号,以便客户端能够更新到最新组件,如下图:

3.png 3、启动K/3 Cloud客户端桌面版程序,这时程序会自动按照服务器地址设定检查组件版本,并按需要下载相关客制化组件到本地的 【%Program Files %\Kingdee\K3Cloud\DeskClient\K3CloudClient\controlplugins】目录下。


4、启动定制登录UI组件,在【%Program Files %\Kingdee\K3Cloud\WebSite\App_Data\】目录下,打开编辑Common.config,找到Appsettings节点,在该节点子节点中加入如下新节点,保存即启动插件成功:
    <!--定制化登录界面-->
    <add key ="CustomLoginUI" value="Kingdee.XPF.CustomControlPlugins.CustomLoginUI,Kingdee.XPF.CustomControlPlugins" />
特别注意:(千万不要修改上面的key属性,固定必须是“CustomLoginUI"value可以替换为你自己开发的控件组件,例如“LoginTest.LoginUI,LoginTest”,通用的DotNet类描述格式)


三、制作定制登录UI界面组件

1、在Visual Studio 2012中新增类库工程;需要新增有WPF界面元素的,必须新建WPF类库类型的工程。

 

2、引用服务器安装目录下IDE的基础组件如下(安装K/3 Cloud安装包+最新补丁,可得下面组件):
Kingdee.BOS.dll [必选],
Kingdee.BOS.Client.Core.dll [必选],
Kingdee.BOS.ServiceFacade.KDServiceClient.dll [可选],
Kingdee.BOS.ServiceFacade.KDServiceClientFx.dll [可选],

Kingdee.BOS.XPF.ControlPlugins.Contracts.dll [可选]

 

3、新建继承自DotNetWPF框架的UserControl(WPF)的类,编写定制化登录UI控件桌面客户端代码如下。重点实现IKDLoginControl接口。

重点关注LoginInfo GetLoginInfo()接口实现和调用 this.Owner.DoLogin()以及成功登录后调用this.Owner.LoadMainWindow()接口进入主控界面。
4、2015-11-09,6.0发布后,6.0的This.Owner接口改为IKDLoginControlOwner类型了。二开代码访问必须符合该接口类型。


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Kingdee.BOS.Client.Core;
using Kingdee.BOS.Authentication;
using Kingdee.BOS.ServiceFacade.KDServiceClient.Account;
using Kingdee.BOS.ServiceFacade.KDServiceClient;
using Kingdee.BOS.DataCenterInfo;
namespace Kingdee.XPF.CustomControlPlugins
{
    /// <summary>
    /// Interaction logic for CustomLoginUI.xaml
    /// </summary>
    public partial class CustomLoginUI : UserControl ,IKDLoginControl
    {
        IKDLoginControlOwner Owner { get; set; }
        ItemModel currentDataCenter { get; set; }
        public CustomLoginUI()
        {
            InitializeComponent();
        }
        public void ClearData()
        {
        }
        public void DoLogin()
        {
        }
        public bool Focus(string key)
        {
            return true;
        }
        public LoginInfo GetLoginInfo()
        {
            var sDCName = DCName.Text;
            var proxy = new AccountClientProxy();
            var dt = DateTime.Now;
            var dclist = proxy.GetDataCenterList();
            var dcItem = dclist.Find(new Predicate<DataCenter>((dc) =>
            {
                return dc.Name.Equals(sDCName);
            }));
            this.currentDataCenter = new ItemModel()
            {
                ID = dcItem.Id,
                Header = dcItem.Name
            };
            string userName = this.UserName.Text.Trim();
            string userPwd = this.PWD.Text.Trim();
            int lcid = 2052;
            string acctID = this.currentDataCenter.ID;
            var loginInfo = new LoginInfo()
            {
                Username = userName,
                Password = userPwd,
                AcctID = acctID,
                Lcid = lcid,
                AuthenticateType = AuthenticationType.PwdAuthentication,
                ClientInfo = this.GetOwner().GetClientInfo()
            };
            return loginInfo;
        }
        public IKDLoginControlOwner GetOwner()
        {
            return this.Owner;
        }
        /// <summary>
        /// 获取窗口标题信息
        /// </summary>
        /// <returns></returns>
        public string GetFormTitle()
        {
            return "Customize Login UI For Third Provider.";
        }
        public bool IsDataLoaded()
        {
            return true;
        }
        public void LoadLocalSettings()
        {
            ;
        }
        public IKDLoginControl NewInstance()
        {
            return new CustomLoginUI();
        }
        public void SaveLoginSettings()
        {
            ;
        }
        public void SetOwner(IKDLoginControlOwner owner)
        {
            this.Owner = owner;
        }
        public void SetProgressTips(string tips)
        {
            ;
        }
        public void UpdateGobalLocalId(string localId)
        {
            ;
        }
        public void Release()
        {
            this.Owner = null;
        }
        public KDSize GetUISize()
        {
            return new KDSize() { Height = 500, Width = 700 };
        }
        private void btnDoLogin_Click(object sender, RoutedEventArgs e)
        {
            var sDCName = DCName.Text;
            var ret = this.Owner.DoLogin();
            ret.Context.DataCenterName = sDCName;
            if (ret.LoginResultType == LoginResultType.Success)
            {
                this.Owner.LoadMainWindow();
            }
            else
            {
                this.Owner.ShowErrorMessage(new Exception(ret.Message));
            }
        }
    }
}


四、例子
1、按照【二、部署二次开发插件】中的第4小点打开默认插件;
2、运行客户端GUI程序应用,将会看到登录界面变成如下Demo定制登录UI插件的界面(演示界面,未做任何修饰和密码处理),如下图:
4.png

五、登录后逻辑 。(2016-03-18补丁功能)
1、登陆后获取LoginResult对象,判断是否需要窗口提示,并参考2中的工具类进行使用;
2、登录窗口弹出工具类:
2.1 使用系统默认密码修改框提示密码修改

Kingdee.BOS.XPF.Component.Utils.KDLoginUtils.ShowModifyPwdWindow(this.Owner as Window, new Action(() =>{
        this.pbx_Pwd.Password = "";
        this.pbx_Pwd.Focus();
}));


2.2 制定自定义单据FormId密码修改框提示密码修改
var arg = new Kingdee.BOS.Client.Core.KDLoginInfoChangeArgs()
{
        OldPwd = oldPwd,
        UserId = userid,
        FormId = pwdFormid,//自定义单据
        LayoutId = layoutid//自定义单据布局ID,为空默认布局
};
Kingdee.BOS.XPF.Component.Utils.KDLoginUtils.KDLoginUtils.ShowModifyPwdWindow(arg, AfterOpenPublishForm);


2.3 制定自定义单据FormId提示相关操作
var arg = new KDLoginInfoChangeArgs()
{
    FormId = formId,//自定义单据
    InputData = inputData//自定义单据传入数据,格式自定义
};
Kingdee.BOS.XPF.Component.Utils.KDLoginUtils.KDLoginUtils.ShowSpecialForm(arg, AfterOpenSpecialForm);

2.4在K/3 Cloud的默认登录界面中,针对LoginResult.LoginResultType的处理如下,可以作为你的插件参考:a


                        switch (loginRet.LoginResultType)
                        {
                            case LoginResultType.Failure:
                                KDMessageBox.Show(loginRet.Message,
                                    ResManager.LoadKDString("信息提示", "014001000000097"),
                                    this.Owner as Window, KDMesType.Error);
                                this.pbx_Pwd.Focus();
                                return;
                            case LoginResultType.PWError:
                                KDMessageBox.Show(loginRet.Message,
                                    ResManager.LoadKDString("信息提示", "014001000000097"),
                                    this.Owner as Window, KDMesType.Warn);
                                this.pbx_Pwd.Focus();
                                this.pbx_Pwd.Password = "";
                                return;
                            case LoginResultType.PWInvalid_Optional:
                                this.pbx_Pwd.Password = "";
                                if (KDMessageBox.Show(loginRet.Message,
                                    ResManager.LoadKDString("密码修改提示", "014001000000100"),
                                    this.Owner as Window, KDMesType.Question, KDMesButtons.YesNo) == KDMesResult.Yes)
                                {
                                    ShowModifyPwdWindow(oldPwd, loginRet.Context == null ? "" : loginRet.Context.UserId.ToString());
                                    return;
                                }
                                break;
                            case LoginResultType.PWInvalid_Required:
                                this.pbx_Pwd.Password = "";
                                KDMessageBox.Show(loginRet.Message,
                                    ResManager.LoadKDString("密码修改提示", "014001000000100"),
                                    this.Owner as Window, KDMesType.Warn);
                                ShowModifyPwdWindow(oldPwd, loginRet.Context == null ? "" : loginRet.Context.UserId.ToString());
                                return;
                            case LoginResultType.Activation:
                                ShowModifyPwdWindow(oldPwd, loginRet.Context == null ? "" : loginRet.Context.UserId.ToString(), "SEC_SetPwd");
                                return;
                            case LoginResultType.Wanning:
                                KDMessageBox.Show(loginRet.Message,
                                    ResManager.LoadKDString("警告提示", "014001000001548"),
                                    this.Owner as Window, KDMesType.Warn, KDMesButtons.Ok);
                                break;
                            case LoginResultType.DealWithForm:
                                if (string.IsNullOrWhiteSpace(loginRet.FormId)) break;
                                ShowSpecialForm(loginRet.FormId, loginRet.FormInputObject);
                                return;
                            default:
                                break;
                        }



3、在工具类显示指定表单后,在该表单的业务插件中编写自己的业务逻辑。
传入数据在业务插件中提取:

var custArgs = this.View.OpenParameter.GetCustomParameter("inputData");




六、web端的定制登录方案
1、制作定制登录网页;
2、制作定制登录逻辑实现免登录服务端插件,参考:【利用启动插件校验机制实现免登录功能,实现跨系统无缝集成】链接地址: https://vip.kingdee.com/article/25013
3、在定制登录网页登录后实现免登跳转;


赞 6