导出机制

数据导出机制

数据导出一直是企业比较关心的问题,原先OMS支持两种数据导出方式,一种是数据量少于500条的时候直接渲染数据输出csv文件,一种是通过系统脚本上部署crontab脚本循环执行一个个导出任务。

原先的方式最大的问题就是导出数据处理的效率,以及导出数据数据量的瓶颈。

新版导出(基于3.5.0新增的任务管理服务),更大程序上的优化了这块。

新老版本导出比较

老版导出:

预分配5个进程,循环所有用户列表,取用户的一条任务进行执行,进程设定超时时间为30分钟,有些任务数据10w多就可能无法完成中断,或者导出任务多、或者大数据的时候导致任务处理比较慢,而且进程开的多对脚本机的负载大,有的时候进程会僵死。

新版导出:

大体上采用任务队列+多线程的技术架构。导出任务支持指定主内容导出的字段自定义以及先后顺序,并且可以选择是否需要导出明细内容,处理效率提升,处理导出任务数增加,处理的数据量增加,更加稳定高效。

目录结构说明

app\taoexlib\lib\ietask.php 增加系统识别的走后台导出的任务定义

app\ome\lib\export\whitelist.php 使用新版导出的相关数据定义

路径: app/ome/lib/autotask

exportsplit.php 任务切片

dataquerybysheet.php 常规分片任务查询

dataquerybyquciksheet.php 快速分片任务查询

dataquerybywhole.php 无法切片的全局查询

createfile.php 导出数据组装合并生成文件

逻辑梳理说明

  1. 将数据量大于一定数量满足条件的,支持后台导出的数据内容导出任务塞进队列

  2. 读取导出任务进行拆分,可拆分的根据查询条件找到记录可以唯一定位的主键数组,或者没有主键定位的用导出的总数量,根据上述两种数据进行任务的切分,一般200个切为1个小任务比较合理高效,然后根据预先判断的大于1000的进常规分片查询任务队列,小于1000的进快速分片查询任务队列,而有些不能切分的任务复杂的查询导出,走直接全局查询任务队列

  3. 读取分片任务(快/慢)以及全局查询任务队列的任务,进行结果内容的查询,并将任务保存在缓存中,当所有分片任务或整个全局查询任务结束时判断,是否都已经完成,完成的添加创建导出文件的队列任务

  4. 读取创建导出文件的组装任务,根据分片数(全局任务结果查询后也会分片保存在缓存中)组装数据在远程ftp里生成csv导出文件

二开及代码解读

增加一个导出数据模型支持后台导出

找到app\taoexlib\lib\ietask.php 文件,在$support_model变量中进行追加

var $support_model = array('omeanalysts_mdl_ome_shop','omeanalysts_mdl_ome_sales','ome_mdl_orders','omeanalysts_mdl_ome_delivery','sales_mdl_sales','wms_mdl_inventory','inventorydepth_mdl_shop_frame','omeanalysts_mdl_ome_products','omeanalysts_mdl_ome_goodsale','omeanalysts_mdl_ome_storeStatus','omeanalysts_mdl_ome_goodsrank','omeanalysts_ome_shop','omeanalysts_mdl_ome_branchdelivery','omeanalysts_mdl_ome_aftersale','ome_mdl_goods','finance_mdl_bill_order','finance_mdl_ar_statistics','omedlyexport_mdl_ome_delivery','iostock_mdl_iostocksearch','omeanalysts_mdl_ome_income','drm_mdl_distributor_product_sku','finance_mdl_analysis_bills','finance_mdl_analysis_book_bills','ome_mdl_branch_product','tgstockcost_mdl_costselect','tgstockcost_mdl_branch_product','console_mdl_branch_product','wms_mdl_branch_product','ome_mdl_reship','omeanalysts_mdl_ome_cod','invoice_mdl_order','wms_mdl_delivery','taoguaniostockorder_mdl_iso','wms_mdl_delivery_outerlogi','ome_mdl_reship_refuse','console_mdl_inventory_apply');

定义导出任务的处理方式和配置参数

找到app\ome\lib\export\whitelist.php文件

<?PHP
/**
 * 导出白名单
 *
 * @author kamisama.xia@gmail.com 
 * @version 0.1
 */

class ome_export_whitelist
{

    static public function allowed_lists($source=''){
        $data_source = array(
            'ome_mdl_orders' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'order_id', 'structure'=>'multi'),
            'sales_mdl_sales' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'sale_id', 'structure'=>'multi'),
            'ome_mdl_goods' => array('cansplit'=>0, 'splitnums'=>200),
            'iostock_mdl_iostocksearch' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'iostock_id', 'structure'=>'single'),
            'omedlyexport_mdl_ome_delivery' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'delivery_id', 'structure'=>'spec'),
            'wms_mdl_inventory' => array('cansplit'=>0, 'splitnums'=>200),
            'omeanalysts_mdl_ome_goodsale' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'item_id', 'structure'=>'single'),
            'omeanalysts_mdl_ome_products' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_sales' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_aftersale' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'item_id', 'structure'=>'single'),
            'omeanalysts_mdl_ome_shop' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_income' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_cod' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'delivery_id', 'structure'=>'single'),
            'omeanalysts_mdl_ome_branchdelivery' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'tgstockcost_mdl_costselect' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'tgstockcost_mdl_branch_product' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_goodsrank' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_storeStatus' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'omeanalysts_mdl_ome_delivery' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'finance_mdl_bill_order' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'finance_mdl_ar_statistics' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'finance_mdl_analysis_bills' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'finance_mdl_analysis_book_bills' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'console_mdl_branch_product' => array('cansplit'=>0, 'splitnums'=>200),
            'wms_mdl_branch_product' => array('cansplit'=>0, 'splitnums'=>200),
            'drm_mdl_distributor_product_sku' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'inventorydepth_mdl_shop_frame' => array('cansplit'=>1, 'splitnums'=>200, 'structure'=>'single'),
            'ome_mdl_reship' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'reship_id', 'structure'=>'multi'),
            'invoice_mdl_order' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'id', 'structure'=>'single'),
            'wms_mdl_delivery'=>array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'delivery_id', 'structure'=>'spec'),
            'wms_mdl_delivery_outerlogi'=>array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'delivery_id', 'structure'=>'spec'),
            'taoguaniostockorder_mdl_iso'=>array('cansplit'=>1, 'splitnums'=>200, 'primary_key'=>'iso_id', 'structure'=>'multi'),
            'ome_mdl_reship_refuse' => array('cansplit'=>1, 'splitnums'=>200, 'primary_key' => 'reship_id', 'structure'=>'multi'),
        );

        if(!empty($source)){
            return isset($data_source[$source]) ? $data_source[$source] : '';
        }else{
            return $data_source;    
        }
    }
}

参数说明:

cansplit代表这个导出任务是否可以分片,绝大多数90%的都是可以的

splitnums 分片任务的切分数量,一般为200,合理高效

primary_key 任务分片的主键,有的话就根据主键数量切分,没的话根据count出来的结果数量切分

structure 导出数据的结构:single 单层、multi 双层、spec 特殊(发货单是比较特殊的明细和主内容在一行)

任务是否可拆分分片

具体根据业务数据是否有主键,按主键维度可以分片查询,比如有的数据订单,销售单,每个单据都有唯一的主键,这样的数据就可以定义为'cansplit'=>1。

这里要注意如果分片的主键无法用getList框架方法获取,需要在model层中定义方法getPrimaryIdsByCustom

有些数据因为数据是临时从多张表拼接组成或者带group by出来的,所以无法拆分,所以只能走非拆分流程

可拆分分片任务查询数据

一种标准的finder查询就是和列表页查询出来的内容一模一样,比如标化的订单,销售单等数据

$exportLib = kernel::single('desktop_finder_export');
$data = $exportLib->work($date_source,$params);

还有种就是报表用的比较多,直接自定义方法,在具体调用的数据model层中定义getExportDataByCustom方法

public function getExportDataByCustom($fields, $filter, $has_detail, $curr_sheet, $start, $end){
    /*具体获取分片数据的处理代码*/
}

扩展导出内容

如果要扩展一个标准finder查询的主内容,可以查看订单导出中的,优惠方案的导出扩展方式,查找关键字export_extra

    /**
     * 订单导出列表扩展字段
     */
    function export_extra_cols(){
        return array(
            'column_discount_plan' => array('label'=>'优惠方案','width'=>'100','func_suffix'=>'discount_plan'),
            'column_mark_type_colour' => array('label'=>'订单备注图标颜色','width'=>'100','func_suffix'=>'mark_type_colour'),
        );
    }

    /**
     * 买家备注扩展字段格式化
     */
    function export_extra_discount_plan($rows){
        return kernel::single('ome_exportextracolumn_order_discountplan')->process($rows);
    }
    /**
     * 订单备注图标颜色扩展字段格式化
     */
    function export_extra_mark_type_colour($rows){
        return kernel::single('ome_exportextracolumn_order_marktypecolour')->process($rows);
    }

1). export_extra_cols 方法定义要扩展的字段

2). export_extra加func_suffix后缀方法,定义根据结果内容追加扩展的结果内容到结果数组中

完成以上两步即可

自定义的方法要扩展一般本身列表项就是通过get_schema自定义的,所以只要在该方面里增加字段,并且在上面的getexportdatabycustom方法里增加处理即可。

双层结构的涵明细的怎么扩展,基本就是找到查询方法自定义,finder类的标准明细内容查询是调用getexportdetail方法


沪ICP备05002918号

© 2003-2017 ShopEx,Inc.All rights reserved.