本帖最后由 dongxf 于 2020-5-12 12:26 编辑
大功告成,调试SQL语句和在这么多层中倒腾,写死我了
自动拆分订单程序,后台定时运行
#encoding: utf-8=beginUsage: This ruby file will recode & split crmeb original order to small orders sort by temp_idarguments: ruby split-orders.rb [start_date start_time backward_hours]Example: ruby split-orders.rb 2019-07-09 08:00 24'=endload 'rds_api.rb'etime = ( ARGV[0] && ARGV[1] ) ? Time.parse("#{ARGV[0]} #{ARGV[1]}") : Time.nowbhours = ARGV[2] ? ARGV[2].to_i : 24stime = etime - bhours*3600 + 1 #leave one second#为减少风险,只搜寻有未发货、无退款相关、已付过款的订单def get_splitable_orders_during stime, etime orders = [] #inq = "select id, pay_time, order_id, uid, cart_id, shipping_type, status, refund_status, paid inq = "select * from crmeb.eb_store_order where paid = 1 and order_id not like 'FC%' and status = 0 and refund_status = 0 ;" res = @rds.query inq res.each { |order| orders += [order] } return ordersend#提供一项保险措施, 这个逻辑与get_splitable_orders_during是一致的def leave_alone? order #只有付过款、未发货、未退款、且未重编码的订单才可以被重命名编码 return order['paid'] != 1 || order['order_id'][0..1] == 'FC' || order['status'] != 0 || order['refund_status'] == 2enddef pickup_able? order return order['shipping_type'] == 2end#单一订单用FC4-开头,拆分的订单用FCS开头#统一订单打印程序只会处理代码为FC开头的订单, 见print-orders.rbdef rename_order_code order code = sprintf("FC4-%08d",order['id']) puts "recoding order##{order['id']} to #{code}" return queryRds "update crmeb.eb_store_order set order_id = '#{code}' where id = #{order['id']}"end#根据邮件模版数量返回多个cart, 每个邮件模版一个cartdef group_cart_items order #首先找出所有购物车物品 cart_infos = [] inq = "select * from crmeb.eb_store_order_cart_info where oid = #{order['id']};" queryRds(inq).each {|r| cart_infos += [r['cart_info']]} #用temp_id作为键值重组carts, 每个包邮组装入一个cart carts = {} cart_infos.each do |cart_info| item = JSON.parse cart_info temp_id = item['productInfo']['temp_id'] carts.store temp_id, [] if carts[temp_id].nil? cart = carts[temp_id] cart += [item] carts.store temp_id, cart end return cartsenddef fork_order_by_carts order, carts fields=['id','order_id','uid','real_name','user_phone','user_address','cart_id','freight_price','total_num','total_price','total_postage','pay_price','pay_postage','deduction_price','coupon_id','coupon_price','paid','pay_time','pay_type','add_time','status','refund_status','refund_reason_wap_img','refund_reason_wap_explain','refund_reason_time','refund_reason_wap','refund_reason','refund_price','delivery_name','delivery_type','delivery_id','gain_integral','use_integral','back_integral','mark','is_del','unique','remark','mer_id','is_mer_check','combination_id','pink_id','cost','seckill_id','bargain_id','verify_code','store_id','shipping_type','clerk_id','is_channel','is_remind','is_system_del'] sqls = ['use crmeb;'] (carts.size-1).times do |idx| #insert into 表1(字段1,字段2,字段3) select 字段1,字段2,字段3 from 表1 where id=1 #如果不用"`",则unique字段将导致出错 sql = "insert into crmeb.eb_store_order (" fields[1..fields.length-1].each { |field| sql += " `#{field}`," } sql[sql.length-1] = ')' #remove last comma sql += " select " (1..fields.length-1).each do |i| field = fields[i] case field when 'unique' sql += " getUUID(uuid())," when 'order_id' sql += " 'TEMP-#{order['uid']}-#{order['id']}-#{idx}'," #商品数、总价、运费、等,不从原始订单继承 when 'total_num', 'total_price', 'total_postage', 'pay_price', 'pay_postage', 'deducation_price' sql += " 0," else sql += " `#{field}`," end end sql[sql.length-1] = ' ' sql += " from crmeb.eb_store_order where id = #{order['id']};" sqls += [sql] end #sqls.each { |sql| puts sql } commitTrans sqls #get all forked orders forked_orders = [order] inq = "select * from crmeb.eb_store_order where order_id like 'TEMP-#{order['uid']}-#{order['id']}-%'" queryRds(inq).each { |r| forked_orders += [r] } #建立路线数组,将所有的购物车及订单Hash化 routes = [] orders = {} item_list = {} appendix = {} idx = 0 carts.each do |route,items| routes += [route] orders.store route, forked_orders[idx] #每条线路对应的订单 tmp_list = [] items.each { |item| tmp_list += [item['id']]} item_list.store route, tmp_list #每条线路下的购物车项目 appendix.store route, "#{idx}" #子单号 idx += 1 end #用原生订单的内部id生成订单编码的主要部分 order_code_base = sprintf("%08d",order['id']) #遍历每条线路,更新订单,更新item中的对应订单号 routes.each do |route| this_cart = carts[route] this_order = orders[route] this_list = item_list[route] #update key fields: order_id, cart_id, total_num, total_price in eb_store_order order_id = "FCS-#{order_code_base}-#{appendix[route]}" cart_id = this_list.to_json total_num = 0 total_price = 0 this_cart.each do |item| total_num += item['cart_num'] total_price += item['truePrice'] end inq = "update crmeb.eb_store_order set order_id = '#{order_id}', cart_id = '#{cart_id}', total_num = #{total_num}, total_price = #{total_price} where id = #{this_order['id']};" queryRds inq #update order_id in eb_store_order_cart_info this_cart.each do |item| inq = "update eb_store_order_cart_info set oid = #{this_order['id']} where cart_id = #{item['id']};" queryRds inq end endend#风险:重编码完成时,用户对旧订单号提交退款或评论,有可能会有问题(待测试取决于是否采用cart id)#需要在一个事务中锁住,避免对订单重新编码时,用户同时修改def split_orders orders orders.each do |order| next if leave_alone? order carts = group_cart_items order #如果是自提订单,或者只有一个模版(单一商品也必然只有一个模版),直接改编码后下一条 if pickup_able?(order) || carts.size == 1 rename_order_code order else #puts "order# #{order['id']} will be forked" fork_order_by_carts order, carts end endendorders = get_splitable_orders_during stime, etimesplit_orders orders