From ccc54e4d064e061b497df5b8f7998fbfee16a22b Mon Sep 17 00:00:00 2001
From: liu <2021943741@qq.com>
Date: 星期一, 12 十月 2026 13:13:34 +0800
Subject: [PATCH] feat: 质检四模块导出按筛选条件、考勤节假日配置改为时间段

---
 /dev/null         | 1775 ---------------------------------------
 hm.bat            |  451 ++++++++++
 trt.bat           |  451 ++++++++++
 company.config.ts |   12 
 4 files changed, 914 insertions(+), 1,775 deletions(-)

diff --git a/company.config.ts b/company.config.ts
index 6f0227f..0fee5ea 100644
--- a/company.config.ts
+++ b/company.config.ts
@@ -71,4 +71,16 @@
     favicon: '/logos/YZFXLogo.ico',
     apiUrl: 'http://36.213.150.237:9006/admin-api',
   },
+  TRT: {
+    name: '闀胯緣鐢靛姏',
+    logo: '/logos/YZFXLogo.png',
+    favicon: '/logos/YZFXLogo.ico',
+    apiUrl: 'http://36.213.150.237:9013/admin-api',
+  },
+  HM: {
+    name: '闀胯緣鐢靛姏',
+    logo: '/logos/YZFXLogo.png',
+    favicon: '/logos/YZFXLogo.ico',
+    apiUrl: 'http://36.213.150.237:9015/admin-api',
+  },
 };
diff --git a/hm.bat b/hm.bat
index e69de29..64135b3 100644
--- a/hm.bat
+++ b/hm.bat
@@ -0,0 +1,451 @@
+@echo off
+setlocal EnableExtensions EnableDelayedExpansion
+
+REM ============================================================
+REM Vue Frontend Deploy Script
+REM ============================================================
+
+REM =========================
+REM Configuration
+REM =========================
+
+set "COMPANY=HM"
+
+set "REMOTE_USER=root"
+set "REMOTE_HOST=36.213.150.237"
+set "REMOTE_PORT=65022"
+
+set "PASSWORD=Sh@1008600"
+
+set "ZIP_FILE=dist.zip"
+set "REMOTE_DIR=/data/vue/mom/hm/dist"
+
+set "SSH_OPTS=-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=15 -o ServerAliveCountMax=3"
+
+set "RETRY_COUNT=3"
+
+set "SSHPASS_DIR=%~dp0bin"
+
+
+REM ============================================================
+REM Start
+REM ============================================================
+
+echo.
+echo ============================================================
+echo              Vue Dist Auto Deploy
+echo ============================================================
+echo.
+echo Company    : %COMPANY%
+echo Server     : %REMOTE_USER%@%REMOTE_HOST%
+echo Port       : %REMOTE_PORT%
+echo Remote Dir : %REMOTE_DIR%
+echo Package    : %ZIP_FILE%
+echo.
+
+
+REM ============================================================
+REM Check sshpass
+REM ============================================================
+
+echo [1/7] Checking sshpass...
+
+if exist "%SSHPASS_DIR%\sshpass.exe" (
+    set "PATH=%SSHPASS_DIR%;%PATH%"
+)
+
+where sshpass >nul 2>&1
+
+if not errorlevel 1 (
+    echo [OK] sshpass found.
+    goto CHECK_PNPM
+)
+
+echo [WARN] sshpass not found.
+
+if not exist "%SSHPASS_DIR%" (
+    mkdir "%SSHPASS_DIR%" >nul 2>&1
+)
+
+if exist "%SSHPASS_DIR%\sshpass.exe" (
+    set "PATH=%SSHPASS_DIR%;%PATH%"
+    echo [OK] sshpass found.
+    goto CHECK_PNPM
+)
+
+echo [INFO] Downloading sshpass...
+
+powershell -NoProfile -ExecutionPolicy Bypass -Command "$url='https://github.com/xhcoding/sshpass-win32/releases/download/v1.0.3/sshpass.exe'; $out='%SSHPASS_DIR%\sshpass.exe'; Invoke-WebRequest -Uri $url -OutFile $out"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to download sshpass.
+    echo [ERROR] Please install sshpass manually.
+    goto ERROR_EXIT
+)
+
+set "PATH=%SSHPASS_DIR%;%PATH%"
+
+echo [OK] sshpass installed.
+
+
+REM ============================================================
+REM Check pnpm
+REM ============================================================
+
+:CHECK_PNPM
+
+echo.
+echo [2/7] Checking pnpm...
+
+where pnpm >nul 2>&1
+
+if errorlevel 1 (
+    echo [ERROR] pnpm not found.
+    echo [HINT] npm install -g pnpm
+    goto ERROR_EXIT
+)
+
+call pnpm --version
+
+if errorlevel 1 (
+    echo [ERROR] pnpm execution failed.
+    goto ERROR_EXIT
+)
+
+
+REM ============================================================
+REM Check node
+REM ============================================================
+
+echo.
+echo [3/7] Checking Node.js...
+
+where node >nul 2>&1
+
+if errorlevel 1 (
+    echo [ERROR] Node.js not found.
+    goto ERROR_EXIT
+)
+
+call node --version
+
+if errorlevel 1 (
+    echo [ERROR] Node.js execution failed.
+    goto ERROR_EXIT
+)
+
+
+REM ============================================================
+REM Check node_modules
+REM ============================================================
+
+if not exist "node_modules" (
+    echo.
+    echo [INFO] node_modules not found.
+    echo [INFO] Running pnpm install...
+
+    call pnpm install
+
+    if errorlevel 1 (
+        echo [ERROR] pnpm install failed.
+        goto ERROR_EXIT
+    )
+
+    echo [OK] pnpm install completed.
+) else (
+    echo [OK] node_modules exists.
+)
+
+
+REM ============================================================
+REM Build
+REM ============================================================
+
+echo.
+echo [4/7] Building project...
+
+if exist "%ZIP_FILE%" (
+    echo.
+    echo [WARN] %ZIP_FILE% already exists.
+    set "REBUILD="
+    set /p "REBUILD=Rebuild? Y/N (default Y): "
+
+    if /I "!REBUILD!"=="N" (
+        echo [INFO] Skip build.
+        goto CHECK_ZIP
+    )
+)
+
+echo [INFO] Company: %COMPANY%
+echo [INFO] Command: pnpm run build
+echo.
+
+set "VITE_COMPANY=%COMPANY%"
+
+call pnpm run build
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] Build failed.
+    goto ERROR_EXIT
+)
+
+echo.
+echo [OK] Build completed.
+
+
+REM ============================================================
+REM Check ZIP
+REM ============================================================
+
+:CHECK_ZIP
+
+echo.
+echo [5/7] Checking package...
+
+if not exist "%ZIP_FILE%" (
+    echo [ERROR] %ZIP_FILE% not found.
+    echo [HINT] Please check whether your build generates dist.zip.
+    goto ERROR_EXIT
+)
+
+for %%F in ("%ZIP_FILE%") do set "ZIP_BYTES=%%~zF"
+
+set /a ZIP_MB=ZIP_BYTES/1024/1024
+
+echo [OK] Package found.
+echo [INFO] File size: !ZIP_BYTES! bytes
+echo [INFO] File size: !ZIP_MB! MB
+
+
+REM ============================================================
+REM Set sshpass password
+REM ============================================================
+
+set "SSHPASS=%PASSWORD%"
+
+
+REM ============================================================
+REM Test SSH
+REM ============================================================
+
+echo.
+echo [6/7] Testing SSH connection...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "echo SSH_OK"
+
+if errorlevel 1 (
+    echo [ERROR] SSH connection failed.
+    goto ERROR_EXIT
+)
+
+echo [OK] SSH connection successful.
+
+
+REM ============================================================
+REM Create remote directory
+REM ============================================================
+
+echo.
+echo [INFO] Creating remote directory...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "mkdir -p '%REMOTE_DIR%'"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to create remote directory.
+    goto ERROR_EXIT
+)
+
+echo [OK] Remote directory ready.
+
+
+REM ============================================================
+REM Upload temporary file
+REM ============================================================
+
+echo.
+echo [INFO] Uploading package...
+
+set "REMOTE_TMP=%REMOTE_DIR%/.dist.zip.uploading"
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "rm -f '%REMOTE_TMP%'"
+
+sshpass -e scp -P %REMOTE_PORT% %SSH_OPTS% "%ZIP_FILE%" %REMOTE_USER%@%REMOTE_HOST%:"%REMOTE_TMP%"
+
+if errorlevel 1 (
+    echo [ERROR] Upload failed.
+    goto ERROR_EXIT
+)
+
+echo [OK] Upload completed.
+
+
+REM ============================================================
+REM Check remote file
+REM ============================================================
+
+echo.
+echo [INFO] Checking remote package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "test -f '%REMOTE_TMP%'"
+
+if errorlevel 1 (
+    echo [ERROR] Remote package does not exist.
+    goto ERROR_EXIT
+)
+
+echo [OK] Remote package exists.
+
+
+REM ============================================================
+REM Compare file size
+REM ============================================================
+
+echo.
+echo [INFO] Checking package size...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "stat -c %%s '%REMOTE_TMP%'"
+
+echo.
+
+
+REM ============================================================
+REM Rename temporary file
+REM ============================================================
+
+echo [INFO] Activating package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "mv -f '%REMOTE_TMP%' '%REMOTE_DIR%/%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to activate package.
+    goto ERROR_EXIT
+)
+
+echo [OK] Package activated.
+
+
+REM ============================================================
+REM Check unzip
+REM ============================================================
+
+echo.
+echo [INFO] Checking unzip...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "command -v unzip"
+
+if errorlevel 1 (
+    echo [ERROR] unzip is not installed on server.
+    echo.
+    echo CentOS/RHEL:
+    echo yum install -y unzip
+    echo.
+    echo Ubuntu/Debian:
+    echo apt install -y unzip
+    goto ERROR_EXIT
+)
+
+echo [OK] unzip found.
+
+
+REM ============================================================
+REM Test ZIP
+REM ============================================================
+
+echo.
+echo [INFO] Testing remote ZIP...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "cd '%REMOTE_DIR%' && unzip -t '%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] ZIP test failed.
+    echo [INFO] Remote ZIP has been kept.
+    goto ERROR_EXIT
+)
+
+echo [OK] ZIP test passed.
+
+
+REM ============================================================
+REM Extract
+REM ============================================================
+
+echo.
+echo [INFO] Extracting package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "cd '%REMOTE_DIR%' && unzip -o '%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] Remote unzip failed.
+    echo [INFO] Remote ZIP has been kept.
+    goto ERROR_EXIT
+)
+
+echo.
+echo [OK] Extract completed.
+
+
+REM ============================================================
+REM Remove ZIP
+REM ============================================================
+
+echo.
+echo [INFO] Removing remote ZIP...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "rm -f '%REMOTE_DIR%/%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo [WARN] Failed to remove remote ZIP.
+) else (
+    echo [OK] Remote ZIP removed.
+)
+
+
+REM ============================================================
+REM Success
+REM ============================================================
+
+echo.
+echo ============================================================
+echo                 DEPLOY SUCCESS
+echo ============================================================
+echo.
+echo Company    : %COMPANY%
+echo Server     : %REMOTE_HOST%:%REMOTE_PORT%
+echo Remote Dir : %REMOTE_DIR%
+echo Package    : %ZIP_FILE%
+echo Size       : !ZIP_MB! MB
+echo.
+echo Deployment completed successfully.
+echo.
+
+goto END
+
+
+REM ============================================================
+REM Error
+REM ============================================================
+
+:ERROR_EXIT
+
+echo.
+echo ============================================================
+echo                  DEPLOY FAILED
+echo ============================================================
+echo.
+echo Please check the error message above.
+echo.
+
+goto END
+
+
+REM ============================================================
+REM End
+REM ============================================================
+
+:END
+
+pause
+endlocal
diff --git a/src/packages/@core/base/shared/dist/cache/index.d.ts b/src/packages/@core/base/shared/dist/cache/index.d.ts
deleted file mode 100644
index fb67433..0000000
--- a/src/packages/@core/base/shared/dist/cache/index.d.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-//#region src/cache/types.d.ts
-interface IStorageDriver {
-  clear(): Promise<void>;
-  getItem<T>(key: string): Promise<null | T>;
-  keys(): Promise<string[]>;
-  removeItem(key: string): Promise<void>;
-  setItem(key: string, value: unknown): Promise<void>;
-}
-interface StorageItem<T> {
-  expiry?: number;
-  value: T;
-}
-interface StorageManagerOptions {
-  driver?: IStorageDriver;
-  prefix?: string;
-}
-//#endregion
-//#region src/cache/indexeddb-driver.d.ts
-interface IndexedDBDriverOptions {
-  dbName?: string;
-  dbVersion?: number;
-  storeName?: string;
-}
-declare class IndexedDBDriver implements IStorageDriver {
-  private dbName;
-  private dbPromise;
-  private dbVersion;
-  private storeName;
-  constructor({
-    dbName,
-    dbVersion,
-    storeName
-  }?: IndexedDBDriverOptions);
-  clear(): Promise<void>;
-  getItem<T>(key: string): Promise<null | T>;
-  keys(): Promise<string[]>;
-  removeItem(key: string): Promise<void>;
-  setItem(key: string, value: unknown): Promise<void>;
-  private getDB;
-  private openDB;
-}
-//#endregion
-//#region src/cache/local-storage-driver.d.ts
-type StorageType = 'localStorage' | 'sessionStorage';
-interface LocalStorageDriverOptions {
-  storageType?: StorageType;
-}
-declare class LocalStorageDriver implements IStorageDriver {
-  private storage;
-  constructor({
-    storageType
-  }?: LocalStorageDriverOptions);
-  clear(): Promise<void>;
-  getItem<T>(key: string): Promise<null | T>;
-  keys(): Promise<string[]>;
-  removeItem(key: string): Promise<void>;
-  setItem(key: string, value: unknown): Promise<void>;
-}
-//#endregion
-//#region src/cache/memory-storage-driver.d.ts
-declare class MemoryStorageDriver implements IStorageDriver {
-  private store;
-  clear(): Promise<void>;
-  getItem<T>(key: string): Promise<null | T>;
-  keys(): Promise<string[]>;
-  removeItem(key: string): Promise<void>;
-  setItem(key: string, value: unknown): Promise<void>;
-}
-//#endregion
-//#region src/cache/storage-manager.d.ts
-declare class StorageManager {
-  private driver;
-  private prefix;
-  constructor({
-    driver,
-    prefix
-  }?: StorageManagerOptions);
-  clear(): Promise<void>;
-  clearExpiredItems(): Promise<void>;
-  getItem<T>(key: string, defaultValue?: null | T): Promise<null | T>;
-  keys(): Promise<string[]>;
-  removeItem(key: string): Promise<void>;
-  setItem(key: string, value: unknown, ttl?: number): Promise<void>;
-  private createDefaultDriver;
-  private getFullKey;
-}
-//#endregion
-export { type IStorageDriver, IndexedDBDriver, type IndexedDBDriverOptions, LocalStorageDriver, type LocalStorageDriverOptions, MemoryStorageDriver, type StorageItem, StorageManager, type StorageManagerOptions };
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/cache/index.mjs b/src/packages/@core/base/shared/dist/cache/index.mjs
deleted file mode 100644
index 2c447c6..0000000
--- a/src/packages/@core/base/shared/dist/cache/index.mjs
+++ /dev/null
@@ -1,255 +0,0 @@
-//#region src/cache/indexeddb-driver.ts
-/**
-* IndexedDB 椹卞姩
-* 閲囩敤鎳掑垵濮嬪寲妯″紡锛岄娆℃搷浣滄椂鑷姩鎵撳紑鏁版嵁搴�
-*/
-var IndexedDBDriver = class {
-	dbName;
-	dbPromise = null;
-	dbVersion;
-	storeName;
-	constructor({ dbName = "vben-storage", dbVersion = 1, storeName = "kv-store" } = {}) {
-		this.dbName = dbName;
-		this.dbVersion = dbVersion;
-		this.storeName = storeName;
-	}
-	async clear() {
-		const db = await this.getDB();
-		return new Promise((resolve, reject) => {
-			const tx = db.transaction(this.storeName, "readwrite");
-			tx.objectStore(this.storeName).clear();
-			tx.addEventListener("complete", () => resolve());
-			tx.addEventListener("error", () => reject(tx.error));
-			tx.addEventListener("abort", () => reject(tx.error ?? /* @__PURE__ */ new Error("Transaction aborted")));
-		});
-	}
-	async getItem(key) {
-		const db = await this.getDB();
-		return new Promise((resolve, reject) => {
-			const request = db.transaction(this.storeName, "readonly").objectStore(this.storeName).get(key);
-			request.addEventListener("success", () => resolve(request.result ?? null));
-			request.addEventListener("error", () => reject(request.error));
-		});
-	}
-	async keys() {
-		const db = await this.getDB();
-		return new Promise((resolve, reject) => {
-			const request = db.transaction(this.storeName, "readonly").objectStore(this.storeName).getAllKeys();
-			request.addEventListener("success", () => resolve(request.result.map(String)));
-			request.addEventListener("error", () => reject(request.error));
-		});
-	}
-	async removeItem(key) {
-		const db = await this.getDB();
-		return new Promise((resolve, reject) => {
-			const tx = db.transaction(this.storeName, "readwrite");
-			tx.objectStore(this.storeName).delete(key);
-			tx.addEventListener("complete", () => resolve());
-			tx.addEventListener("error", () => reject(tx.error));
-			tx.addEventListener("abort", () => reject(tx.error ?? /* @__PURE__ */ new Error("Transaction aborted")));
-		});
-	}
-	async setItem(key, value) {
-		const db = await this.getDB();
-		return new Promise((resolve, reject) => {
-			const tx = db.transaction(this.storeName, "readwrite");
-			tx.objectStore(this.storeName).put(value, key);
-			tx.addEventListener("complete", () => resolve());
-			tx.addEventListener("error", () => reject(tx.error));
-			tx.addEventListener("abort", () => reject(tx.error ?? /* @__PURE__ */ new Error("Transaction aborted")));
-		});
-	}
-	/**
-	* 鎳掑垵濮嬪寲锛氶娆¤皟鐢ㄦ椂鎵撳紑鏁版嵁搴擄紝鍚庣画澶嶇敤鍚屼竴涓� Promise
-	*/
-	getDB() {
-		if (!this.dbPromise) this.dbPromise = this.openDB().catch((error) => {
-			this.dbPromise = null;
-			throw error;
-		});
-		return this.dbPromise;
-	}
-	openDB() {
-		return new Promise((resolve, reject) => {
-			const request = indexedDB.open(this.dbName, this.dbVersion);
-			request.addEventListener("upgradeneeded", () => {
-				const db = request.result;
-				if (!db.objectStoreNames.contains(this.storeName)) db.createObjectStore(this.storeName);
-			});
-			request.addEventListener("success", () => resolve(request.result));
-			request.addEventListener("error", () => reject(request.error));
-		});
-	}
-};
-//#endregion
-//#region src/cache/local-storage-driver.ts
-/**
-* LocalStorage / SessionStorage 椹卞姩
-* 鐢� async 鍖呰鍚屾 API锛屼繚鎸佹帴鍙g粺涓�
-*/
-var LocalStorageDriver = class {
-	storage;
-	constructor({ storageType = "localStorage" } = {}) {
-		if (typeof window === "undefined") throw new TypeError("LocalStorageDriver is not available in non-browser environments. Use MemoryStorageDriver instead.");
-		this.storage = storageType === "localStorage" ? window.localStorage : window.sessionStorage;
-	}
-	async clear() {
-		this.storage.clear();
-	}
-	async getItem(key) {
-		const raw = this.storage.getItem(key);
-		if (raw === null) return null;
-		try {
-			return JSON.parse(raw);
-		} catch {
-			this.storage.removeItem(key);
-			return null;
-		}
-	}
-	async keys() {
-		const result = [];
-		for (let i = 0; i < this.storage.length; i++) {
-			const key = this.storage.key(i);
-			if (key !== null) result.push(key);
-		}
-		return result;
-	}
-	async removeItem(key) {
-		this.storage.removeItem(key);
-	}
-	async setItem(key, value) {
-		this.storage.setItem(key, JSON.stringify(value));
-	}
-};
-//#endregion
-//#region src/cache/memory-storage-driver.ts
-/**
-* 鍐呭瓨瀛樺偍椹卞姩
-* 閫傜敤浜庢祴璇曠幆澧冨拰 SSR 鍦烘櫙锛屾暟鎹笉鎸佷箙鍖�
-*/
-var MemoryStorageDriver = class {
-	store = /* @__PURE__ */ new Map();
-	async clear() {
-		this.store.clear();
-	}
-	async getItem(key) {
-		return this.store.get(key) ?? null;
-	}
-	async keys() {
-		return [...this.store.keys()];
-	}
-	async removeItem(key) {
-		this.store.delete(key);
-	}
-	async setItem(key, value) {
-		this.store.set(key, value);
-	}
-};
-//#endregion
-//#region src/cache/storage-manager.ts
-/**
-* 瀛樺偍绠$悊鍣紙绛栫暐妯″紡锛�
-* - prefix锛堝懡鍚嶇┖闂撮殧绂伙級鍦ㄦ灞傚鐞�
-* - TTL锛堣繃鏈熸満鍒讹級鍦ㄦ灞傚鐞�
-* - Driver 鍙礋璐g函绮圭殑 KV 瀛樺彇
-*/
-var StorageManager = class {
-	driver;
-	prefix;
-	constructor({ driver, prefix = "" } = {}) {
-		this.driver = driver || this.createDefaultDriver();
-		this.prefix = prefix;
-		if (!this.prefix && this.driver instanceof LocalStorageDriver) console.warn("[StorageManager] empty prefix combined with LocalStorageDriver 鈥� clear()/keys() will affect every localStorage entry.");
-	}
-	/**
-	* 娓呴櫎鎵�鏈夊甫鍓嶇紑鐨勫瓨鍌ㄩ」
-	*/
-	async clear() {
-		const allKeys = await this.driver.keys();
-		const fullPrefix = this.prefix ? `${this.prefix}-` : "";
-		const prefixedKeys = allKeys.filter((key) => key.startsWith(fullPrefix));
-		await Promise.all(prefixedKeys.map((key) => this.driver.removeItem(key)));
-	}
-	/**
-	* 娓呴櫎鎵�鏈夎繃鏈熺殑瀛樺偍椤�
-	*/
-	async clearExpiredItems() {
-		const allKeys = await this.driver.keys();
-		const fullPrefix = this.prefix ? `${this.prefix}-` : "";
-		const prefixedKeys = allKeys.filter((key) => key.startsWith(fullPrefix));
-		for (const fullKey of prefixedKeys) {
-			const raw = await this.driver.getItem(fullKey);
-			if (raw && raw.expiry && Date.now() > raw.expiry) await this.driver.removeItem(fullKey);
-		}
-	}
-	/**
-	* 鑾峰彇瀛樺偍椤�
-	* @param key 閿�
-	* @param defaultValue 褰撻」涓嶅瓨鍦ㄦ垨宸茶繃鏈熸椂杩斿洖鐨勯粯璁ゅ��
-	* @returns 鍊硷紝濡傛灉椤瑰凡杩囨湡鍒欒繑鍥為粯璁ゅ��
-	*/
-	async getItem(key, defaultValue = null) {
-		const fullKey = this.getFullKey(key);
-		const raw = await this.driver.getItem(fullKey);
-		if (!raw) return defaultValue;
-		if (raw.expiry && Date.now() > raw.expiry) {
-			await this.driver.removeItem(fullKey);
-			return defaultValue;
-		}
-		return raw.value;
-	}
-	/**
-	* 鑾峰彇褰撳墠鍓嶇紑涓嬬殑鎵�鏈夊瓨鍌ㄩ敭锛堝凡鍘婚櫎鍓嶇紑閮ㄥ垎锛�
-	*/
-	async keys() {
-		const allKeys = await this.driver.keys();
-		const fullPrefix = this.prefix ? `${this.prefix}-` : "";
-		if (!fullPrefix) return allKeys;
-		return allKeys.filter((key) => key.startsWith(fullPrefix)).map((key) => key.slice(fullPrefix.length));
-	}
-	/**
-	* 绉婚櫎瀛樺偍椤�
-	* @param key 閿�
-	*/
-	async removeItem(key) {
-		const fullKey = this.getFullKey(key);
-		await this.driver.removeItem(fullKey);
-	}
-	/**
-	* 璁剧疆瀛樺偍椤�
-	* @param key 閿�
-	* @param value 鍊�
-	* @param ttl 瀛樻椿鏃堕棿锛堟绉掞級
-	*/
-	async setItem(key, value, ttl) {
-		const fullKey = this.getFullKey(key);
-		const item = {
-			expiry: ttl ? Date.now() + ttl : void 0,
-			value
-		};
-		await this.driver.setItem(fullKey, item);
-	}
-	/**
-	* 鏍规嵁杩愯鐜鍒涘缓榛樿椹卞姩锛�
-	* - 娴忚鍣ㄧ幆澧冿紙window.localStorage 鍙敤锛夆啋 LocalStorageDriver
-	* - SSR / Node 鐜 鈫� MemoryStorageDriver
-	*/
-	createDefaultDriver() {
-		try {
-			if (typeof window !== "undefined" && window.localStorage) return new LocalStorageDriver();
-		} catch (error) {
-			console.warn("localStorage is not accessible, falling back to MemoryStorageDriver:", error);
-		}
-		return new MemoryStorageDriver();
-	}
-	/**
-	* 鑾峰彇瀹屾暣鐨勫瓨鍌ㄩ敭锛堝甫鍓嶇紑锛�
-	* @param key 鍘熷閿�
-	* @returns 甯﹀墠缂�鐨勫畬鏁撮敭
-	*/
-	getFullKey(key) {
-		return this.prefix ? `${this.prefix}-${key}` : key;
-	}
-};
-//#endregion
-export { IndexedDBDriver, LocalStorageDriver, MemoryStorageDriver, StorageManager };
diff --git a/src/packages/@core/base/shared/dist/color/index.d.ts b/src/packages/@core/base/shared/dist/color/index.d.ts
deleted file mode 100644
index 3ba2825..0000000
--- a/src/packages/@core/base/shared/dist/color/index.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { TinyColor } from "@ctrl/tinycolor";
-
-//#region src/color/color.d.ts
-declare function isDarkColor(color: string): boolean;
-declare function isLightColor(color: string): boolean;
-//#endregion
-//#region src/color/convert.d.ts
-declare function convertToHsl(color: string): string;
-declare function convertToHslCssVar(color: string): string;
-declare function convertToRgb(str: string): string;
-declare function isValidColor(color?: string): boolean;
-//#endregion
-//#region src/color/generator.d.ts
-interface ColorItem {
-  alias?: string;
-  color: string;
-  name: string;
-}
-declare function generatorColorVariables(colorItems: ColorItem[]): Record<string, string>;
-//#endregion
-export { TinyColor, convertToHsl, convertToHslCssVar, convertToRgb, generatorColorVariables, isDarkColor, isLightColor, isValidColor };
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/color/index.mjs b/src/packages/@core/base/shared/dist/color/index.mjs
deleted file mode 100644
index 52ec567..0000000
--- a/src/packages/@core/base/shared/dist/color/index.mjs
+++ /dev/null
@@ -1,82 +0,0 @@
-import { TinyColor, TinyColor as TinyColor$1 } from "@ctrl/tinycolor";
-import { getColors } from "theme-colors";
-//#region src/color/color.ts
-function isDarkColor(color) {
-	return new TinyColor$1(color).isDark();
-}
-function isLightColor(color) {
-	return new TinyColor$1(color).isLight();
-}
-//#endregion
-//#region src/color/convert.ts
-/**
-* 灏嗛鑹茶浆鎹负HSL鏍煎紡銆�
-*
-* HSL鏄竴绉嶉鑹叉ā鍨嬶紝鍖呮嫭鑹茬浉(Hue)銆侀ケ鍜屽害(Saturation)鍜屼寒搴�(Lightness)涓変釜閮ㄥ垎銆�
-*
-* @param {string} color 杈撳叆鐨勯鑹层��
-* @returns {string} HSL鏍煎紡鐨勯鑹插瓧绗︿覆銆�
-*/
-function convertToHsl(color) {
-	const { a, h, l, s } = new TinyColor(color).toHsl();
-	const hsl = `hsl(${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%)`;
-	return a < 1 ? `${hsl} ${a}` : hsl;
-}
-/**
-* 灏嗛鑹茶浆鎹负HSL CSS鍙橀噺銆�
-*
-* 杩欎釜鍑芥暟涓巆onvertToHsl鍑芥暟绫讳技锛屼絾鏄繑鍥炵殑瀛楃涓叉牸寮忕◢鏈変笉鍚岋紝
-* 浠ヤ究鍙互浣滀负CSS鍙橀噺浣跨敤銆�
-*
-* @param {string} color 杈撳叆鐨勯鑹层��
-* @returns {string} 鍙互浣滀负CSS鍙橀噺浣跨敤鐨凥SL鏍煎紡鐨勯鑹插瓧绗︿覆銆�
-*/
-function convertToHslCssVar(color) {
-	const { a, h, l, s } = new TinyColor(color).toHsl();
-	const hsl = `${Math.round(h)} ${Math.round(s * 100)}% ${Math.round(l * 100)}%`;
-	return a < 1 ? `${hsl} / ${a}` : hsl;
-}
-/**
-* 灏嗛鑹茶浆鎹负RGB棰滆壊瀛楃涓�
-* TinyColor鏃犳硶澶勭悊hsl鍐呭寘鍚�'deg'銆�'grad'銆�'rad'鎴�'turn'鐨勫瓧绗︿覆
-* 姣斿 hsl(231deg 98% 65%)灏嗚瑙f瀽涓簉gb(0, 0, 0)
-* 杩欓噷鍦ㄨ浆鎹箣鍓嶅厛灏嗚繖浜涘崟浣嶅幓鎺�
-* @param str 琛ㄧずHLS棰滆壊鍊肩殑瀛楃涓�
-* @returns 濡傛灉棰滆壊鍊兼湁鏁堬紝鍒欒繑鍥炲搴旂殑RGB棰滆壊瀛楃涓诧紱濡傛灉鏃犳晥锛屽垯杩斿洖rgb(0, 0, 0)
-*/
-function convertToRgb(str) {
-	return new TinyColor(str.replaceAll(/deg|grad|rad|turn/g, "")).toRgbString();
-}
-/**
-* 妫�鏌ラ鑹叉槸鍚︽湁鏁�
-* @param {string} color - 寰呮鏌ョ殑棰滆壊
-* 濡傛灉棰滆壊鏈夋晥杩斿洖true锛屽惁鍒欒繑鍥瀎alse
-*/
-function isValidColor(color) {
-	if (!color) return false;
-	return new TinyColor(color).isValid;
-}
-//#endregion
-//#region src/color/generator.ts
-function generatorColorVariables(colorItems) {
-	const colorVariables = {};
-	colorItems.forEach(({ alias, color, name }) => {
-		if (color) {
-			const colorsMap = getColors(new TinyColor(color).toHexString());
-			let mainColor = colorsMap["500"];
-			Object.keys(colorsMap).forEach((key) => {
-				const colorValue = colorsMap[key];
-				if (colorValue) {
-					const hslColor = convertToHslCssVar(colorValue);
-					colorVariables[`--${name}-${key}`] = hslColor;
-					if (alias) colorVariables[`--${alias}-${key}`] = hslColor;
-					if (key === "500") mainColor = hslColor;
-				}
-			});
-			if (alias && mainColor) colorVariables[`--${alias}`] = mainColor;
-		}
-	});
-	return colorVariables;
-}
-//#endregion
-export { TinyColor, convertToHsl, convertToHslCssVar, convertToRgb, generatorColorVariables, isDarkColor, isLightColor, isValidColor };
diff --git a/src/packages/@core/base/shared/dist/constants/index.d.ts b/src/packages/@core/base/shared/dist/constants/index.d.ts
deleted file mode 100644
index c3b5a0f..0000000
--- a/src/packages/@core/base/shared/dist/constants/index.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-//#region src/constants/globals.d.ts
-declare const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = "--vben-content-height";
-declare const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = "--vben-content-width";
-declare const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = "--vben-header-height";
-declare const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = "--vben-footer-height";
-declare const ELEMENT_ID_MAIN_CONTENT = "__vben_main_content";
-declare const DEFAULT_NAMESPACE = "vben";
-//#endregion
-//#region src/constants/vben.d.ts
-declare const VBEN_GITHUB_URL = "https://github.com/yudaocode/yudao-ui-admin-vben";
-declare const VBEN_DOC_URL = "https://doc.iocoder.cn/";
-declare const VBEN_LOGO_URL = "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp";
-declare const VBEN_PREVIEW_URL = "https://www.vben.pro";
-declare const VBEN_ANTDV_NEXT_PREVIEW_URL = "https://antdv-next.vben.pro";
-declare const VBEN_ELE_PREVIEW_URL = "https://ele.vben.pro";
-declare const VBEN_NAIVE_PREVIEW_URL = "https://naive.vben.pro";
-declare const VBEN_ANT_PREVIEW_URL = "https://ant.vben.pro";
-declare const VBEN_TD_PREVIEW_URL = "https://tdesign.vben.pro";
-//#endregion
-export { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT, CSS_VARIABLE_LAYOUT_CONTENT_WIDTH, CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT, CSS_VARIABLE_LAYOUT_HEADER_HEIGHT, DEFAULT_NAMESPACE, ELEMENT_ID_MAIN_CONTENT, VBEN_ANTDV_NEXT_PREVIEW_URL, VBEN_ANT_PREVIEW_URL, VBEN_DOC_URL, VBEN_ELE_PREVIEW_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_NAIVE_PREVIEW_URL, VBEN_PREVIEW_URL, VBEN_TD_PREVIEW_URL };
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/constants/index.mjs b/src/packages/@core/base/shared/dist/constants/index.mjs
deleted file mode 100644
index bfb9d7b..0000000
--- a/src/packages/@core/base/shared/dist/constants/index.mjs
+++ /dev/null
@@ -1,40 +0,0 @@
-//#region src/constants/globals.ts
-/** layout content 缁勪欢鐨勯珮搴� */
-const CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT = `--vben-content-height`;
-/** layout content 缁勪欢鐨勫搴� */
-const CSS_VARIABLE_LAYOUT_CONTENT_WIDTH = `--vben-content-width`;
-/** layout header 缁勪欢鐨勯珮搴� */
-const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`;
-/** layout footer 缁勪欢鐨勯珮搴� */
-const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`;
-/** 鍐呭鍖哄煙鐨勭粍浠禝D */
-const ELEMENT_ID_MAIN_CONTENT = `__vben_main_content`;
-/**
-* @zh_CN 榛樿鍛藉悕绌洪棿
-*/
-const DEFAULT_NAMESPACE = "vben";
-//#endregion
-//#region src/constants/vben.ts
-/**
-* @zh_CN GITHUB 浠撳簱鍦板潃
-*/
-const VBEN_GITHUB_URL = "https://github.com/yudaocode/yudao-ui-admin-vben";
-/**
-* @zh_CN 鏂囨。鍦板潃
-*/
-const VBEN_DOC_URL = "https://doc.iocoder.cn/";
-/**
-* @zh_CN Vben Logo
-*/
-const VBEN_LOGO_URL = "https://unpkg.com/@vbenjs/static-source@0.1.7/source/logo-v1.webp";
-/**
-* @zh_CN Vben Admin 棣栭〉鍦板潃
-*/
-const VBEN_PREVIEW_URL = "https://www.vben.pro";
-const VBEN_ANTDV_NEXT_PREVIEW_URL = "https://antdv-next.vben.pro";
-const VBEN_ELE_PREVIEW_URL = "https://ele.vben.pro";
-const VBEN_NAIVE_PREVIEW_URL = "https://naive.vben.pro";
-const VBEN_ANT_PREVIEW_URL = "https://ant.vben.pro";
-const VBEN_TD_PREVIEW_URL = "https://tdesign.vben.pro";
-//#endregion
-export { CSS_VARIABLE_LAYOUT_CONTENT_HEIGHT, CSS_VARIABLE_LAYOUT_CONTENT_WIDTH, CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT, CSS_VARIABLE_LAYOUT_HEADER_HEIGHT, DEFAULT_NAMESPACE, ELEMENT_ID_MAIN_CONTENT, VBEN_ANTDV_NEXT_PREVIEW_URL, VBEN_ANT_PREVIEW_URL, VBEN_DOC_URL, VBEN_ELE_PREVIEW_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_NAIVE_PREVIEW_URL, VBEN_PREVIEW_URL, VBEN_TD_PREVIEW_URL };
diff --git a/src/packages/@core/base/shared/dist/global-state.d.ts b/src/packages/@core/base/shared/dist/global-state.d.ts
deleted file mode 100644
index 51b6a71..0000000
--- a/src/packages/@core/base/shared/dist/global-state.d.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-//#region src/global-state.d.ts
-interface ComponentsState {
-  [key: string]: any;
-}
-interface MessageState {
-  copyPreferencesSuccess?: (title: string, content?: string) => void;
-}
-interface IGlobalSharedState {
-  components: ComponentsState;
-  message: MessageState;
-}
-declare class GlobalShareState {
-  #private;
-  defineMessage({
-    copyPreferencesSuccess
-  }: MessageState): void;
-  getComponents(): ComponentsState;
-  getMessage(): MessageState;
-  setComponents(value: ComponentsState): void;
-}
-declare const globalShareState: GlobalShareState;
-//#endregion
-export { IGlobalSharedState, globalShareState };
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/global-state.mjs b/src/packages/@core/base/shared/dist/global-state.mjs
deleted file mode 100644
index 9897fc7..0000000
--- a/src/packages/@core/base/shared/dist/global-state.mjs
+++ /dev/null
@@ -1,23 +0,0 @@
-//#region src/global-state.ts
-var GlobalShareState = class {
-	#components = {};
-	#message = {};
-	/**
-	* 瀹氫箟妗嗘灦鍐呴儴鍚勪釜鍦烘櫙鐨勬秷鎭彁绀�
-	*/
-	defineMessage({ copyPreferencesSuccess }) {
-		this.#message = { copyPreferencesSuccess };
-	}
-	getComponents() {
-		return this.#components;
-	}
-	getMessage() {
-		return this.#message;
-	}
-	setComponents(value) {
-		this.#components = value;
-	}
-};
-const globalShareState = new GlobalShareState();
-//#endregion
-export { globalShareState };
diff --git a/src/packages/@core/base/shared/dist/store.d.ts b/src/packages/@core/base/shared/dist/store.d.ts
deleted file mode 100644
index d865cea..0000000
--- a/src/packages/@core/base/shared/dist/store.d.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from "@tanstack/vue-store";
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/store.mjs b/src/packages/@core/base/shared/dist/store.mjs
deleted file mode 100644
index f076568..0000000
--- a/src/packages/@core/base/shared/dist/store.mjs
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "@tanstack/vue-store";
-export {};
diff --git a/src/packages/@core/base/shared/dist/utils/index.d.ts b/src/packages/@core/base/shared/dist/utils/index.d.ts
deleted file mode 100644
index 2cf75dc..0000000
--- a/src/packages/@core/base/shared/dist/utils/index.d.ts
+++ /dev/null
@@ -1,269 +0,0 @@
-import { ClassValue } from "clsx";
-import dayjs from "dayjs";
-import { isFunction, isObject, isString } from "@vue/shared";
-import { createDefu as createMerge, defu as merge } from "defu";
-import { get, isEqual, set } from "es-toolkit/compat";
-import cloneDeep from "lodash.clonedeep";
-
-//#region src/utils/cn.d.ts
-declare function cn(...inputs: ClassValue[]): string;
-//#endregion
-//#region src/utils/date.d.ts
-type FormatDate = Date | dayjs.Dayjs | number | string;
-type Format = 'HH' | 'HH:mm' | 'HH:mm:ss' | 'YYYY' | 'YYYY-MM' | 'YYYY-MM-DD' | 'YYYY-MM-DD HH' | 'YYYY-MM-DD HH:mm' | 'YYYY-MM-DD HH:mm:ss' | (string & {});
-declare function formatDate(time?: FormatDate, format?: Format): string;
-declare function formatDateTime(time?: FormatDate): string;
-declare function formatDate2(date: Date, format?: string): string;
-declare function isDate(value: any): value is Date;
-declare function isDayjsObject(value: any): value is dayjs.Dayjs;
-declare function dateFormatter(_row: any, _column: any, cellValue: any): string;
-declare const getSystemTimezone: () => string;
-declare const setCurrentTimezone: (timezone?: string) => void;
-declare const getCurrentTimezone: () => string;
-declare function formatDayjs(value: dayjs.Dayjs | null | string | undefined): string;
-//#endregion
-//#region src/utils/diff.d.ts
-declare function arraysEqual<T>(a: T[], b: T[]): boolean;
-type DiffResult<T> = Partial<{ [K in keyof T]: T[K] extends object ? DiffResult<T[K]> : T[K] }>;
-declare function diff<T extends Record<string, any>>(obj1: T, obj2: T): DiffResult<T>;
-//#endregion
-//#region src/utils/dom.d.ts
-interface VisibleDomRect {
-  bottom: number;
-  height: number;
-  left: number;
-  right: number;
-  top: number;
-  width: number;
-}
-declare function getElementVisibleRect(element?: HTMLElement | null | undefined): VisibleDomRect;
-declare function getScrollbarWidth(): number;
-declare function needsScrollbar(): boolean;
-declare function triggerWindowResize(): void;
-//#endregion
-//#region src/utils/download.d.ts
-interface DownloadOptions<T = string> {
-  fileName?: string;
-  source: T;
-  target?: string;
-}
-declare function downloadFileFromUrl({
-  fileName,
-  source,
-  target
-}: DownloadOptions): Promise<void>;
-declare function downloadImageByCanvas({
-  url,
-  canvasWidth,
-  canvasHeight,
-  drawWithImageSize
-}: {
-  canvasHeight?: number;
-  canvasWidth?: number;
-  drawWithImageSize?: boolean;
-  url: string;
-}): void;
-declare function downloadFileFromBase64({
-  fileName,
-  source
-}: DownloadOptions): void;
-declare function downloadFileFromImageUrl({
-  fileName,
-  source
-}: DownloadOptions): Promise<void>;
-declare function downloadFileFromBlob({
-  fileName,
-  source
-}: DownloadOptions<Blob>): void;
-declare function downloadFileFromBlobPart({
-  fileName,
-  source
-}: DownloadOptions<BlobPart>): void;
-declare function dataURLtoBlob(base64Buf: string): Blob;
-declare function urlToBase64(url: string, mineType?: string): Promise<string>;
-declare function base64ToFile(base64: string, fileName: string): File;
-declare function triggerDownload(href: string, fileName: string | undefined, revokeDelay?: number): void;
-//#endregion
-//#region src/utils/encrypt.d.ts
-declare const AES: {
-  encrypt(data: string, key: string): string;
-  decrypt(encryptedData: string, key: string): string;
-};
-declare const RSA: {
-  encrypt(data: string, publicKey: string): false | string;
-  decrypt(encryptedData: string, privateKey: string): false | string;
-};
-interface ApiEncryptConfig {
-  algorithm: 'AES' | 'RSA';
-  enable: boolean;
-  header: string;
-  requestKey: string;
-  responseKey: string;
-}
-declare class ApiEncrypt {
-  private config;
-  constructor(config: ApiEncryptConfig);
-  decryptResponse(encryptedData: string): any;
-  encryptRequest(data: any): string;
-  getEncryptHeader(): string;
-}
-declare function createApiEncrypt(env: Record<string, any>): ApiEncrypt;
-//#endregion
-//#region src/utils/formatNumber.d.ts
-declare function formatToFractionDigit(num: number | string | undefined, digit?: number): string;
-declare function formatToFraction(num: number | string | undefined): string;
-declare function floatToFixed2(num: number | string | undefined): string;
-declare function convertToInteger(num: number | string | undefined): number;
-declare function yuanToFen(amount: number | string): number;
-declare function fenToYuan(price: number | string): string;
-declare const fenToYuanFormat: (_: any, __: any, cellValue: any, ___: any) => string;
-declare function calculateRelativeRate(value?: number, reference?: number): number;
-declare function erpNumberFormatter(num: number | string | undefined, digit: number): string;
-declare function erpCountInputFormatter(num: number | string | undefined): string;
-declare function erpCountTableColumnFormatter(cellValue: any): string;
-declare function erpPriceInputFormatter(num: number | string | undefined): string;
-declare function erpPriceTableColumnFormatter(cellValue: any): string;
-declare function erpPriceMultiply(price: number, count: number): number | undefined;
-declare function erpCalculatePercentage(value: number, total: number): string | 0;
-//#endregion
-//#region src/utils/inference.d.ts
-declare function isUndefined(value?: unknown): value is undefined;
-declare function isBoolean(value: unknown): value is boolean;
-declare function isEmpty<T = unknown>(value?: T): boolean;
-declare function isEmptyVal(value?: unknown): value is '' | null | undefined;
-declare function isHttpUrl(url?: string): boolean;
-declare function isWindow(value: any): value is Window;
-declare function isMacOs(): boolean;
-declare function isWindowsOs(): boolean;
-declare function isNumber(value: any): value is number;
-declare function getFirstNonNullOrUndefined<T>(...values: (null | T | undefined)[]): T | undefined;
-//#endregion
-//#region src/utils/letter.d.ts
-declare function capitalizeFirstLetter(string: string): string;
-declare function toLowerCaseFirstLetter(str: string): string;
-declare function toCamelCase(key: string, parentKey: string): string;
-declare function kebabToCamelCase(str: string): string;
-//#endregion
-//#region src/utils/merge.d.ts
-declare const mergeWithArrayOverride: import("defu").DefuFn;
-//#endregion
-//#region src/utils/nprogress.d.ts
-declare function startProgress(): Promise<void>;
-declare function stopProgress(): Promise<void>;
-//#endregion
-//#region src/utils/resources.d.ts
-declare function loadScript(src: string): Promise<void>;
-//#endregion
-//#region src/utils/stack.d.ts
-declare class Stack<T> {
-  get size(): number;
-  private readonly dedup;
-  private items;
-  private readonly maxSize?;
-  constructor(dedup?: boolean, maxSize?: number);
-  clear(): void;
-  peek(): T | undefined;
-  pop(): T | undefined;
-  push(...items: T[]): void;
-  remove(...itemList: T[]): void;
-  retain(itemList: T[]): void;
-  toArray(): T[];
-}
-declare const createStack: <T>(dedup?: boolean, maxSize?: number) => Stack<T>;
-//#endregion
-//#region src/utils/state-handler.d.ts
-declare class StateHandler {
-  private condition;
-  private rejectCondition;
-  private resolveCondition;
-  isConditionTrue(): boolean;
-  reset(): void;
-  setConditionFalse(): void;
-  setConditionTrue(): void;
-  waitForCondition(): Promise<void>;
-  private clearPromises;
-}
-//#endregion
-//#region src/utils/time.d.ts
-declare function formatTime(time: Date | number | string, fmt: string): string;
-declare function getWeek(dateTime: Date): number;
-declare function formatPast(param: Date | string, format?: string): string;
-declare function formatAxis(param: Date): string;
-declare function formatPast2(ms: number): string;
-declare function beginOfDay(param: Date): Date;
-declare function endOfDay(param: Date): Date;
-declare function betweenDay(param1: Date, param2: Date): number;
-declare function addTime(param1: Date, param2: number): Date;
-declare function convertDate(param: Date | string): Date;
-declare function isSameDay(a: dayjs.ConfigType, b: dayjs.ConfigType): boolean;
-declare function getDayRange(date: dayjs.ConfigType, days: number): [dayjs.ConfigType, dayjs.ConfigType];
-declare function getLast7Days(): [dayjs.ConfigType, dayjs.ConfigType];
-declare function getLast30Days(): [dayjs.ConfigType, dayjs.ConfigType];
-declare function getLast1Year(): [dayjs.ConfigType, dayjs.ConfigType];
-declare function getDateRange(beginDate: dayjs.ConfigType, endDate: dayjs.ConfigType): [string, string];
-//#endregion
-//#region src/utils/to.d.ts
-declare function to<T, U = Error>(promise: Readonly<Promise<T>>, errorExt?: object): Promise<[null, T] | [U, undefined]>;
-//#endregion
-//#region src/utils/tree.d.ts
-interface TreeConfigOptions {
-  childProps: string;
-}
-interface TreeNode {
-  [key: string]: any;
-  children?: TreeNode[];
-}
-declare function traverseTreeValues<T, V>(tree: T[], getValue: (node: T) => V, options?: TreeConfigOptions): V[];
-declare function filterTree<T extends Record<string, any>>(tree: T[], filter: (node: T) => boolean, options?: TreeConfigOptions): T[];
-declare function mapTree<T, V extends Record<string, any>>(tree: T[], mapper: (node: T) => V, options?: TreeConfigOptions): V[];
-declare function handleTree(data: TreeNode[], id?: string, parentId?: string, children?: string): TreeNode[];
-declare function treeToString(tree: any[], nodeId: number | string): any;
-declare function sortTree<T extends Record<string, any>>(treeData: T[], sortFunction: (a: T, b: T) => number, options?: TreeConfigOptions): T[];
-//#endregion
-//#region src/utils/unique.d.ts
-declare function uniqueByField<T>(arr: T[], key: keyof T): T[];
-//#endregion
-//#region src/utils/update-css-variables.d.ts
-declare function updateCSSVariables(variables: {
-  [key: string]: string;
-}, id?: string, selector?: string): void;
-//#endregion
-//#region src/utils/upload.d.ts
-declare function generateAcceptedFileTypes(supportedFileTypes: string[]): string;
-declare function getFileNameFromUrl(url: null | string | undefined): string;
-declare const defaultImageAccepts: string[];
-declare function isImage(filename: null | string | undefined, accepts?: string[]): boolean;
-declare function checkFileType(file: File, accepts: string[]): boolean;
-declare function formatFileSize(bytes: number, digits?: number): string;
-declare function getFileIcon(filename: null | string | undefined): string;
-declare function getFileTypeClass(filename: null | string | undefined): string;
-//#endregion
-//#region src/utils/url.d.ts
-declare function isUrl(path: string): boolean;
-declare function isOpenableUrl(url?: null | string): boolean;
-declare function openSafeUrl(url?: null | string): void;
-//#endregion
-//#region src/utils/util.d.ts
-declare function bindMethods<T extends object>(instance: T): void;
-declare function getNestedValue<T>(obj: T, path: string): any;
-declare function getUrlNumberValue(key: string, urlStr?: string): number;
-declare function getUrlValue(key: string, urlStr?: string): string;
-declare function copyValueToTarget(target: any, source: any): void;
-declare function groupBy(array: any[], key: string): Record<string, any[]>;
-declare function jsonParse(str: string): any;
-declare function getStableObjectKey(item: object, generator?: () => string): string;
-//#endregion
-//#region src/utils/uuid.d.ts
-declare function buildUUID(): string;
-declare function buildShortUUID(prefix?: string): string;
-//#endregion
-//#region src/utils/window.d.ts
-interface OpenWindowOptions {
-  noopener?: boolean;
-  noreferrer?: boolean;
-  target?: '_blank' | '_parent' | '_self' | '_top' | string;
-}
-declare function openWindow(url: string, options?: OpenWindowOptions): void;
-declare function openRouteInNewWindow(path: string): void;
-//#endregion
-export { AES, ApiEncrypt, ApiEncryptConfig, RSA, Stack, StateHandler, VisibleDomRect, addTime, arraysEqual, base64ToFile, beginOfDay, betweenDay, bindMethods, buildShortUUID, buildUUID, calculateRelativeRate, capitalizeFirstLetter, checkFileType, cloneDeep, cn, convertDate, convertToInteger, copyValueToTarget, createApiEncrypt, createMerge, createStack, dataURLtoBlob, dateFormatter, defaultImageAccepts, diff, downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageByCanvas, endOfDay, erpCalculatePercentage, erpCountInputFormatter, erpCountTableColumnFormatter, erpNumberFormatter, erpPriceInputFormatter, erpPriceMultiply, erpPriceTableColumnFormatter, fenToYuan, fenToYuanFormat, filterTree, floatToFixed2, formatAxis, formatDate, formatDate2, formatDateTime, formatDayjs, formatFileSize, formatPast, formatPast2, formatTime, formatToFraction, formatToFractionDigit, generateAcceptedFileTypes, get, getCurrentTimezone, getDateRange, getDayRange, getElementVisibleRect, getFileIcon, getFileNameFromUrl, getFileTypeClass, getFirstNonNullOrUndefined, getLast1Year, getLast30Days, getLast7Days, getNestedValue, getScrollbarWidth, getStableObjectKey, getSystemTimezone, getUrlNumberValue, getUrlValue, getWeek, groupBy, handleTree, isBoolean, isDate, isDayjsObject, isEmpty, isEmptyVal, isEqual, isFunction, isHttpUrl, isImage, isMacOs, isNumber, isObject, isOpenableUrl, isSameDay, isString, isUndefined, isUrl, isWindow, isWindowsOs, jsonParse, kebabToCamelCase, loadScript, mapTree, merge, mergeWithArrayOverride, needsScrollbar, openRouteInNewWindow, openSafeUrl, openWindow, set, setCurrentTimezone, sortTree, startProgress, stopProgress, to, toCamelCase, toLowerCaseFirstLetter, traverseTreeValues, treeToString, triggerDownload, triggerWindowResize, uniqueByField, updateCSSVariables, urlToBase64, yuanToFen };
\ No newline at end of file
diff --git a/src/packages/@core/base/shared/dist/utils/index.mjs b/src/packages/@core/base/shared/dist/utils/index.mjs
deleted file mode 100644
index d7ec0e7..0000000
--- a/src/packages/@core/base/shared/dist/utils/index.mjs
+++ /dev/null
@@ -1,1775 +0,0 @@
-import { clsx } from "clsx";
-import { twMerge } from "tailwind-merge";
-import dayjs from "dayjs";
-import timezone from "dayjs/plugin/timezone.js";
-import utc from "dayjs/plugin/utc.js";
-import CryptoJS from "crypto-js";
-import { JSEncrypt } from "jsencrypt";
-import { isFunction, isObject, isString } from "@vue/shared";
-import { createDefu, createDefu as createMerge, defu as merge } from "defu";
-import { get, isEqual, set } from "es-toolkit/compat";
-import cloneDeep from "lodash.clonedeep";
-//#region src/utils/cn.ts
-function cn(...inputs) {
-	return twMerge(clsx(inputs));
-}
-//#endregion
-//#region src/utils/date.ts
-dayjs.extend(utc);
-dayjs.extend(timezone);
-function formatDate(time, format = "YYYY-MM-DD") {
-	if (time === void 0 || time === null || time === "") return "";
-	try {
-		const date = dayjs.isDayjs(time) ? time : dayjs(time);
-		if (!date.isValid()) throw new Error("Invalid date");
-		return date.tz().format(format);
-	} catch (error) {
-		console.error(`Error formatting date: ${error}`);
-		return String(time ?? "");
-	}
-}
-function formatDateTime(time) {
-	return formatDate(time, "YYYY-MM-DD HH:mm:ss");
-}
-function formatDate2(date, format) {
-	if (!date) return "";
-	return date ? dayjs(date).format(format ?? "YYYY-MM-DD HH:mm:ss") : "";
-}
-function isDate(value) {
-	return value instanceof Date;
-}
-function isDayjsObject(value) {
-	return dayjs.isDayjs(value);
-}
-/**
-* element plus 鐨勬椂闂� Formatter 瀹炵幇锛屼娇鐢� YYYY-MM-DD HH:mm:ss 鏍煎紡
-*
-* @param _row
-* @param _column
-* @param cellValue 瀛楁鍊�
-*/
-function dateFormatter(_row, _column, cellValue) {
-	return cellValue ? formatDate(cellValue)?.toString() || "" : "";
-}
-/**
-* 鑾峰彇褰撳墠鏃跺尯
-* @returns 褰撳墠鏃跺尯
-*/
-const getSystemTimezone = () => {
-	return dayjs.tz.guess();
-};
-/**
-* 鑷畾涔夎缃殑鏃跺尯
-*/
-let currentTimezone = getSystemTimezone();
-/**
-* 璁剧疆榛樿鏃跺尯
-* @param timezone
-*/
-const setCurrentTimezone = (timezone) => {
-	currentTimezone = timezone || getSystemTimezone();
-	dayjs.tz.setDefault(currentTimezone);
-};
-/**
-* 鑾峰彇璁剧疆鐨勬椂鍖�
-* @returns 璁剧疆鐨勬椂鍖�
-*/
-const getCurrentTimezone = () => {
-	return currentTimezone;
-};
-/**
-* 鎶� antd TimePicker / DatePicker `@update:value` 鍥炰紶鐨勫�肩粺涓�鎴愬瓧绗︿覆銆�
-*
-* antd 鍦ㄨ缃簡 `value-format` 鍚庡疄闄呭彧浼氬洖浼犲瓧绗︿覆锛�
-* 浣� `@update:value` 鐨勭被鍨嬩粛鍖呭惈 `Dayjs`锛岃皟鐢ㄦ柟闇�瑕佸仛涓�娆$被鍨嬪綊涓�銆�
-*
-* - 绌哄�硷紙null / undefined / '' / 0锛夎繑鍥� ''
-* - 宸茬粡鏄瓧绗︿覆锛氬師鏍疯繑鍥烇紙淇濇寔 `value-format` 宸叉牸寮忓寲鐨勭粨鏋滐級
-* - 鍏滃簳鐨� Dayjs锛氳皟鐢� `.format()` 杞粯璁� ISO 瀛楃涓�
-*/
-function formatDayjs(value) {
-	if (!value) return "";
-	return typeof value === "string" ? value : value.format();
-}
-//#endregion
-//#region src/utils/diff.ts
-function arraysEqual(a, b) {
-	if (a.length !== b.length) return false;
-	const counter = /* @__PURE__ */ new Map();
-	for (const value of a) counter.set(value, (counter.get(value) || 0) + 1);
-	for (const value of b) {
-		const count = counter.get(value);
-		if (count === void 0 || count === 0) return false;
-		counter.set(value, count - 1);
-	}
-	return true;
-}
-function diff(obj1, obj2) {
-	function findDifferences(o1, o2) {
-		if (Array.isArray(o1) && Array.isArray(o2)) {
-			if (!arraysEqual(o1, o2)) return o2;
-			return;
-		}
-		if (typeof o1 === "object" && typeof o2 === "object" && o1 !== null && o2 !== null) {
-			const diffResult = {};
-			(/* @__PURE__ */ new Set([...Object.keys(o1), ...Object.keys(o2)])).forEach((key) => {
-				const valueDiff = findDifferences(o1[key], o2[key]);
-				if (valueDiff !== void 0) diffResult[key] = valueDiff;
-			});
-			return Object.keys(diffResult).length > 0 ? diffResult : void 0;
-		}
-		return o1 === o2 ? void 0 : o2;
-	}
-	return findDifferences(obj1, obj2);
-}
-//#endregion
-//#region src/utils/dom.ts
-/**
-* 鑾峰彇鍏冪礌鍙淇℃伅
-* @param element
-*/
-function getElementVisibleRect(element) {
-	if (!element) return {
-		bottom: 0,
-		height: 0,
-		left: 0,
-		right: 0,
-		top: 0,
-		width: 0
-	};
-	const rect = element.getBoundingClientRect();
-	const viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
-	const top = Math.max(rect.top, 0);
-	const bottom = Math.min(rect.bottom, viewHeight);
-	const viewWidth = Math.max(document.documentElement.clientWidth, window.innerWidth);
-	const left = Math.max(rect.left, 0);
-	const right = Math.min(rect.right, viewWidth);
-	if (top >= viewHeight || bottom <= 0 || left >= viewWidth || right <= 0) return {
-		bottom: 0,
-		height: 0,
-		left: 0,
-		right: 0,
-		top: 0,
-		width: 0
-	};
-	return {
-		bottom,
-		height: Math.max(0, bottom - top),
-		left,
-		right,
-		top,
-		width: Math.max(0, right - left)
-	};
-}
-function getScrollbarWidth() {
-	const scrollDiv = document.createElement("div");
-	scrollDiv.style.visibility = "hidden";
-	scrollDiv.style.overflow = "scroll";
-	scrollDiv.style.position = "absolute";
-	scrollDiv.style.top = "-9999px";
-	document.body.append(scrollDiv);
-	const innerDiv = document.createElement("div");
-	scrollDiv.append(innerDiv);
-	const scrollbarWidth = scrollDiv.offsetWidth - innerDiv.offsetWidth;
-	scrollDiv.remove();
-	return scrollbarWidth;
-}
-function needsScrollbar() {
-	const doc = document.documentElement;
-	const body = document.body;
-	const overflowY = window.getComputedStyle(body).overflowY;
-	if (overflowY === "scroll" || overflowY === "auto") return doc.scrollHeight > window.innerHeight;
-	return doc.scrollHeight > window.innerHeight;
-}
-function triggerWindowResize() {
-	const resizeEvent = new Event("resize");
-	window.dispatchEvent(resizeEvent);
-}
-//#endregion
-//#region src/utils/window.ts
-/**
-* 鏂扮獥鍙f墦寮�URL銆�
-*
-* @param url - 闇�瑕佹墦寮�鐨勭綉鍧�銆�
-* @param options - 鎵撳紑绐楀彛鐨勯�夐」銆�
-*/
-function openWindow(url, options = {}) {
-	const { noopener = true, noreferrer = true, target = "_blank" } = options;
-	const features = [noopener && "noopener=yes", noreferrer && "noreferrer=yes"].filter(Boolean).join(",");
-	window.open(url, target, features);
-}
-/**
-* 鍦ㄦ柊绐楀彛涓墦寮�璺敱銆�
-* @param path
-*/
-function openRouteInNewWindow(path) {
-	const { hash, origin } = location;
-	const fullPath = path.startsWith("/") ? path : `/${path}`;
-	openWindow(`${origin}${hash && !fullPath.startsWith("/#") ? "/#" : ""}${fullPath}`, { target: "_blank" });
-}
-//#endregion
-//#region src/utils/download.ts
-const DEFAULT_FILENAME = "downloaded_file";
-/**
-* 閫氳繃 URL 涓嬭浇鏂囦欢锛屾敮鎸佽法鍩�
-* @throws {Error} - 褰撲笅杞藉け璐ユ椂鎶涘嚭閿欒
-*/
-async function downloadFileFromUrl({ fileName, source, target = "_blank" }) {
-	if (!source || typeof source !== "string") throw new Error("Invalid URL.");
-	const isChrome = window.navigator.userAgent.toLowerCase().includes("chrome");
-	const isSafari = window.navigator.userAgent.toLowerCase().includes("safari");
-	if (/iP/.test(window.navigator.userAgent)) {
-		console.error("Your browser does not support download!");
-		return;
-	}
-	if (isChrome || isSafari) {
-		triggerDownload(source, resolveFileName(source, fileName));
-		return;
-	}
-	if (!source.includes("?")) source += "?download";
-	openWindow(source, { target });
-}
-/**
-* 涓嬭浇鍥剧墖锛堝厑璁歌法鍩燂級
-* @param url - 鍥剧墖 URL
-* @param canvasWidth - 鐢诲竷瀹藉害
-* @param canvasHeight - 鐢诲竷楂樺害
-* @param drawWithImageSize - 灏嗗浘鐗囩粯鍒跺湪鐢诲竷涓婃椂甯︿笂鍥剧墖鐨勫楂樺��, 榛樿鏄甯︿笂鐨�
-* @returns
-*/
-function downloadImageByCanvas({ url, canvasWidth, canvasHeight, drawWithImageSize = true }) {
-	const image = new Image();
-	image.src = url;
-	image.addEventListener("load", () => {
-		const canvas = document.createElement("canvas");
-		canvas.width = canvasWidth || image.width;
-		canvas.height = canvasHeight || image.height;
-		const ctx = canvas.getContext("2d");
-		ctx?.clearRect(0, 0, canvas.width, canvas.height);
-		if (drawWithImageSize) ctx.drawImage(image, 0, 0, image.width, image.height);
-		else ctx.drawImage(image, 0, 0);
-		downloadFileFromImageUrl({
-			source: canvas.toDataURL("image/png"),
-			fileName: "image.png"
-		});
-	});
-}
-/**
-* 閫氳繃 Base64 涓嬭浇鏂囦欢
-*/
-function downloadFileFromBase64({ fileName, source }) {
-	if (!source || typeof source !== "string") throw new Error("Invalid Base64 data.");
-	triggerDownload(source, fileName || DEFAULT_FILENAME);
-}
-/**
-* 閫氳繃鍥剧墖 URL 涓嬭浇鍥剧墖鏂囦欢
-*/
-async function downloadFileFromImageUrl({ fileName, source }) {
-	downloadFileFromBase64({
-		fileName,
-		source: await urlToBase64(source)
-	});
-}
-/**
-* 閫氳繃 Blob 涓嬭浇鏂囦欢
-*/
-function downloadFileFromBlob({ fileName = DEFAULT_FILENAME, source }) {
-	if (!(source instanceof Blob)) throw new TypeError("Invalid Blob data.");
-	triggerDownload(URL.createObjectURL(source), fileName);
-}
-/**
-* 涓嬭浇鏂囦欢锛屾敮鎸� Blob銆佸瓧绗︿覆鍜屽叾浠� BlobPart 绫诲瀷
-*/
-function downloadFileFromBlobPart({ fileName = DEFAULT_FILENAME, source }) {
-	const blob = source instanceof Blob ? source : new Blob([source], { type: "application/octet-stream" });
-	triggerDownload(URL.createObjectURL(blob), fileName);
-}
-/**
-* @description: base64 to blob
-*/
-function dataURLtoBlob(base64Buf) {
-	const arr = base64Buf.split(",");
-	const mime = arr[0].match(/:(.*?);/)[1];
-	const bstr = window.atob(arr[1]);
-	let n = bstr.length;
-	const u8arr = new Uint8Array(n);
-	while (n--) u8arr[n] = bstr.codePointAt(n);
-	return new Blob([u8arr], { type: mime });
-}
-/**
-* img url to base64
-* @param url
-*/
-function urlToBase64(url, mineType) {
-	return new Promise((resolve, reject) => {
-		let canvas = document.createElement("CANVAS");
-		const ctx = canvas?.getContext("2d");
-		const img = new Image();
-		img.crossOrigin = "";
-		img.addEventListener("load", () => {
-			if (!canvas || !ctx) return reject(/* @__PURE__ */ new Error("Failed to create canvas."));
-			canvas.height = img.height;
-			canvas.width = img.width;
-			ctx.drawImage(img, 0, 0);
-			const dataURL = canvas.toDataURL(mineType || "image/png");
-			canvas = null;
-			resolve(dataURL);
-		});
-		img.src = url;
-	});
-}
-/**
-* 灏� Base64 瀛楃涓茶浆鎹负鏂囦欢瀵硅薄
-* @param base64 - Base64 瀛楃涓�
-* @param fileName - 鏂囦欢鍚�
-* @returns File 瀵硅薄
-*/
-function base64ToFile(base64, fileName) {
-	if (!base64 || typeof base64 !== "string") throw new Error("base64 鍙傛暟蹇呴』鏄潪绌哄瓧绗︿覆");
-	const data = base64.split(",");
-	if (data.length !== 2 || !data[0] || !data[1]) throw new Error("鏃犳晥鐨� base64 鏍煎紡");
-	const typeMatch = data[0].match(/:(.*?);/);
-	if (!typeMatch || !typeMatch[1]) throw new Error("鏃犳硶瑙f瀽 base64 绫诲瀷淇℃伅");
-	const type = typeMatch[1];
-	const typeParts = type.split("/");
-	if (typeParts.length !== 2 || !typeParts[1]) throw new Error("鏃犳晥鐨� MIME 绫诲瀷鏍煎紡");
-	const suffix = typeParts[1];
-	try {
-		const bstr = window.atob(data[1]);
-		const n = bstr.length;
-		const u8arr = new Uint8Array(n);
-		for (let i = 0; i < n; i++) u8arr[i] = bstr.charCodeAt(i);
-		return new File([u8arr], `${fileName}.${suffix}`, { type });
-	} catch (error) {
-		throw new Error(`Base64 瑙g爜澶辫触: ${error instanceof Error ? error.message : "鏈煡閿欒"}`, { cause: error });
-	}
-}
-/**
-* 閫氱敤涓嬭浇瑙﹀彂鍑芥暟
-* @param href - 鏂囦欢涓嬭浇鐨� URL
-* @param fileName - 涓嬭浇鏂囦欢鐨勫悕绉帮紝濡傛灉鏈彁渚涘垯鑷姩璇嗗埆
-* @param revokeDelay - 娓呯悊 URL 鐨勫欢杩熸椂闂� (姣)
-*/
-function triggerDownload(href, fileName, revokeDelay = 100) {
-	const finalFileName = fileName || "downloaded_file";
-	const link = document.createElement("a");
-	link.href = href;
-	link.download = finalFileName;
-	link.style.display = "none";
-	if (link.download === void 0) link.setAttribute("target", "_blank");
-	document.body.append(link);
-	link.click();
-	link.remove();
-	setTimeout(() => URL.revokeObjectURL(href), revokeDelay);
-}
-function resolveFileName(url, fileName) {
-	return fileName || url.slice(url.lastIndexOf("/") + 1) || DEFAULT_FILENAME;
-}
-//#endregion
-//#region src/utils/encrypt.ts
-/**
-* API 鍔犺В瀵嗗伐鍏风被
-* 鏀寔 AES 鍜� RSA 鍔犲瘑绠楁硶
-*/
-/**
-* AES 鍔犲瘑宸ュ叿绫�
-*/
-const AES = {
-	/**
-	* AES 鍔犲瘑
-	* @param data 瑕佸姞瀵嗙殑鏁版嵁
-	* @param key 鍔犲瘑瀵嗛挜
-	* @returns 鍔犲瘑鍚庣殑瀛楃涓�
-	*/
-	encrypt(data, key) {
-		try {
-			if (!key) throw new Error("AES 鍔犲瘑瀵嗛挜涓嶈兘涓虹┖");
-			if (key.length !== 32 && key.length !== 16) throw new Error(`AES 鍔犲瘑瀵嗛挜闀垮害蹇呴』涓� 32 浣嶆垨 16 浣嶏紝褰撳墠闀垮害: ${key.length}`);
-			const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
-			return CryptoJS.AES.encrypt(data, keyUtf8, {
-				mode: CryptoJS.mode.ECB,
-				padding: CryptoJS.pad.Pkcs7
-			}).toString();
-		} catch (error) {
-			console.error("AES 鍔犲瘑澶辫触:", error);
-			throw error;
-		}
-	},
-	/**
-	* AES 瑙e瘑
-	* @param encryptedData 鍔犲瘑鐨勬暟鎹�
-	* @param key 瑙e瘑瀵嗛挜
-	* @returns 瑙e瘑鍚庣殑瀛楃涓�
-	*/
-	decrypt(encryptedData, key) {
-		try {
-			if (!key) throw new Error("AES 瑙e瘑瀵嗛挜涓嶈兘涓虹┖");
-			if (key.length !== 32) throw new Error(`AES 瑙e瘑瀵嗛挜闀垮害蹇呴』涓� 32 浣嶏紝褰撳墠闀垮害: ${key.length}`);
-			if (!encryptedData) throw new Error("AES 瑙e瘑鏁版嵁涓嶈兘涓虹┖");
-			const keyUtf8 = CryptoJS.enc.Utf8.parse(key);
-			const result = CryptoJS.AES.decrypt(encryptedData, keyUtf8, {
-				mode: CryptoJS.mode.ECB,
-				padding: CryptoJS.pad.Pkcs7
-			}).toString(CryptoJS.enc.Utf8);
-			if (!result) throw new Error("AES 瑙e瘑缁撴灉涓虹┖锛屽彲鑳芥槸瀵嗛挜閿欒鎴栨暟鎹崯鍧�");
-			return result;
-		} catch (error) {
-			console.error("AES 瑙e瘑澶辫触:", error);
-			throw error;
-		}
-	}
-};
-/**
-* RSA 鍔犲瘑宸ュ叿绫�
-*/
-const RSA = {
-	/**
-	* RSA 鍔犲瘑
-	* @param data 瑕佸姞瀵嗙殑鏁版嵁
-	* @param publicKey 鍏挜锛堝繀闇�锛�
-	* @returns 鍔犲瘑鍚庣殑瀛楃涓�
-	*/
-	encrypt(data, publicKey) {
-		try {
-			if (!publicKey) throw new Error("RSA 鍏挜涓嶈兘涓虹┖");
-			const encryptor = new JSEncrypt();
-			encryptor.setPublicKey(publicKey);
-			const result = encryptor.encrypt(data);
-			if (result === false) throw new Error("RSA 鍔犲瘑澶辫触锛屽彲鑳芥槸鍏挜鏍煎紡閿欒鎴栨暟鎹繃闀�");
-			return result;
-		} catch (error) {
-			console.error("RSA 鍔犲瘑澶辫触:", error);
-			throw error;
-		}
-	},
-	/**
-	* RSA 瑙e瘑
-	* @param encryptedData 鍔犲瘑鐨勬暟鎹�
-	* @param privateKey 绉侀挜锛堝繀闇�锛�
-	* @returns 瑙e瘑鍚庣殑瀛楃涓�
-	*/
-	decrypt(encryptedData, privateKey) {
-		try {
-			if (!privateKey) throw new Error("RSA 绉侀挜涓嶈兘涓虹┖");
-			if (!encryptedData) throw new Error("RSA 瑙e瘑鏁版嵁涓嶈兘涓虹┖");
-			const encryptor = new JSEncrypt();
-			encryptor.setPrivateKey(privateKey);
-			const result = encryptor.decrypt(encryptedData);
-			if (result === false) throw new Error("RSA 瑙e瘑澶辫触锛屽彲鑳芥槸绉侀挜閿欒鎴栨暟鎹崯鍧�");
-			return result;
-		} catch (error) {
-			console.error("RSA 瑙e瘑澶辫触:", error);
-			throw error;
-		}
-	}
-};
-/**
-* API 鍔犺В瀵嗕富绫�
-*/
-var ApiEncrypt = class {
-	config;
-	constructor(config) {
-		this.config = config;
-	}
-	/**
-	* 瑙e瘑鍝嶅簲鏁版嵁
-	* @param encryptedData 鍔犲瘑鐨勫搷搴旀暟鎹�
-	* @returns 瑙e瘑鍚庣殑鏁版嵁
-	*/
-	decryptResponse(encryptedData) {
-		if (!this.config.enable) return encryptedData;
-		try {
-			let decryptedData = "";
-			if (this.config.algorithm.toUpperCase() === "AES") {
-				if (!this.config.responseKey) throw new Error("AES 鍝嶅簲瑙e瘑瀵嗛挜鏈厤缃�");
-				decryptedData = AES.decrypt(encryptedData, this.config.responseKey);
-			} else if (this.config.algorithm.toUpperCase() === "RSA") {
-				if (!this.config.responseKey) throw new Error("RSA 绉侀挜鏈厤缃�");
-				decryptedData = RSA.decrypt(encryptedData, this.config.responseKey);
-				if (decryptedData === false) throw new Error("RSA 瑙e瘑澶辫触");
-			} else throw new Error(`涓嶆敮鎸佺殑瑙e瘑绠楁硶: ${this.config.algorithm}`);
-			if (!decryptedData) throw new Error("瑙e瘑缁撴灉涓虹┖");
-			try {
-				return JSON.parse(decryptedData);
-			} catch {
-				return decryptedData;
-			}
-		} catch (error) {
-			console.error("鍝嶅簲鏁版嵁瑙e瘑澶辫触:", error);
-			throw error;
-		}
-	}
-	/**
-	* 鍔犲瘑璇锋眰鏁版嵁
-	* @param data 瑕佸姞瀵嗙殑鏁版嵁
-	* @returns 鍔犲瘑鍚庣殑鏁版嵁
-	*/
-	encryptRequest(data) {
-		if (!this.config.enable) return data;
-		try {
-			const jsonData = typeof data === "string" ? data : JSON.stringify(data);
-			if (this.config.algorithm.toUpperCase() === "AES") {
-				if (!this.config.requestKey) throw new Error("AES 璇锋眰鍔犲瘑瀵嗛挜鏈厤缃�");
-				return AES.encrypt(jsonData, this.config.requestKey);
-			} else if (this.config.algorithm.toUpperCase() === "RSA") {
-				if (!this.config.requestKey) throw new Error("RSA 鍏挜鏈厤缃�");
-				const result = RSA.encrypt(jsonData, this.config.requestKey);
-				if (result === false) throw new Error("RSA 鍔犲瘑澶辫触");
-				return result;
-			} else throw new Error(`涓嶆敮鎸佺殑鍔犲瘑绠楁硶: ${this.config.algorithm}`);
-		} catch (error) {
-			console.error("璇锋眰鏁版嵁鍔犲瘑澶辫触:", error);
-			throw error;
-		}
-	}
-	/**
-	* 鑾峰彇鍔犲瘑澶村悕绉�
-	*/
-	getEncryptHeader() {
-		return this.config.header;
-	}
-};
-/**
-* 鍒涘缓鍩轰簬鐜鍙橀噺鐨� API 鍔犺В瀵嗗疄渚�
-* @param env 鐜鍙橀噺瀵硅薄
-* @returns ApiEncrypt 瀹炰緥
-*/
-function createApiEncrypt(env) {
-	return new ApiEncrypt({
-		enable: env.VITE_APP_API_ENCRYPT_ENABLE === "true",
-		header: env.VITE_APP_API_ENCRYPT_HEADER || "X-Api-Encrypt",
-		algorithm: env.VITE_APP_API_ENCRYPT_ALGORITHM || "AES",
-		requestKey: env.VITE_APP_API_ENCRYPT_REQUEST_KEY || "",
-		responseKey: env.VITE_APP_API_ENCRYPT_RESPONSE_KEY || ""
-	});
-}
-//#endregion
-//#region src/utils/inference.ts
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负undefined銆�
-*
-* @param {unknown} value 瑕佹鏌ョ殑鍊笺��
-* @returns {boolean} 濡傛灉鍊兼槸undefined锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isUndefined(value) {
-	return value === void 0;
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负boolean
-* @param value
-* @returns 濡傛灉鍊兼槸甯冨皵鍊硷紝杩斿洖true锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isBoolean(value) {
-	return typeof value === "boolean";
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负绌恒��
-*
-* 浠ヤ笅鎯呭喌灏嗚璁や负鏄┖锛�
-* - 鍊间负null銆�
-* - 鍊间负undefined銆�
-* - 鍊间负涓�涓┖瀛楃涓层��
-* - 鍊间负涓�涓暱搴︿负0鐨勬暟缁勩��
-* - 鍊间负涓�涓病鏈夊厓绱犵殑Map鎴朣et銆�
-* - 鍊间负涓�涓病鏈夊睘鎬х殑瀵硅薄銆�
-*
-* @param {T} value 瑕佹鏌ョ殑鍊笺��
-* @returns {boolean} 濡傛灉鍊间负绌猴紝杩斿洖true锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isEmpty(value) {
-	if (value === null || value === void 0) return true;
-	if (Array.isArray(value) || isString(value)) return value.length === 0;
-	if (value instanceof Map || value instanceof Set) return value.size === 0;
-	if (isObject(value)) return Object.keys(value).length === 0;
-	return false;
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负绌哄�笺��
-*
-* 浠呬互涓嬫儏鍐靛皢琚涓烘槸绌哄�硷細
-* - 鍊间负 null銆�
-* - 鍊间负 undefined銆�
-* - 鍊间负绌哄瓧绗︿覆銆�
-*
-* @param value 瑕佹鏌ョ殑鍊笺��
-* @returns 濡傛灉鍊间负绌哄�硷紝杩斿洖 true锛屽惁鍒欒繑鍥� false銆�
-*/
-function isEmptyVal(value) {
-	return value === "" || value === null || value === void 0;
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑瀛楃涓叉槸鍚︿负鏈夋晥鐨凥TTP鎴朒TTPS URL銆�
-*
-* @param {string} url 瑕佹鏌ョ殑瀛楃涓层��
-* @return {boolean} 濡傛灉瀛楃涓叉槸鏈夋晥鐨凥TTP鎴朒TTPS URL锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isHttpUrl(url) {
-	if (!url) return false;
-	return /^https?:\/\/.*$/.test(url);
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负window瀵硅薄銆�
-*
-* @param {any} value 瑕佹鏌ョ殑鍊笺��
-* @returns {boolean} 濡傛灉鍊兼槸window瀵硅薄锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isWindow(value) {
-	return typeof window !== "undefined" && value !== null && value === value.window;
-}
-/**
-* 妫�鏌ュ綋鍓嶈繍琛岀幆澧冩槸鍚︿负Mac OS銆�
-*
-* 杩欎釜鍑芥暟閫氳繃妫�鏌avigator.userAgent瀛楃涓叉潵鍒ゆ柇褰撳墠杩愯鐜銆�
-* 濡傛灉userAgent瀛楃涓蹭腑鍖呭惈"macintosh"鎴�"mac os x"锛堜笉鍖哄垎澶у皬鍐欙級锛屽垯璁や负褰撳墠鐜鏄疢ac OS銆�
-*
-* @returns {boolean} 濡傛灉褰撳墠鐜鏄疢ac OS锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isMacOs() {
-	return /macintosh|mac os x/i.test(navigator.userAgent);
-}
-/**
-* 妫�鏌ュ綋鍓嶈繍琛岀幆澧冩槸鍚︿负Windows OS銆�
-*
-* 杩欎釜鍑芥暟閫氳繃妫�鏌avigator.userAgent瀛楃涓叉潵鍒ゆ柇褰撳墠杩愯鐜銆�
-* 濡傛灉userAgent瀛楃涓蹭腑鍖呭惈"windows"鎴�"win32"锛堜笉鍖哄垎澶у皬鍐欙級锛屽垯璁や负褰撳墠鐜鏄疻indows OS銆�
-*
-* @returns {boolean} 濡傛灉褰撳墠鐜鏄疻indows OS锛岃繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse銆�
-*/
-function isWindowsOs() {
-	return /windows|win32/i.test(navigator.userAgent);
-}
-/**
-* 妫�鏌ヤ紶鍏ョ殑鍊兼槸鍚︿负鏁板瓧
-* @param value
-*/
-function isNumber(value) {
-	return typeof value === "number" && Number.isFinite(value);
-}
-/**
-* Returns the first value in the provided list that is neither `null` nor `undefined`.
-*
-* This function iterates over the input values and returns the first one that is
-* not strictly equal to `null` or `undefined`. If all values are either `null` or
-* `undefined`, it returns `undefined`.
-*
-* @template T - The type of the input values.
-* @param {...(T | null | undefined)[]} values - A list of values to evaluate.
-* @returns {T | undefined} - The first value that is not `null` or `undefined`, or `undefined` if none are found.
-*
-* @example
-* // Returns 42 because it is the first non-null, non-undefined value.
-* getFirstNonNullOrUndefined(undefined, null, 42, 'hello'); // 42
-*
-* @example
-* // Returns 'hello' because it is the first non-null, non-undefined value.
-* getFirstNonNullOrUndefined(null, undefined, 'hello', 123); // 'hello'
-*
-* @example
-* // Returns undefined because all values are either null or undefined.
-* getFirstNonNullOrUndefined(undefined, null); // undefined
-*/
-function getFirstNonNullOrUndefined(...values) {
-	for (const value of values) if (value !== void 0 && value !== null) return value;
-}
-//#endregion
-//#region src/utils/formatNumber.ts
-/**
-* 灏嗕竴涓暣鏁拌浆鎹负鍒嗘暟淇濈暀浼犲叆鐨勫皬鏁�
-* @param num
-* @param digit
-*/
-function formatToFractionDigit(num, digit = 2) {
-	if (isUndefined(num)) return "0.00";
-	return ((isString(num) ? Number.parseFloat(num) : num) / 100).toFixed(digit);
-}
-/**
-* 灏嗕竴涓暣鏁拌浆鎹负鍒嗘暟淇濈暀涓や綅灏忔暟
-* @param num
-*/
-function formatToFraction(num) {
-	return formatToFractionDigit(num, 2);
-}
-/**
-* 灏嗕竴涓暟杞崲涓� 1.00 杩欐牱
-* 鏁版嵁鍛堢幇鐨勬椂鍊欎娇鐢�
-*
-* @param num 鏁存暟
-*/
-function floatToFixed2(num) {
-	let str = "0.00";
-	if (isUndefined(num)) return str;
-	const f = formatToFraction(num);
-	const decimalPart = f.toString().split(".")[1];
-	switch (decimalPart ? decimalPart.length : 0) {
-		case 0:
-			str = `${f.toString()}.00`;
-			break;
-		case 1:
-			str = `${f.toString()}0`;
-			break;
-		case 2:
-			str = f.toString();
-			break;
-	}
-	return str;
-}
-/**
-* 灏嗕竴涓垎鏁拌浆鎹负鏁存暟
-* @param num
-*/
-function convertToInteger(num) {
-	if (isUndefined(num)) return 0;
-	const parsedNumber = isString(num) ? Number.parseFloat(num) : num;
-	return Math.round(parsedNumber * 100);
-}
-/**
-* 鍏冭浆鍒�
-*/
-function yuanToFen(amount) {
-	return convertToInteger(amount);
-}
-/**
-* 鍒嗚浆鍏�
-*/
-function fenToYuan(price) {
-	return formatToFraction(price);
-}
-const fenToYuanFormat = (_, __, cellValue, ___) => {
-	return `锟�${floatToFixed2(cellValue)}`;
-};
-/**
-* 璁$畻鐜瘮
-*
-* @param value 褰撳墠鏁板��
-* @param reference 瀵规瘮鏁板��
-*/
-function calculateRelativeRate(value, reference) {
-	if (!reference || reference === 0) return 0;
-	return Number.parseFloat((100 * ((value || 0) - reference) / reference).toFixed(0));
-}
-const ERP_COUNT_DIGIT = 3;
-const ERP_PRICE_DIGIT = 2;
-/**
-* 銆怑RP銆戞牸寮忓寲 Input 鏁板瓧
-*
-* 渚嬪璇达細搴撳瓨鏁伴噺
-*
-* @param num 鏁伴噺
-* @package
-* @return 鏍煎紡鍖栧悗鐨勬暟閲�
-*/
-function erpNumberFormatter(num, digit) {
-	if (num === null || num === void 0) return "";
-	if (typeof num === "string") num = Number.parseFloat(num);
-	if (Number.isNaN(num)) return "";
-	return num.toFixed(digit);
-}
-/**
-* 銆怑RP銆戞牸寮忓寲鏁伴噺锛屼繚鐣欎笁浣嶅皬鏁�
-*
-* 渚嬪璇达細搴撳瓨鏁伴噺
-*
-* @param num 鏁伴噺
-* @return 鏍煎紡鍖栧悗鐨勬暟閲�
-*/
-function erpCountInputFormatter(num) {
-	return erpNumberFormatter(num, ERP_COUNT_DIGIT);
-}
-/**
-* 銆怑RP銆戞牸寮忓寲鏁伴噺锛屼繚鐣欎笁浣嶅皬鏁�
-*
-* @param cellValue 鏁伴噺
-* @return 鏍煎紡鍖栧悗鐨勬暟閲�
-*/
-function erpCountTableColumnFormatter(cellValue) {
-	return erpNumberFormatter(cellValue, ERP_COUNT_DIGIT);
-}
-/**
-* 銆怑RP銆戞牸寮忓寲閲戦锛屼繚鐣欎簩浣嶅皬鏁�
-*
-* 渚嬪璇达細搴撳瓨鏁伴噺
-*
-* @param num 鏁伴噺
-* @return 鏍煎紡鍖栧悗鐨勬暟閲�
-*/
-function erpPriceInputFormatter(num) {
-	return erpNumberFormatter(num, ERP_PRICE_DIGIT);
-}
-/**
-* 銆怑RP銆戞牸寮忓寲閲戦锛屼繚鐣欎簩浣嶅皬鏁�
-*
-* @param cellValue 鏁伴噺
-* @return 鏍煎紡鍖栧悗鐨勬暟閲�
-*/
-function erpPriceTableColumnFormatter(cellValue) {
-	return erpNumberFormatter(cellValue, ERP_PRICE_DIGIT);
-}
-/**
-* 銆怑RP銆戜环鏍艰绠楋紝鍥涜垗浜斿叆淇濈暀涓や綅灏忔暟
-*
-* @param price 浠锋牸
-* @param count 鏁伴噺
-* @return 鎬讳环鏍笺�傚鏋滄湁浠讳竴涓虹┖锛屽垯杩斿洖 undefined
-*/
-function erpPriceMultiply(price, count) {
-	if (isEmpty(price) || isEmpty(count)) return void 0;
-	return Number.parseFloat((price * count).toFixed(ERP_PRICE_DIGIT));
-}
-/**
-* 銆怑RP銆戠櫨鍒嗘瘮璁$畻锛屽洓鑸嶄簲鍏ヤ繚鐣欎袱浣嶅皬鏁�
-*
-* 濡傛灉 total 涓� 0锛屽垯杩斿洖 0
-*
-* @param value 褰撳墠鍊�
-* @param total 鎬诲��
-*/
-function erpCalculatePercentage(value, total) {
-	if (total === 0) return 0;
-	return (value / total * 100).toFixed(2);
-}
-//#endregion
-//#region src/utils/letter.ts
-/**
-* 灏嗗瓧绗︿覆鐨勯瀛楁瘝澶у啓
-* @param string
-*/
-function capitalizeFirstLetter(string) {
-	return string.charAt(0).toUpperCase() + string.slice(1);
-}
-/**
-* 灏嗗瓧绗︿覆鐨勯瀛楁瘝杞崲涓哄皬鍐欍��
-*
-* @param str 瑕佽浆鎹㈢殑瀛楃涓�
-* @returns 棣栧瓧姣嶅皬鍐欑殑瀛楃涓�
-*/
-function toLowerCaseFirstLetter(str) {
-	if (!str) return str;
-	return str.charAt(0).toLowerCase() + str.slice(1);
-}
-/**
-*  鐢熸垚椹煎嘲鍛藉悕娉曠殑閿悕
-* @param key
-* @param parentKey
-*/
-function toCamelCase(key, parentKey) {
-	if (!parentKey) return key;
-	return parentKey + key.charAt(0).toUpperCase() + key.slice(1);
-}
-function kebabToCamelCase(str) {
-	return str.split("-").filter(Boolean).map((word, index) => index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1)).join("");
-}
-//#endregion
-//#region src/utils/merge.ts
-const mergeWithArrayOverride = createDefu((originObj, key, updates) => {
-	if (Array.isArray(originObj[key]) && Array.isArray(updates)) {
-		originObj[key] = updates;
-		return true;
-	}
-});
-//#endregion
-//#region src/utils/nprogress.ts
-let nProgressInstance = null;
-/**
-* 鍔ㄦ�佸姞杞絅Progress搴擄紝骞惰繘琛岄厤缃��
-* 姝ゅ嚱鏁伴鍏堟鏌ユ槸鍚﹀凡缁忓姞杞借繃NProgress搴擄紝濡傛灉宸茬粡鍔犺浇杩囷紝鍒欑洿鎺ヨ繑鍥濶Progress瀹炰緥銆�
-* 鍚﹀垯锛屽姩鎬佸鍏Progress搴擄紝杩涜閰嶇疆锛岀劧鍚庤繑鍥濶Progress瀹炰緥銆�
-*
-* @returns  NProgress瀹炰緥鐨凱romise瀵硅薄銆�
-*/
-async function loadNprogress() {
-	if (nProgressInstance) return nProgressInstance;
-	nProgressInstance = await import("nprogress");
-	nProgressInstance.configure({
-		showSpinner: true,
-		speed: 300
-	});
-	return nProgressInstance;
-}
-/**
-* 寮�濮嬫樉绀鸿繘搴︽潯銆�
-* 姝ゅ嚱鏁伴鍏堝姞杞絅Progress搴擄紝鐒跺悗璋冪敤NProgress鐨剆tart鏂规硶寮�濮嬫樉绀鸿繘搴︽潯銆�
-*/
-async function startProgress() {
-	(await loadNprogress())?.start();
-}
-/**
-* 鍋滄鏄剧ず杩涘害鏉★紝骞堕殣钘忚繘搴︽潯銆�
-* 姝ゅ嚱鏁伴鍏堝姞杞絅Progress搴擄紝鐒跺悗璋冪敤NProgress鐨刣one鏂规硶鍋滄骞堕殣钘忚繘搴︽潯銆�
-*/
-async function stopProgress() {
-	(await loadNprogress())?.done();
-}
-//#endregion
-//#region src/utils/resources.ts
-/**
-* 鍔犺浇js鏂囦欢
-* @param src js鏂囦欢鍦板潃
-*/
-function loadScript(src) {
-	return new Promise((resolve, reject) => {
-		if (document.querySelector(`script[src="${src}"]`)) return resolve();
-		const script = document.createElement("script");
-		script.src = src;
-		script.addEventListener("load", () => resolve());
-		script.addEventListener("error", () => reject(/* @__PURE__ */ new Error(`Failed to load script: ${src}`)));
-		document.head.append(script);
-	});
-}
-//#endregion
-//#region src/utils/stack.ts
-/**
-* @zh_CN 鏍堟暟鎹粨鏋�
-*/
-var Stack = class {
-	/**
-	* @zh_CN 鏍堝唴鍏冪礌鏁伴噺
-	*/
-	get size() {
-		return this.items.length;
-	}
-	/**
-	* @zh_CN 鏄惁鍘婚噸
-	*/
-	dedup;
-	/**
-	* @zh_CN 鏍堝唴鍏冪礌
-	*/
-	items = [];
-	/**
-	* @zh_CN 鏍堢殑鏈�澶у閲�
-	*/
-	maxSize;
-	constructor(dedup = true, maxSize) {
-		this.maxSize = maxSize;
-		this.dedup = dedup;
-	}
-	/**
-	* @zh_CN 娓呯┖鏍堝唴鍏冪礌
-	*/
-	clear() {
-		this.items.length = 0;
-	}
-	/**
-	* @zh_CN 鏌ョ湅鏍堥《鍏冪礌
-	* @returns 鏍堥《鍏冪礌
-	*/
-	peek() {
-		return this.items[this.items.length - 1];
-	}
-	/**
-	* @zh_CN 鍑烘爤
-	* @returns 鏍堥《鍏冪礌
-	*/
-	pop() {
-		return this.items.pop();
-	}
-	/**
-	* @zh_CN 鍏ユ爤
-	* @param items 瑕佸叆鏍堢殑鍏冪礌
-	*/
-	push(...items) {
-		items.forEach((item) => {
-			if (this.dedup) {
-				const index = this.items.indexOf(item);
-				if (index !== -1) this.items.splice(index, 1);
-			}
-			this.items.push(item);
-			if (this.maxSize && this.items.length > this.maxSize) this.items.splice(0, this.items.length - this.maxSize);
-		});
-	}
-	/**
-	* @zh_CN 绉婚櫎鏍堝唴鍏冪礌
-	* @param itemList 瑕佺Щ闄ょ殑鍏冪礌鍒楄〃
-	*/
-	remove(...itemList) {
-		this.items = this.items.filter((i) => !itemList.includes(i));
-	}
-	/**
-	* @zh_CN 淇濈暀鏍堝唴鍏冪礌
-	* @param itemList 瑕佷繚鐣欑殑鍏冪礌鍒楄〃
-	*/
-	retain(itemList) {
-		this.items = this.items.filter((i) => itemList.includes(i));
-	}
-	/**
-	* @zh_CN 杞崲涓烘暟缁�
-	* @returns 鏍堝唴鍏冪礌鏁扮粍
-	*/
-	toArray() {
-		return [...this.items];
-	}
-};
-/**
-* @zh_CN 鍒涘缓涓�涓爤瀹炰緥
-* @param dedup 鏄惁鍘婚噸
-* @param maxSize 鏍堢殑鏈�澶у閲�
-* @returns 鏍堝疄渚�
-*/
-const createStack = (dedup = true, maxSize) => new Stack(dedup, maxSize);
-//#endregion
-//#region src/utils/state-handler.ts
-var StateHandler = class {
-	condition = false;
-	rejectCondition = null;
-	resolveCondition = null;
-	isConditionTrue() {
-		return this.condition;
-	}
-	reset() {
-		this.condition = false;
-		this.clearPromises();
-	}
-	setConditionFalse() {
-		this.condition = false;
-		if (this.rejectCondition) {
-			this.rejectCondition(/* @__PURE__ */ new Error("Condition was set to false"));
-			this.clearPromises();
-		}
-	}
-	setConditionTrue() {
-		this.condition = true;
-		if (this.resolveCondition) {
-			this.resolveCondition();
-			this.clearPromises();
-		}
-	}
-	waitForCondition() {
-		return new Promise((resolve, reject) => {
-			if (this.condition) resolve();
-			else {
-				this.resolveCondition = resolve;
-				this.rejectCondition = reject;
-			}
-		});
-	}
-	clearPromises() {
-		this.resolveCondition = null;
-		this.rejectCondition = null;
-	}
-};
-//#endregion
-//#region src/utils/time.ts
-/**
-* @param {Date | number | string} time 闇�瑕佽浆鎹㈢殑鏃堕棿
-* @param {string} fmt 闇�瑕佽浆鎹㈢殑鏍煎紡 濡� yyyy-MM-dd銆亂yyy-MM-dd HH:mm:ss
-*/
-function formatTime(time, fmt) {
-	if (time) {
-		const date = new Date(time);
-		const o = {
-			"M+": date.getMonth() + 1,
-			"d+": date.getDate(),
-			"H+": date.getHours(),
-			"m+": date.getMinutes(),
-			"s+": date.getSeconds(),
-			"q+": Math.floor((date.getMonth() + 3) / 3),
-			S: date.getMilliseconds()
-		};
-		const yearMatch = fmt.match(/y+/);
-		if (yearMatch) fmt = fmt.replace(yearMatch[0], `${date.getFullYear()}`.slice(4 - yearMatch[0].length));
-		for (const k in o) {
-			const match = fmt.match(new RegExp(`(${k})`));
-			if (match) fmt = fmt.replace(match[0], match[0].length === 1 ? o[k] : `00${o[k]}`.slice(`${o[k]}`.length));
-		}
-		return fmt;
-	} else return "";
-}
-/**
-* 鑾峰彇褰撳墠鏃ユ湡鏄鍑犲懆
-* @param dateTime 褰撳墠浼犲叆鐨勬棩鏈熷��
-* @returns 杩斿洖绗嚑鍛ㄦ暟瀛楀��
-*/
-function getWeek(dateTime) {
-	const temptTime = new Date(dateTime);
-	const weekday = temptTime.getDay() || 7;
-	temptTime.setDate(temptTime.getDate() - weekday + 1 + 5);
-	let firstDay = new Date(temptTime.getFullYear(), 0, 1);
-	const dayOfWeek = firstDay.getDay();
-	let spendDay = 1;
-	if (dayOfWeek !== 0) spendDay = 7 - dayOfWeek + 1;
-	firstDay = new Date(temptTime.getFullYear(), 0, 1 + spendDay);
-	const d = Math.ceil((temptTime.valueOf() - firstDay.valueOf()) / 864e5);
-	return Math.ceil(d / 7);
-}
-/**
-* 灏嗘椂闂磋浆鎹负 `鍑犵鍓峘銆乣鍑犲垎閽熷墠`銆乣鍑犲皬鏃跺墠`銆乣鍑犲ぉ鍓峘
-* @param param 褰撳墠鏃堕棿锛宯ew Date() 鏍煎紡鎴栬�呭瓧绗︿覆鏃堕棿鏍煎紡
-* @param format 闇�瑕佽浆鎹㈢殑鏃堕棿鏍煎紡瀛楃涓�
-* @description param 10绉掞細  10 * 1000
-* @description param 1鍒嗭細   60 * 1000
-* @description param 1灏忔椂锛� 60 * 60 * 1000
-* @description param 24灏忔椂锛�60 * 60 * 24 * 1000
-* @description param 3澶╋細   60 * 60* 24 * 1000 * 3
-* @returns 杩斿洖鎷兼帴鍚庣殑鏃堕棿瀛楃涓�
-*/
-function formatPast(param, format = "YYYY-MM-DD HH:mm:ss") {
-	let s, t;
-	let time = Date.now();
-	typeof param === "string" || typeof param === "object" ? t = new Date(param).getTime() : t = param;
-	time = Number.parseInt(`${time - t}`);
-	if (time < 1e4) return "鍒氬垰";
-	else if (time < 6e4 && time >= 1e4) {
-		s = Math.floor(time / 1e3);
-		return `${s}绉掑墠`;
-	} else if (time < 36e5 && time >= 6e4) {
-		s = Math.floor(time / 6e4);
-		return `${s}鍒嗛挓鍓峘;
-	} else if (time < 864e5 && time >= 36e5) {
-		s = Math.floor(time / 36e5);
-		return `${s}灏忔椂鍓峘;
-	} else if (time < 2592e5 && time >= 864e5) {
-		s = Math.floor(time / 864e5);
-		return `${s}澶╁墠`;
-	} else return formatDate(typeof param === "string" || typeof param === "object" ? new Date(param) : param, format);
-}
-/**
-* 鏃堕棿闂�欒
-* @param param 褰撳墠鏃堕棿锛宯ew Date() 鏍煎紡
-* @description param 璋冪敤 `formatAxis(new Date())` 杈撳嚭 `涓婂崍濂絗
-* @returns 杩斿洖鎷兼帴鍚庣殑鏃堕棿瀛楃涓�
-*/
-function formatAxis(param) {
-	const hour = new Date(param).getHours();
-	if (hour < 6) return "鍑屾櫒濂�";
-	else if (hour < 9) return "鏃╀笂濂�";
-	else if (hour < 12) return "涓婂崍濂�";
-	else if (hour < 14) return "涓崍濂�";
-	else if (hour < 17) return "涓嬪崍濂�";
-	else if (hour < 19) return "鍌嶆櫄濂�";
-	else if (hour < 22) return "鏅氫笂濂�";
-	else return "澶滈噷濂�";
-}
-/**
-* 灏嗘绉掞紝杞崲鎴愭椂闂村瓧绗︿覆銆備緥濡傝锛寈x 鍒嗛挓
-*
-* @param ms 姣
-* @returns {string} 瀛楃涓�
-*/
-function formatPast2(ms) {
-	const day = Math.floor(ms / (1440 * 60 * 1e3));
-	const hour = Math.floor(ms / (3600 * 1e3) - day * 24);
-	const minute = Math.floor(ms / (60 * 1e3) - day * 24 * 60 - hour * 60);
-	const second = Math.floor(ms / 1e3 - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60);
-	if (day > 0) return `${day} 澶�${hour} 灏忔椂 ${minute} 鍒嗛挓`;
-	if (hour > 0) return `${hour} 灏忔椂 ${minute} 鍒嗛挓`;
-	if (minute > 0) return `${minute} 鍒嗛挓`;
-	return second > 0 ? `${second} 绉抈 : `0 绉抈;
-}
-/**
-* 璁剧疆璧峰鏃ユ湡锛屾椂闂翠负00:00:00
-* @param param 浼犲叆鏃ユ湡
-* @returns 甯︽椂闂�00:00:00鐨勬棩鏈�
-*/
-function beginOfDay(param) {
-	return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 0, 0, 0);
-}
-/**
-* 璁剧疆缁撴潫鏃ユ湡锛屾椂闂翠负23:59:59
-* @param param 浼犲叆鏃ユ湡
-* @returns 甯︽椂闂�23:59:59鐨勬棩鏈�
-*/
-function endOfDay(param) {
-	return new Date(param.getFullYear(), param.getMonth(), param.getDate(), 23, 59, 59);
-}
-/**
-* 璁$畻涓や釜鏃ユ湡闂撮殧澶╂暟
-* @param param1 鏃ユ湡1
-* @param param2 鏃ユ湡2
-*/
-function betweenDay(param1, param2) {
-	param1 = convertDate(param1);
-	param2 = convertDate(param2);
-	return Math.floor((param2.getTime() - param1.getTime()) / (24 * 3600 * 1e3));
-}
-/**
-* 鏃ユ湡璁$畻
-* @param param1 鏃ユ湡
-* @param param2 娣诲姞鐨勬椂闂�
-*/
-function addTime(param1, param2) {
-	param1 = convertDate(param1);
-	return new Date(param1.getTime() + param2);
-}
-/**
-* 鏃ユ湡杞崲
-* @param param 鏃ユ湡
-*/
-function convertDate(param) {
-	if (typeof param === "string") return new Date(param);
-	return param;
-}
-/**
-* 鎸囧畾鐨勪袱涓棩鏈�, 鏄惁涓哄悓涓�澶�
-* @param a 鏃ユ湡 A
-* @param b 鏃ユ湡 B
-*/
-function isSameDay(a, b) {
-	if (!a || !b) return false;
-	const aa = dayjs(a);
-	const bb = dayjs(b);
-	return aa.year() === bb.year() && aa.month() === bb.month() && aa.day() === bb.day();
-}
-/**
-* 鑾峰彇涓�澶╃殑寮�濮嬫椂闂淬�佹埅姝㈡椂闂�
-* @param date 鏃ユ湡
-* @param days 澶╂暟
-*/
-function getDayRange(date, days) {
-	const day = dayjs(date).add(days, "d");
-	return getDateRange(day, day);
-}
-/**
-* 鑾峰彇鏈�杩�7澶╃殑寮�濮嬫椂闂淬�佹埅姝㈡椂闂�
-*/
-function getLast7Days() {
-	return getDateRange(dayjs().subtract(7, "d"), dayjs().subtract(1, "d"));
-}
-/**
-* 鑾峰彇鏈�杩�30澶╃殑寮�濮嬫椂闂淬�佹埅姝㈡椂闂�
-*/
-function getLast30Days() {
-	return getDateRange(dayjs().subtract(30, "d"), dayjs().subtract(1, "d"));
-}
-/**
-* 鑾峰彇鏈�杩�1骞寸殑寮�濮嬫椂闂淬�佹埅姝㈡椂闂�
-*/
-function getLast1Year() {
-	return getDateRange(dayjs().subtract(1, "y"), dayjs().subtract(1, "d"));
-}
-/**
-* 鑾峰彇鎸囧畾鏃ユ湡鐨勫紑濮嬫椂闂淬�佹埅姝㈡椂闂�
-* @param beginDate 寮�濮嬫棩鏈�
-* @param endDate 鎴鏃ユ湡
-*/
-function getDateRange(beginDate, endDate) {
-	return [dayjs(beginDate).startOf("d").format("YYYY-MM-DD HH:mm:ss"), dayjs(endDate).endOf("d").format("YYYY-MM-DD HH:mm:ss")];
-}
-//#endregion
-//#region src/utils/to.ts
-/**
-* @param { Readonly<Promise> } promise
-* @param {object=} errorExt - Additional Information you can pass to the err object
-* @return { Promise }
-*/
-async function to(promise, errorExt) {
-	try {
-		return [null, await promise];
-	} catch (error) {
-		if (errorExt) return [Object.assign({}, error, errorExt), void 0];
-		return [error, void 0];
-	}
-}
-//#endregion
-//#region src/utils/tree.ts
-/**
-* @zh_CN 閬嶅巻鏍戝舰缁撴瀯锛屽苟杩斿洖鎵�鏈夎妭鐐逛腑鎸囧畾鐨勫�笺��
-* @param tree 鏍戝舰缁撴瀯鏁扮粍
-* @param getValue 鑾峰彇鑺傜偣鍊肩殑鍑芥暟
-* @param options 浣滀负瀛愯妭鐐规暟缁勭殑鍙�夊睘鎬у悕绉般��
-* @returns 鎵�鏈夎妭鐐逛腑鎸囧畾鐨勫�肩殑鏁扮粍
-*/
-function traverseTreeValues(tree, getValue, options) {
-	const result = [];
-	const { childProps } = options || { childProps: "children" };
-	const dfs = (treeNode) => {
-		const value = getValue(treeNode);
-		result.push(value);
-		const children = treeNode?.[childProps];
-		if (!children) return;
-		if (children.length > 0) for (const child of children) dfs(child);
-	};
-	for (const treeNode of tree) dfs(treeNode);
-	return result.filter(Boolean);
-}
-/**
-* 鏍规嵁鏉′欢杩囨护缁欏畾鏍戠粨鏋勭殑鑺傜偣锛屽苟浠ュ師鏈夐『搴忚繑鍥炴墍鏈夊尮閰嶈妭鐐圭殑鏁扮粍銆�
-* @param tree 瑕佽繃婊ょ殑鏍戠粨鏋勭殑鏍硅妭鐐规暟缁勩��
-* @param filter 鐢ㄤ簬鍖归厤姣忎釜鑺傜偣鐨勬潯浠躲��
-* @param options 浣滀负瀛愯妭鐐规暟缁勭殑鍙�夊睘鎬у悕绉般��
-* @returns 鍖呭惈鎵�鏈夊尮閰嶈妭鐐圭殑鏁扮粍銆�
-*/
-function filterTree(tree, filter, options) {
-	const { childProps } = options || { childProps: "children" };
-	const _filterTree = (nodes) => {
-		return nodes.filter((node) => {
-			if (filter(node)) {
-				if (node[childProps]) node[childProps] = _filterTree(node[childProps]);
-				return true;
-			}
-			return false;
-		});
-	};
-	return _filterTree(tree);
-}
-/**
-* 鏍规嵁鏉′欢閲嶆柊鏄犲皠缁欏畾鏍戠粨鏋勭殑鑺�
-* @param tree 瑕佽繃婊ょ殑鏍戠粨鏋勭殑鏍硅妭鐐规暟缁勩��
-* @param mapper 鐢ㄤ簬map姣忎釜鑺傜偣鐨勬潯浠躲��
-* @param options 浣滀负瀛愯妭鐐规暟缁勭殑鍙�夊睘鎬у悕绉般��
-*/
-function mapTree(tree, mapper, options) {
-	const { childProps } = options || { childProps: "children" };
-	return tree.map((node) => {
-		const mapperNode = mapper(node);
-		if (mapperNode[childProps]) mapperNode[childProps] = mapTree(mapperNode[childProps], mapper, options);
-		return mapperNode;
-	});
-}
-/**
-* 鏋勯�犳爲鍨嬬粨鏋勬暟鎹�
-*
-* @param {*} data 鏁版嵁婧�
-* @param {*} id id瀛楁 榛樿 'id'
-* @param {*} parentId 鐖惰妭鐐瑰瓧娈� 榛樿 'parentId'
-* @param {*} children 瀛╁瓙鑺傜偣瀛楁 榛樿 'children'
-*/
-function handleTree(data, id = "id", parentId = "parentId", children = "children") {
-	if (!Array.isArray(data)) {
-		console.warn("data must be an array");
-		return [];
-	}
-	const config = {
-		id,
-		parentId,
-		childrenList: children
-	};
-	const childrenListMap = {};
-	const nodeIds = {};
-	const tree = [];
-	for (const d of data) {
-		const pId = d[config.parentId];
-		if (childrenListMap[pId] === void 0) childrenListMap[pId] = [];
-		nodeIds[d[config.id]] = d;
-		childrenListMap[pId].push(d);
-	}
-	for (const d of data) if (nodeIds[d[config.parentId]] === void 0) tree.push(d);
-	const adaptToChildrenList = (node) => {
-		const nodeId = node[config.id];
-		if (childrenListMap[nodeId]) {
-			node[config.childrenList] = childrenListMap[nodeId];
-			for (const child of node[config.childrenList]) adaptToChildrenList(child);
-		}
-	};
-	for (const rootNode of tree) adaptToChildrenList(rootNode);
-	return tree;
-}
-/**
-* 鑾峰彇鑺傜偣鐨勫畬鏁寸粨鏋�
-* @param tree 鏍戞暟鎹�
-* @param nodeId 鑺傜偣 id
-*/
-function treeToString(tree, nodeId) {
-	if (tree === void 0 || !Array.isArray(tree) || tree.length === 0) {
-		console.warn("tree must be an array");
-		return "";
-	}
-	const node = tree.find((item) => item.id === nodeId);
-	if (node !== void 0) return node.name;
-	let str = "";
-	function performAThoroughValidation(arr) {
-		if (arr === void 0 || !Array.isArray(arr) || arr.length === 0) return false;
-		for (const item of arr) if (item.id === nodeId) {
-			str += ` / ${item.name}`;
-			return true;
-		} else if (item.children !== void 0 && item.children.length > 0) {
-			str += ` / ${item.name}`;
-			if (performAThoroughValidation(item.children)) return true;
-		}
-		return false;
-	}
-	for (const item of tree) {
-		str = `${item.name}`;
-		if (performAThoroughValidation(item.children)) break;
-	}
-	return str;
-}
-/**
-* 瀵规爲褰㈢粨鏋勬暟鎹繘琛岄�掑綊鎺掑簭
-* @param treeData - 鏍戝舰鏁版嵁鏁扮粍
-* @param sortFunction - 鎺掑簭鍑芥暟锛岀敤浜庡畾涔夋帓搴忚鍒�
-* @param options - 閰嶇疆閫夐」锛屽寘鎷瓙鑺傜偣灞炴�у悕
-* @returns 鎺掑簭鍚庣殑鏍戝舰鏁版嵁
-*/
-function sortTree(treeData, sortFunction, options) {
-	const { childProps } = options || { childProps: "children" };
-	return treeData.toSorted(sortFunction).map((item) => {
-		const children = item[childProps];
-		if (children && Array.isArray(children) && children.length > 0) return {
-			...item,
-			[childProps]: sortTree(children, sortFunction, options)
-		};
-		return item;
-	});
-}
-//#endregion
-//#region src/utils/unique.ts
-/**
-* 鏍规嵁鎸囧畾瀛楁瀵瑰璞℃暟缁勮繘琛屽幓閲�
-* @param arr 瑕佸幓閲嶇殑瀵硅薄鏁扮粍
-* @param key 鍘婚噸渚濇嵁鐨勫瓧娈靛悕
-* @returns 鍘婚噸鍚庣殑瀵硅薄鏁扮粍
-*/
-function uniqueByField(arr, key) {
-	const seen = /* @__PURE__ */ new Map();
-	return arr.filter((item) => {
-		const value = item[key];
-		return seen.has(value) ? false : (seen.set(value, item), true);
-	});
-}
-//#endregion
-//#region src/utils/update-css-variables.ts
-/**
-* 鏇存柊 CSS 鍙橀噺鐨勫嚱鏁�
-* @param variables 瑕佹洿鏂扮殑 CSS 鍙橀噺涓庡叾鏂板�肩殑鏄犲皠
-* @param id 鍐呰仈鏍峰紡琛ㄧ殑 id锛屼究浜庡鐢ㄤ笌瑕嗙洊
-* @param selector CSS 鍙橀噺鎸傝浇鐨勯�夋嫨鍣紝榛樿 `:root`銆�
-*  瀵逛簬鍍� TDesign 杩欑灏嗗彉閲忓畾涔夊湪 `:root[theme-mode='dark']` 绛夋洿楂樹紭鍏堢骇閫夋嫨鍣ㄤ笅鐨勭粍浠跺簱锛�
-*  闇�瑕佷紶鍏ョ浉鍚岋紙鎴栨洿楂橈級浼樺厛绾х殑閫夋嫨鍣ㄦ墠鑳芥纭鐩栥��
-*/
-function updateCSSVariables(variables, id = "__vben-styles__", selector = ":root") {
-	const styleElement = document.querySelector(`#${id}`) || document.createElement("style");
-	styleElement.id = id;
-	let cssText = `${selector} {`;
-	for (const key in variables) if (Object.prototype.hasOwnProperty.call(variables, key)) cssText += `${key}: ${variables[key]};`;
-	cssText += "}";
-	styleElement.textContent = cssText;
-	if (!document.querySelector(`#${id}`)) setTimeout(() => {
-		document.head.append(styleElement);
-	});
-}
-//#endregion
-//#region src/utils/upload.ts
-/**
-* 鏍规嵁鏀寔鐨勬枃浠剁被鍨嬬敓鎴� accept 灞炴�у��
-*
-* @param supportedFileTypes 鏀寔鐨勬枃浠剁被鍨嬫暟缁勶紝濡� ['PDF', 'DOC', 'DOCX']
-* @returns 鐢ㄤ簬鏂囦欢涓婁紶缁勪欢 accept 灞炴�х殑瀛楃涓�
-*/
-function generateAcceptedFileTypes(supportedFileTypes) {
-	const allowedExtensions = supportedFileTypes.map((ext) => ext.toLowerCase());
-	const mimeTypes = [];
-	if (allowedExtensions.includes("txt")) mimeTypes.push("text/plain");
-	if (allowedExtensions.includes("pdf")) mimeTypes.push("application/pdf");
-	if (allowedExtensions.includes("html") || allowedExtensions.includes("htm")) mimeTypes.push("text/html");
-	if (allowedExtensions.includes("csv")) mimeTypes.push("text/csv");
-	if (allowedExtensions.includes("xlsx") || allowedExtensions.includes("xls")) mimeTypes.push("application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
-	if (allowedExtensions.includes("docx") || allowedExtensions.includes("doc")) mimeTypes.push("application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
-	if (allowedExtensions.includes("pptx") || allowedExtensions.includes("ppt")) mimeTypes.push("application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
-	if (allowedExtensions.includes("xml")) mimeTypes.push("application/xml", "text/xml");
-	if (allowedExtensions.includes("md") || allowedExtensions.includes("markdown")) mimeTypes.push("text/markdown");
-	if (allowedExtensions.includes("epub")) mimeTypes.push("application/epub+zip");
-	if (allowedExtensions.includes("eml")) mimeTypes.push("message/rfc822");
-	if (allowedExtensions.includes("msg")) mimeTypes.push("application/vnd.ms-outlook");
-	const extensions = allowedExtensions.map((ext) => `.${ext}`);
-	return [...mimeTypes, ...extensions].join(",");
-}
-/**
-* 浠� URL 涓彁鍙栨枃浠跺悕
-*
-* @param url 鏂囦欢 URL
-* @returns 鏂囦欢鍚嶏紝濡傛灉鏃犳硶鎻愬彇鍒欒繑鍥� 'unknown'
-*/
-function getFileNameFromUrl(url) {
-	if (!url) return "unknown";
-	try {
-		const fileName = new URL(url).pathname.split("/").pop() || "unknown";
-		return decodeURIComponent(fileName);
-	} catch {
-		const parts = url.split("/");
-		return parts[parts.length - 1] || "unknown";
-	}
-}
-/**
-* 榛樿鍥剧墖绫诲瀷
-*/
-const defaultImageAccepts = [
-	"bmp",
-	"gif",
-	"jpeg",
-	"jpg",
-	"png",
-	"svg",
-	"webp"
-];
-/**
-* 鍥剧墖绫� MIME 瀛愮被鍨嬪埌鎵╁睍鍚嶇殑鍒悕鏄犲皠锛涙湭鍒楀嚭鐨勫瓙绫诲瀷鎸夊瓧闈㈤噺涓庢墿灞曞悕姣旇緝
-*/
-const IMAGE_MIME_SUBTYPE_ALIASES = {
-	apng: ["apng", "png"],
-	jpeg: ["jpeg", "jpg"],
-	pjpeg: ["jpeg", "jpg"],
-	"svg+xml": ["svg"],
-	tiff: ["tif", "tiff"],
-	"x-icon": ["ico"]
-};
-/**
-* 鍒ゆ柇 MIME 瀛愮被鍨嬫槸鍚︿笌鏂囦欢鎵╁睍鍚嶅尮閰嶏紱image/* 闄愬畾涓哄凡鐭ュ浘鐗囨墿灞曞悕闆嗗悎
-*/
-function matchMimeSubtype(subtype, ext) {
-	if (subtype === "*") return defaultImageAccepts.includes(ext);
-	const aliases = IMAGE_MIME_SUBTYPE_ALIASES[subtype];
-	if (aliases) return aliases.includes(ext);
-	return subtype === ext;
-}
-/**
-* 鍒ゆ柇鏂囦欢鏄惁涓哄浘鐗�
-*
-* @param filename 鏂囦欢鍚�
-* @param accepts 鏀寔鐨勬枃浠剁被鍨嬶紝鍏煎 MIME锛堝 image/png锛夈��.ext锛堝 .png锛変笌绾悗缂�锛堝 png锛�
-* @returns 鏄惁涓哄浘鐗�
-*/
-function isImage(filename, accepts = defaultImageAccepts) {
-	if (!filename || accepts.length === 0) return false;
-	const ext = filename.split(".").pop()?.toLowerCase() || "";
-	if (!ext) return false;
-	return accepts.some((accept) => {
-		const lower = accept.toLowerCase();
-		if (lower.includes("/")) return matchMimeSubtype(lower.split("/").pop() || "", ext);
-		if (lower.startsWith(".")) return lower.slice(1) === ext;
-		return lower === ext;
-	});
-}
-/**
-* 鍒ゆ柇鏂囦欢鏄惁涓烘寚瀹氱被鍨�
-*
-* @param file 鏂囦欢
-* @param accepts 鏀寔鐨勬枃浠剁被鍨�
-* @returns 鏄惁涓烘寚瀹氱被鍨�
-*/
-function checkFileType(file, accepts) {
-	if (!accepts || accepts.length === 0) return true;
-	const newTypes = accepts.join("|");
-	return new RegExp(`${String.raw`\.(` + newTypes})$`, "i").test(file.name);
-}
-/**
-* 鏍煎紡鍖栨枃浠跺ぇ灏�
-*
-* @param bytes 鏂囦欢澶у皬锛堝瓧鑺傦級
-* @returns 鏍煎紡鍖栧悗鐨勬枃浠跺ぇ灏忓瓧绗︿覆
-*/
-function formatFileSize(bytes, digits = 2) {
-	if (bytes === 0) return "0 B";
-	const k = 1024;
-	const unitArr = [
-		"B",
-		"KB",
-		"MB",
-		"GB",
-		"TB",
-		"PB",
-		"EB",
-		"ZB",
-		"YB"
-	];
-	const index = Math.floor(Math.log(bytes) / Math.log(k));
-	return `${Number.parseFloat((bytes / k ** index).toFixed(digits))} ${unitArr[index]}`;
-}
-/**
-* 鑾峰彇鏂囦欢鍥炬爣锛圠ucide Icons锛�
-*
-* @param filename 鏂囦欢鍚�
-* @returns Lucide 鍥炬爣鍚嶇О
-*/
-function getFileIcon(filename) {
-	if (!filename) return "lucide:file";
-	const ext = filename.split(".").pop()?.toLowerCase() || "";
-	if (isImage(ext)) return "lucide:image";
-	if (["pdf"].includes(ext)) return "lucide:file-text";
-	if (["doc", "docx"].includes(ext)) return "lucide:file-text";
-	if (["xls", "xlsx"].includes(ext)) return "lucide:file-spreadsheet";
-	if (["ppt", "pptx"].includes(ext)) return "lucide:presentation";
-	if ([
-		"aac",
-		"m4a",
-		"mp3",
-		"wav"
-	].includes(ext)) return "lucide:music";
-	if ([
-		"avi",
-		"mov",
-		"mp4",
-		"wmv"
-	].includes(ext)) return "lucide:video";
-	return "lucide:file";
-}
-/**
-* 鑾峰彇鏂囦欢绫诲瀷鏍峰紡绫伙紙Tailwind CSS 娓愬彉鑹诧級
-*
-* @param filename 鏂囦欢鍚�
-* @returns Tailwind CSS 娓愬彉绫诲悕
-*/
-function getFileTypeClass(filename) {
-	if (!filename) return "from-gray-500 to-gray-700";
-	const ext = filename.split(".").pop()?.toLowerCase() || "";
-	if (isImage(ext)) return "from-yellow-400 to-orange-500";
-	if (["pdf"].includes(ext)) return "from-red-500 to-red-700";
-	if (["doc", "docx"].includes(ext)) return "from-blue-600 to-blue-800";
-	if (["xls", "xlsx"].includes(ext)) return "from-green-600 to-green-800";
-	if (["ppt", "pptx"].includes(ext)) return "from-orange-600 to-orange-800";
-	if ([
-		"aac",
-		"m4a",
-		"mp3",
-		"wav"
-	].includes(ext)) return "from-purple-500 to-purple-700";
-	if ([
-		"avi",
-		"mov",
-		"mp4",
-		"wmv"
-	].includes(ext)) return "from-red-500 to-red-700";
-	return "from-gray-500 to-gray-700";
-}
-//#endregion
-//#region src/utils/url.ts
-const SAFE_PROTOCOLS = /* @__PURE__ */ new Set(["http:", "https:"]);
-/**
-* URL 楠岃瘉
-* @param path URL 璺緞
-*/
-function isUrl(path) {
-	try {
-		return Boolean(new URL(path));
-	} catch {
-		return false;
-	}
-}
-/** URL 鏄惁鍙畨鍏ㄦ墦寮� */
-function isOpenableUrl(url) {
-	if (!url) return false;
-	try {
-		const parsed = new URL(url, window.location.origin);
-		return SAFE_PROTOCOLS.has(parsed.protocol);
-	} catch {
-		return false;
-	}
-}
-/** 鎵撳紑瀹夊叏 URL */
-function openSafeUrl(url) {
-	if (!url || !isOpenableUrl(url)) return;
-	openWindow(url);
-}
-//#endregion
-//#region src/utils/uuid.ts
-const hexList = [];
-for (let i = 0; i <= 15; i++) hexList[i] = i.toString(16);
-function buildUUID() {
-	let uuid = "";
-	for (let i = 1; i <= 36; i++) switch (i) {
-		case 9:
-		case 14:
-		case 19:
-		case 24:
-			uuid += "-";
-			break;
-		case 15:
-			uuid += 4;
-			break;
-		case 20:
-			uuid += hexList[Math.random() * 4 | 8];
-			break;
-		default: uuid += hexList[Math.trunc(Math.random() * 16)];
-	}
-	return uuid.replaceAll("-", "");
-}
-let unique = 0;
-function buildShortUUID(prefix = "") {
-	const time = Date.now();
-	const random = Math.floor(Math.random() * 1e9);
-	unique++;
-	return `${prefix}_${random}${unique}${String(time)}`;
-}
-//#endregion
-//#region src/utils/util.ts
-function bindMethods(instance) {
-	const prototype = Object.getPrototypeOf(instance);
-	Object.getOwnPropertyNames(prototype).forEach((propertyName) => {
-		const descriptor = Object.getOwnPropertyDescriptor(prototype, propertyName);
-		const propertyValue = instance[propertyName];
-		if (typeof propertyValue === "function" && propertyName !== "constructor" && descriptor && !descriptor.get && !descriptor.set) instance[propertyName] = propertyValue.bind(instance);
-	});
-}
-/**
-* 鑾峰彇宓屽瀵硅薄鐨勫瓧娈靛��
-* @param obj - 瑕佹煡鎵剧殑瀵硅薄
-* @param path - 鐢ㄤ簬鏌ユ壘瀛楁鐨勮矾寰勶紝浣跨敤灏忔暟鐐瑰垎闅�
-* @returns 瀛楁鍊硷紝鎴栬�呮湭鎵惧埌鏃惰繑鍥� undefined
-*/
-function getNestedValue(obj, path) {
-	if (typeof path !== "string" || path.length === 0) throw new Error("Path must be a non-empty string");
-	const keys = path.split(".");
-	let current = obj;
-	for (const key of keys) {
-		if (current === null || current === void 0) return;
-		current = current[key];
-	}
-	return current;
-}
-/**
-* 鑾峰彇閾炬帴鐨勫弬鏁板�硷紙鍊肩被鍨嬶級
-* @param key 鍙傛暟閿悕
-* @param urlStr 閾炬帴鍦板潃锛岄粯璁や负褰撳墠娴忚鍣ㄧ殑鍦板潃
-*/
-function getUrlNumberValue(key, urlStr = location.href) {
-	return Number(getUrlValue(key, urlStr));
-}
-/**
-* 鑾峰彇閾炬帴鐨勫弬鏁板��
-* @param key 鍙傛暟閿悕
-* @param urlStr 閾炬帴鍦板潃锛岄粯璁や负褰撳墠娴忚鍣ㄧ殑鍦板潃
-*/
-function getUrlValue(key, urlStr = location.href) {
-	if (!urlStr || !key) return "";
-	return new URL(decodeURIComponent(urlStr)).searchParams.get(key) ?? "";
-}
-/**
-* 灏嗗�煎鍒跺埌鐩爣瀵硅薄锛屼笖浠ョ洰鏍囧璞″睘鎬т负鍑嗭紝渚嬶細target: {a:1} source:{a:2,b:3} 缁撴灉涓猴細{a:2}
-* @param target 鐩爣瀵硅薄
-* @param source 婧愬璞�
-*/
-function copyValueToTarget(target, source) {
-	const newObj = Object.assign({}, target, source);
-	Object.keys(newObj).forEach((key) => {
-		if (!Object.keys(target).includes(key)) delete newObj[key];
-	});
-	Object.assign(target, newObj);
-}
-/** 瀹炵幇 groupBy 鍔熻兘 */
-function groupBy(array, key) {
-	const result = {};
-	for (const item of array) {
-		const groupKey = item[key];
-		if (!result[groupKey]) result[groupKey] = [];
-		result[groupKey].push(item);
-	}
-	return result;
-}
-/**
-* 瑙f瀽 JSON 瀛楃涓�
-*
-* @param str
-*/
-function jsonParse(str) {
-	try {
-		return JSON.parse(str);
-	} catch {
-		console.warn(`str[${str}] 涓嶆槸涓�涓� JSON 瀛楃涓瞏);
-		return str;
-	}
-}
-const stableObjectKeyMap = /* @__PURE__ */ new WeakMap();
-/**
-* 涓哄璞″紩鐢ㄧ敓鎴愮ǔ瀹� key锛屼笉鍐欏叆瀵硅薄鏈韩銆�
-*
-* 閫傜敤浜� v-for 浣跨敤瀵硅薄鎴栨暟缁勯」浣滀负娓叉煋鍗曚綅锛屼絾涓嶅笇鏈涙妸 UI 瀛楁娣峰叆涓氬姟鏁版嵁鐨勫満鏅��
-*/
-function getStableObjectKey(item, generator = buildShortUUID) {
-	let key = stableObjectKeyMap.get(item);
-	if (!key) {
-		key = generator();
-		stableObjectKeyMap.set(item, key);
-	}
-	return key;
-}
-//#endregion
-export { AES, ApiEncrypt, RSA, Stack, StateHandler, addTime, arraysEqual, base64ToFile, beginOfDay, betweenDay, bindMethods, buildShortUUID, buildUUID, calculateRelativeRate, capitalizeFirstLetter, checkFileType, cloneDeep, cn, convertDate, convertToInteger, copyValueToTarget, createApiEncrypt, createMerge, createStack, dataURLtoBlob, dateFormatter, defaultImageAccepts, diff, downloadFileFromBase64, downloadFileFromBlob, downloadFileFromBlobPart, downloadFileFromImageUrl, downloadFileFromUrl, downloadImageByCanvas, endOfDay, erpCalculatePercentage, erpCountInputFormatter, erpCountTableColumnFormatter, erpNumberFormatter, erpPriceInputFormatter, erpPriceMultiply, erpPriceTableColumnFormatter, fenToYuan, fenToYuanFormat, filterTree, floatToFixed2, formatAxis, formatDate, formatDate2, formatDateTime, formatDayjs, formatFileSize, formatPast, formatPast2, formatTime, formatToFraction, formatToFractionDigit, generateAcceptedFileTypes, get, getCurrentTimezone, getDateRange, getDayRange, getElementVisibleRect, getFileIcon, getFileNameFromUrl, getFileTypeClass, getFirstNonNullOrUndefined, getLast1Year, getLast30Days, getLast7Days, getNestedValue, getScrollbarWidth, getStableObjectKey, getSystemTimezone, getUrlNumberValue, getUrlValue, getWeek, groupBy, handleTree, isBoolean, isDate, isDayjsObject, isEmpty, isEmptyVal, isEqual, isFunction, isHttpUrl, isImage, isMacOs, isNumber, isObject, isOpenableUrl, isSameDay, isString, isUndefined, isUrl, isWindow, isWindowsOs, jsonParse, kebabToCamelCase, loadScript, mapTree, merge, mergeWithArrayOverride, needsScrollbar, openRouteInNewWindow, openSafeUrl, openWindow, set, setCurrentTimezone, sortTree, startProgress, stopProgress, to, toCamelCase, toLowerCaseFirstLetter, traverseTreeValues, treeToString, triggerDownload, triggerWindowResize, uniqueByField, updateCSSVariables, urlToBase64, yuanToFen };
diff --git a/trt.bat b/trt.bat
index e69de29..a10fe6c 100644
--- a/trt.bat
+++ b/trt.bat
@@ -0,0 +1,451 @@
+@echo off
+setlocal EnableExtensions EnableDelayedExpansion
+
+REM ============================================================
+REM Vue Frontend Deploy Script
+REM ============================================================
+
+REM =========================
+REM Configuration
+REM =========================
+
+set "COMPANY=TRT"
+
+set "REMOTE_USER=root"
+set "REMOTE_HOST=36.213.150.237"
+set "REMOTE_PORT=65022"
+
+set "PASSWORD=Sh@1008600"
+
+set "ZIP_FILE=dist.zip"
+set "REMOTE_DIR=/data/vue/mom/trt/dist"
+
+set "SSH_OPTS=-o StrictHostKeyChecking=no -o ConnectTimeout=10 -o ServerAliveInterval=15 -o ServerAliveCountMax=3"
+
+set "RETRY_COUNT=3"
+
+set "SSHPASS_DIR=%~dp0bin"
+
+
+REM ============================================================
+REM Start
+REM ============================================================
+
+echo.
+echo ============================================================
+echo              Vue Dist Auto Deploy
+echo ============================================================
+echo.
+echo Company    : %COMPANY%
+echo Server     : %REMOTE_USER%@%REMOTE_HOST%
+echo Port       : %REMOTE_PORT%
+echo Remote Dir : %REMOTE_DIR%
+echo Package    : %ZIP_FILE%
+echo.
+
+
+REM ============================================================
+REM Check sshpass
+REM ============================================================
+
+echo [1/7] Checking sshpass...
+
+if exist "%SSHPASS_DIR%\sshpass.exe" (
+    set "PATH=%SSHPASS_DIR%;%PATH%"
+)
+
+where sshpass >nul 2>&1
+
+if not errorlevel 1 (
+    echo [OK] sshpass found.
+    goto CHECK_PNPM
+)
+
+echo [WARN] sshpass not found.
+
+if not exist "%SSHPASS_DIR%" (
+    mkdir "%SSHPASS_DIR%" >nul 2>&1
+)
+
+if exist "%SSHPASS_DIR%\sshpass.exe" (
+    set "PATH=%SSHPASS_DIR%;%PATH%"
+    echo [OK] sshpass found.
+    goto CHECK_PNPM
+)
+
+echo [INFO] Downloading sshpass...
+
+powershell -NoProfile -ExecutionPolicy Bypass -Command "$url='https://github.com/xhcoding/sshpass-win32/releases/download/v1.0.3/sshpass.exe'; $out='%SSHPASS_DIR%\sshpass.exe'; Invoke-WebRequest -Uri $url -OutFile $out"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to download sshpass.
+    echo [ERROR] Please install sshpass manually.
+    goto ERROR_EXIT
+)
+
+set "PATH=%SSHPASS_DIR%;%PATH%"
+
+echo [OK] sshpass installed.
+
+
+REM ============================================================
+REM Check pnpm
+REM ============================================================
+
+:CHECK_PNPM
+
+echo.
+echo [2/7] Checking pnpm...
+
+where pnpm >nul 2>&1
+
+if errorlevel 1 (
+    echo [ERROR] pnpm not found.
+    echo [HINT] npm install -g pnpm
+    goto ERROR_EXIT
+)
+
+call pnpm --version
+
+if errorlevel 1 (
+    echo [ERROR] pnpm execution failed.
+    goto ERROR_EXIT
+)
+
+
+REM ============================================================
+REM Check node
+REM ============================================================
+
+echo.
+echo [3/7] Checking Node.js...
+
+where node >nul 2>&1
+
+if errorlevel 1 (
+    echo [ERROR] Node.js not found.
+    goto ERROR_EXIT
+)
+
+call node --version
+
+if errorlevel 1 (
+    echo [ERROR] Node.js execution failed.
+    goto ERROR_EXIT
+)
+
+
+REM ============================================================
+REM Check node_modules
+REM ============================================================
+
+if not exist "node_modules" (
+    echo.
+    echo [INFO] node_modules not found.
+    echo [INFO] Running pnpm install...
+
+    call pnpm install
+
+    if errorlevel 1 (
+        echo [ERROR] pnpm install failed.
+        goto ERROR_EXIT
+    )
+
+    echo [OK] pnpm install completed.
+) else (
+    echo [OK] node_modules exists.
+)
+
+
+REM ============================================================
+REM Build
+REM ============================================================
+
+echo.
+echo [4/7] Building project...
+
+if exist "%ZIP_FILE%" (
+    echo.
+    echo [WARN] %ZIP_FILE% already exists.
+    set "REBUILD="
+    set /p "REBUILD=Rebuild? Y/N (default Y): "
+
+    if /I "!REBUILD!"=="N" (
+        echo [INFO] Skip build.
+        goto CHECK_ZIP
+    )
+)
+
+echo [INFO] Company: %COMPANY%
+echo [INFO] Command: pnpm run build
+echo.
+
+set "VITE_COMPANY=%COMPANY%"
+
+call pnpm run build
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] Build failed.
+    goto ERROR_EXIT
+)
+
+echo.
+echo [OK] Build completed.
+
+
+REM ============================================================
+REM Check ZIP
+REM ============================================================
+
+:CHECK_ZIP
+
+echo.
+echo [5/7] Checking package...
+
+if not exist "%ZIP_FILE%" (
+    echo [ERROR] %ZIP_FILE% not found.
+    echo [HINT] Please check whether your build generates dist.zip.
+    goto ERROR_EXIT
+)
+
+for %%F in ("%ZIP_FILE%") do set "ZIP_BYTES=%%~zF"
+
+set /a ZIP_MB=ZIP_BYTES/1024/1024
+
+echo [OK] Package found.
+echo [INFO] File size: !ZIP_BYTES! bytes
+echo [INFO] File size: !ZIP_MB! MB
+
+
+REM ============================================================
+REM Set sshpass password
+REM ============================================================
+
+set "SSHPASS=%PASSWORD%"
+
+
+REM ============================================================
+REM Test SSH
+REM ============================================================
+
+echo.
+echo [6/7] Testing SSH connection...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "echo SSH_OK"
+
+if errorlevel 1 (
+    echo [ERROR] SSH connection failed.
+    goto ERROR_EXIT
+)
+
+echo [OK] SSH connection successful.
+
+
+REM ============================================================
+REM Create remote directory
+REM ============================================================
+
+echo.
+echo [INFO] Creating remote directory...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "mkdir -p '%REMOTE_DIR%'"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to create remote directory.
+    goto ERROR_EXIT
+)
+
+echo [OK] Remote directory ready.
+
+
+REM ============================================================
+REM Upload temporary file
+REM ============================================================
+
+echo.
+echo [INFO] Uploading package...
+
+set "REMOTE_TMP=%REMOTE_DIR%/.dist.zip.uploading"
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "rm -f '%REMOTE_TMP%'"
+
+sshpass -e scp -P %REMOTE_PORT% %SSH_OPTS% "%ZIP_FILE%" %REMOTE_USER%@%REMOTE_HOST%:"%REMOTE_TMP%"
+
+if errorlevel 1 (
+    echo [ERROR] Upload failed.
+    goto ERROR_EXIT
+)
+
+echo [OK] Upload completed.
+
+
+REM ============================================================
+REM Check remote file
+REM ============================================================
+
+echo.
+echo [INFO] Checking remote package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "test -f '%REMOTE_TMP%'"
+
+if errorlevel 1 (
+    echo [ERROR] Remote package does not exist.
+    goto ERROR_EXIT
+)
+
+echo [OK] Remote package exists.
+
+
+REM ============================================================
+REM Compare file size
+REM ============================================================
+
+echo.
+echo [INFO] Checking package size...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "stat -c %%s '%REMOTE_TMP%'"
+
+echo.
+
+
+REM ============================================================
+REM Rename temporary file
+REM ============================================================
+
+echo [INFO] Activating package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "mv -f '%REMOTE_TMP%' '%REMOTE_DIR%/%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo [ERROR] Failed to activate package.
+    goto ERROR_EXIT
+)
+
+echo [OK] Package activated.
+
+
+REM ============================================================
+REM Check unzip
+REM ============================================================
+
+echo.
+echo [INFO] Checking unzip...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "command -v unzip"
+
+if errorlevel 1 (
+    echo [ERROR] unzip is not installed on server.
+    echo.
+    echo CentOS/RHEL:
+    echo yum install -y unzip
+    echo.
+    echo Ubuntu/Debian:
+    echo apt install -y unzip
+    goto ERROR_EXIT
+)
+
+echo [OK] unzip found.
+
+
+REM ============================================================
+REM Test ZIP
+REM ============================================================
+
+echo.
+echo [INFO] Testing remote ZIP...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "cd '%REMOTE_DIR%' && unzip -t '%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] ZIP test failed.
+    echo [INFO] Remote ZIP has been kept.
+    goto ERROR_EXIT
+)
+
+echo [OK] ZIP test passed.
+
+
+REM ============================================================
+REM Extract
+REM ============================================================
+
+echo.
+echo [INFO] Extracting package...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "cd '%REMOTE_DIR%' && unzip -o '%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo.
+    echo [ERROR] Remote unzip failed.
+    echo [INFO] Remote ZIP has been kept.
+    goto ERROR_EXIT
+)
+
+echo.
+echo [OK] Extract completed.
+
+
+REM ============================================================
+REM Remove ZIP
+REM ============================================================
+
+echo.
+echo [INFO] Removing remote ZIP...
+
+sshpass -e ssh -p %REMOTE_PORT% %SSH_OPTS% %REMOTE_USER%@%REMOTE_HOST% "rm -f '%REMOTE_DIR%/%ZIP_FILE%'"
+
+if errorlevel 1 (
+    echo [WARN] Failed to remove remote ZIP.
+) else (
+    echo [OK] Remote ZIP removed.
+)
+
+
+REM ============================================================
+REM Success
+REM ============================================================
+
+echo.
+echo ============================================================
+echo                 DEPLOY SUCCESS
+echo ============================================================
+echo.
+echo Company    : %COMPANY%
+echo Server     : %REMOTE_HOST%:%REMOTE_PORT%
+echo Remote Dir : %REMOTE_DIR%
+echo Package    : %ZIP_FILE%
+echo Size       : !ZIP_MB! MB
+echo.
+echo Deployment completed successfully.
+echo.
+
+goto END
+
+
+REM ============================================================
+REM Error
+REM ============================================================
+
+:ERROR_EXIT
+
+echo.
+echo ============================================================
+echo                  DEPLOY FAILED
+echo ============================================================
+echo.
+echo Please check the error message above.
+echo.
+
+goto END
+
+
+REM ============================================================
+REM End
+REM ============================================================
+
+:END
+
+pause
+endlocal

--
Gitblit v1.9.3