定制GUI登录界面插件 (仅支持到桌面GUI客户端)

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

定制GUI登录界面插件 (仅支持到桌面GUI客户端)

定制GUI登录界面插件 (仅支持到桌面GUI客户端)


本篇基础:BOS平台的二开编程(论坛),C#编程(ms),WPF编程(ms),Python语法, XML语法,VistualStudio2012(up)工具(ms),C/S基础知识,x86与x64基础知识


一、应用背景

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


二、部署二次开发组件

1、在K/3 Cloud服务器安装目录 的【WebSite\ClientBin\K3CloudClient\controlplugins】目录下部署二次开发.deploy组件。具体部署方法参考《答疑3:通过BOSIDE新建解决方案或应用方案


2、(可选-部署方案,如果使用1的方案,这个步骤可忽略)增量.KDZ文件部署方式:

2.1、在云星空应用服务器安装目录的【WebSite/ClientBin/CustomControl/WPF】目录下部署二次开发组件,这个目录安装包会创建。

2.2、自定义组件可以用Zip压缩文件压缩为Zip格式,后修改后缀名为.kdz。

2.3、配置组件下载列表MainDownloadList.xml(篇幅调整,参考答疑的【疑问2】)


3、启动金蝶云星空客户端桌面版程序的桌面链接,这时程序会自动按照服务器地址设定检查组件版本,并按需要下载相关客制化组件到客户端电脑本地的 【%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" /> 

  <!--当定制化登录界面构建失败时,允许使用默认的登录界面代替-->

  <add key ="AllowCustomUseDefLoginUI" value="true" />


特别注意:(千万不要修改上面的key属性,固定必须是“CustomLoginUI",value可以替换为你自己开发的控件组件,例如“LoginTest.LoginUI,LoginTest”,通用的DotNet类描述格式)


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

1、在Visual Studio 2012中新增类库工程;需要新增有WPF界面元素的,必须新建WPF类库类型的工程。(.Net Framework 4 参考图片)

image.webp


2、可下载运行客户端后,引用客户端目录下的基础组件如下(安装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 [可选]

* 以上组件安装云星空桌面客户端后,在磁盘目录可以找到 【C:\Program Files (x86)\Kingdee\K3Cloud\DeskClient\K3CloudClient

image.webp


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 ZQWCustomLoginUI

{
    /// <summary>
    /// Interaction logic for ZQWLoginV1.xaml
    /// </summary>
    public partial class ZQWLoginV1: UserControl ,IKDLoginControl
    {
        IKDLoginControlOwner Owner { get; set; }
        ItemModel currentDataCenter { get; set; }
        public CustomLoginUI()
        {
            InitializeComponent();

            this.Dispatcher.BeginInvoke(new Action(() => InitDataCenterList()));

        }

        private void InitDataCenterList()

        { 

            CboDCName.DisplayMemberPath = "Name";

            CboDCName.SelectedValuePath = "Id";

            var proxy = new AccountClientProxy();

            var dclist = proxy.GetDataCenterList();

            CboDCName.ItemsSource = dclist;

            CboDCName.SelectedIndex = 0;

        }


        public void ClearData()
        {
        }
        public void DoLogin()
        {
        }
        public bool Focus(string key)
        {
            return true;
        }
        public LoginInfo GetLoginInfo()
        {

            var acctID = CboDCName.SelectedValue as string;            

            string userName = this.TxtUserName.Text.Trim(); 

            string userPwd = this.TxtPassword.Password.Trim(); 

            int lcid = 2052; 

            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 "ZQWLoginV1";
        }
        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;
            // owner.EnableShapeWindow(true); //只显示登录窗体定制部分.

        }
        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插件的界面(演示界面,未做任何修饰和密码处理),如下图:


           image.webp


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

Kingdee.BOS.XPF.Component.Utils.KDLoginUtils.ShowModifyPwdWindow(this.Owner as Window, new Action(() =>{
        this.TxtPassword.Password = "";
        this.TxtPassword.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的处理如下,可以作为你的插件参考:

                        switch (loginRet.LoginResultType)
                        {
                            case LoginResultType.Failure:
                                KDMessageBox.Show(loginRet.Message, 
                                    ResManager.LoadKDString("信息提示", "014001000000097"), 
                                    this.Owner as Window, KDMesType.Error);
                                this.TxtPassword.Focus();
                                return;
                            case LoginResultType.PWError:
                                KDMessageBox.Show(loginRet.Message, 
                                    ResManager.LoadKDString("信息提示", "014001000000097"), 
                                    this.Owner as Window, KDMesType.Warn);
                                this.TxtPassword.Focus();
                                this.TxtPassword.Password = "";
                                return;
                            case LoginResultType.PWInvalid_Optional:
                                this.TxtPassword.Password = "";
                                if (KDMessageBox.Show(loginRet.Message, 
                                    ResManager.LoadKDString("密码修改提示", "014001000000100"),
                                    this.Owner as Window, KDMesType.Question, KDMesButtons.YesNo) == KDMesResult.Yes)
                                {
                                    ShowModifyPwdWindow(oldPwd, loginRet.C == null ? "" : loginRet.C.UserId.ToString());
                                    return;
                                }
                                break;
                            case LoginResultType.PWInvalid_Required:
                                this.TxtPassword.Password = "";
                                KDMessageBox.Show(loginRet.Message, 
                                    ResManager.LoadKDString("密码修改提示", "014001000000100"), 
                                    this.Owner as Window, KDMesType.Warn);
                                ShowModifyPwdWindow(oldPwd, loginRet.C == null ? "" : loginRet.C.UserId.ToString());
                                return;
                            case LoginResultType.Activation:
                                ShowModifyPwdWindow(oldPwd, loginRet.C == null ? "" : loginRet.C.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;
                                //答疑5

                                return;
                            default:
                                break;
                        }



3、在工具类显示指定表单后,在该表单的业务插件中编写自己的业务逻辑。
      传入数据在业务插件中提取:
      var custArgs = this.View.OpenParameter.GetCustomParameter("inputData");


六、web端的定制登录方案
1、制作定制登录网页,aspx/html/jsp 都可以;

2、生成免登连接,或制作定制登录逻辑实现免登录服务端插件,参考:【免登功能 - 答疑篇】 https://vip.kingdee.com/article/171574  (生成ud免登参数) ;

3、调用或打开生成的免登链接即可 ( https://xxx/k3cloud/html5/index.aspx?ud=xxxx);


七、答疑篇

疑问1】、如何实现客户端免登逻辑?

【答】:

    参考【免登功能 - 答疑篇】https://vip.kingdee.com/article/171574  【疑25、客户端登陆界面也想定制,如何定制?】


疑问2】、如何配置MainDownloadList.xml实现提前下载组件?

【答】:(这是老版本部署方案,不建议再使用,部署推荐【答疑3】的方式)

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

1.webp


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

image.webp


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

image.webp



答疑3】:

客制化控件已经编译完成,如何制作安装包?

【答】:特别推荐的部署方式

通过BOSIDE新建解决方案或应用方案,具体方法参考下面教程:

《协同平台之客户端插件扩展篇》【https://vip.kingdee.com/school/97996311328065024 】指引

制作好安装包后,一定要进行本地测试验证:

【验证步骤】

1、安装客户环境匹配的标准产品版本和补丁;

2、安装新构建的二开功能补丁安装包;

3、从桌面启动客户端程序快捷方式,并等待组件更新;

4、更新完成后检查【%Program Files %\Kingdee\K3Cloud\DeskClient\K3CloudClient\controlplugins】目录是否正确更新到组件;

5、登入系统执行相关二开业务功能,检验是否正常;

6、如二开功能需要修改重新打包,则验证过程需要从第一步开始再来一遍;

7、以上完成确认无误后,再在系统闲时部署到正式生产环境;


答疑4】:

如何调试自定义登录界面组件?

【答】:参考 https://vip.kingdee.com/article/8751  疑问6 


答疑5】:如何弹出修改密码提示框,在新用户首次登入时?

【答】使用出厂的密码管理体系即可,自定义的登入界面只需要下面处理下返回的登入界面即可。登入接口返回的LoginResult 对象判断并执行返回表单即可,调用下面示例代码即可。

if ( loginRet.LoginResultType == LoginResultType.DealWithForm )
{
            var arg = new KDLoginInfoChangeArgs()
            {
                FormId = loginRet.FormId,
                InputData = loginRet.FormInputObject
            };
            KDLoginUtils.ShowSpecialForm(arg, AfterOpenSpecialForm);
}



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

创建于2019年4月19日 10:02:25

编辑于2021年5月26日 19:24:10


ZQWCustomLoginUI.zip

定制GUI登录界面插件 (仅支持到桌面GUI客户端)

定制GUI登录界面插件 (仅支持到桌面GUI客户端)本篇基础:BOS平台的二开编程(论坛),C#编程(ms),WPF编程(ms),Python语法, XML语法,Vi...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息