解析大型.NET ERP系統 通用附件管理功能

大型系統具有一個通用的附件管理功能,對於單據中沒法清晰表達的字段,用一個附件圖片或附件文檔表示是最好的方法了。好比物料清單附加一張CAD圖紙,銷售訂單評審功能中附加客戶的各類表格,通用附件功能對系統起到畫龍點睛的做用。一圖解千言,先來看一下界面設計模式,看起來和通常的數據輸入功能相同。html

image

首先是設計附件表,它的定義參考下面的代碼。數據庫

CREATE TABLE [dbo].[Attachment]
(
[Index] [int] NOT NULL,
[MasterTable] [nvarchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF__Attachmen__Maste__5165187F] DEFAULT (''),
[MasterKey] [decimal] (10, 0) NOT NULL CONSTRAINT [DF__Attachmen__Maste__52593CB8] DEFAULT ((0)),
[FileType] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL CONSTRAINT [DF__Attachmen__FileT__534D60F1] DEFAULT (''),
[FilePath] [nvarchar] (250) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[CreatedDate] [datetime] NULL,
[CreatedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[RevisedDate] [datetime] NULL,
[RevisedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Description] [nvarchar] (60) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[KeySegment1] [nvarchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[KeySegment2] [nvarchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[KeySegment3] [nvarchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[KeySegment4] [nvarchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[KeySegment5] [nvarchar] (30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[Size] [decimal] (18, 0) NULL,
[File] [image] NULL,
[UploadedBy] [nvarchar] (10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[UploadedDate] [datetime] NULL,
[Md5Hash] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[Attachment] ADD CONSTRAINT [PK_Attachment] PRIMARY KEY CLUSTERED  ([Index], [MasterTable], [MasterKey]) ON [PRIMARY]
GO
EXEC sp_addextendedproperty N'MS_Description', N'附件', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', NULL, NULL
GO
EXEC sp_addextendedproperty N'MS_Description', N'索引', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'Index'
GO
EXEC sp_addextendedproperty N'MS_Description', N'附件所附加的主表', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'MasterTable'
GO
EXEC sp_addextendedproperty N'MS_Description', N'主鍵', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'MasterKey'
GO
EXEC sp_addextendedproperty N'MS_Description', N'文件類型', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'FileType'
GO
EXEC sp_addextendedproperty N'MS_Description', N'文件路徑', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'FilePath'
GO
EXEC sp_addextendedproperty N'MS_Description', N'建立日期', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'CreatedDate'
GO
EXEC sp_addextendedproperty N'MS_Description', N'創建人', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'CreatedBy'
GO
EXEC sp_addextendedproperty N'MS_Description', N'修改日期', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'RevisedDate'
GO
EXEC sp_addextendedproperty N'MS_Description', N'修改人', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'RevisedBy'
GO
EXEC sp_addextendedproperty N'MS_Description', N'名稱', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'Description'
GO
EXEC sp_addextendedproperty N'MS_Description', N'關鍵詞', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'KeySegment1'
GO
EXEC sp_addextendedproperty N'MS_Description', N'關鍵詞', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'KeySegment2'
GO
EXEC sp_addextendedproperty N'MS_Description', N'關鍵詞', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'KeySegment3'
GO
EXEC sp_addextendedproperty N'MS_Description', N'關鍵詞', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'KeySegment4'
GO
EXEC sp_addextendedproperty N'MS_Description', N'關鍵詞', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'KeySegment5'
GO
EXEC sp_addextendedproperty N'MS_Description', N'附件大小', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'Size'
GO
EXEC sp_addextendedproperty N'MS_Description', N'附件內容', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'File'
GO
EXEC sp_addextendedproperty N'MS_Description', N'上傳人', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'UploadedBy'
GO
EXEC sp_addextendedproperty N'MS_Description', N'上傳日期', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'UploadedDate'
GO
EXEC sp_addextendedproperty N'MS_Description', N'哈希值', 'SCHEMA', N'dbo', 'TABLE', N'Attachment', 'COLUMN', N'Md5Hash'
GO

 

在之前的一篇文章中解釋過,爲何須要給每一個數據庫表增長一個Recnum(記錄編號)的數字值字段,咱們在這裏要記錄下的業務功能表中要使用附件的功能,也就是要記下表中的Recnum的值。設計模式

MasterTable用於程序分組顯示附件,當上傳的附件比較多而又不容易到每一個獨立的功能中去查找,須要設計一個附件瀏覽器功能,用於查看系統中的全部附件。瀏覽器

有了以上兩個基礎,附件功能基本上完成。再來增長附件文件存儲或下載查看功能。服務器

先來看一下附件的存儲方法。能夠直接將附件存放在數據庫中,也能夠考慮增長一個FTP服務器,將附件傳送到文件服務器中。當附件文件過大時,存在數據庫中會影響數據庫性能,優勢是便於遷移。存放在FTP服務器中,優勢是性能會好,缺點是要考慮文件系統的相關事項。好比用戶A上傳一個附件文件DOC20150718.pdf,用戶B也上傳了一份一樣的文件DOC20150718.pdf,後上傳的文件名不能覆蓋前面已經上傳的文件名。解決方法是用GUID表示文件名,數據庫中記錄下文件的GUID,這樣能夠解決文件重複性問題,但不能解決文件可讀性問題。在FTP目錄中打開文件夾結構,看到都是GUID做文件名的文件,不利於搜索。因而須要考慮文件名可讀性的問題,好比按照用戶和時間的組合來命名。仍是之前面的文件名DOC20150718.pdf爲例子,當前登錄用戶名是A,我能夠將此文件重命名爲用戶+年+月+日+小時分鐘+ 文件名+ 流水號的文件編碼方案給文件命名,因而上面的文件名變成A-201507182110-DOC20150718-0012.pdf,文件名中的時間部分已經精確到分鐘,重複的可能性大大下降,增長了可讀性。我按照這個規則再寫一個文件重命名工具,萬一這些文件與ERP系統脫離關係,用軟件工具簡單的重命名,也能夠恢復到當初用戶上傳時使用的文件名。ide

 

再來看閱讀器編碼。PDF閱讀器和DOCX閱讀器來自於RadControls_WinForms_2013,它內置了這兩種文檔的閱讀器控件,調用起來簡潔。PDF閱讀器代碼調用以下:工具

private Telerik.WinControls.UI.RadPdfViewer readerPDF;

this.readerPDF.Visible = true;
if (attachment != null && attachment.Length > 0)
{
       MemoryStream stream = new MemoryStream(attachment);
       this.readerPDF.LoadDocument(stream);
}

DOCX文檔閱讀器代碼調用參考以下:性能

IDocumentFormatProvider provider = GetProviderByExtension(extension);
if (provider == null)
{
    throw new FileLoadException("Unable to find format provider for extension " + extension);
}
using (Stream stream = File.OpenRead(file))
{
    RadDocument document = provider.Import(stream);
    this.readerWord.Document = document;
    document.LayoutMode = DocumentLayoutMode.Paged;
    readerWord.ChangeSectionPageOrientation(PageOrientation.Rotate270);
    readerWord.Focus();
}

.NET有功能強大的文件API Aspose 軟件包,包含市面上幾乎全部文件的轉換接口,這是.NET的File API。對於不可直接閱讀的文件,如Excel,PowerPoint等常見文件格式,可考慮調用Aspose 文件接口轉化爲PDF,再調用PDF閱讀器顯示。Aspose 在文件處理方面應用至關普遍,與文件轉化相關的功能推薦用此接口。this

總結一下通用附件管理功能的三個要點:編碼

1  如何關聯業務功能表,主要保存Recnum記錄編號。

2  如何存儲附件,  FTP文件服務器或數據庫image二進制字段。

3  如何查看文檔, PDF和DOCX文檔閱讀器,其它常見文檔轉化爲PDF。

相關文章
相關標籤/搜索