需求描述:现有项目,需实现外卖订单,商城物流订单,代驾订单,酒店入住,以及其他服务类订单的逻辑关系,不同逻辑不同实现
首先:按关系建立主体表一张,扩展表多张,扩展表使用orderId关联主体表
drop table if exists t_order; /*==============================================================*/ /* Table: t_order */ /*==============================================================*/ create table t_order ( id varchar(20) not null, coupon_id int(11) comment '订单优惠券', user_id int(11) comment '用户id', shop_id int(11) comment '关联店铺', shop_index int(11) default 1 comment '店铺今日的订单序号', type int(11) default 0 comment ' 订单类型,0外卖订单、1物流订单(积分商城)、2跑腿代送、3、代驾订单、4酒店入住订单,5服务类订单', buyer_remark varchar(255) comment '买家备注', sale_remark varchar(255) comment '卖家备注', custom_status int(3) default 0 comment '客户状态,0正常,1已读,-10删除', sale_status int(3) default 0 comment '卖家状态,0正常,1已读,-10删除', status int(3) default 0 comment '订单结转状态:0处理红、10已完成、11已取消', business_order_no varchar(20) comment '业务订单号,支付', business_order_refund_no varchar(20) comment '业务订单号,退款', order_total_amount int(11) default 1 comment '订单商品总数', payment_status int(11) default 0 comment '支付状态,0未支付,1已支付', payment_type int(11) default 0 comment '支付方式,0支付宝,1微信,2余额', refund_price double(11, 2) default 0 comment '退款金额', coupon_sum double(11, 2) default 0 comment '优惠金额', discount_sum double(11, 2) default 0 comment '活动折扣金额', order_sum double(11, 2) default 0 comment '订单金额', actual_payment_sum double(11, 2) default 0 comment '实际支付金额', platform_commission double(11, 2) unsigned default 0 comment '平台佣金', sale_income double(11, 2) default 0 comment '商家收入', is_refund int(1) default 0 comment '订单是否退款,0否,1是', is_comment int(1) default 0 comment '订单是否评论,0否,1是', is_report int(1) default 0 comment '订单是否报备,0否,1是', report_content varchar(255) comment '报备原因内容', cancel_content varchar(255) comment '取消原因内容', end_time datetime comment '结束时间', receive_time datetime comment '接单时间', pay_time datetime comment '支付时间', create_time datetime, primary key (id) ); alter table t_order comment '订单主体'; drop table if exists t_order_take_out_detail; /*==============================================================*/ /* Table: t_order_take_out_detail */ /*==============================================================*/ create table t_order_take_out_detail ( id int not null, order_id varchar(20), status int(3) default 0 comment '订单结转状态:0新订单、1待接单、2备餐中、3待配送、4待取餐、5配送中、10已完成、11已取消', run_status int(3) default 0 comment '外卖配送结转状态:0待抢单(2|3),1待派单(转单未分配的订单列表),2待取货,3待送达,10已完成', delivery_distance double(11, 2) comment '配送距离', delivery_duration double(11, 2) default 30.00 comment '配送时间', delivery_price double(11, 2) default 0 comment '配送价格', package_price double(11, 2) default 0 comment '包装费', tableware_num int(11) default 0 comment '餐具数量', is_out_time int(1) default 0 comment '是否配送超时,0否,1是', take_meal_time datetime comment '取餐时间', prepare_meal_time datetime comment '备餐完成时间', primary key (id) ); alter table t_order_take_out_detail comment '外卖订单详细,与订单 1:1关系'; drop table if exists t_order_logistics_detail; /*==============================================================*/ /* Table: t_order_logistics_detail */ /*==============================================================*/ create table t_order_logistics_detail ( id int not null, order_id varchar(20), status int(3) default 0 comment '订单结转状态:0新订单、1待发货、2待收货、10已完成、11已取消', delivery_price double(11, 2) default 0 comment '配送价格', is_out_time int(1) default 0 comment '是否配送超时,0否,1是', logistics_name varchar(20) comment '物流名称', logistics_no varchar(20) comment '物流单号', integral int comment '使用积分', deducation_money double comment '抵扣金额', deliver_time datetime comment '配送时间', primary key (id) ); alter table t_order_logistics_detail comment '商城物流订单详细,与订单 1:1关系'; drop table if exists t_order_replace_drive_detail; /*==============================================================*/ /* Table: t_order_replace_drive_detail */ /*==============================================================*/ create table t_order_replace_drive_detail ( id int not null, order_id varchar(20), status int(3) default 0 comment '订单结转状态:0待接单、1待出发、2待抵达、3待结算、10已完成,11已取消', run_status int(3) default 0 comment '骑手订单,代驾执行结转状态:0待抢单(0),1待派单(转单未分配的订单列表),2待出发(1),3待抵达(2),4待结算(3),10已完成', start_addr varchar(255) comment '起始位置详细', start_location_addr varchar(255) comment '起始定位位置', start_lon double comment '起始位置经度', start_lat double comment '起始位置维度', end_addr varchar(255) comment '终点位置详细', end_location_addr varchar(255) comment '终点定位位置', end_lon double comment '终点位置经度', end_lat double comment '终点位置维度', name varchar(50) comment '姓名', tel varchar(20) comment '联系电话', car_model varchar(50) comment '汽车商标型号', car_no varchar(10) comment '车牌号', distance double comment '距离', starting_price double default 0 comment '起步价', distance_surcharge double default 0 comment '距离附加费', start_time datetime comment '出发时间', arrive_time datetime comment '抵达时间', primary key (id) ); alter table t_order_replace_drive_detail comment '代驾订单详细,与订单 1:1关系';
还有其余几张扩展表因演示处理逻辑所以不做处理
controller代码,调用订单Service层
ResponseVO responseVO = orderService.completeOrder("1234567890");
Service层处理逻辑:首先处理一些共用逻辑,如订单是否已被删除等,获取当前线程得到的方法名,进入委托调用逻辑
public ResponseVO completeOrder(String orderId) { Order order = orderMapper.selectByPrimaryKey(orderId); if (order == null) { return ResponseVO.error("订单已被删除"); } String methodname = Thread.currentThread() .getStackTrace()[1].getMethodName(); try { return (ResponseVO) invoke(methodname, order.getType(), order); } catch (Exception e) { e.printStackTrace(); return ResponseVO.error("调用异常"); } }
委托方法:
/** * 具体委托方法 * @param methodname 表示调用哪个方法 * @param type 表示使用哪个业务类,订单类型,0外卖订单、1物流订单(积分商城)、2跑腿代送、3代驾订单、4酒店入住订单,5服务类订单 * @return * @throws Exception */ private Object invoke(String methodname, int type, Object... args) throws Exception { Object objectInstance = null; // 各种类型初始化状态,获取Class switch(type){ case Constants.Order.Type.TAKE_OUT : objectInstance = orderTakeOutService; break; case Constants.Order.Type.LOGISTICS : objectInstance = orderTakeOutService; break; case Constants.Order.Type.RUN_ERRAND : objectInstance = orderTakeOutService; break; case Constants.Order.Type.REPLACE_DRIVE : objectInstance = orderTakeOutService; break; case Constants.Order.Type.HOTEL_ENTRY : objectInstance = orderTakeOutService; break; case Constants.Order.Type.SERVE : objectInstance = orderTakeOutService; break; default: throw new Exception(); } Class clazz = objectInstance.getClass(); // Method thisMethod = null; // // 方法一:获取类下的所有方法,根据方法名去匹配 // Method[] methods = clazz.getMethods(); // for (Integer i = 0; i < methods.length; i++){ // // 获取对应的方法 // if (methods[i].getName().equals(methodname)){ // Class<?>[] parameterTypes = methods[i].getParameterTypes(); // for (Integer j = 0; j < parameterTypes.length; j++) { // System.out.println("方法的第" + j + "个参数类型为:" + parameterTypes[j].getName()); // } // thisMethod = clazz.getMethod(methodname, parameterTypes); // } // } // 方法二 根据可变长入参,获取可变长入参的class类型,查询方法 Class<?>[] parameterTypes = new Class<?>[args.length]; for (Integer i = 0; i < args.length; i++) { System.out.println("1方法的第" + i + "个参数类型为:" + args[i].getClass()); parameterTypes[i] = args[i].getClass(); } Method thisMethod = clazz.getMethod(methodname, parameterTypes); // 调用方法,此处不能通过Class去newInstance,因为要获取的Service有对应的依赖注入,自己new的话是没有的 return thisMethod.invoke(objectInstance, args); }
以上代码大概分为三步,主要使用反射功能处理:
1、通过订单的类型,获取对应业务逻辑的Service类
2、获取可变长入参方法的类型数组
3、通过得到的对应Service的Class,以及入参方法的类型数组,通过getMethod()方法获取对应实例中的方法信息
4、使用invoke()调用对应类中的对应方法