From 7776ab29ed198f8a7e749bf2a8d42c405f94e3f1 Mon Sep 17 00:00:00 2001 From: qyzh Date: Thu, 13 May 2021 11:15:54 +0800 Subject: [PATCH] coinchange chart --- app/controllers/wallets_controller.rb | 57 ++++++++++++++++-- app/models/user.rb | 6 +- app/views/wallets/balance_chart.json.jbuilder | 31 ++++++++++ config/routes.rb | 1 + public/images/undefined | Bin 0 -> 9928 bytes 5 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 app/views/wallets/balance_chart.json.jbuilder create mode 100644 public/images/undefined diff --git a/app/controllers/wallets_controller.rb b/app/controllers/wallets_controller.rb index 064db910..1b811acc 100644 --- a/app/controllers/wallets_controller.rb +++ b/app/controllers/wallets_controller.rb @@ -1,5 +1,5 @@ class WalletsController < ApplicationController - before_action :require_login + before_action :require_login, except: :balance_chart def balance user = User.find_by_id(params[:id]) @@ -20,9 +20,58 @@ class WalletsController < ApplicationController sort = params[:sort_by] || "created_at" sort_direction = params[:sort_direction] || "desc" - scope = scope.reorder("#{sort} #{sort_direction}") + scope = scope.reorder("#{sort} #{sort_direction}") unless scope.nil? - @total = scope.length - @coin_changes = kaminari_paginate(scope) + @total = 0 + @total = scope.length unless scope.nil? + @coin_changes = kaminari_paginate(scope) unless scope.nil? + end + + def balance_chart + user = User.find_by_id(params[:id]) + @wallet = user.get_wallet + scope = CoinChange.where('to_wallet_id = ? OR from_wallet_id = ?', @wallet.id, @wallet.id) + t1 = Time.now + t2 = Time.new(t1.year, t1.month, t1.day-6) + @balance_chart_data = scope.where('created_at > ? AND created_at < ?', t2, t1) + @balance_chart_array = to_array(@balance_chart_data, @wallet.id) + end + + private + def to_array(data, id) + t1 = Time.now + start_time = Time.new(t1.year, t1.month, t1.day-6) + end_time = Time.new(start_time.year, start_time.month, start_time.day+1) + + income = Array.new(7, 0) # 收入、支出 + outcome = Array.new(7, 0) + date = Array.new(7) + date[0] = Time.new(start_time.year, start_time.month, start_time.day) + index = 0 + + data.each do |i| + until (i.created_at >= start_time) && (i.created_at < end_time) + index += 1 + start_time = end_time + end_time = Time.new(start_time.year, start_time.month, start_time.day + 1) + date[index] = Time.new(start_time.year, start_time.month, start_time.day) + end + + if i.from_wallet_id == id + outcome[index] += i.amount + else + income[index] += i.amount + end + + end + + until end_time >= Time.now + index += 1 + start_time = end_time + end_time = Time.new(start_time.year, start_time.month, start_time.day + 1) + date[index] = Time.new(start_time.year, start_time.month, start_time.day) + end + + Array[income, outcome, date] end end diff --git a/app/models/user.rb b/app/models/user.rb index 15e47cb7..39d32b0b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -767,13 +767,13 @@ class User < Owner # end # end if wallet.nil? - Wallet.wallet_lock.lock + Wallet.transaction(isolation: :serializable) do if wallet.nil? create_wallet(balance: 100) reason = "系统初始赠送" - CoinChange.create(amount: amount, reason: reason, to_wallet_id: wallet.id) + CoinChange.create(amount: 100, reason: reason, to_wallet_id: wallet.id) end - Wallet.wallet_lock.unlock + end end wallet end diff --git a/app/views/wallets/balance_chart.json.jbuilder b/app/views/wallets/balance_chart.json.jbuilder new file mode 100644 index 00000000..ba57d0f7 --- /dev/null +++ b/app/views/wallets/balance_chart.json.jbuilder @@ -0,0 +1,31 @@ +# json.income do +# json.array! (0..6).each do |i| +# json.amount @balance_chart_array[0][i] +# json.date @balance_chart_array[2][i] +# end +# end +# json.outcome do +# json.array! (0..6).each do |i| +# json.amount @balance_chart_array[1][i] +# json.date @balance_chart_array[2][i] +# end +# end +json.array! (0..1).each do |index| + if index == 0 + json.label '收入' + json.data do + json.array! (0..6).each do |i| + json.primary @balance_chart_array[2][i] + json.secondary @balance_chart_array[0][i] + end + end + else + json.label '支出' + json.data do + json.array! (0..6).each do |i| + json.primary @balance_chart_array[2][i] + json.secondary @balance_chart_array[1][i] + end + end + end +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index b450c11f..67a3386f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -26,6 +26,7 @@ Rails.application.routes.draw do scope '/api' do get 'wallets/balance' get 'wallets/coin_changes' + get 'wallets/balance_chart' get 'log/list', to: 'log#list' # post 'log/download', to: 'log#download' diff --git a/public/images/undefined b/public/images/undefined new file mode 100644 index 0000000000000000000000000000000000000000..b2478a82122713efa732225c84af361f152266d8 GIT binary patch literal 9928 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 Ztzl9D?#N&G|NL7fE2#vk5&shSe*i-0!jk|1 literal 0 HcmV?d00001