记录日期: 2013-8-30
最后更新日期:2013-10-16
1.背景
此需求最初作为在出现传单故障时,需要一个能人工干预的单据补送工具。有一个简单的辅助工具aid_tool可用于手动发送指定的记录。
SVN位置:trunk\Server\util\aid_tool
该工具直接访问数据库,是个临时性的工具,功能和操作性有局限。
可以在以下不正常的情况下,对指定的单据(一张特定的单据)进行重发:
- 系统状态没有进入“已送达”,长时间处于已发送状态,而且目标方申告没有接收到单据,
- 系统状态显示"已送达",但目标方无法查看到单据:数据被删除?或者是程序缺陷导致的?
出现这些情况时,需要立即触发重发。
本模块的作用就是在需要的时候,由客服人员人工确认问题和执行重发。
操作在单据发送方进行。
确认是指可以通过tb_0031查看单据的发送情况,如发送状态,发送次数,上次发送时间,单据进入队列时间。
2.功能定义
该工具属于客服人员使用的工具中的一个功能。CST: Customer Service Tool (供应宝客户服务工具)
.单据补发(或者手动发送)功能----正式名称:单据手动发送功能
支持2种方式:
(1)从待发送队列(SEMQ)中发送:从tb_0031中发送:已进入队列。可根据“发送机构ID,目标机构ID,单据编号”查询,单据编号支持模糊查询。
查询结果显示单据的发送状态,发送次数,上次发送时间。
可发送查询结果中的多条记录。
(2)从单据表中发送:用户选择单据类型后从单据表中查询单据
2种方式都支持查看单据的详细内容。
3.实现
3.1要求
.采用C/S方式实现,客户端采用基于hotfox的框架开发插件,对应的服务端插件调用相关模块的功能(如通过bbox访问tb_0031).CST工具以插件的形式实现,手动发单是其中一个功能。
.CST的插件名称:客户端--cst_c,服务端---cst_s
3.2实现思路
对于方式(1),从tb_0031查询符合提交的记录(仅单据),可通过关联信息打开单据。单据内容采用简单的列表格式(不采用格式文件)----完善时再考虑支持格式文件。对于方式(2),根据提供的单据类型条件,服务端从tb_0044(通过IBiz接口调用)确定主从表名信息,再从相应的单据表中查找单据。
利用bbox中的协议可以(1)查询SEMQ的记录,(2)发送指定的记录
利用现有的查询单据类型和单据列表的协议可以实现方式(2)的功能
首先支持按单据编号模糊查找,查看单据内容,触发发送,
方式2暂时不考虑支持。(其价值待确认)
3.2.1 功能协议及服务端实现
利用SEMQ(tb_0031为其存储)的实现bbox作为服务端。
bbox已经实现以下协议,协议定义在"ESE应用协议定义"文档中.
{805,MT_REQUEST,(MSGFUNC)&OnQueryItemData,true,"查询待发送消息","查询待发送消息"},
{806,MT_REQUEST,(MSGFUNC)&OnCount,true,"待发送消息统计","待发送消息统计"},
{807,MT_REQUEST,(MSGFUNC)&OnQueryItem,true,"查询待发送消息列表","查询待发送消息列表"},
{811,MT_REQUEST,(MSGFUNC)&OnUpdateItemStatus,true,"修改待发送消息状态","修改待发送消息状态"},
{825,MT_REQUEST,(MSGFUNC)&OnQueryCheckItem,true,"查询待校验消息","查询待校验消息"},
{826,MT_REQUEST,(MSGFUNC)&OnUpdateCheckStatus,true,"修改校验标志","修改校验标志"},
{827,MT_REQUEST,(MSGFUNC)&OnGetMQItemInfo,true,"获取队列元素内容","获取队列元素内容"},
仅在必要时可对上述协议扩充。
3.2.2 关于获取单据类型列表
关于“查询单据类型”,用于客户端列表显示,有2种方式
(1).利用2001协议
直接从tb_0044中查询。协议处理函数CSowBasePlugin::OnQueryBillType。(在sowbase插件的sowbase.cpp中)。
(2).利用IBiz接口
单据类型信息在lm加载时读入内存.
已实现的IBiz可用的取单据列表的方法如下:
class IBiz {
public:
virtual short GetSheetTypeCount() const = 0; ///< 取单据类型个数
virtual ISheetTypeInfo* GetSheetTypeInfo(CQQ_BILLTYPE type) = 0; ///< 根据类型取单据类型信息
};
可见,缺少一个按序号读ISheetTypeInfo的方法.
目前第2种方法不可行,而且缓存有个缺陷,在单据类型信息改变时没有更新,需要重新启动服务器。
如需要及时更新缓存,需要在data_model模块中维护单据类型信息时执行缓存更新操作,相关协议有:
MSG_FUNC_MAP CDataModel::func_[] = {
{871,MT_REQUEST,(MSGFUNC)&OnRecv871,true,"新建单据类型模型","新建单据类型模型"},
{872,MT_REQUEST,(MSGFUNC)&OnRecv872,true,"修改单据类型模型","修改单据类型模型"},
{875,MT_REQUEST,(MSGFUNC)&OnRecv875,true,"删除单据类型模型","删除单据类型模型"},
};
单据类型基本上是在部署阶段确定,运行时期不需要调整。
为了避免扩展IBiz接口,可采用方式(1).
3.2.3本地SEMQ中查询单据
807协议可用于从平台查询任一本地的SEMQ的信息,不能直接满足本应用的需要。
新增查询本地SEMQ信息协议(829)。
829是对SEMQ的特殊处理,针对单据查询.实现CST服务端。
829协议要求支持分页。
分页定义见“ESE应用协议定义”2.4.1 通用查询模板"。
查询条件:
。单据编号(sheet_id):可选,模糊查询
。单据类型(data_type):可选(保留)
。发送机构(src_orgid):可选
。目标机构(dest_orgid):可选
。开始时间(begin_time):可选
。截止时间(end_time):可选
。发送状态(status) :可选
对于tb_0031表,对应字段为:
开始和截止时间指写入队列的时间: f008d_0031
单据类型,单据编号:从应用关联键字段f020v_0031中解析,
应用关联键的格式:域,数据类型,子类型,记录定位键.
对于单据,数据类型为100,子类型为单据类型,记录定位键包括机构ID和单据编号。
发送机构:src_type=1,src_id=机构ID
目标机构:dest_type=1,dest_id=机构ID
tb_0031中是单据的判定:
。f006n_0031=100 : 规定了单据的数据类型,此条件也可单独使用
。f012n_0031=7 abd f013n_0031=2800 : 2800-Indication表示单据消息包,以此为条件即可
按单据类型和单据编号查询需要对MySQL扩展,增加一个专用函数:
--取第N项数据,各项数据之间用","分开.
C++原型:
int GetNthItem(int n,string &val);
参数:n:从1开始
val:成功时返回项值
返回值:0:成功 -1:失败(没有第n项)
如何扩展MySQL见:
http://dev.mysql.com/doc/refman/5.1/zh/extending-mysql.html#adding-functions
为了避免对MySQL扩展,目前不支持按单据类型查询,按单据编号模糊查询也不严谨。
3.2.4关于分页处理
bbox实现的协议在处理分页时是早期的方式,其机制不能和客户端分页处理器兼容。
客户端分页处理器见
http://blog.csdn.net/wherwh/article/details/8976586
服务端分页处理见
http://blog.csdn.net/wherwh/article/details/8913948
实现829协议采用新的分页方式。
服务端参考GDSNSup插件11154协议的处理,主要是CPagizeHelper的使用。
CPagizeHelper PageHelper;
客户端参考gdsn_supplier此协议的处理。
3.2.3 客户端实现
客户端实现参考CenterPlugin插件的实现,如TFrmMsgQueue窗体。