mirror of
https://gitlink.org.cn/Gitlink/forgeplus.git
synced 2026-05-03 11:50:49 +08:00
init project
This commit is contained in:
138
app/views/admins/users/edit.html.erb
Normal file
138
app/views/admins/users/edit.html.erb
Normal 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>
|
||||
42
app/views/admins/users/index.html.erb
Normal file
42
app/views/admins/users/index.html.erb
Normal 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' %>
|
||||
1
app/views/admins/users/index.js.erb
Normal file
1
app/views/admins/users/index.js.erb
Normal file
@@ -0,0 +1 @@
|
||||
$('.users-list-container').html("<%= j( render partial: 'admins/users/shared/user_list', locals: { users: @users } ) %>");
|
||||
6
app/views/admins/users/index.json.jbuilder
Normal file
6
app/views/admins/users/index.json.jbuilder
Normal 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
|
||||
30
app/views/admins/users/shared/_import_user_modal.html.erb
Normal file
30
app/views/admins/users/shared/_import_user_modal.html.erb
Normal 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">×</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>
|
||||
26
app/views/admins/users/shared/_reward_grade_modal.html.erb
Normal file
26
app/views/admins/users/shared/_reward_grade_modal.html.erb
Normal 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">×</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>
|
||||
67
app/views/admins/users/shared/_user_list.html.erb
Normal file
67
app/views/admins/users/shared/_user_list.html.erb
Normal 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 } %>
|
||||
6
app/views/admins/users/show.html.erb
Normal file
6
app/views/admins/users/show.html.erb
Normal file
@@ -0,0 +1,6 @@
|
||||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('用户管理', admins_users_path) %>
|
||||
<% add_admin_breadcrumb('用户详情') %>
|
||||
<% end %>
|
||||
|
||||
<h3>Users Show</h3>
|
||||
Reference in New Issue
Block a user