Bläddra i källkod

实现SMB的新建文件夹功能

onecold 8 månader sedan
förälder
incheckning
665372b871

+ 19 - 0
entry/src/main/ets/common/network/SmbBridge.ets

@@ -17,6 +17,10 @@ export interface SmbDeleteOptions extends SmbConnectionOptions {
   isDirectory?: boolean;
 }
 
+export interface SmbCreateOptions extends SmbConnectionOptions {
+  path: string;
+}
+
 export interface SmbDirectoryEntry {
   name: string;
   isDirectory: boolean;
@@ -62,6 +66,12 @@ export class NativeSambaTree {
     bridge.deleteEntry(this.treeId, normalized, isDirectory);
   }
 
+  createDirectory(path?: string): void {
+    this.ensureOpen();
+    const normalized = this.normalizePath(path);
+    bridge.createDirectory(this.treeId, normalized);
+  }
+
   async close(): Promise<void> {
     if (this.closed) {
       return;
@@ -164,3 +174,12 @@ export async function deleteSmbEntry(options: SmbDeleteOptions): Promise<void> {
     tree.deleteEntry(options.path, options.isDirectory === true);
   });
 }
+
+export async function createSmbDirectory(options: SmbCreateOptions): Promise<void> {
+  if (!options.path || options.path.length === 0) {
+    throw new Error('Remote path must not be empty');
+  }
+  await withSmbTree(options, async (tree: NativeSambaTree) => {
+    tree.createDirectory(options.path);
+  });
+}

+ 63 - 1
entry/src/main/ets/common/util/RemoteDriveManager.ets

@@ -17,7 +17,7 @@ import { CommonConstants } from '../constants/CommonConstants';
 import { GlobalContext, PreferencesUtil } from '@pura/harmony-utils';
 import { MusicInfo, parseMusicFileName, Utility } from './Utility';
 import { RemoteDriveType } from '../enums/RemoteDriveType';
-import { deleteSmbEntry, listSmbDirectory, SmbDirectoryEntry } from '../network/SmbBridge';
+import { createSmbDirectory, deleteSmbEntry, listSmbDirectory, SmbDirectoryEntry } from '../network/SmbBridge';
 import { NavidromeApi, NavidromeAlbumDetail, NavidromeArtist, NavidromeArtistDetail, NavidromeSong } from '../network/NavidromeApi';
 import { WebDavUrlUtil } from './WebDavUrlUtil';
 import MediaTable from './MediaTable';
@@ -2916,6 +2916,68 @@ export class RemoteDriveManager {
       throw err;
     }
   }
+
+  /**
+   * 在SMB服务器上创建文件夹
+   * @param account SMB账户
+   * @param folderName 要创建的文件夹名称
+   * @param parentPath 父级路径,默认为当前路径
+   * @returns Promise<string> 创建成功后的完整路径
+   */
+  public async createSMBFolder(account: WebDavAccount, folderName: string, parentPath?: string): Promise<string> {
+    if (!account || account.webType !== RemoteDriveType.Smb) {
+      throw new Error('只支持在SMB账户中创建文件夹');
+    }
+
+    if (!folderName || folderName.trim().length === 0) {
+      throw new Error('文件夹名称不能为空');
+    }
+
+    // 检查文件夹名称是否包含非法字符
+    const invalidChars = /[\\/:*?"<>|]/;
+    if (invalidChars.test(folderName.trim())) {
+      throw new Error('文件夹名称不能包含 \\ / : * ? " < > | 字符');
+    }
+
+    // 确定服务器地址
+    const host = account.isUseLocalHost && account.localHost ? account.localHost : account.host;
+    if (!host || host.length === 0) {
+      throw new Error('SMB账户缺少服务器地址');
+    }
+
+    if (!account.smbShare || account.smbShare.length === 0) {
+      throw new Error('SMB账户缺少共享名称');
+    }
+
+    // 确定父级路径
+    const basePath = parentPath || this.currentPath;
+
+    // 构建完整的文件夹路径
+    const fullPath = basePath === '' || basePath === '/'
+      ? `${folderName.trim()}`
+      : `${basePath.replace(/\/$/, '').replace(/^\/+/, '')}/${folderName.trim()}`;
+
+    Logger.info(TAG, `heanup 准备在SMB服务器创建文件夹: ${fullPath}`);
+
+    try {
+      // 调用createSmbDirectory函数
+      await createSmbDirectory({
+        host,
+        share: account.smbShare,
+        username: account.account || '',
+        password: account.password || '',
+        domain: account.smbDomain,
+        path: fullPath
+      });
+
+      Logger.info(TAG, `heanup SMB文件夹创建成功: ${fullPath}`);
+      return `/${fullPath}`;
+    } catch (error) {
+      const err = error as Error;
+      Logger.error(TAG, `heanup SMB文件夹创建失败: ${err.message}`);
+      throw err;
+    }
+  }
 }
 
 /**

+ 7 - 7
entry/src/main/ets/pages/WebDavMainPage.ets

@@ -1632,21 +1632,21 @@ export struct WebDavMainPage {
       this.isLoading = true;
       if(this.selectedAccount.webType==RemoteDriveType.Baidu){
         // 调用RemoteDriveManager的createBaiduFolder方法
-        const createdPath = await this.webdavManager.createBaiduFolder(this.selectedAccount, folderName);
+        await this.webdavManager.createBaiduFolder(this.selectedAccount, folderName);
 
-        // 创建成功后刷新当前目录
-        await this.webdavManager.loadFilesInfoFromAccount(this.selectedAccount, this.webdavManager.currentPath);
       }else if(this.selectedAccount.webType==RemoteDriveType.WebDav){
         // 调用RemoteDriveManager的createWebDavFolder方法
-        const createdPath = await this.webdavManager.createWebDavFolder(this.selectedAccount, folderName);
+        await this.webdavManager.createWebDavFolder(this.selectedAccount, folderName);
 
-        // 创建成功后刷新当前目录
-        await this.webdavManager.loadFilesInfoFromAccount(this.selectedAccount, this.webdavManager.currentPath);
+      }else if(this.selectedAccount.webType==RemoteDriveType.Smb){
+        // 调用RemoteDriveManager的createSMBFolder方法
+        await this.webdavManager.createSMBFolder(this.selectedAccount, folderName);
       }else{
         throw new Error('当前账户类型不支持创建文件夹');
       }
 
-
+      // 创建成功后刷新当前目录
+      await this.webdavManager.loadFilesInfoFromAccount(this.selectedAccount, this.webdavManager.currentPath);
       this.getUIContext().getPromptAction().showToast({
         message: `文件夹 "${folderName}" 创建成功`
       });