educode_sales 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f53f1760e66e10622abeeb7b8487804a5905e70b6adaec22df103fccd5e91bde
4
- data.tar.gz: 5ba593e92ec3ec068cf850fcb4f5ff2ab61c47a0b3c93104649b0e38f96cc9b5
3
+ metadata.gz: d6a4ffe19355fdf757cb3714a1332b6159b0c3825f2b788cdc85c27a2ea35ce1
4
+ data.tar.gz: 31407d9b5ac98caff94bd770a06bf90c4b0326bd98a1813eb7e8405808b02d12
5
5
  SHA512:
6
- metadata.gz: 3ae71fcb67e0946049f0cbe4f3b99dc1cbc6109042726beebfa78d1b59e7b4b00d3f84d261d1f9c3d8dfcd29d4a7b9d489827225d6d45e4c1678a85d80f702cd
7
- data.tar.gz: a43d02fa863b87ae1df795af04f71080dda11153cc54c8cfeedcc43e10c2d5ab7104f598de8bdb1eb5983646ee6a6176be872b95ecc6f87973c54b602c1b7c94
6
+ metadata.gz: 3246c013b2e6a35a0fe3ed9c9fba8076000569c86e9df03b945e0a65918a25db265a63d730f1e0a9a4ccec56b9186ef9c464b8e7d6424cc71fcb7300ec941abc
7
+ data.tar.gz: 983547ec16762c558b4b5162c7c95b0cdb53530b58f74bf536a990e816954d7690539c5d033eca1baba5603939f214b34689dcfed9e5c518404d4ebf9f737b58
@@ -16,7 +16,9 @@ module EducodeSales
16
16
  end
17
17
 
18
18
  def authenticate_request
19
- unless current_user
19
+ if current_user
20
+ current_user.check_login_status(request)
21
+ else
20
22
  redirect_to login_path
21
23
  end
22
24
  end
@@ -45,7 +45,7 @@ module EducodeSales
45
45
 
46
46
  count_type = params[:count_type] || "actual_amount"
47
47
  common = Common.find_by(clazz: 'staff_type', name: '销售')
48
- names = Staff.includes(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id] }
48
+ names = Staff.includes(:user).where(job_type: common.id).map { |d| [d.user.real_name, d.id, d.role_id] }
49
49
  x_business_ids = []
50
50
  default_dates = (30.day.ago.to_date..Date.today).map { |d| d.strftime("%Y-%W") }.uniq #默认时间范围
51
51
  Business.all.each do |d|
@@ -249,6 +249,7 @@ module EducodeSales
249
249
  datasets: names.map.with_index do |name, i|
250
250
  {
251
251
  # hidden: i < 3 ? false : true,
252
+ hidden: name[2] == 11,
252
253
  label: name[0],
253
254
  data: dates.map { |d| @follow_up = FollowUp.where(staff_id: name[1], created_at: d.beginning_of_day..d.end_of_day).where.not(business: x_business_ids).count },
254
255
  backgroundColor: "#fff",
@@ -279,6 +280,7 @@ module EducodeSales
279
280
  {
280
281
  # hidden: i < 3 ? false : true,
281
282
  label: name[0],
283
+ hidden: name[2] == 11, #role_id:11 离职角色
282
284
  data: dates.map { |d|
283
285
  d = d.split("-")
284
286
  year = d[0].to_i
@@ -306,6 +308,7 @@ module EducodeSales
306
308
  {
307
309
  # hidden: i < 3 ? false : true,
308
310
  label: name[0],
311
+ hidden: name[2] == 11,
309
312
  data: dates.map { |d| @follow_up = FollowUp.where(staff_id: name[1]).where("created_at >= ? AND created_at <= ?", "#{d}-01", "#{d}-31").where.not(business: x_business_ids).count },
310
313
  backgroundColor: "#fff",
311
314
  pointBorderColor: colors[i % 15 + 1],
@@ -324,6 +327,7 @@ module EducodeSales
324
327
  {
325
328
  # hidden: i < 3 ? false : true,
326
329
  label: name[0],
330
+ hidden: name[2] == 11,
327
331
  data: dates.map { |d| @follow_up = FollowUp.where(staff_id: name[1]).where("created_at >= ? AND created_at <= ?", "#{d}-01-01", "#{d}-12-31").where.not(business: x_business_ids).count },
328
332
  backgroundColor: "#fff",
329
333
  pointBorderColor: colors[i % 15 + 1],
@@ -40,6 +40,7 @@ module EducodeSales
40
40
  staff.save unless staff.persisted?
41
41
  end
42
42
  session[:admin_id] = staff.id
43
+ staff.create_login_history(request)
43
44
  return render_success
44
45
  else
45
46
  return render_failure('账号或密码错误')
@@ -0,0 +1,26 @@
1
+ require_dependency "educode_sales/application_controller"
2
+
3
+ module EducodeSales
4
+ class UserBehaviorsController < ApplicationController
5
+ def index
6
+ respond_to do |format|
7
+ format.html do
8
+ end
9
+ format.json do
10
+ if params[:sort].present? && params[:sort][:field]
11
+ if params[:sort][:field] == 'name'
12
+ @data = LoginHistory.joins(staff: :user).order("users.lastname #{params[:sort][:order]}")
13
+ else
14
+ @data = LoginHistory.order("#{params[:sort][:field]} #{params[:sort][:order]}")
15
+ end
16
+ else
17
+ @data = LoginHistory.order(created_at: :desc)
18
+ end
19
+ @data = @data.page(params[:page]).per(params[:limit])
20
+ end
21
+ end
22
+ end
23
+
24
+
25
+ end
26
+ end
@@ -0,0 +1,5 @@
1
+ module EducodeSales
2
+ class LoginHistory < ApplicationRecord
3
+ belongs_to :staff
4
+ end
5
+ end
@@ -15,12 +15,34 @@ module EducodeSales
15
15
  has_many :sale_plans, dependent: :destroy
16
16
  has_many :staff_schools, dependent: :destroy
17
17
 
18
+ has_many :login_histories, dependent: :destroy
19
+
18
20
  has_many :market_areas, dependent: :destroy
19
21
  has_many :areas, through: :market_areas
20
22
  validates :user_id, uniqueness: { message: '已存在' }
21
23
 
22
24
  # attr_writer :month
23
25
 
26
+ def last_login_key
27
+ "login_user_#{self.id}"
28
+ end
29
+
30
+ def check_login_status(request)
31
+ unless Rails.cache.data.get(self.last_login_key)
32
+ # 第二天还在线访问,记用户登录一次
33
+ create_login_history(request)
34
+ end
35
+ end
36
+
37
+ def create_login_history(request)
38
+ # 登录状态保存到当天结束时间后+10分钟
39
+ Rails.cache.data.set(self.last_login_key, 1)
40
+ Rails.cache.data.expireat(self.last_login_key, Time.now.end_of_day.to_i + 600)
41
+
42
+ last_history = self.login_histories.last
43
+ self.login_histories.create(current_ip: request.remote_ip, last_ip: last_history&.current_ip, last_login_at: last_history&.created_at)
44
+ end
45
+
24
46
  def self.month_list
25
47
  list = []
26
48
  24.times.map do |d|
@@ -474,12 +474,10 @@
474
474
 
475
475
 
476
476
  form.on('select(year)', function(data){
477
- console.log(data, )
478
477
  year = data.value
479
478
  window.location.href = "/missions/sale_trends/trends?year=" + data.value
480
479
  })
481
480
  form.on('select(follow_count)', function(data){
482
- console.log(data, )
483
481
  const value = data.value;
484
482
  if(value == "month"){
485
483
  $(".year").addClass('layui-hide')
@@ -506,7 +504,6 @@
506
504
  })
507
505
 
508
506
  form.on('select(goal_count)', function(data){
509
- console.log(data, )
510
507
  const value = data.value;
511
508
  if(value == "month"){
512
509
  $(".goal_year").addClass('layui-hide')
@@ -0,0 +1,80 @@
1
+ <script type="text/html" id="user_behaviors_topbar">
2
+ <div class="layui-btn-container">
3
+ <span class="table-label">行为分析</span>
4
+ </div>
5
+ </script>
6
+ <div class="min-height-table">
7
+ <table class="layui-hide" id="user_behaviors_table" lay-filter="user_behaviors_table"></table>
8
+ </div>
9
+
10
+ <script>
11
+ layui.use(['form', 'table', 'miniPage', 'element', 'request'], function () {
12
+ var $ = layui.jquery,
13
+ form = layui.form,
14
+ table = layui.table,
15
+ request = layui.request,
16
+ miniPage = layui.miniPage;
17
+
18
+ table.render({
19
+ elem: '#user_behaviors_table',
20
+ url: '/missions/user_behaviors',
21
+ totalRow:true,
22
+ toolbar: '#user_behaviors_topbar',
23
+ defaultToolbar: [],
24
+ cols: [
25
+ [
26
+ {
27
+ field: 'id',
28
+ title:'序号',
29
+ type: 'numbers',
30
+ width: 60
31
+ },
32
+ {
33
+ field: 'name',
34
+ title: '用户名',
35
+ width: 120,
36
+ sort: true,
37
+ },
38
+ {
39
+ field: 'last_ip',
40
+ title: '上次登录IP',
41
+ width: 120
42
+ },
43
+ {
44
+ field: 'current_ip',
45
+ title: '当前登录IP',
46
+ width: 120
47
+ },
48
+ {
49
+ field: 'last_login_at',
50
+ width: 200,
51
+ title: '上次登录时间',
52
+ sort: true,
53
+ },
54
+ {
55
+ field: 'created_at',
56
+ width: 200,
57
+ title: '当前登录时间',
58
+ sort: true,
59
+ }
60
+ ]
61
+ ],
62
+ limit: 20,
63
+ limits: [10,15,20,30,40,50,60,70,80,90],
64
+ page: true
65
+ });
66
+
67
+ var sort = {};
68
+ table.on('sort(user_behaviors_table)', function (obj) {
69
+ sort.field = obj.field;
70
+ sort.order = obj.type;
71
+ table.reload('user_behaviors_table', {
72
+ initSort: obj,
73
+ where: {
74
+ sort: sort
75
+ }
76
+ });
77
+ })
78
+
79
+ });
80
+ </script>
@@ -0,0 +1,13 @@
1
+ json.data do
2
+ json.array! @data do |d|
3
+ json.id d.id
4
+ json.last_login_at d.last_login_at.to_s
5
+ json.created_at d.created_at.to_s
6
+ json.last_ip d.last_ip
7
+ json.current_ip d.current_ip
8
+ json.name d.staff&.user&.real_name
9
+ end
10
+ end
11
+
12
+ json.code 0
13
+ json.count @data.total_count
@@ -121,13 +121,18 @@
121
121
  <% end %>
122
122
  </dl>
123
123
  </li>
124
- <% if @current_admin.is_admin %>
124
+ <% if @current_admin.is_admin || @current_admin.code == 'userbe' %>
125
125
  <li class="layui-nav-item layui-nav-itemed menu-li">
126
126
  <a class="" href="javascript:;"><b><%= image_tag "educode_sales/13.系统设置.png",size:"15"%><i style="font-size: 25px; padding-right: 25px"></i>系统设置</b></a>
127
127
  <dl class="layui-nav-child">
128
+ <% if @current_admin.is_admin %>
128
129
  <dd><a href="/missions/roles" class="<%= current?('layui-this', roles_path) %>"><i style="padding-right: 35px"></i><%= image_tag "educode_sales/14.角色管理.png",size:"15"%><i style="font-size: 25px; padding-right: 15px"></i>角色管理</a></dd>
129
130
  <dd><a href="/missions/staffs" class="<%= current?('layui-this', staffs_path) %>"><i style="padding-right: 35px"></i><%= image_tag "educode_sales/15.人员管理.png",size:"15"%><i style="font-size: 25px; padding-right: 15px"></i>人员管理</a></dd>
130
131
  <dd><a href="/missions/commons" class="<%= current?('layui-this', commons_path) %>"><i style="padding-right: 35px"></i><%= image_tag "educode_sales/16.字典列表.png",size:"15"%><i style="font-size: 25px; padding-right: 15px"></i>字典列表</a></dd>
132
+ <% end %>
133
+ <% if @current_admin.code == 'userbe' %>
134
+ <dd><a href="/missions/user_behaviors" class="<%= current?('layui-this', user_behaviors_path) %>"><i style="padding-right: 35px"></i><%= image_tag "educode_sales/9.运营分工.png",size:"15"%><i style="font-size: 25px; padding-right: 15px"></i>行为分析</a></dd>
135
+ <% end %>
131
136
  </dl>
132
137
  </li>
133
138
  <% end %>
data/config/routes.rb CHANGED
@@ -19,7 +19,7 @@ EducodeSales::Engine.routes.draw do
19
19
  resources :sessions do
20
20
  end
21
21
 
22
-
22
+ resources :user_behaviors
23
23
  resources :customer_extensions do
24
24
  end
25
25
  resources :customer_follows do
@@ -0,0 +1,13 @@
1
+ class CreateEducodeSalesLoginHistories < ActiveRecord::Migration[5.2]
2
+ def change
3
+ create_table :educode_sales_login_histories do |t|
4
+ t.references :staff
5
+ t.string :last_ip
6
+ t.string :current_ip
7
+ t.datetime :last_login_at
8
+
9
+ t.timestamps
10
+ end
11
+ add_column :educode_sales_staffs, :code, :string, comment: '特别业务权限用途'
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module EducodeSales
2
- VERSION = '0.9.2'
2
+ VERSION = '0.9.3'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: educode_sales
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - anke1460
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-07-01 00:00:00.000000000 Z
11
+ date: 2022-08-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -105,7 +105,6 @@ files:
105
105
  - app/assets/images/educode_sales/icon-login.png
106
106
  - app/assets/images/educode_sales/icon.png
107
107
  - app/assets/images/educode_sales/indexLogo.png
108
- - app/assets/images/educode_sales/indexlogo.png
109
108
  - app/assets/images/educode_sales/loading-0.gif
110
109
  - app/assets/images/educode_sales/loading-1.gif
111
110
  - app/assets/images/educode_sales/loading-2.gif
@@ -168,6 +167,7 @@ files:
168
167
  - app/controllers/educode_sales/teacher_follows_controller.rb
169
168
  - app/controllers/educode_sales/teachers_controller.rb
170
169
  - app/controllers/educode_sales/upload_files_controller.rb
170
+ - app/controllers/educode_sales/user_behaviors_controller.rb
171
171
  - app/helpers/educode_sales/activities_helper.rb
172
172
  - app/helpers/educode_sales/application_helper.rb
173
173
  - app/helpers/educode_sales/assessments_help.rb
@@ -197,6 +197,7 @@ files:
197
197
  - app/models/educode_sales/filter.rb
198
198
  - app/models/educode_sales/follow_up.rb
199
199
  - app/models/educode_sales/key_person.rb
200
+ - app/models/educode_sales/login_history.rb
200
201
  - app/models/educode_sales/market_area.rb
201
202
  - app/models/educode_sales/money_plan.rb
202
203
  - app/models/educode_sales/operation_plan.rb
@@ -401,6 +402,8 @@ files:
401
402
  - app/views/educode_sales/teachers/show_follow_record.html.erb
402
403
  - app/views/educode_sales/teachers/unfinish_plans.json.jbuilder
403
404
  - app/views/educode_sales/upload_files/index.json.jbuilder
405
+ - app/views/educode_sales/user_behaviors/index.html.erb
406
+ - app/views/educode_sales/user_behaviors/index.json.jbuilder
404
407
  - app/views/layouts/educode_sales/application.html.erb
405
408
  - app/views/layouts/educode_sales/login.html.erb
406
409
  - config/locales/sale.zh-CN.yml
@@ -461,6 +464,7 @@ files:
461
464
  - db/migrate/20220512031715_add_column_o_business_deployment_to_follow_ups.rb
462
465
  - db/migrate/20220523023609_update_assessment_month_column_to_assessment_settings.rb
463
466
  - db/migrate/20220523101628_update_column_to_follow_ups.rb
467
+ - db/migrate/20220827130438_create_educode_sales_login_histories.rb
464
468
  - lib/educode_sales.rb
465
469
  - lib/educode_sales/engine.rb
466
470
  - lib/educode_sales/version.rb
@@ -469,7 +473,7 @@ homepage: https://www.educoder.net
469
473
  licenses:
470
474
  - MIT
471
475
  metadata: {}
472
- post_install_message:
476
+ post_install_message:
473
477
  rdoc_options: []
474
478
  require_paths:
475
479
  - lib
@@ -484,8 +488,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
484
488
  - !ruby/object:Gem::Version
485
489
  version: '0'
486
490
  requirements: []
487
- rubygems_version: 3.0.9
488
- signing_key:
491
+ rubygems_version: 3.0.0
492
+ signing_key:
489
493
  specification_version: 4
490
494
  summary: Summary of EducodeSales.
491
495
  test_files: []