一个完整的接口技术解决方案(四)
发表这篇解决方案,属于非盈利目的。主要是为了让大家了解一种接口技术解决方案文档的编写格式以及让大家评审在我的这个技术解决方案中的不足之处,以便大家指出并加以改进。
转载,下载或与各种形式使用这篇文章,必须注明文章的作者,出处。
其他未尽事宜,以国家法律规定的为准!
作者:南疯
8.2.3 修改一条记录
施工系统在修改了一条记录的时候,上传的报文中与新增的报文类似,只是主键的信息不能为空。外协系统判断主键的信息,如果发现主键的信息不为空,则认为是修改了一条记录。如果施工系统报文中主键不为空,而外协系统在数据库对应的表中又没有发现对应的记录,则自动转换成新增的方式来处理这条记录。
外协系统在反馈中,还是会把主键返回给施工系统。但是,这种情况下,施工系统可能不再需要维护这个主键。
即使是仅仅修改了一个字段,施工单位还得需要上传全部的字段信息(包含被修改的字段)给外协系统。
施工系统不是对记录做物理删除,而仅仅是作了逻辑删除,即仅仅在记录的删除标志位上面做了“
<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>
响应报文:
<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> |
一行记录中的英文字段名称。实际中,这些标签都是字典的英文名。字段的标签全部是大写。 具体的字段名称请参见提供的数据模型 |
|
|
|
|
8.2.4 删除一条记录
这里的删除指的是物理删除。逻辑删除在记录修改的时候已经说明。
物理删除是彻底的从数据库中删除一条记录,不能恢复。物理删除的时候,施工系统只要在报文中提供主键的信息提交,就能够实现。
同样的,外协系统在反馈的报文中返回成功删除主键的信息,如果其中一条记录不能正常物理删除,则外协自动回滚所有删除的操作。即一条记录不能删除,则所有的记录都不能删除。
请求报文:<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>
响应报文:
<XmlData>
<Description>
<Result>成功</Result> <!--如果失败,则<Result>里面内容是:失败:(错误原因),同时,KeyField的值为空-->
</Description>
<Records>
<Record>
<KeyField>Value1</KeyField>
</Record>
<Record>
<KeyField>Value2</KeyField>
</Record>
</Records>
</XmlData>
报文说明:(参见数据修改说明)
8.2.5 文档上传
外协系统中,文档的信息是保存在另外的一个表中当中的,所以,许多的业务表,往往存在一个FileID的主键关联到文档表。在业务表中档,可能有一个FileID的字段,也可能会有两个或两个以上的FileID字段关联到文档信息表。
涉及到文档的地方,往往文档的信息会比较大,所以,文档的信息不能包含在基础业务数据的报文当中一起上传。处理的方法是:
先上传文档的实体,从反馈的信息当中得到生成的文档ID(FileID),然后,施工系统在本地记录中的相应字段赋值文档的ID,最后再上传基本业务信息。
如果一条记录中包含有两个或两个以上的文档字段,则施工系统必须依次上传文档获得文档ID之后,赋值,再上传基本业务信息。
一个文档报文当中,只能上传一个文档。
文档报文如下:
<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>
响应报文:
<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> |
反馈报文中的保存成功与否信息。 如果保存成功,则信息是“成功” 如果保存失败,则信息是“失败:(后面是错误的详细信息)” |
8.2.6 一条记录中一个文档字段上传多个文件
外协系统中,文档是以一种“有关系”的方式来存储的。假设有这样一个业务表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,向外协系统请求以获得他的所有历史文档。