ERP通用附件管理功能設計與實現


ERP系統中要管理用戶為單據上傳的一些附件,比如增值稅發票,退貨發票,ROHS檢測報告,這時,需要設計一個通用的附件管理模塊來管理用戶上傳的附件。

數據表設計

IF OBJECT_ID ('dbo.Attachment') IS NOT NULL
    DROP TABLE dbo.Attachment
GO

CREATE TABLE dbo.Attachment
    (
    Index        INT NOT NULL,
    MasterTable  NVARCHAR (50) DEFAULT ('') NOT NULL,
    MasterKey    DECIMAL (10) DEFAULT ((0)) NOT NULL,
    FileType     NVARCHAR (10) DEFAULT ('') NOT NULL,
    FilePath     NVARCHAR (250) NULL,
    CreatedDate  DATETIME NULL,
    CreatedBy    NVARCHAR (10) NULL,
    RevisedDate  DATETIME NULL,
    RevisedBy    NVARCHAR (10) NULL,
    Description  NVARCHAR (60) NULL,
    KeySegment1  NVARCHAR (30) NULL,
    KeySegment2  NVARCHAR (30) NULL,
    KeySegment3  NVARCHAR (30) NULL,
    KeySegment4  NVARCHAR (30) NULL,
    KeySegment5  NVARCHAR (30) NULL,
    Size         DECIMAL (18) NULL,
    File         IMAGE NULL,
    UploadedBy   NVARCHAR (10) NULL,
    UploadedDate DATETIME NULL,
    Md5Hash      NVARCHAR (32) NULL,
    CONSTRAINT PK_Attachment PRIMARY KEY (Index,MasterTable,MasterKey)
    )
GO

5個Key Segment是用來查找附件用的,相當於文章的關鍵字,用來標記此附件的大致內容。這里不提供附件內容的實際搜索功能,而只對設置的Key Segment進行查找與比較。我的另一個項目Data Solution對搜索存儲於SQL Server中的文件字節流進行搜索,進行了探索和嘗試。

4個必須要有的字段,Created By, Created Date, Revised By ,Revised Date用來記錄創建和修改附件的用戶,對IT審計有作用。ERP系統中的日記帳表基本上都有這4個字段供分析審計。

FileType 是自定義的可上傳的文件類型,比如傳真文件tif,圖片文件jpg/bmp/gif,Office 辦公文件Word/Excel/PPT

還有跨平台的通用文件格式PDF。

image

注意工具欄最后一個按鈕上面有個數字8,表示此客戶有附帶8個附件文件,點擊該按鈕,彈出附件管理窗口

image

工具欄中有新增,刪除按鈕,可對附件數據進行操作。

當附件的數量相當多的時候,還需要寫一個通用的附件瀏覽工具,以查看附件內容。

執行功能SAMFAB或SQAPTR,打開附件瀏覽器程序。

image

找到客戶編號001,可以從圖中看到,它有8個附件,在這里以附件類型進行了分組呈現。

雙擊一個附件圖標文件,File Explorer可為您打開它的內容,進行在線瀏覽。如果想把附件保存到本地,可以選中附件,點工具欄中的Export按鈕,彈出另存為對話框,為您保存附件文檔。

左邊的樹是從一個配置文件中讀取的,它保存數據表的分類以供加載到不同的模塊組別中。

image 

讀取這個文件的方式是Linq to xml技術,自從掌握了Linq技術之后,簡單的幾句話完成復雜的讀取和寫入功能,代碼簡潔,容易維護。

string sql = Kingston.SystemAdminstration.Properties.Resources.LibraryExplorer;
byte[] array = Encoding.ASCII.GetBytes(sql);
MemoryStream stream = new MemoryStream(array);   
XDocument doc = XDocument.Load(stream);
string library = doc.Root.Name.ToString();
treeView.BeginUpdate();
treeView.Nodes.Clear();
UltraTreeNode root=new UltraTreeNode(library,library);
root.Tag = "Library";
root.LeftImages.Add(imgList.Images[0]);
foreach(XElement node in doc.Root.Elements())
      {
                UltraTreeNode module = new UltraTreeNode(node.Name.ToString(), node.Name.ToString());
                module.Tag = "Module";
                module.LeftImages.Add(imgList.Images[1]);
                foreach (XElement table in node.Elements())
                {
                    UltraTreeNode tableNode = new UltraTreeNode(table.Attribute("Name").Value, table.Attribute("Name").Value);
                    tableNode.Tag = "Table";
                    tableNode.LeftImages.Add(imgList.Images[2]);
                    module.Nodes.Add(tableNode);
                }
                root.Nodes.Add(module);
        }
treeView.Nodes.Add(root);
treeView.EndUpdate();

以資源文件嵌入到程序集中,讀取時它是個字符串,XDocument可接受一個文件名,或是一個字節流,所以開頭幾句我把它轉化為流來供Linq解析。

 

在系統設置中,有一個參數是控制附件的保存方式。系統是保存附件的路徑(File Path),還是保存附件的內容(字節流)。

image

如圖所示,Control Checklist的最后一項設定 Attachment Save into Database,即把附件的字節流保存到數據(Image)字段中,此選項會影響數據庫大小,但也有好的移植性。

以文件保存在本地為例,它只是對文件進行一個簡單的Copy動作,代碼如下所示

AttachmentEntity attachment = item.Tag as AttachmentEntity;
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Filter = "Excel 97-2003|*.xls|Microsoft Word|*.doc|Adobe PDF|*.pdf|All File|*.*";
saveDialog.FileName = attachment.FilePath;
if (saveDialog.ShowDialog() == DialogResult.OK)
{
             string fileName = saveDialog.FileName;
              if (!string.IsNullOrWhiteSpace(attachment.FilePath))
              {
                       File.Copy(attachment.FilePath, saveDialog.FileName);
              }
}

VB或DELPHI程序的習慣,會拖動一個SaveFileDialog 組件(component)到界面中,然后在這里直接引用。我傾向於在這里直接創建一個SaveFileDialog ,用完了讓它Dispose。use it and burn it,電影里面講到人與人的雇佣關系時,常用這個句子,用完了就拋棄。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM