diff --git a/插件库/Lskj.Main/Hosting/IExternalMainShell.cs b/插件库/Lskj.Main/Hosting/IExternalMainShell.cs index 53d0ef0..16864f7 100644 --- a/插件库/Lskj.Main/Hosting/IExternalMainShell.cs +++ b/插件库/Lskj.Main/Hosting/IExternalMainShell.cs @@ -10,6 +10,8 @@ namespace Lskj.Main.Hosting { bool IsOpen { get; } + DialogResult ShowLoginDialog(object loginRuntime); + DialogResult ShowDialog(); void RequestRelogin(); diff --git a/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs b/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs index febbf40..3bc8d05 100644 --- a/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs +++ b/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs @@ -1,5 +1,17 @@ using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using DevExpress.LookAndFeel; +using Lskj.Business; +using Lskj.Business.Impl; +using Lskj.Control.Model; +using Lskj.Core; +using Lskj.Data; using Lskj.Main.Model; +using Lskj.Model; +using Lskj.Util; namespace Lskj.Main.Hosting { @@ -26,4 +38,402 @@ namespace Lskj.Main.Hosting } } } + + /// + /// 向外部 WPF 登录页提供旧账套、用户、认证和会话状态写入能力。 + /// 该类型不创建 WinForms 控件,也不引用 WPF。 + /// + public sealed class LegacyLoginRuntime + { + private DataTable _ledgerTable; + + public LegacyLoginRuntime() + { + ERPInfo.Instance.LoginResult = false; + } + + public string SelectedLedgerName { get; private set; } + + public string LoginName + { + get { return DBConfig.Instance.LoginName ?? string.Empty; } + } + + public bool RememberPasswordEnabled + { + get { return !SystemInfo.Instance.DisableRememberPassword; } + } + + public DataTable LoadLedgers() + { + _ledgerTable = MainImpl.GetLedgerList() ?? new DataTable("Ledgers"); + SelectedLedgerName = ResolveSelectedLedgerName(_ledgerTable); + return _ledgerTable; + } + + public DataTable LoadUsers() + { + DataTable users = SystemInfo.Instance.DisplayUserCode + ? MainImpl.GetEmployeeListNew() + : MainImpl.GetEmployeeList(); + return users ?? new DataTable("Users"); + } + + public DataTable SelectLedger(string ledgerName) + { + if (string.IsNullOrWhiteSpace(ledgerName)) + throw new InvalidOperationException("请选择账套。"); + if (_ledgerTable == null) + LoadLedgers(); + + DataRow ledger = _ledgerTable.Rows.Cast().FirstOrDefault( + row => string.Equals( + Value(row, "ShowName"), + ledgerName, + StringComparison.OrdinalIgnoreCase)); + if (ledger == null) + throw new InvalidOperationException("未找到所选账套,请重新选择。"); + + string serverName = Value(ledger, "IP"); + string database = Value(ledger, "DBName"); + string dataBook = Value(ledger, "ShowName"); + if (string.IsNullOrWhiteSpace(serverName) || + string.IsNullOrWhiteSpace(database)) + { + throw new InvalidOperationException(ResourceKeys.UnSetServerAddress); + } + + string oldServerName = DBConfig.Instance.ServerName; + string oldDatabase = DBConfig.Instance.DataBase; + string oldDataBook = DBConfig.Instance.DataBook; + string oldSelectedLedgerName = SelectedLedgerName; + string oldAccountBook = ERPInfo.Instance.AccountBook; + try + { + DBConfig.Instance.ServerName = serverName; + DBConfig.Instance.DataBase = database; + DBConfig.Instance.DataBook = dataBook; + + if (!DBConfig.Instance.CreateConnection(DBConfig.Instance.Connection)) + throw new InvalidOperationException(ResourceKeys.ServerAddressFault); + if (!DBConfig.Instance.ServerType.Equals("达梦数据库") && + DelphiHelper.Delphi_Init(new StringBuilder( + DBConfig.Instance.GetDelphiConnection( + DBConfig.Instance.dephiConnection))) == 0) + { + throw new InvalidOperationException( + ResourceKeys.UnConnectServer + "[By Delphi]"); + } + + SystemInfo.RefreshSystemParam(); + DataTable users = LoadUsers(); + + SelectedLedgerName = dataBook; + ERPInfo.Instance.AccountBook = dataBook; + return users; + } + catch (Exception switchException) + { + DBConfig.Instance.ServerName = oldServerName; + DBConfig.Instance.DataBase = oldDatabase; + DBConfig.Instance.DataBook = oldDataBook; + SelectedLedgerName = oldSelectedLedgerName; + ERPInfo.Instance.AccountBook = oldAccountBook; + try + { + DBConfig.Instance.CreateConnection(DBConfig.Instance.Connection); + if (!DBConfig.Instance.ServerType.Equals("达梦数据库")) + { + DelphiHelper.Delphi_Init(new StringBuilder( + DBConfig.Instance.GetDelphiConnection( + DBConfig.Instance.dephiConnection))); + } + SystemInfo.RefreshSystemParam(); + } + catch (Exception restoreException) + { + LogHelper.Instance.WriteError(restoreException); + } + + LogHelper.Instance.WriteError(switchException); + throw; + } + } + + public string LoadRememberedPassword(string loginName) + { + if (!RememberPasswordEnabled || string.IsNullOrWhiteSpace(loginName)) + return null; + + try + { + string encrypted = IniHelper.Read( + DBConfig.Instance.ServerName + loginName); + if (string.IsNullOrWhiteSpace(encrypted)) + return null; + + string[] parts = AESUtil.Decrypt(encrypted).Split('^'); + bool remember; + if (parts.Length < 2 || + !bool.TryParse(parts[0], out remember) || + !remember) + { + return null; + } + + return string.Join("^", parts.Skip(1).ToArray()); + } + catch + { + return null; + } + } + + public string Login( + string loginName, + string password, + bool rememberPassword) + { + ERPInfo.Instance.LoginResult = false; + if (string.IsNullOrWhiteSpace(loginName)) + return ResourceKeys.UserNameNotNull; + if (password == null) + password = string.Empty; + + try + { + DataTable users = MainImpl.GetEmployeeList(); + string displayColumn = ResolveDisplayColumn(users); + List matches = users.Rows.Cast() + .Where(row => + string.Equals( + Value(row, displayColumn), + loginName, + StringComparison.OrdinalIgnoreCase) || + string.Equals( + Value(row, "UserCode"), + loginName, + StringComparison.OrdinalIgnoreCase)) + .ToList(); + if (matches.Count == 0) + return ResourceKeys.NameOrPasswordError; + if (matches.Count > 1) + return ResourceKeys.DuplicatedNameError; + + DataRow user = matches[0]; + string userId = Value(user, "UserId"); + string userName = Value(user, "UserName"); + string loginAccount = Value(user, "UserCode"); + if (string.IsNullOrWhiteSpace(userId)) + return ResourceKeys.UserNotFound; + + ERPInfo.Instance.LoginResult = false; + if (SystemInfo.Instance.MacEnabled) + { + int macResult = MainImpl.CheckMacAddress( + ERPInfo.Instance.MacAddress, + userId); + MainImpl.LoginAfterRegister( + ERPInfo.Instance.MacAddress, + userId); + if (macResult == 0) + return ResourceKeys.LoginFault + ResourceKeys.UnKownMacAddress; + if (macResult == -1) + return ResourceKeys.LoginFault + ResourceKeys.UnKownMacAddressTable; + } + + string keyError = VerifyEncryptionKey(); + if (!string.IsNullOrEmpty(keyError)) + return keyError; + + if (!MainImpl.CheckingMacAddress(userId)) + return ResourceKeys.MacAddressError + + ",当前地址:" + ERPInfo.Instance.MacAddress; + + int loginResult = MainImpl.Login(userId, password, false); + if (loginResult != 0) + return LoginError(loginResult); + + CompleteLogin( + userId, + userName, + loginAccount, + loginName, + password, + rememberPassword); + ERPInfo.Instance.LoginResult = true; + LogUtil.WriteDebug("", "登录软件", "进入操作", "系统登录"); + return string.Empty; + } + catch (Exception exception) + { + ERPInfo.Instance.LoginResult = false; + LogUtil.WriteError(ResourceKeys.UserLogin, exception); + return ResourceKeys.LoginFault; + } + } + + private static string VerifyEncryptionKey() + { + if (!SystemInfo.Instance.IsEncrypt) + return string.Empty; + + int[] keyHandles = ERPInfo.Instance.keyHandles = new int[8]; + int[] keyNumbers = ERPInfo.Instance.keyNumber = new int[8]; + SmartX1Api.SmartX1Find(DBConfig.Instance.ServerName, keyHandles, keyNumbers); + + int keyHandle = keyHandles[0]; + int pin1 = Convert.ToInt32("0x987F6BCD", 16); + int pin2 = Convert.ToInt32("0xE193C5B2", 16); + int pin3 = Convert.ToInt32("0xD507CC28", 16); + int pin4 = Convert.ToInt32("0x4B125AF6", 16); + return SmartX1Api.SmartX1Open(keyHandle, pin1, pin2, pin3, pin4) == 0 + ? string.Empty + : "U盾数据获取失败,请重试或联系管理员"; + } + + private void CompleteLogin( + string userId, + string userName, + string loginAccount, + string enteredLoginName, + string password, + bool rememberPassword) + { + if (!MainImpl.HasExistsColumn("p_employeetab", "MacAdress")) + BaseImpl.ExecSqlValue("alter table p_employeetab add MacAdress varchar(100)"); + BaseImpl.ExecSqlValue(string.Format( + "update p_employeetab set MacAdress = '{0}' where employeeid='{1}'", + (ERPInfo.Instance.MacAddress ?? string.Empty).Replace("'", "''"), + userId.Replace("'", "''"))); + + if (!MainImpl.HasExistsColumn("p_employeetab", "ClientIp")) + BaseImpl.ExecSqlValue("alter table p_employeetab add ClientIp varchar(100)"); + BaseImpl.ExecSqlValue(string.Format( + "update p_employeetab set ClientIp = '{0}' where employeeid='{1}'", + (ERPInfo.Instance.LoginIPV4 ?? string.Empty).Replace("'", "''"), + userId.Replace("'", "''"))); + + if (SystemInfo.Instance.AutoSystemDataFormat) + { + FormatSystemDatetime formatter = new FormatSystemDatetime(); + formatter.SetDateTimeFormat(); + } + + string skinName = MainImpl.GetUserSkin(userId); + skinName = string.IsNullOrEmpty(skinName) + ? ERPInfo.Instance.SkinName + : skinName; + UserLookAndFeel.Default.SetSkinStyle(skinName); + + IniHelper.Write( + DBConfig.Instance.ServerName + enteredLoginName, + AESUtil.Encrypt(rememberPassword + "^" + password)); + + ERPInfo.Instance.SeriesId = SystemInfo.Instance.seriesid; + ERPInfo.Instance.UserLinkPhone = MainImpl.GetUserPhone(userId); + ERPInfo.Instance.UserId = userId; + ERPInfo.Instance.UserName = userName; + ERPInfo.Instance.Password = SHAHelper.EncryptPassword(password); + ERPInfo.Instance.SkinName = skinName; + string accountBook = string.IsNullOrWhiteSpace(SelectedLedgerName) + ? DBConfig.Instance.DataBook + : SelectedLedgerName; + ERPInfo.Instance.AccountBook = accountBook; + ERPInfo.Instance.LoginAccount = loginAccount; + ERPInfo.Instance.InPassWord = password; + ERPInfo.Instance.PrimitiveBrowser = SystemInfo.Instance.PrimitiveBrowser; + + DBConfig.Instance.LoginName = enteredLoginName; + DBConfig.Instance.NoticeUserID = userId; + DBConfig.Instance.NoticeUserName = userName; + DBConfig.Instance.DataBook = accountBook; + DBConfig.Instance.WriteConfig(); + + if (userName.Equals("管理员") && + !string.IsNullOrWhiteSpace(loginAccount)) + { + ERPInfo.Instance.Password = SqlHelper.ExecuteString( + "Password", + "select Password from P_EmployeeTab where LoginAccount='" + + loginAccount.Replace("'", "''") + "'"); + } + + ERPInfo.Instance.LanguageName = "中文"; + LanguageTranslation.GetLanguageComparisonTable(); + TrySetDelphiParameters(); + PubUtil.ClearFilesInDirectory(PubUtil.ImageDownloadPath); + } + + private static void TrySetDelphiParameters() + { + try + { + DelphiHelper.Delphi_SetParams( + Convert.ToInt32(ERPInfo.Instance.UserId), + string.IsNullOrWhiteSpace(ERPInfo.Instance.SubSysId) + ? 0 + : Convert.ToInt32(ERPInfo.Instance.SubSysId), + new StringBuilder(ERPInfo.Instance.UserName), + new StringBuilder(ERPInfo.Instance.WindowName), + new StringBuilder(ERPInfo.Instance.SkinName)); + } + catch (Exception exception) + { + LogHelper.Instance.WriteError(exception); + } + } + + private static string LoginError(int loginResult) + { + switch (loginResult) + { + case 1: + return ResourceKeys.NameOrPasswordError; + case 2: + return ResourceKeys.AlreadyLogin; + case -2: + return ResourceKeys.MultiFailedLogin; + default: + return ResourceKeys.LoginFault; + } + } + + private static string ResolveSelectedLedgerName(DataTable ledgers) + { + DataRow selected = ledgers.Rows.Cast().FirstOrDefault( + row => string.Equals( + Value(row, "DBName"), + DBConfig.Instance.DataBase, + StringComparison.OrdinalIgnoreCase)); + if (selected == null && !string.IsNullOrWhiteSpace(DBConfig.Instance.DataBook)) + { + selected = ledgers.Rows.Cast().FirstOrDefault( + row => string.Equals( + Value(row, "ShowName"), + DBConfig.Instance.DataBook, + StringComparison.OrdinalIgnoreCase)); + } + if (selected == null) + selected = ledgers.Rows.Cast().FirstOrDefault(); + + return selected == null ? string.Empty : Value(selected, "ShowName"); + } + + private static string ResolveDisplayColumn(DataTable users) + { + string configured = SystemInfo.Instance.LoginUsername; + return !string.IsNullOrWhiteSpace(configured) && + users.Columns.Contains(configured) + ? configured + : "UserName"; + } + + private static string Value(DataRow row, string columnName) + { + return row != null && row.Table.Columns.Contains(columnName) + ? row[columnName] + string.Empty + : string.Empty; + } + } } diff --git a/插件库/Lskj.Main/Model/Manager.cs b/插件库/Lskj.Main/Model/Manager.cs index 3f49a41..2faece4 100644 --- a/插件库/Lskj.Main/Model/Manager.cs +++ b/插件库/Lskj.Main/Model/Manager.cs @@ -675,6 +675,9 @@ namespace Lskj.Main.Model /// DialogResult. private static DialogResult RunLoginForm() { + if (ExternalMainShell != null) + return ExternalMainShell.ShowLoginDialog(new LegacyLoginRuntime()); + FrmLogin frmLogin = new FrmLogin(); return frmLogin.ShowDialog(); }