Files
lserp_cs_6.0/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs
T

736 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
{
public sealed class LegacyProcessStartResult
{
internal LegacyProcessStartResult(
bool shouldRunApplication,
int exitCode)
{
ShouldRunApplication = shouldRunApplication;
ExitCode = exitCode;
}
public bool ShouldRunApplication { get; private set; }
public int ExitCode { get; private set; }
}
/// <summary>
/// 为独立的新启动程序公开原 Ls_ERP 初始化和登录流程。
/// </summary>
public static class LegacyApplicationHost
{
private static readonly object ProcessSync = new object();
private static bool _mainProcessInitializationStarted;
private static bool _mainProcessInitialized;
private static bool _mainProcessShutdown;
public static LegacyProcessStartResult PrepareProcess(string[] args)
{
int code = Program.PrepareProcess(args ?? new string[0]);
return new LegacyProcessStartResult(code == -1, code);
}
public static void InitializeMainProcess(IExternalMainShell externalMainShell)
{
lock (ProcessSync)
{
if (_mainProcessInitialized)
throw new InvalidOperationException(
"旧主进程运行时已经初始化。");
if (_mainProcessShutdown)
throw new InvalidOperationException(
"旧主进程运行时已经关闭。");
_mainProcessInitializationStarted = true;
Manager.ExternalMainShell = externalMainShell;
try
{
Program.InitializeMainProcess();
_mainProcessInitialized = true;
}
catch
{
try
{
Program.ShutdownMainProcess();
}
finally
{
_mainProcessShutdown = true;
Manager.ExternalMainShell = null;
}
throw;
}
}
}
public static void ShutdownMainProcess()
{
lock (ProcessSync)
{
if (!_mainProcessInitializationStarted ||
_mainProcessShutdown)
{
return;
}
try
{
Manager.EndExternalSessionServices();
Manager.ExitSystem();
}
finally
{
try
{
Program.ShutdownMainProcess();
}
finally
{
_mainProcessInitialized = false;
_mainProcessShutdown = true;
Manager.ExternalMainShell = null;
}
}
}
}
public static object CreateLoginRuntime()
{
return new LegacyLoginRuntime();
}
public static string PrepareAuthenticatedSession()
{
if (!ERPInfo.Instance.LoginResult)
return ResourceKeys.LoginFault;
DataTable enabled = MainImpl.EnableSubSystem();
ERPInfo.Instance.SubMenuCount = enabled == null
? 0
: enabled.Rows.Count;
if (!Manager.TrySelectExternalMainShellSubSystem())
return ResourceKeys.SubSystemUnEnabled;
LegacyLoginRuntime.RefreshDelphiParameters();
Manager.BeginExternalSessionServices();
return string.Empty;
}
public static void CompleteAuthenticatedSession()
{
Manager.EndExternalSessionServices();
}
public static void ActivateSubSystem(string id, string caption)
{
ERPInfo.Instance.SubSysId = id ?? string.Empty;
ERPInfo.Instance.SubSysName = caption ?? string.Empty;
LegacyLoginRuntime.RefreshDelphiParameters();
}
}
/// <summary>
/// 向外部 WPF 登录页提供旧账套、用户、认证和会话状态写入能力。
/// 该类型不创建 WinForms 控件,也不引用 WPF。
/// </summary>
public sealed partial class LegacyLoginRuntime
{
private DataTable _ledgerTable;
private bool _connectionInitialized;
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 bool AutoUpdate
{
get
{
return SystemInfo.Instance.AutomaticUpdates ||
DBConfig.Instance.UpdateSet;
}
}
public bool AutoUpdateEnabled
{
get { return !SystemInfo.Instance.AutomaticUpdates; }
}
public bool SmartClient
{
get { return DBConfig.Instance.SmallClient; }
}
public bool SmartClientEnabled
{
get { return !SystemInfo.Instance.HiddenIntelligentClient; }
}
public bool SmartClientVisible
{
get { return !SystemInfo.Instance.HiddenIntelligentClient; }
}
public bool Notice
{
get
{
return SystemInfo.Instance.AutoCheckedNotice ||
SystemInfo.Instance.StartMessageBox ||
DBConfig.Instance.NoticeClient;
}
}
public bool NoticeEnabled
{
get { return !SystemInfo.Instance.StartMessageBox; }
}
public DataTable LoadLedgers()
{
EnsureInitialConnection();
_ledgerTable = MainImpl.GetLedgerList() ?? new DataTable("Ledgers");
SelectedLedgerName = ResolveSelectedLedgerName(_ledgerTable);
return _ledgerTable;
}
private void EnsureInitialConnection()
{
if (_connectionInitialized)
return;
if (string.Equals(
IniHelper.Read(SystemResourcesIniName, ConnectionModeKey),
"1",
StringComparison.Ordinal))
{
int port;
string host = IniHelper.Read(
SystemResourcesIniName,
DirectLastHostKey);
string name = IniHelper.Read(
SystemResourcesIniName,
DirectLastNameKey);
if (!int.TryParse(
IniHelper.Read(
SystemResourcesIniName,
DirectLastPortKey),
out port))
{
throw new InvalidOperationException(
"保存的直连端口无效,请重新设置连接。");
}
string error = ApplyDirectConnection(host, port, name);
if (!string.IsNullOrWhiteSpace(error))
throw new InvalidOperationException(error);
}
else
{
if (!DBConfig.Instance.CreateConnection(
DBConfig.Instance.Connection))
{
throw new InvalidOperationException(
ResourceKeys.UnConnectServer);
}
if (!string.Equals(
DBConfig.Instance.ServerType,
"达梦数据库",
StringComparison.Ordinal) &&
DelphiHelper.Delphi_Init(new StringBuilder(
DBConfig.Instance.GetDelphiConnection(
DBConfig.Instance.dephiConnection))) == 0)
{
throw new InvalidOperationException(
ResourceKeys.UnConnectServer + "[By Delphi]");
}
SystemInfo.RefreshSystemParam();
}
BaseResources.Localization(LocalizationType.CHS);
_connectionInitialized = true;
}
public DataTable LoadUsers()
{
DataTable users = SystemInfo.Instance.DisplayUserCode
? MainImpl.GetEmployeeListNew()
: MainImpl.GetEmployeeList();
return NormalizeUsersForLogin(
users ?? new DataTable("Users"),
SystemInfo.Instance.LoginUsername,
SystemInfo.Instance.DisplayUserCode);
}
public DataTable SelectLedger(string ledgerName)
{
if (string.IsNullOrWhiteSpace(ledgerName))
throw new InvalidOperationException("请选择账套。");
if (_ledgerTable == null)
LoadLedgers();
DataRow ledger = _ledgerTable.Rows.Cast<DataRow>().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;
bool oldConnectionInitialized = _connectionInitialized;
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();
BaseResources.Localization(LocalizationType.CHS);
DataTable users = LoadUsers();
SelectedLedgerName = dataBook;
ERPInfo.Instance.AccountBook = dataBook;
_connectionInitialized = true;
return users;
}
catch (Exception switchException)
{
DBConfig.Instance.ServerName = oldServerName;
DBConfig.Instance.DataBase = oldDatabase;
DBConfig.Instance.DataBook = oldDataBook;
SelectedLedgerName = oldSelectedLedgerName;
ERPInfo.Instance.AccountBook = oldAccountBook;
_connectionInitialized = oldConnectionInitialized;
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,
bool forceLogin,
bool autoUpdate,
bool smartClient,
bool notice)
{
ERPInfo.Instance.LoginResult = false;
if (string.IsNullOrWhiteSpace(loginName))
return ResourceKeys.UserNameNotNull;
password = NormalizePassword(password);
try
{
DataTable users = MainImpl.GetEmployeeList();
string displayColumn = ResolveDisplayColumn(users);
List<DataRow> matches = users.Rows.Cast<DataRow>()
.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,
forceLogin);
if (loginResult != 0)
return LoginError(loginResult);
CompleteLogin(
userId,
userName,
loginAccount,
loginName,
password,
rememberPassword,
autoUpdate,
smartClient,
notice);
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,
bool autoUpdate,
bool smartClient,
bool notice)
{
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.UpdateSet = autoUpdate;
DBConfig.Instance.SmallClient = smartClient;
DBConfig.Instance.NoticeClient = notice;
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();
RefreshDelphiParameters();
PubUtil.ClearFilesInDirectory(PubUtil.ImageDownloadPath);
}
internal static void RefreshDelphiParameters()
{
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<DataRow>().FirstOrDefault(
row => string.Equals(
Value(row, "DBName"),
DBConfig.Instance.DataBase,
StringComparison.OrdinalIgnoreCase));
if (selected == null && !string.IsNullOrWhiteSpace(DBConfig.Instance.DataBook))
{
selected = ledgers.Rows.Cast<DataRow>().FirstOrDefault(
row => string.Equals(
Value(row, "ShowName"),
DBConfig.Instance.DataBook,
StringComparison.OrdinalIgnoreCase));
}
if (selected == null)
selected = ledgers.Rows.Cast<DataRow>().FirstOrDefault();
return selected == null ? string.Empty : Value(selected, "ShowName");
}
private static DataTable NormalizeUsersForLogin(
DataTable users,
string configuredLoginColumn,
bool displayUserCode)
{
DataTable normalized = new DataTable("Users");
normalized.Columns.Add("UserId", typeof(string));
normalized.Columns.Add("LoginName", typeof(string));
normalized.Columns.Add("DisplayName", typeof(string));
if (users == null)
return normalized;
string loginColumn = ResolveLoginColumn(
users,
configuredLoginColumn);
foreach (DataRow row in users.Rows)
{
string loginName = Value(row, loginColumn).Trim();
string userCode = Value(row, "UserCode").Trim();
if (string.IsNullOrWhiteSpace(loginName))
loginName = userCode;
if (string.IsNullOrWhiteSpace(loginName))
continue;
string displayName = loginName;
if (displayUserCode &&
!string.IsNullOrWhiteSpace(userCode) &&
!string.Equals(
loginName,
userCode,
StringComparison.OrdinalIgnoreCase))
{
displayName = loginName + "" + userCode + "";
}
normalized.Rows.Add(
Value(row, "UserId"),
loginName,
displayName);
}
return normalized;
}
private static string NormalizePassword(string password)
{
return (password ?? string.Empty).Trim();
}
private static string ResolveDisplayColumn(DataTable users)
{
return ResolveLoginColumn(
users,
SystemInfo.Instance.LoginUsername);
}
private static string ResolveLoginColumn(
DataTable users,
string configuredLoginColumn)
{
if (users != null &&
!string.IsNullOrWhiteSpace(configuredLoginColumn) &&
users.Columns.Contains(configuredLoginColumn))
{
return configuredLoginColumn;
}
return users != null && users.Columns.Contains("UserName")
? "UserName"
: "UserCode";
}
private static string Value(DataRow row, string columnName)
{
return row != null && row.Table.Columns.Contains(columnName)
? row[columnName] + string.Empty
: string.Empty;
}
}
}