init project

This commit is contained in:
Jasder
2020-03-09 00:40:16 +08:00
commit 2937b2a94d
6549 changed files with 7215173 additions and 0 deletions

View File

@@ -0,0 +1,138 @@
<%
define_admin_breadcrumbs do
add_admin_breadcrumb('用户管理', admins_users_path)
add_admin_breadcrumb('用户详情')
end
%>
<div class="box user-edit-container">
<div class="user-info mb-4 row">
<%= link_to "/users/#{@user.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %>
<img src="/images/<%= url_to_avatar(@user) %>" class="rounded-circle" width="80" height="80" />
<% end %>
<div class="d-flex flex-column justify-content-between col-md-3 user-info-content">
<div class="user-info-name flex"><%= @user.real_name %> | <%= @user.id %> | <%= @user.login %></div>
<div class="d-flex flex-row user-info-auth">
<% if @user.authentication? %>
<i class="fa fa-user text-success" data-toggle="tooltip" data-placement="bottom" title="已实名认证"></i>
<% elsif @user.process_real_name_apply.present? %>
<i class="fa fa-user text-danger" data-toggle="tooltip" data-placement="bottom" title="实名认证中"></i>
<% else %>
<i class="fa fa-user text-muted" data-toggle="tooltip" data-placement="bottom" title="未实名认证"></i>
<% end %>
<% if @user.professional_certification %>
<i class="fa fa-list-alt text-success" data-toggle="tooltip" data-placement="bottom" title="已职业认证"></i>
<% elsif @user.process_professional_apply.present? %>
<i class="fa fa-list-alt text-danger" data-toggle="tooltip" data-placement="bottom" title="职业认证中"></i>
<% else %>
<i class="fa fa-list-alt text-muted" data-toggle="tooltip" data-placement="bottom" title="未职业认证"></i>
<% end %>
<% if @user.phone.present? %>
<i class="fa fa-mobile text-success" data-toggle="tooltip" data-placement="bottom" title="已绑定手机"></i>
<% else %>
<i class="fa fa-mobile text-muted" data-toggle="tooltip" data-placement="bottom" title="未绑定手机"></i>
<% end %>
<% if @user.mail.present? %>
<i class="fa fa-envelope text-success" data-toggle="tooltip" data-placement="bottom" title="已绑定邮箱"></i>
<% else %>
<i class="fa fa-envelope text-muted" data-toggle="tooltip" data-placement="bottom" title="未绑定邮箱"></i>
<% end %>
</div>
<div class="user-info-last-login">最近登录:<%= @user.last_login_on&.strftime('%Y-%m-%d %H:%M') %></div>
</div>
</div>
<%= simple_form_for(@user, url: admins_user_path(@user)) do |f| %>
<div><h6>基本信息</h6></div>
<div class="form-group px-2">
<div class="form-row">
<%= f.input :lastname, label: '姓名', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-md-11', value: @user.only_real_name } %>
</div>
<div class="form-row">
<%= f.input :nickname, label: '昵称', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-md-11' } %>
<%= f.input :gender, as: :radio_buttons, label: '性别', collection: [%w(男 0), %w(女 1)], wrapper_html: { class: 'col-md-3' } %>
</div>
<div class="form-row user-identity-select">
<div class="form-group select optional col-md-1">
<%= f.label :identity, label: '职业' %>
<%= select_tag('user[identity]', [], class: 'form-control identity-select optional', 'data-value': @user.user_extension&.identity, 'data-first-title': '请选择') %>
</div>
<div class="form-group technical-title-select-wrapper optional col-md-1" style="<%= @user.user_extension.student? ? 'display:none;' : '' %>">
<%= f.label :technical_title, label: '职称' %>
<%= select_tag('user[technical_title]', [], class: 'form-control technical-title-select optional', 'data-value': @user.technical_title) %>
</div>
<%= f.input :student_id, as: :tel, label: '学号', wrapper_html: { class: 'col-md-2', style: @user.user_extension.student? ? '' : 'display:none;' }, input_html: { class: 'student-id-input' } %>
</div>
<div class="form-row">
<%= f.input :mail, as: :email, label: '邮箱地址', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11' } %>
<%= f.input :phone, as: :tel, label: '手机号', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'off' } %>
</div>
<div class="form-row province-city-select">
<div class="form-group select optional col-md-2">
<%= f.label :location, label: '省份' %>
<%= select_tag('user[location]', [], class: 'form-control province-select optional', 'data-value': @user.location, 'data-first-title': '请选择') %>
</div>
<div class="form-group select optional col-md-2">
<%= f.label :location_city, label: '城市' %>
<%= select_tag('user[location_city]', [], class: 'form-control city-select optional', 'data-value': @user.location_city) %>
</div>
</div>
<div class="form-row">
<%= f.input :school_id, as: :hidden %>
<%= f.input :department_id, as: :hidden %>
<div class="form-group select optional col-md-2">
<%= f.label :school_name, label: '所属学校/单位' %>
<%= f.select :school_name, [@user.school_id], {}, class: 'form-control school-select optional' %>
</div>
<div class="form-group select optional col-md-2">
<%= f.label :department_name, label: '所属学院/部门' %>
<%= f.select :department_name, [@user.department_id], {}, class: 'form-control department-select optional' %>
</div>
</div>
</div>
<div class="mt-4"><h6>管理</h6></div>
<div class="form-group px-2">
<% if current_user.admin? %>
<div class="form-group check_boxes optional">
<%= f.label :role, label: '角色' %>
<div class="d-flex">
<%= f.input :admin, as: :boolean, label: '管理员', checked_value: 1, unchecked_value: 0 %>
<%= f.input :business, as: :boolean, label: '运营人员', wrapper_html: { class: 'ml-3' }, checked_value: 1, unchecked_value: 0 %>
<%= f.input :is_test, as: :boolean, label: '测试账号', wrapper_html: { class: 'ml-3' }, checked_value: 1, unchecked_value: 0 %>
</div>
</div>
<% end %>
<div class="form-group check_boxes optional">
<%= f.label :role, label: '认证信息' %>
<div class="d-flex">
<%= f.input :professional_certification, as: :boolean, label: '职业认证', checked_value: 1, unchecked_value: 0 %>
<%= f.input :authentication, as: :boolean, label: '实名认证', wrapper_html: { class: 'ml-3' }, checked_value: 1, unchecked_value: 0 %>
<%= f.input :is_shixun_marker, as: :boolean, label: '实训制作', wrapper_html: { class: 'ml-3' }, checked_value: 1, unchecked_value: 0 %>
</div>
</div>
<div class="form-row">
<%= f.input :password, as: :password, label: '修改密码', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'new-password' } %>
<%= f.input :password_confirmation, as: :password, label: '确认密码', wrapper_html: { class: 'col-md-3' }, input_html: { class: 'col-sm-11', autocomplete: 'new-password' } %>
</div>
</div>
<div class="form-row mt-4">
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %>
<%= link_to '取消', admins_users_path, class: 'btn btn-secondary px-4' %>
</div>
<% end %>
</div>

View File

@@ -0,0 +1,42 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('用户管理', admins_users_path) %>
<% end %>
<div class="box search-form-container user-list-form">
<%= form_tag(admins_users_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group mr-2">
<label for="status">状态:</label>
<% status_options = [['全部', ''], ['正常', User::STATUS_ACTIVE], ['未激活', User::STATUS_REGISTERED], ['已锁定', User::STATUS_LOCKED]] %>
<%= select_tag(:status, options_for_select(status_options), class: 'form-control') %>
</div>
<div class="form-group mr-2">
<label for="identity">职业:</label>
<% identity_options = [['全部', ''], ['教师', 0], ['学生', 1], ['专业人士', 2]] %>
<%= select_tag(:identity, options_for_select(identity_options), class: 'form-control') %>
</div>
<div class="form-group mr-2">
<label for="identity">授权类型:</label>
<% auto_trial_options = [['全部', ''], ['自动授权', 1], ['手动授权', 0]] %>
<%= select_tag(:auto_trial, options_for_select(auto_trial_options), class: 'form-control') %>
</div>
<%= text_field_tag(:keyword, params[:keyword], class: 'form-control col-sm-2 ml-3', placeholder: 'ID/姓名/邮箱/手机号检索') %>
<%= text_field_tag(:school_name, params[:school_name], class: 'form-control col-sm-2', placeholder: '学校/单位检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<% end %>
<%= javascript_void_link '导入用户', class: 'btn btn-secondary btn-sm', data: { toggle: 'modal', target: '.admin-import-user-modal'} %>
<%= javascript_void_link '导入课堂成员', class: 'btn btn-secondary btn-sm ml-2', data: { toggle: 'modal', target: '.admin-import-course-member-modal'} %>
</div>
<div class="box admin-list-container users-list-container">
<%= render partial: 'admins/users/shared/user_list', locals: { users: @users } %>
</div>
<%= render partial: 'admins/users/shared/reward_grade_modal' %>
<%= render partial: 'admins/users/shared/import_user_modal' %>
<!-- TODO: move to course list page -->
<%= render partial: 'admins/courses/shared/import_course_member_modal' %>

View File

@@ -0,0 +1 @@
$('.users-list-container').html("<%= j( render partial: 'admins/users/shared/user_list', locals: { users: @users } ) %>");

View File

@@ -0,0 +1,6 @@
json.count @users.total_count
json.users do
json.array! @users.each do |user|
json.extract! user, :id, :login, :real_name, :identity, :school_name, :hidden_phone
end
end

View File

@@ -0,0 +1,30 @@
<div class="modal fade admin-import-user-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">导入用户</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-import-user-form" enctype="multipart/form-data">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">文件</span>
</div>
<div class="custom-file">
<input type="file" name="file" class="upload-file-input" id="import-user-input" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
<label class="custom-file-label file-names" for="import-user-input">选择文件</label>
</div>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,26 @@
<div class="modal fade admin-users-reward-grade-modal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">奖励金币</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<form class="admin-users-reward-grade-form">
<%= hidden_field_tag(:user_id, nil) %>
<div class="form-group">
<label for="grade" class="col-form-label">金币数量:</label>
<%= number_field_tag(:grade, nil, class: 'form-control') %>
</div>
<div class="error text-danger"></div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary submit-btn">确认</button>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,67 @@
<table class="table table-hover users-list-table">
<thead class="thead-light">
<tr>
<th width="4%">序号</th>
<th width="8%" class="text-left">真实姓名</th>
<th width="13%">邮件地址</th>
<th width="10%">手机号码</th>
<th width="14%">单位</th>
<th width="7%">角色</th>
<th width="10%"><%= sort_tag('创建于', name: 'created_on', path: admins_users_path) %></th>
<th width="10%"><%= sort_tag('最后登录', name: 'last_login_on', path: admins_users_path) %></th>
<th width="6%"><%= sort_tag('经验值', name: 'experience', path: admins_users_path) %></th>
<th width="6%"><%= sort_tag('金币', name: 'grade', path: admins_users_path) %></th>
<th width="14%">操作</th>
</tr>
</thead>
<tbody>
<% if users.present? %>
<% users.each_with_index do |user, index| %>
<tr class="user-item-<%= user.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td class="text-left">
<%= link_to "/users/#{user.login}", target: '_blank' do %>
<%= overflow_hidden_span user.real_name, width: 100 %>
<% end %>
</td>
<td><%= overflow_hidden_span display_text(user.mail), width: 150 %></td>
<td><%= overflow_hidden_span display_text(user.phone), width: 100 %></td>
<td><%= overflow_hidden_span display_text(user.school_name), width: 150 %></td>
<td><%= user.identity %></td>
<td><%= display_text(user.created_on&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= display_text(user.last_login_on&.strftime('%Y-%m-%d %H:%M')) %></td>
<td><%= user.experience.to_i %></td>
<td class="grade-content"><%= user.grade.to_i %></td>
<td class="action-container">
<%= link_to '编辑', edit_admins_user_path(user), class: 'action' %>
<%= javascript_void_link '解锁', class: 'action unlock-action', data: { id: user.id }, style: user.locked? ? '' : 'display: none;' %>
<% if user.registered? %>
<%= javascript_void_link '激活', class: 'action active-action', data: { id: user.id } %>
<% end %>
<% if user.id != current_user.id %>
<%= javascript_void_link '加锁', class: 'action lock-action', data: { id: user.id }, style: user.locked? || user.registered? ? 'display: none;' : '' %>
<% end %>
<div class="d-inline">
<%= javascript_void_link('更多', class: 'action dropdown-toggle', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) %>
<div class="dropdown-menu more-action-dropdown">
<%= javascript_void_link('奖励', class: 'dropdown-item reward-grade-action', data: { toggle: 'modal', target: '.admin-users-reward-grade-modal', id: user.id }) %>
<%= javascript_void_link '恢复禁密账号', class: 'dropdown-item reset-login-times-action', data: { id: user.id } %>
<%= delete_link '删除', admins_user_path(user, element: ".user-item-#{user.id}"), class: 'dropdown-item delete-user-action' %>
</div>
</div>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: users } %>

View File

@@ -0,0 +1,6 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('用户管理', admins_users_path) %>
<% add_admin_breadcrumb('用户详情') %>
<% end %>
<h3>Users Show</h3>