`
南京老油条
  • 浏览: 55817 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

电商网站订单系统设计

阅读更多

 

原文 

http://oldfritter.iteye.com/blog/2103337

200行代码搞定订单系统主体

概述

订单更新绝大多数是控制订单状态的改变.在此,我将订单状态抽象成点(order_status),改变订单状态的方法称为operation,operation不直接与订单相关,只与order_status相关.

 

 

当订单状态发生改变时,订单包含的操作便自然变更为新的可执行操作

 

样例

以下是一个电商网站的状态流转图

  

 

我是这样做模型层的

class Order < ActiveRecord::Base
  belongs_to :order_status
  has_many :operations, through: :order_status


  def do operation, &block
   return 'No method match' unless operations.find_by(name: operation)
    block_given? ? send(operation, &block) : set_order_status(send(operation))
  end
    
  # 提醒买家,订单将要被自动确认收货,如果尚未到货,请点击延长收货时间
  # email或者短信
  def message_notice
    
  end
  
  private
  
  # 用户支付货款至my_site
  def pay_my_site &block
    set_order_status order_status.do __method__.to_s and save
    "#{yield}?target_uuid=#{uuid}&target_type=trade&amount=#{payment_amount}&paid_by=#{payment_way.name}&foo_type=Order" if block_given?#根据block返回一个支付页面
  end
  
  # 取消订单
  def cancel
    order_status.do __method__.to_s
  end
  
  # 系统自动取消订单
  def auto_cancel
    order_status.do __method__.to_s if operations.find_by(name: operation)
  end
  
  # 确认到款
  def payment_receive
    order_status.do __method__.to_s if spill?
  end
  
  # 取消并退款
  def cancel_with_refund
    refund_money
    order_status.do __method__.to_s
  end
  
  # 发货
  def shipping
    delay(run_at: 3.day.from_now).message_notice
    set_received_at and order_status.do __method__.to_s
  end
  
  # 退款
  def refund
    refund_money
    order_status.do __method__.to_s
  end
  
  # 确认收货
  def receive
    order_status.do __method__.to_s
  end
  
  # 延长收货时间
  def extend_time
    update_attribute :received_at, received_at + 7.days.from_now
    order_status.do __method__.to_s
  end
  
  # 到期自动确认收货(默认7天)
  def auto_receive
    order_status.do __method__.to_s
  end
  
  # 退货/换货
  def return_goods
    order_status.do __method__.to_s
  end
end

 

 

class OrderStatus < ActiveRecord::Base
  
  has_many :operations
  
  def do operation
    operations.find_by(name: operation).do_operation
  end
  
end

 

 

class Operation < ActiveRecord::Base
  
  belongs_to :order_status
  belongs_to :result, class_name: :OrderStatus
  
  def do_operation
    result
  end
  
end

 

 

简单的状态变迁列表

 

 

我的初始化脚本(rake)

 

 

#encoding: utf-8
namespace :order_status do

  task init: :environment do
    Operation.delete_all
    File.open(File.expand_path('../../../docs/order_status', __FILE__)).each_line do |line|
      arr = line.split(/[\t\n]+/).first(7)
      order_status = OrderStatus.find_by name: arr[1]
      order_status = OrderStatus.create(name: arr[1]) if order_status.blank?
      result = OrderStatus.find_by name: arr[5]
      result = OrderStatus.create(name: arr[5]) if result.blank?

      Operation.create({
        name: arr[3],
        order_status: order_status,
        result: result,
        operator: arr[6]
      })
      
    end
  end
  
end

 

 

 

 

控制器是这样设计的

 

 

class CartsController < ApplicationController
  before_action :set_order, only: [:to_pay_page, :operate_by_buyer, :operate_by_seller, :buyer_operations,:seller_operations]

  # redirect_to pay_page
  # params: :id => order.id, :payment_name => 'alipay'
  # 需检测是否已经选择了支付方式
  def to_pay_page
    @order.payment_way = BasicSettings::PaymentWay.find_by name: params[:payment_name]
    pay_params = Proc.new {url = '/pays/pay'}
    redirect_to @order.do('pay_my_site', &pay_params)
  end

 # 买家操作
   # params: order.id, operation
   def operate_by_buyer
     if params[:operation] == 'pay_my_site'
       return redirect_to select_payment_carts_path(id: @order.id)
     end
     @order.do params[:operation] if @order.operations.find_by(operator: 'buyer', name: params[:operation])
     redirect_to controller: 'my/orders', action: 'index'
   end 

  # 卖家操作
  # params: order.id, operation
  def operate_by_seller
    @order.do params[:operation] if @order.operations.find_by(operator: 'seller', name: params[:operation])
    redirect_to controller: params[:controller], action: params[:action]
  end

  # 买家可执行的操作
  def buyer_operations
    render json: @order.operations.where(operator: 'buyer').collect{|t|t.name}.to_json
  end

  # 卖家可执行的操作
  def seller_operations
    render json: @order.operations.where(operator: 'seller').collect{|t|t.name}.to_json
  end

  private
  def set_order
    @order = Slms::Order.find_by id: params[:id]
  end

end

 

 

 

 

至此基本完工

 

注: 为了便于开发,order_status和operation都存在数据库中,部署生产环境时需缓存

  • 大小: 3.8 KB
  • 大小: 44.4 KB
  • 大小: 195.5 KB
分享到:
评论

相关推荐

    数据库系统课程设计.txt

    数据库课程设计数据库课程设计数据库课程设计数据库课程设计

    外汇经纪CRM软件,全球前10强生产商排名及市场份额.docx

    外汇经纪CRM软件,全球前10强生产商排名及市场份额

    BS EN 60068-2-5-2011.pdf

    BS EN 60068-2-5-2011.pdf

    MS2磁化率系统操作手册

    MS2磁化率系统操作手册

    2016年美赛A~F题特等奖论文合集.pdf

    大学生,数学建模,美国大学生数学建模竞赛,MCM/ICM,历年美赛特等奖O奖论文

    自动化测试装置

    自动化测试装置

    大华网络硬盘录像机用户手册.pdf

    大华网络硬盘录像机用户手册

    大型民营企业数字化转型综合解决方案.pptx

    大型民营企业数字化转型综合解决方案.pptx

    2024年中国5G智能手机背光模组行业研究报告.docx

    2024年中国5G智能手机背光模组行业研究报告

    node-v8.15.0-sunos-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    海关商品编码/HS编码表

    用于海关申报商品编码/HS编码信息

    奥维互动地图软件安装包

    奥维互动地图软件安装包

    《统计与数据分析基础》02数据采集.pptx

    《统计与数据分析基础》02数据采集

    node-v9.11.2-linux-s390x.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    BIM+ESE数字化:低碳园区智慧能源数字化管理解决方案.pptx

    BIM+ESE数字化:低碳园区智慧能源数字化管理解决方案.pptx

    node-v11.5.0-linux-armv6l.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

    各城市-人口就业和工资数据(1978-2022年).xlsx

    样例数据及详细介绍:https://blog.csdn.net/li514006030/article/details/138510754

    广东工业大学-2010计算机系统结构试题附答案考试试题回忆版以及答案解析.doc

    此试题是考试后回忆版本,你会发现是惊喜。恭喜你考个好成绩。

    德勤:2024年技术趋势报告.pdf

    德勤:2024年技术趋势报告.pdf

    node-v9.9.0-linux-x86.tar.xz

    Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。

Global site tag (gtag.js) - Google Analytics