Commit 843c69a7 by ivan Lan

Improve routes & controller for customer

parent 3735d662
...@@ -79,7 +79,7 @@ module Shotengai ...@@ -79,7 +79,7 @@ module Shotengai
def merchant_routes def merchant_routes
product, order = @product.underscore, @order.underscore product, order = @product.underscore, @order.underscore
" "
namespace :#{@namespace.to_sym} do namespace :#{@namespace} do
resources :#{product.pluralize}, shallow: true do resources :#{product.pluralize}, shallow: true do
member do member do
post :put_on_shelf post :put_on_shelf
...@@ -103,29 +103,26 @@ module Shotengai ...@@ -103,29 +103,26 @@ module Shotengai
def customer_routes def customer_routes
product, order = @product.underscore, @order.underscore product, order = @product.underscore, @order.underscore
" "
namespace :#{@namespace.to_sym} do namespace :#{@namespace} do
resources :#{product.pluralize}, shallow: true, only: [:index, :show] do resources :#{product.pluralize}, shallow: true, only: [:index, :show] do
resources :#{product}_series, only: [:index, :show] resources :product_series, only: [:index, :show]
end end
resources :#{product}_snapshots, only: [:index, :show] resources :#{product}_snapshots, only: [:index, :show]
resources :#{order.pluralize}, shallow: true do # order_cart
resource :cart, only: [:show, :update] do
resources :#{product}_snapshots
end
resources :#{order.pluralize} do
resources :#{product}_snapshots
member do member do
post :pay post :pay
post :cancel post :confirm
post :get_it
end
collection do
get :cart
post :create_directly
post :add_to_cart
end end
resources :#{product}_snapshots, only: [:index, :create]
end end
end" end
"
end end
end end
end end
end end
\ No newline at end of file
...@@ -29,14 +29,14 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -29,14 +29,14 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
@orders = create_list(:order, 3, buyer: @user) @orders = create_list(:order, 3, buyer: @user)
@order_1 = @orders.first @order_1 = @orders.first
@cart = @order_1.class.cart_class.create!(buyer: @user) @cart = @user.order_cart
@snapshot_1.update!(order: @order_1) @snapshot_1.update!(order: @order_1)
@snapshot_other.update!(order: @order_1) @snapshot_other.update!(order: @order_1)
@snapshot_2.update!(order_cart: @cart) @snapshot_2.update!(order_cart: @cart)
end end
path "/#{namespace}/orders/cart" do path "/#{namespace}/cart" do
get(summary: '用户 购物车') do get(summary: '用户 购物车') do
produces 'application/json' produces 'application/json'
...@@ -52,7 +52,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -52,7 +52,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
end end
end end
path "/#{namespace}/orders/add_to_cart" do path "/#{namespace}/cart/product_snapshots" do
post(summary: '用户 添加快照至购物车( using series_id & count )') do post(summary: '用户 添加快照至购物车( using series_id & count )') do
produces 'application/json' produces 'application/json'
...@@ -63,9 +63,9 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -63,9 +63,9 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
let(:buyer_type) { @user.class.name } let(:buyer_type) { @user.class.name }
parameter :snapshot, in: :body, schema: { parameter :product_snapshot, in: :body, schema: {
type: :object, properties: { type: :object, properties: {
snapshot: { product_snapshot: {
type: :object, properties: { type: :object, properties: {
shotengai_series_id: { type: :integer }, shotengai_series_id: { type: :integer },
count: { type: :integer }, count: { type: :integer },
...@@ -75,9 +75,9 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -75,9 +75,9 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
} }
response(201, description: 'Create snapshot and add it to the cart') do response(201, description: 'Create snapshot and add it to the cart') do
let(:snapshot) { let(:product_snapshot) {
{ {
snapshot: { product_snapshot: {
shotengai_series_id: @series_1.id, shotengai_series_id: @series_1.id,
count: 10, count: 10,
} }
...@@ -177,7 +177,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -177,7 +177,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
end end
path "/#{namespace}/orders/create_directly" do path "/#{namespace}/orders" do
post(summary: 'create order') do post(summary: 'create order') do
produces 'application/json' produces 'application/json'
consumes 'application/json' consumes 'application/json'
...@@ -193,7 +193,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -193,7 +193,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
address: { type: :string }, address: { type: :string },
user_remark: { type: :text }, user_remark: { type: :text },
}, },
snapshot: { snapshots: {
type: :object, properties: { type: :object, properties: {
shotengai_series_id: { type: :integer }, shotengai_series_id: { type: :integer },
count: { type: :integer }, count: { type: :integer },
...@@ -210,7 +210,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -210,7 +210,7 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
address: 'This is an special address.', address: 'This is an special address.',
user_remark: 'user remark ...' user_remark: 'user remark ...'
}, },
snapshot: { snapshots: {
shotengai_series_id: @series_1.id, shotengai_series_id: @series_1.id,
count: 10, count: 10,
} }
...@@ -303,14 +303,8 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -303,14 +303,8 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
} }
end end
end end
end
path "/#{namespace}/orders/{id}/pay" do
parameter :id, in: :path, type: :integer
let(:id) { @order_1.id }
post(summary: '用户 支付订单') do delete(summary: '用户 取消未支付订单') do
produces 'application/json' produces 'application/json'
consumes 'application/json' consumes 'application/json'
parameter :buyer_type, in: :query, type: :string parameter :buyer_type, in: :query, type: :string
...@@ -320,18 +314,17 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -320,18 +314,17 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
produces 'application/json' produces 'application/json'
consumes 'application/json' consumes 'application/json'
response(200, description: 'successful') do response(204, description: 'successful') do
it { expect(JSON.parse(response.body)['pay_time']).not_to be_nil }
end end
end end
end end
path "/#{namespace}/orders/{id}/cancel" do path "/#{namespace}/orders/{id}/pay" do
parameter :id, in: :path, type: :integer parameter :id, in: :path, type: :integer
let(:id) { @order_1.id } let(:id) { @order_1.id }
post(summary: '用户 取消未支付订单') do post(summary: '用户 支付订单') do
produces 'application/json' produces 'application/json'
consumes 'application/json' consumes 'application/json'
parameter :buyer_type, in: :query, type: :string parameter :buyer_type, in: :query, type: :string
...@@ -342,17 +335,12 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta ...@@ -342,17 +335,12 @@ RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, ta
produces 'application/json' produces 'application/json'
consumes 'application/json' consumes 'application/json'
response(200, description: 'successful') do response(200, description: 'successful') do
it { expect(JSON.parse(response.body)['status']).to eq('canceled') } it { expect(JSON.parse(response.body)['pay_time']).not_to be_nil }
end
response(400, description: 'failed , you can cancel a order which status is unpaid') do
before { @order_1.pay! }
it { expect(response.status).to eq(400) }
end end
end end
end end
path "/#{namespace}/orders/{id}/get_it" do path "/#{namespace}/orders/{id}/confirm" do
parameter :id, in: :path, type: :integer parameter :id, in: :path, type: :integer
let(:id) { @order_1.id } let(:id) { @order_1.id }
......
...@@ -2,6 +2,7 @@ require 'swagger_helper' ...@@ -2,6 +2,7 @@ require 'swagger_helper'
namespace = '<%= @namespace %>' namespace = '<%= @namespace %>'
RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_examples: true, tags: ["#{namespace} API", "product_snapshots"] do RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_examples: true, tags: ["#{namespace} API", "product_snapshots"] do
before do before do
@user = create(:user)
@products = create_list(:product, 3) @products = create_list(:product, 3)
@product_1 = @products.first @product_1 = @products.first
...@@ -27,7 +28,7 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example ...@@ -27,7 +28,7 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example
@snapshot_other = create(:product_snapshot, series: @series_2, count: 5) @snapshot_other = create(:product_snapshot, series: @series_2, count: 5)
@order = create(:order) @order = create(:order)
@cart = Order::Cart.create! @cart = @user.order_cart
@snapshot_1.update!(order: @order) @snapshot_1.update!(order: @order)
@snapshot_other.update!(order: @order) @snapshot_other.update!(order: @order)
@snapshot_2.update!(order_cart: @cart) @snapshot_2.update!(order_cart: @cart)
...@@ -36,7 +37,11 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example ...@@ -36,7 +37,11 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example
path "/#{namespace}/product_snapshots" do path "/#{namespace}/product_snapshots" do
get(summary: '用户 快照列表 三参数可仍以任意组合') do get(summary: '用户 快照列表 三参数可仍以任意组合') do
parameter :buyer_type, in: :query, type: :string
parameter :buyer_id, in: :query, type: :integer
let(:buyer_id) { @user.id }
let(:buyer_type) { @user.class.name }
parameter :page, in: :query, type: :string parameter :page, in: :query, type: :string
parameter :per_page, in: :query, type: :string parameter :per_page, in: :query, type: :string
parameter :series_id, in: :query, type: :integer parameter :series_id, in: :query, type: :integer
...@@ -73,6 +78,11 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example ...@@ -73,6 +78,11 @@ RSpec.describe "#{namespace}/product_snapshots", type: :request, capture_example
end end
path "/#{namespace}/product_snapshots/{id}" do path "/#{namespace}/product_snapshots/{id}" do
parameter :buyer_type, in: :query, type: :string
parameter :buyer_id, in: :query, type: :integer
let(:buyer_id) { @user.id }
let(:buyer_type) { @user.class.name }
let(:id) { @snapshot_1.id } let(:id) { @snapshot_1.id }
get(summary: '商户 商品快照的详情') do get(summary: '商户 商品快照的详情') do
......
...@@ -17,17 +17,18 @@ module Shotengai ...@@ -17,17 +17,18 @@ module Shotengai
autoload :Base, 'shotengai/controllers/base' autoload :Base, 'shotengai/controllers/base'
module Merchant module Merchant
autoload :ProductsController, 'shotengai/controllers/merchant/products_controller' autoload :ProductsController, 'shotengai/controllers/merchant/products_controller'
autoload :ProductSnapshotsController, 'shotengai/controllers/merchant/product_snapshots_controller' autoload :ProductSnapshotsController, 'shotengai/controllers/merchant/product_snapshots_controller'
autoload :ProductSeriesController, 'shotengai/controllers/merchant/product_series_controller' autoload :ProductSeriesController, 'shotengai/controllers/merchant/product_series_controller'
autoload :OrdersController, 'shotengai/controllers/merchant/orders_controller' autoload :OrdersController, 'shotengai/controllers/merchant/orders_controller'
end end
module Customer module Customer
autoload :ProductsController, 'shotengai/controllers/customer/products_controller' autoload :ProductsController, 'shotengai/controllers/customer/products_controller'
autoload :ProductSnapshotsController, 'shotengai/controllers/customer/product_snapshots_controller' autoload :ProductSnapshotsController, 'shotengai/controllers/customer/product_snapshots_controller'
autoload :ProductSeriesController, 'shotengai/controllers/customer/product_series_controller' autoload :ProductSeriesController, 'shotengai/controllers/customer/product_series_controller'
autoload :OrdersController, 'shotengai/controllers/customer/orders_controller' autoload :OrdersController, 'shotengai/controllers/customer/orders_controller'
autoload :CartsController, 'shotengai/controllers/customer/carts_controller'
end end
end end
end end
...@@ -33,11 +33,11 @@ module Shotengai ...@@ -33,11 +33,11 @@ module Shotengai
) )
end end
def buy_it_immediately snapshot_params, order_params def buy_it_immediately snapshots_params, order_params
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
order = self.#{collection_name}.create!(order_params) order = self.#{collection_name}.create!(order_params)
Shotengai::Series.find(snapshot_params[:shotengai_series_id]).snapshots.create!( snapshots_params && Shotengai::Series.find(snapshots_params[:shotengai_series_id]).snapshots.create!(
snapshot_params.merge({ snapshots_params.merge({
shotengai_order: order shotengai_order: order
}) })
) )
......
module Shotengai
module Controller
module Customer
class CartsController < Shotengai::Controller::Base
self.resources = Cart
self.template_dir = 'shotengai/customer/cart'
before_action :buyer_auth
before_action :set_resource
# NOTE: before_action would not keep the super methods' "only" condition
remove_actions :index, :create, :destroy
default_query do |resource, params|
end
index_query do |resource, params|
end
private
def buyer_auth
@buyer = params[:buyer_type].constantize.find(params[:buyer_id])
end
def set_resource
@resource = @buyer.order_cart
end
def resource_params
params.require(resource_key).permit(
:address, :customer_remark,
incr_snapshot_ids: [], gone_snapshot_ids: []
)
end
def snapshot_params
params.require(:snapshot).permit(
:shotengai_series_id, :count
)
end
def edit_only_unpaid
raise Shotengai::WebError.new('订单已支付,不可修改。', '-1', 403) unless @resource.unpaid?
end
end
end
end
end
...@@ -7,8 +7,6 @@ module Shotengai ...@@ -7,8 +7,6 @@ module Shotengai
before_action :buyer_auth before_action :buyer_auth
before_action :edit_only_unpaid, only: [:update] before_action :edit_only_unpaid, only: [:update]
# before_action would not keep the super methods' "only" condition
skip_before_action :set_resource, only: [:cart, :add_to_cart, :create_directly]
remove_actions :destroy remove_actions :destroy
...@@ -18,19 +16,9 @@ module Shotengai ...@@ -18,19 +16,9 @@ module Shotengai
index_query do |resource, params| index_query do |resource, params|
resource.status_is(params[:status]) resource.status_is(params[:status])
end end
def cart
@resource = @buyer.order_cart
respond_with @resource, template: "shotengai/customer/cart/show"
end
def add_to_cart def create # Use :series_id & :count
snapshot = @buyer.add_to_order_cart(snapshot_params) @resource = @buyer.buy_it_immediately(snapshots_params, resource_params)
respond_with @resource = snapshot, template: 'shotengai/customer/snapshots/show', status: 201
end
def create_directly # using :series_id & :count
@resource = @buyer.buy_it_immediately(snapshot_params, resource_params)
respond_with @resource, template: "#{@@template_dir}/show", status: 201 respond_with @resource, template: "#{@@template_dir}/show", status: 201
end end
...@@ -39,13 +27,13 @@ module Shotengai ...@@ -39,13 +27,13 @@ module Shotengai
respond_with @resource, template: "#{@@template_dir}/show" respond_with @resource, template: "#{@@template_dir}/show"
end end
def cancel def destroy
@resource.cancel! @resource.cancel!
respond_with @resource, template: "#{@@template_dir}/show" head 204
end end
def get_it def confirm
@resource.get_it @resource.confirm!
respond_with @resource, template: "#{@@template_dir}/show" respond_with @resource, template: "#{@@template_dir}/show"
end end
...@@ -55,14 +43,14 @@ module Shotengai ...@@ -55,14 +43,14 @@ module Shotengai
end end
def resource_params def resource_params
params.require(resource_key).permit( params[resource_key] && params.require(resource_key).permit(
:address, :customer_remark, :address, :customer_remark,
incr_snapshot_ids: [], gone_snapshot_ids: [] incr_snapshot_ids: [], gone_snapshot_ids: []
) )
end end
def snapshot_params def snapshots_params
params.require(:snapshot).permit( params[:snapshots] && params.require(:snapshots).permit(
:shotengai_series_id, :count :shotengai_series_id, :count
) )
end end
......
...@@ -5,8 +5,8 @@ module Shotengai ...@@ -5,8 +5,8 @@ module Shotengai
self.resources = ProductSnapshot self.resources = ProductSnapshot
self.template_dir = 'shotengai/customer/snapshots/' self.template_dir = 'shotengai/customer/snapshots/'
before_action :edit_only_unpaid, only: [:update, :destroy] before_action :buyer_auth
before_action :edit_only_unpaid, except: [:index, :show, :create]
default_query do |resource, params| default_query do |resource, params|
# /orders/:order_id/snapshots # /orders/:order_id/snapshots
# /series/:series_id/snapshots # /series/:series_id/snapshots
...@@ -21,19 +21,22 @@ module Shotengai ...@@ -21,19 +21,22 @@ module Shotengai
params[:in_cart] ? resource.in_cart : resource.in_order params[:in_cart] ? resource.in_cart : resource.in_order
end end
# 不指定 order 时,默认创建在 cart 中
# TODO: WARNING: snapshots
def create def create
buyer_type, buyer_id = resource_params.values_at(:buy_type, :buyer_id) order_or_cart = Shotengai::Order.find_by_id(params[:order_id]) || @buyer.order_cart
@buyer = buyer_type.constantize.find(buyer_id) if buyer_type && buyer_id @resource = order_or_cart.product_snapshots.create!(resource_params)
@resource = default_resources.create!(
resource_params.merge(buyer: buyer)
)
respond_with @resource, template: "#{@@template_dir}/show", status: 201 respond_with @resource, template: "#{@@template_dir}/show", status: 201
end end
private private
def buyer_auth
@buyer = params[:buyer_type].constantize.find(params[:buyer_id])
end
def resource_params def resource_params
params.require(resource_key).permit( params.require(resource_key).permit(
:count, :shotengai_series_id, :buyer_id, :buy_type :count, :shotengai_series_id
) )
end end
......
...@@ -52,7 +52,7 @@ module Shotengai ...@@ -52,7 +52,7 @@ module Shotengai
transitions from: :paid, to: :delivering transitions from: :paid, to: :delivering
end end
event :get_it, after: :set_receipt_time do event :confirm, after: :set_receipt_time do
transitions from: :delivering, to: :received transitions from: :delivering, to: :received
end end
# event :evaluate { # event :evaluate {
...@@ -102,8 +102,7 @@ module Shotengai ...@@ -102,8 +102,7 @@ module Shotengai
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
ids.each { |id| ids.each { |id|
# using update(shotengai_order_id: id) can not get self.id before save # using update(shotengai_order_id: id) can not get self.id before save
Shotengai::Snapshot.find(id).update!(shotengai_order_id: self.id) Shotengai::Snapshot.find(id).update!(shotengai_order: self)
} }
end end
end end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment