題注:
發表這篇解決方案,屬于非盈利目的。主要是為了讓大家了解一種接口技術解決方案文檔的編寫格式以及讓大家評審在我的這個技術解決方案中的不足之處,以便大家指出并加以改進。
轉載,下載或與各種形式使用這篇文章,必須注明文章的作者,出處。
其他未盡事宜,以國家法律規定的為準!
作者:南瘋
施工系統在修改了一條記錄的時候,上傳的報文中與新增的報文類似,只是主鍵的信息不能為空。外協系統判斷主鍵的信息,如果發現主鍵的信息不為空,則認為是修改了一條記錄。如果施工系統報文中主鍵不為空,而外協系統在數據庫對應的表中又沒有發現對應的記錄,則自動轉換成新增的方式來處理這條記錄。
外協系統在反饋中,還是會把主鍵返回給施工系統。但是,這種情況下,施工系統可能不再需要維護這個主鍵。
即使是僅僅修改了一個字段,施工單位還得需要上傳全部的字段信息(包含被修改的字段)給外協系統。
施工系統不是對記錄做物理刪除,而僅僅是作了邏輯刪除,即僅僅在記錄的刪除標志位上面做了“1”的標志。這種情況對記錄來說,也是修改的范圍。只是需要在<Note>業務的簡單描述中說明“邏輯刪除”。即使是邏輯刪除記錄,施工系統也必須上傳全部的字段到外協系統。
請求報文:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<UserInfo>
<User>ZhangSan</User>
<PassWord>123456</PassWord>
</UserInfo>
<Description>
<Note>停工通知確認</Note>
</Description>
<Records>
<Record>
<KeyField>KeyValue1</KeyField>
<NormalField1>Value1</NormalField1>
<NormalField2>Value2</NormalField2>
<NormalField3>Value3</NormalField3>
<NormalField4>Value4</NormalField4>
</Record>
<Record>
<KeyField>KeyValue2</KeyField>
<NormalField1>Value1</NormalField1>
<NormalField2>Value2</NormalField2>
<NormalField3>Value3</NormalField3>
<NormalField4>Value4</NormalField4>
</Record>
</Records>
</XmlData>


響應報文:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<Description>
<Result>成功</Result> <!--如果失敗,則<Result>里面內容是:失敗:(錯誤原因)-->
</Description>
<Records>
<Record>
<KeyField>Value1</KeyField>
</Record>
<Record>
<KeyField>Value2</KeyField>
</Record>
</Records>
</XmlData>


報文說明:
標簽名
|
說明
|
<XmlData>
|
報文數據主體
|
<Description>
|
報文頭部信息
|
<Records>
|
記錄集合
|
<Record>
|
一行記錄
|
<UserInfo>
|
業務認證的用戶信息
|
<User>
|
業務用戶登錄名
|
<PassWord>
|
業務用戶驗證口令
|
<Note>
|
業務的簡單描述。比如:開工報告、施工組織方案 等
|
請求中的<KeyField>
|
一行記錄中的主鍵字段。在修改的時候,施工系統所給的主鍵字段內容不能為空。外協系統中根據主鍵字段內容不為空,認為這是一條修改的記錄
|
響應中的<KeyField>
|
一行記錄中的主鍵字段。外協系統返回的主鍵值。這里的主鍵值和施工系統發送的記錄的順序是一一對應的。
|
<Result>
|
反饋報文中的保存成功與否信息。
如果保存成功,則信息是“成功”
如果保存失敗,則信息是“失敗:(后面是錯誤的詳細信息)”
|
<NormalField>
|
一行記錄中的英文字段名稱。實際中,這些標簽都是字典的英文名。字段的標簽全部是大寫。
具體的字段名稱請參見提供的數據模型
|
|
|
|
|
這里的刪除指的是物理刪除。邏輯刪除在記錄修改的時候已經說明。
物理刪除是徹底的從數據庫中刪除一條記錄,不能恢復。物理刪除的時候,施工系統只要在報文中提供主鍵的信息提交,就能夠實現。
同樣的,外協系統在反饋的報文中返回成功刪除主鍵的信息,如果其中一條記錄不能正常物理刪除,則外協自動回滾所有刪除的操作。即一條記錄不能刪除,則所有的記錄都不能刪除。
請求報文:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<UserInfo>
<User>ZhangSan</User>
<PassWord>123456</PassWord>
</UserInfo>
<Description>
<Note>物理刪除</Note>
</Description>
<Records>
<Record>
<KeyField>Value1</KeyField>
</Record>
<Record>
<KeyField>Value2</KeyField>
</Record>
</Records>
</XmlData>

響應報文:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<Description>
<Result>成功</Result> <!--如果失敗,則<Result>里面內容是:失敗:(錯誤原因),同時,KeyField的值為空-->
</Description>
<Records>
<Record>
<KeyField>Value1</KeyField>
</Record>
<Record>
<KeyField>Value2</KeyField>
</Record>
</Records>
</XmlData>


報文說明:(參見數據修改說明)
外協系統中,文檔的信息是保存在另外的一個表中當中的,所以,許多的業務表,往往存在一個FileID的主鍵關聯到文檔表。在業務表中檔,可能有一個FileID的字段,也可能會有兩個或兩個以上的FileID字段關聯到文檔信息表。
涉及到文檔的地方,往往文檔的信息會比較大,所以,文檔的信息不能包含在基礎業務數據的報文當中一起上傳。處理的方法是:
先上傳文檔的實體,從反饋的信息當中得到生成的文檔ID(FileID),然后,施工系統在本地記錄中的相應字段賦值文檔的ID,最后再上傳基本業務信息。
如果一條記錄中包含有兩個或兩個以上的文檔字段,則施工系統必須依次上傳文檔獲得文檔ID之后,賦值,再上傳基本業務信息。
一個文檔報文當中,只能上傳一個文檔。
文檔報文如下:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<UserInfo>
<User>ZhangSan</User>
<PassWord>123456</PassWord>
</UserInfo>
<Description>
</Description>
<Records>
<Record>
<ID></ID>
<FILE_PRJ_ID>123456</FILE_PRJ_ID>
<FILE_TYPE>401</FILE_TYPE>
<FILE_NAME>施工組織方案.DOC</FILE_NAME>
<FILE_UNIT>電信工程公司</FILE_UNIT>
<FILE_MAN>張三</FILE_MAN>
<FILE_CREATE_TIME>20061031 153005</FILE_CREATE_TIME>
<FILE_AUTHOR>張三</FILE_AUTHOR>
<FILE_TITLE>項目XXX施工組織方案</FILE_TITLE>
<KeepMutiFile>1</KeepMutiFile>
<FileData>/e5asf@dfgafa#sdgsdg……</FileData>
</Record>
</Records>
</XmlData>


響應報文:
<?xml version="1.0" encoding="utf-8"?>
<XmlData>
<Description>
<Result>成功</Result> <!--如果失敗,則返回信息是“失敗:(錯誤信息)”-->
</Description>
<Records>
<Record>
<ID>123456</ID>
</Record>
</Records>
</XmlData>


報文說明:
標簽名
|
說明
|
<XmlData>
|
報文數據主體
|
<Description>
|
報文頭部信息
|
<Records>
|
記錄集合
|
<Record>
|
一行記錄
|
<UserInfo>
|
業務認證的用戶信息
|
<User>
|
業務用戶登錄名
|
<PassWord>
|
業務用戶驗證口令
|
<ID>
|
文檔的ID,在新增上傳一個文檔的時候,這個ID永遠都是空的。外協系統根據這個文件ID是否為空來判斷是否是新的文件。
|
<FILE_PRJ_ID>
|
文檔所屬的項目ID,對于工程協作系統來說,一個文檔永遠都是會屬于某個項目的。這個項目ID可以是一級項目,也可以是三級項目。
|
<FILE_TYPE>
|
文件類型。標識文件的歸類。比如:
D401施工組織設計= 401
D402施工項目計劃進度= 402
D403施工日報= 403
<FILE_TYPE>里面的值是代碼,文件類型的代碼可以從字典接口中獲得。
|
<FILE_NAME>
|
文檔的文件名稱,帶有擴展名。
|
<FILE_UNIT>
|
文件創建單位,中文名
|
<FILE_MAN>
|
文檔創建人(上傳人)
|
<FILE_CREATE_TIME>
|
文檔創建時間
|
<FILE_AUTHOR>
|
文檔作者 (可為空)
|
<FILE_TITLE>
|
文檔標題 (可為空)
|
<KeepMutiFile>
|
是否允許多個文檔同時有效。這個標簽的值為 1 或 0。當值為1 的時候,則在同樣的項目ID、同樣的文件類型中,同時可以存在多個的文檔同時有效存在。這種情況下,多個文檔之間是兄弟之間的關系,當前的文檔是弟弟,以前的文檔是兄長。當這個值為0的時候,則在同樣的項目ID、同樣的文件類型中,只有最后上傳的文檔有效,后面上傳的文檔會把前面的文檔“擠”到歷史中,成為當前文檔的“父親”。這種情況下,當前的文檔和以前上傳的文檔之間是父子的關系。更詳細的解釋請參見后面的“一條記錄中一個FileID的字段如何上傳多個文件”主題相關內容。
|
<FileData>
|
文件實體內容。文件實體內容用二進制讀取出來之后,然后轉換成base64的格式。
|
<Result>
|
反饋報文中的保存成功與否信息。
如果保存成功,則信息是“成功”
如果保存失敗,則信息是“失敗:(后面是錯誤的詳細信息)”
|
外協系統中,文檔是以一種“有關系”的方式來存儲的。假設有這樣一個業務表Table1,里面有一個文檔的外鍵字段File_ID。當我們往Table1表里面插入一條記錄的時候,針對這一條記錄,我們希望在File_ID字段中可以帶有多個的文檔,也即會有多個的File_ID。當然,我們可以把這個表字段的數據模型這個定義:File1_ID,File2_ID,File3_ID……,需要多少個文件,我們就定義幾個的File_ID字段。但是這樣就會帶來問題了,如果你定義了5個的File_ID字段,但是,用戶如果想在一條記錄中上傳6個文檔,那么,這樣的數據模型就會滿足不了用戶的要求。還有一種情況,如果用戶僅僅上傳了2個文檔,那么剩下的3個File_ID字段就會白白空著。甚至用戶對這條記錄沒有上傳文件,這樣定義的數據模型就白白浪費了數據庫的資源。
還有一種說法,我可以用記錄的形式來表示啊。對的。上傳多個文件,是可以在Table1中新增多條記錄方式來表示。但是,我們的前提是,Table1是一個業務表,里面的一條記錄就是一筆業務。如果你產生了多條記錄,那么意味這這樣的業務進行了多次。顯然違背了業務數據保存的初衷。
外協系統引入了“父子”,“兄弟”的文檔保存機制, 即在文檔信息表(Files表)中保存文檔的基本信息和他們之間的關系。在同樣的項目ID、同樣的文件類型中,如果可以存在多個的文檔同時有效存在,這種情況下,多個文檔之間是兄弟之間的關系。后來者文檔是弟弟,先到的文檔是兄長。在同樣的項目ID、同樣的文件類型中,只有最后上傳的文檔有效,后面上傳的文檔會把前面的文檔“擠”到歷史中,成為當前文檔的“父親”。這種情況下,后來的文檔和以前上傳的文檔之間是父子的關系。
如果文檔之間是兄弟關系的話,則僅僅在業務表Table1中保存最小兄弟的File_ID;如果文檔之間是父子關系的話,則僅僅保存最小輩分的文檔File_ID。
兄弟和父子的文檔保存方式其實都是多個文檔串聯的一種保存方式,但是,還是會有使用上面的區別的。兄弟關系一般使用在文檔之間是平級的情況下。比如施工組織方案,可以有多個文件,但是,這多個文件是互為補充的一部分,互相依賴,又缺一不可。這種情況下,施工系統可以把這類型的文件上傳給外協系統,以兄弟的方式保存,施工系統僅僅在業務表當中保存最后上傳反饋回來的FileID即可。以后,可以使用這個最小兄弟的File_ID,向外協系統請求以獲得他的所有兄長文檔。父子的關系一般使用在下面的情景:當僅允許一個文檔是最終有效的時候,或者一個文檔修改之后再上傳到外協系統,我們想把最后上傳的文檔“覆蓋”前面的文檔,但是,又想保留文檔歷史修改痕跡的時候,一般就會用到父子關系。
父子關系中,施工系統僅僅需要保留最小輩分的文檔信息,以后,可以使用這個最小輩分的File_ID,向外協系統請求以獲得他的所有歷史文檔。