Skip to content

Instantly share code, notes, and snippets.

@diyism
Created November 5, 2012 08:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save diyism/4015990 to your computer and use it in GitHub Desktop.
Save diyism/4015990 to your computer and use it in GitHub Desktop.
OME 笔记

目录结构:

  • model 实体
  • view 模板
  • controller 控制器
  • script 脚本
  • lib 业务逻辑及库
  • config\config.php,install.lock.php 都是在安装的时候生成的,含数据库账号配置
  • data\kvstore\service和setting 在程序运行的时候生成, kvstore下只要这两个不删系统还能跑起来
  • app\ecredis\crontab\config\defined.php redis账号配置

url:

  1. 不需要设rewrite
  2. http://test.diy/a.php/a.htm
  3. 既可能是a.php文件夹下的a.htm文件
  4. 也可能是a.php文件来处理a.htm这个参数

boot过程:

  • 安装完成后config下方install.lock.php表示不再进入安装
  • 根据取到url参数如a.htm来{site/desktop}_router
  • 再dispatch到default controller, new任何controller都会判断是否登录(否则跳到passport页面),
  • //具体是app/desktop/lib/controller.php调app/pam/lib/account.php去判断session里account值有没有当前类型
  • 再call_user_func_array调controller, 比如app/ome/controller/... 也可能 app/ome/lib/finder/...
  • 再取数据设置pagedata
  • 再调->page()套模板和数据放到_response里
  • 可由&findview=...决定view内的html模板, 或者controller再调view, view里取数据:
  • $this->object->$getlist_method(implode(',',$sql),$this->params,($page-1)*$this->pagelimit,$this->pagelimit,$order);
  • 所有model都扩展app/dbeav/lib/model.php, 内有getList, insert, delete, update, save等常用操作

使用:

  • app/base/lib/http.php 支持http的post, get等

  • 创建或取到对象的单例: kernel::single("base_http")

  • app::get('app1')->model('mdl1')取到的是app/app1/model/mdl1.php

  • app :: get('ome')->model('shop')等同于kernel::single('ome_mdl_shop')

  • 创建新表:app/app1/dbschema下建tb1.php里含$db['tb1']定义,然后app/base/cmd update就能自动创建, 注意关掉FirePHP调试代码(包含fb.php没用)

  • 修改app/base/lib/db/connections.php加FirePHP的监测点看sql:

      if (strpos($sql, 'sdb_ome_orders')!==false || strpos($sql, 'sdb_ome_order_items')!==false || strpos($sql, 'sdb_ome_order_objects')!==false)
         {file_put_contents('/data/httpd/kappa_ome/sql.txt', $sql."\n", FILE_APPEND);
         }
    
  • 到app/ome/dbschema看相应表字段的中文定义

  • 定义了从表面后可以查从表: $this->dump($dly_id,'',array('delivery_items'=>array(''),'delivery_order'=>array('*')));

  • $shop_ids=kernel::single('ome_mdl_shop')->getList('shop_id', array('shop_bn'=>'xijie'));echo $shop_ids[0]['shop_id'];

  • 或$shop_info=kernel::single('ome_mdl_shop')->dump(array('shop_bn'=>'xijie'), 'shop_id');echo $shop_info['shop_id'];

  • kernel::database()->select('...the sql...');

  • kernel::database()->selectrow('...the sql...');

  • 查看redis队列:http:///app/ecredis/redisinfo.php http://ome.diy/app/ecredis/redisinfo.php

  • script也可直接:http:///script/xijie/xijie_getorders.php

  • kernel::service('ome.service.order.sdfdata')要到app/ome/services.xml里看注册的类

  • 写调试日志可以:file_put_contents(DATA_DIR.'/log1.txt', var_export($para1, true), FILE_APPEND);

  • ome_mdl_api_log->write_log($task_id, '往西街回写库存', __class__, 'run', array(array('data'=>array($stock), 'task_id'=>$task_id))); 然后调用过程:

    1. view/index.html ajax每30秒调用http://ome.diy/index.php?ctl=default&act=status 但浏览器单站连接数有限
    2. 再desktop_ctl_default->status()
    3. 再base_misc_autotask->trigger()里servicelist('autotask')从sdb_base_kvstore取serveice.autotask得ome_misc_task
      • 会记录时间到sdb_base_task避免一分钟内跑多次
    4. 再ome_misc_task->minute() //这里还会调ome_sync_product->add_stock_sync(), ome_sync_product->sync_stock, 取所有node_id不空的店广播update_stock
    5. 再ome_sync_api_log->auto_retry加到sdb_base_queue里 //这里控制创建超过5分钟的才push到queue, 这里retry+1
  • 再次过来:

    1. view/index.html ajax每30秒调用http://ome.diy/index.php?ctl=default&act=status 但浏览器单站连接数有限
    2. 再desktop_ctl_default->status()
    3. 再base_mdl_queue->flush() //因为flush()在trigger()前面, 即使1.status=running(新任务),2.retry=0(小等于2),3.last_modified=0(肯定超过5分钟)并且sdb_base_queue中少于300条, 也还要刷两次/index.php?ctl=default&act=status页面才会重跑
    4. 再base_mdl_queue->runtask()里base_http->post($url,$_POST) //一次300个连接执行任务, 这里设了2秒超时(base_http默认10秒超时), 虽然这些连接不是并发的, 断开连接不会终止任务(ignore_user_abort(true);), 这里故意把task_id post过去, 直接手工访问'.../task_id/1408'没用
    5. 再访问/openapi/queue/worker/task_id/1408(task_id就是queue_id)
    6. kernel.php/base_rpc_service->process(url)
    7. 再base_service_queue->worker()里call_user_func_array(ome_api_log_to_api, retry), 这里retry+1
    8. 再ome_api_log_to_api->retry()里eval()
    9. 实际调用ome_xijie_orderout->run
  • 模板循环radio不用foreach: <{input type="radio" name="config_name" options=$names value="{$config_name}" onclick="methodchange(this.value);"}>

  • 在js里进行ajax页面跳转:W.page('?app=ome&ctl=admin_predeposit&act=setting&config_name='+this.value);

  • 增加菜单项:desktop.xml里增加一个menu一个permission,两个的permission字段保持相同, "./cmd update"后自动更新到数据表sdb_desktop_menus

  • app::get('ome')->getConf('shop.branch.relationship')是到app/ome/setting.php里查找(第一次放到kstore,以后查kvstore)

  • 也有可能不进setting.php, 在script/initial/wmsmiddleware.php/_set_shop_branch_conf()运行run.php直接进kvstore

  • 界面上订单取消过程:

    1. pre_do_cancel()
      • ome_mdl_orders->pre_order()
      • ome_mdl_delivery->unfreez()
      • ome_mdl_products->unfreez() 释放对应products表xijie_freez 或 ikappa_freeze
    2. do_cancel()
      • ome_mdl_orders->cancel() 释放branch_product表冻结
      • 退还预存款

登录:

  • /openapi/pam_callback/login/module/pam_passport_basic 最终到app/pam/lib/passport/basic.php的login()验证密码
  • 再到app/pam/lib/callback.php里login()
  • 再调app/pam/lib/account.php里update()设$_SESSION['account']表示已登录成功
  • 注意session是存在/var/www/ome/data/kvstore/sessions里的自动保存和恢复
  • 密码存在sdb_pam_account表

OME安装:

  • 在web server里也要设hosts, 要不然会报"不支持pathinfo"

数据表:

  • sdb_ome_payment_cfg 配送方式配置
  • sdb_ome_goods 商品表
  • sdb_ome_products 总库存表 订单新建的时候总库冻结单位, 一货一行记录
  • sdb_ome_branch_product 经销商(预存款拿货)/代销商(不预存款不拿货)实库表 生成发货单的时候分销商虚库冻结单位, 一货多仓记录
  • sdb_ome_warehouse_group_stock as wgs inner join sdb_ome_products op on wgs.sku_id =op.bn 共享库存 sku_id就是goods_bn货号, qi_stock总库存 blocked_stock冻结 occupy_stock 预占
  • 就是说即使wgs有库存如果sdb_ome_products没有这个货号查处来的库存就会是0
  • 而且检查是否缺货是要对应branch仓库来检查的, sdb_ome_branch_product内也要有货
  • sdb_ome_orders 订单表 shop_id(来源店铺) createtime(下单时间) ship_status(1是0否发货)
  • sdb_ome_goods 商品表 weight(重量)
  • sdb_ome_shop 店铺表 shop_bn(字母代号) node_id(网站节点id)
  • sdb_ome_delivery_order 订单和发货单的关联表
  • sdb_ome_delivery 发货单表 'status'=='succ' || 'process'=='true'则'已发货', delivery_bn发货单号
  • sdb_ome_dly_corp 物流快递公司
  • sdb_ome_return_process 售后退货
  • sdb_ome_return_product 售后/退货单, 删掉order时如果未删掉, 可能关联上
  • sdb_desktop_roles 角色表
  • sdb_desktop_users 用户表
  • sdb_ome_groups 订单确认组
  • sdb_ome_group_ops 订单确认组所含操作员

OME业务:

  • 添加订单方法不管是矩阵过来的数据还是OME新建的都是调用同样方法:app/ome/model/orders.php/create_order()
  • 订单的话获取之后我们现在是放在redis
  • 订单入口是在app/ome/lib/rpc/response/order.php/add() 会加入redis队列
  • 之后要区分权限,西街的人会在OME操作,现在的运营古星也会在OME操作
  • 新建订单时(ome_mdl_products->chg_product_store_freeze(),chg_xijie_product_store_freeze)冻结总库存(sdb_ome_products.store_freeze)
  • 生成发货单(ome_mdl_branch_product->freez()/->chg_product_store_freeze())时冻结分仓库存(sdb_ome_branch_product.store_freeze)
  • 出货后会更新实际库存(store)和store_freeze,
  • 可用库存=real store-人为预占($warehousestocks['occupy_stock'])-store_freeze, 见app/ome/lib/service/stock.php/76
  • 之后在每分钟触发点执行队列app/ecredis/crontab/thread/thread_order.php
  • ecredis_manager->exec(app/ecredis/crontab/thread/order.php) //这里可以加diyism_trace.php
  • 然后app/ome/lib/rpc/response/order.php/doAdd() //里面如果是分销店就跳到分支并exit, 直接fast test西街可以在xijie_get_orders.php里加diyism_trace.php
  • 然后app/ome/model/orders.php/create_order()
  • 然后app/ome/lib/stock/process.php/save_warehouse_group_stock()
  • 然后app/ome/model/warehouse/group/stock.php/sync_stock_by_products() //循环各个店库存调下面stock_update()(比如取西街库存xijie_store-xijie_freeze)
  • 最终触发app/ome/lib/rpc/request/stock.php/stock_update()/120: $this->request(...)往redis队列发送数据通知网店更新库存
  • 在这里写分支直接实时更新西街库存(要有失败缓存重试机制)
  • 转库过程: 0. inventory_mdl_appropriation->get_appro_bn() 0. 用初始化调拨单inventory_mdl_appropriation->save() //从save内传址返回appro id 0. 保存调拨项appropriation_items->save() 0. inventory_appropriation_aftersave->do_aftersave() 0. inventory_appropriation_aftersave->save_iostock() //保存调拨项 0. ome_iostock->set() 0. ome_iostock->updateBranchProduct() //更新branch_product表 0. ome_iostock->updateProduct() //更新products表, 里面有max_store_lastmodify会被定时任务扫描到而更新前端
  • 科捷打包/发货先调kappaapi_rpc_service->process, 再调kappaapi_mdl_api_log->write_log(), 然后: 0. 在root crontab里每分钟执行(测试时可手工执行) 0. app/kappaapi/cronjob/auto.php //这里可以加diyism_trace.php 0. kappaapi_sync_api_log->auto_retry() 0. 再kappaapi_api_log_to_api->retry(), 0. 再kernel::single($class)->$method(), 0. 实际调用kappaapi_rpc_response_order->add_orderStatus, 0. 再调hold_transit_deliverysync->status(), 0. 再调wmsmiddleware_service_delivery->consign(),打包时:wmsmiddleware_service_delivery->package() 0. 再调wmsmiddleware_rpc_response_delivery->consign(),打包时:wmsmiddleware_rpc_response_delivery->package() 0. 再调wmsmiddleware_process_delivery->finish_delivery(),打包时:ome_mdl_delivery->finish_package() //释放branch冻结ome_mdl_branch_product->unfreez() 0. 再调ome_mdl_delivery->finish_delivery()来保存科捷返回的数据,打包时:ome_mdl_delivery->finish_package()
  • 科捷发货退货:
    • http://ome.diy/kappa.php

      • serverName填orderStatus
      • CustID填1010000011
    • "WMS接口监控\日志列表"里可以看发货状态

    • 完整操作过程:

      1. 订单\新建订单
      2. 财务\付款确认
      3. 订单\订单分派(可能自动)
      4. 订单\订单处理\订单确认('confirmed')和订单拆分('splited'可能自动), 生成发货单(需要绿色有库存,否则报选择仓库), 订单的发货记录里可以得到发货单号
        • 一个订单有来源shop, 来源shop在setting.php或script/initial/run.php里设了branch, 根据branch和product到sdb_ome_branch_product找库存
        • 可改process_status为'unconfirmed',confirm改成'N',并删除sdb_ome_delivery_order关联后重新处理订单
      5. 科捷打包, 触发预占库存和实际库存被更新
        • 可以把订单的ship_status改0, sdb_ome_delivery里status改ready,package改false,process改false, sdb_ome_order_items里sendnum改0后重新打包发货
      6. 科捷发货, 触发出库
        • 可以只改sdb_ome_delivery.status和process就重新发货
    • 具体代码, action主要看0006是发货, Sign_Code 每次要不同:

        //-----------订单打包
        <Request>
           <Sign_Code>****变动*****</Sign_Code>
           <OutInFlag>1</OutInFlag>
           <Cust_OrderCode>*****发货单号******</Cust_OrderCode>
           <CustID>1010000011</CustID>
           <TmsCode></TmsCode>
           <TmsName></TmsName>
           <MailNo></MailNo>
           <Weight></Weight>
           <Volume></Volume>
           <PlanID>00010001</PlanID>
           <StockID>K1</StockID>
           <InfoCode>0005</InfoCode>
           <InfoContent>打包</InfoContent>
           <StatusTime>2011-5-6 22:48:44</StatusTime>
        </Request>
        
        //---------------订单发货
        <Request>
           <Sign_Code>****变动*****</Sign_Code>
           <OutInFlag>1</OutInFlag>
           <Cust_OrderCode>*****发货单号******</Cust_OrderCode>
           <CustID>1010000011</CustID>
           <TmsCode>SF</TmsCode>
           <TmsName>SF</TmsName>
           <MailNo>*****快递单号要变化******</MailNo>
           <Weight></Weight>
           <Volume></Volume>
           <PlanID>00010001</PlanID>
           <StockID>K1</StockID>
           <InfoCode>0006</InfoCode>
           <InfoContent>发货</InfoContent>
           <StatusTime>2011-5-19 15:01</StatusTime>
        </Request>
        
        //---------------退货入库(新建售后申请,接受申请,收货后)
        <Request>
           <Sign_Code>****变动*****</Sign_Code>
           <OutInFlag>4</OutInFlag>
           <Cust_OrderCode>*******退货单号**********</Cust_OrderCode>
           <CustID>1010000011</CustID>
           <TmsCode></TmsCode>
           <TmsName></TmsName>
           <MailNo></MailNo>
           <Weight></Weight>
           <Volume></Volume>
           <PlanID>00010001</PlanID>
           <StockID>K3</StockID>
           <InfoCode>*****0010为全部过账,0009为部分过账*****</InfoCode>
           <InfoContent>过账完成</InfoContent>
           <StatusTime>2011-5-6 22:48:44</StatusTime>
           <OrderItems>
           <OrderItem>
           <Item>1</Item>
           <Sku_ProductNo>********货号******</Sku_ProductNo>
           <Qty>******入库数量*****</Qty>
           <SN></SN>
           </OrderItem>
           </OrderItems>
        </Request>
      
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment