ADD 后台系统配置管理功能

This commit is contained in:
jasder 2021-09-10 15:29:08 +08:00
parent 36adfcf016
commit 4c41d50506
35 changed files with 505 additions and 105 deletions

View File

@ -0,0 +1,55 @@
class Admins::EduSettingsController < Admins::BaseController
before_action :find_setting, only: [:edit,:update, :destroy]
def index
default_sort('id', 'desc')
edu_settings = Admins::EduSettingQuery.call(params)
@edu_settings = paginate edu_settings
end
def new
@edu_setting = EduSetting.new
end
def edit
end
def create
@edu_setting = EduSetting.new(edu_setting_params)
if @edu_setting.save
redirect_to admins_edu_settings_path
flash[:success] = '创建成功'
else
redirect_to admins_edu_settings_path
flash[:danger] = @edu_setting.errors.full_messages.join(",")
end
end
def update
if @edu_setting.update!(edu_setting_params)
flash[:success] = '更新成功'
else
flash[:danger] = @edu_setting.errors.full_messages.join(",")
end
redirect_to admins_edu_settings_path
end
def destroy
if @edu_setting.destroy!
flash[:success] = '删除成功'
else
lash[:danger] = '删除失败'
end
redirect_to admins_edu_settings_path
end
private
def find_setting
@edu_setting ||= EduSetting.find(params[:id])
end
def edu_setting_params
params.require(:edu_setting).permit(:name, :value, :description)
end
end

View File

@ -0,0 +1,56 @@
class Admins::SitesController < Admins::BaseController
before_action :find_site, only: [:edit,:update, :destroy]
def index
default_sort('id', 'desc')
sites = Admins::SiteQuery.call(params)
@sites = paginate sites
end
def new
@site = Site.new
end
def edit
end
def create
@site = Site.new(site_params)
if @site.save
redirect_to admins_sites_path
flash[:success] = '创建成功'
else
redirect_to admins_sites_path
flash[:danger] = @site.errors.full_messages.join(",")
end
end
def update
if @site.update!(site_params)
flash[:success] = '更新成功'
else
flash[:danger] = @site.errors.full_messages.join(",")
end
redirect_to admins_sites_path
end
def destroy
if @site.destroy!
flash[:success] = '删除成功'
else
lash[:danger] = '删除失败'
end
redirect_to admins_sites_path
end
private
def find_site
@site ||= Site.find(params[:id])
end
def site_params
params.require(:site).permit(:name, :url, :key, :site_type)
end
end

View File

@ -29,10 +29,8 @@ class EduSettingsController < ApplicationController
respond_to do |format|
if @edu_setting.save
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully created.' }
format.json { render :show, status: :created, location: @edu_setting }
else
format.html { render :new }
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
end
end
@ -43,10 +41,8 @@ class EduSettingsController < ApplicationController
def update
respond_to do |format|
if @edu_setting.update(edu_setting_params)
format.html { redirect_to @edu_setting, notice: 'Edu setting was successfully updated.' }
format.json { render :show, status: :ok, location: @edu_setting }
else
format.html { render :edit }
format.json { render json: @edu_setting.errors, status: :unprocessable_entity }
end
end
@ -57,7 +53,6 @@ class EduSettingsController < ApplicationController
def destroy
@edu_setting.destroy
respond_to do |format|
format.html { redirect_to edu_settings_url, notice: 'Edu setting was successfully destroyed.' }
format.json { head :no_content }
end
end

View File

@ -24,4 +24,12 @@ class ApplicationRecord < ActiveRecord::Base
def reset_platform_cache_async_job
ResetPlatformCacheJob.perform_later
end
def self.strip_param(key)
key.to_s.strip.presence
end
def strip_param(key)
key.to_s.strip.presence
end
end

View File

@ -17,6 +17,8 @@
class EduSetting < ApplicationRecord
after_commit :expire_value_cache
scope :by_search, -> (keyword){ where("name LIKE :keyword OR value LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
def value_cache_key
self.class.value_cache_key(name)
end

View File

@ -17,6 +17,9 @@ class Site < ApplicationRecord
# common: 普通链接
enum site_type: { add: 0, personal: 1, common: 2 }
scope :by_search, -> (keyword){ where("name LIKE :keyword OR url LIKE :keyword", keyword: "%#{strip_param(keyword)}%") unless strip_param(keyword).blank? }
scope :by_site_type, -> (site_type){ where(site_type: strip_param(site_type)) unless strip_param(site_type).blank? }
def self.set_default_menu
set_add_menu!
set_personal_menu!
@ -26,8 +29,8 @@ class Site < ApplicationRecord
private
def self.set_add_menu!
adds= [
{name: '新建镜像项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
{name: '新建托管项目', key: 'add_common', url: '/projects/deposit/new'},
{name: '新建项目', key: 'add_mirror_project', url: '/projects/mirror/new'},
{name: '导入项目', key: 'add_common', url: '/projects/deposit/new'},
{name: '新建组织', key: 'add_r', url: '/organize/new'}]
adds.each { |ele|

View File

@ -0,0 +1,28 @@
class Admins::EduSettingQuery < ApplicationQuery
include CustomSortable
attr_reader :params
sort_columns :id, default_by: :id, default_direction: :desc
def initialize(params)
@params = params
end
def call
collection = EduSetting.all
collection = filter_settings(collection)
custom_sort collection, params[:sort_by], params[:sort_direction]
end
def filter_settings(collection)
by_search(collection)
end
def by_search(collection)
keyword = strip_param(:search)
collection.by_search(keyword)
end
end

View File

@ -0,0 +1,35 @@
class Admins::SiteQuery < ApplicationQuery
include CustomSortable
attr_reader :params
sort_columns :id, default_by: :id, default_direction: :desc
def initialize(params)
@params = params
end
def call
collection = Site.all
collection = filter_sites(collection)
custom_sort collection, params[:sort_by], params[:sort_direction]
end
def filter_sites(collection)
collection = by_search(collection)
collection = by_stie_type(collection)
collection
end
def by_search(collection)
keyword = strip_param(:search)
collection.by_search(keyword)
end
def by_stie_type(collection)
site_type = strip_param(:site_type)
collection.by_site_type(site_type)
end
end

View File

@ -0,0 +1,38 @@
<div class="modal fade edu_setting-change-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"><%= type == "create" ? "新增" : "编辑" %></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= form_for @edu_setting, url: {controller: "edu_settings", action: "#{type}"} do |p| %>
<div class="modal-body">
<div class="form-group">
<label>
变量名 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :name, class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
变量值 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :value, class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
备注说明
</label>
<%= p.text_area :description, class: "form-control", placeholder: ""%>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -0,0 +1,36 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="5%">序号</th>
<th width="15%">变量名</th>
<th width="35%">变量值</th>
<th width="20%">备注说明</th>
<th width="10%"><%= sort_tag('创建时间', name: 'created_at', path: admins_edu_settings_path) %></th>
<th width="10%">操作</th>
</tr>
</thead>
<tbody>
<% if edu_settings.present? %>
<% edu_settings.each_with_index do |edu_setting, index| %>
<tr class="edu_setting-item-<%= edu_setting.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= edu_setting.name %>
</td>
<td><%= edu_setting.value %></td>
<td><%= overflow_hidden_span display_text(edu_setting.description), width: 200 %></td>
<td><%= edu_setting.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<%= link_to "编辑", edit_admins_edu_setting_path(edu_setting), remote: true, class: "action" %>
<%= link_to "删除", admins_edu_setting_path(edu_setting), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: edu_settings } %>

View File

@ -0,0 +1,2 @@
$("#edu_setting-modals").html("<%= j render(partial: 'admins/edu_settings/form', locals: {type: 'update'}) %>")
$(".edu_setting-change-modal").modal('show');

View File

@ -0,0 +1,22 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('全局变量配置') %>
<% end %>
<div class="box search-form-container edu_settings-list-form">
<%= form_tag(admins_edu_settings_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '关键字检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<%= link_to "新增", new_admins_edu_setting_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
</div>
<div class="box py-0 pt-4 pl-4 daily-school-statistic-title">
说明:该界面适用于存储全局变量.
</div>
<div class="box admin-list-container edu_settings-list-container">
<%= render partial: 'admins/edu_settings/list', locals: { edu_settings: @edu_settings } %>
</div>
<div id="edu_setting-modals">
</div>

View File

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

View File

@ -0,0 +1,2 @@
$("#edu_setting-modals").html("<%= j render(partial: 'admins/edu_settings/form', locals: {type: 'create'}) %>")
$(".edu_setting-change-modal").modal('show');

View File

@ -43,6 +43,12 @@
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
<% end %>
</li>
<li>
<%= sidebar_item_group('#setting-system', '系统配置', icon: 'wrench') do %>
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %></li>
<li><%= sidebar_item(admins_edu_settings_path, '全局变量配置', icon: 'pencil-square', controller: 'admins-edu_settings') %></li>
<% end %>
</li>
<li>
<%= sidebar_item('/admins/sidekiq', '定时任务', icon: 'bell', controller: 'root') %>
</li>

View File

@ -0,0 +1,42 @@
<div class="modal fade site-change-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"><%= type == "create" ? "新增" : "编辑" %></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<%= form_for @site, url: {controller: "sites", action: "#{type}"} do |p| %>
<div class="modal-body">
<div class="form-group">
<label>
名称 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :name, class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
路由 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :url, class: "form-control input-lg",required: true%>
</div>
<div class="form-group">
<label>
标识 <span class="ml10 color-orange mr20">*</span>
</label>
<%= p.text_field :key, class: "form-control input-lg",required: true%>
</div>
<div class="form-group ">
<label for="status">类型:</label>
<%= p.select :site_type, options_for_select(Site.site_types.map { |key, value| [key.humanize, key] }), {}, class: "form-control" %>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
<%= p.submit "确认", class: "btn btn-primary submit-btn" %>
</div>
<% end %>
</div>
</div>
</div>

View File

@ -0,0 +1,38 @@
<table class="table table-hover text-center subject-list-table">
<thead class="thead-light">
<tr>
<th width="5%">序号</th>
<th width="15%">名称</th>
<th width="30%">路由</th>
<th width="20%">标识</th>
<th width="10%">类型</th>
<th width="20%"><%= sort_tag('创建时间', name: 'created_at', path: admins_sites_path) %></th>
<th width="25%">操作</th>
</tr>
</thead>
<tbody>
<% if sites.present? %>
<% sites.each_with_index do |site, index| %>
<tr class="site-item-<%= site.id %>">
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
<td>
<%= overflow_hidden_span display_text(site.name), width: 150 %>
</td>
<td><%= site.url %></td>
<td><%= overflow_hidden_span display_text(site.key), width: 150 %></td>
<td><%= site.site_type.humanize %></td>
<td><%= site.created_at&.strftime('%Y-%m-%d %H:%M') %></td>
<td class="action-container">
<%= link_to "编辑", edit_admins_site_path(site), remote: true, class: "action" %>
<%= link_to "删除", admins_site_path(site), method: :delete, data:{confirm: "确认删除的吗?"}, class: "action" %>
</td>
</tr>
<% end %>
<% else %>
<%= render 'admins/shared/no_data_for_table' %>
<% end %>
</tbody>
</table>
<%= render partial: 'admins/shared/paginate', locals: { objects: sites } %>

View File

@ -0,0 +1,2 @@
$("#site-modals").html("<%= j render(partial: 'admins/sites/form', locals: {type: 'update'}) %>")
$(".site-change-modal").modal('show');

View File

@ -0,0 +1,24 @@
<% define_admin_breadcrumbs do %>
<% add_admin_breadcrumb('Setting接口配置') %>
<% end %>
<div class="box search-form-container sites-list-form">
<%= form_tag(admins_sites_path, method: :get, class: 'form-inline search-form flex-1', remote: true) do %>
<div class="form-group mr-2">
<label for="status">类型:</label>
<% type_options = [['全部', ''], ['Add', Site.site_types[:add]], ['Personal', Site.site_types[:personal]], ['Common', Site.site_types[:common]]] %>
<%= select_tag(:site_type, options_for_select(type_options), class: 'form-control') %>
</div>
<%= text_field_tag(:search, params[:search], class: 'form-control col-12 col-md-2 mr-3', placeholder: '关键字检索') %>
<%= submit_tag('搜索', class: 'btn btn-primary ml-3', 'data-disable-with': '搜索中...') %>
<input type="reset" class="btn btn-secondary clear-btn" value="清空"/>
<% end %>
<%= link_to "新增", new_admins_site_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
</div>
<div class="box admin-list-container sites-list-container">
<%= render partial: 'admins/sites/list', locals: { sites: @sites } %>
</div>
<div id="site-modals">
</div>

View File

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

View File

@ -0,0 +1,2 @@
$("#site-modals").html("<%= j render(partial: 'admins/sites/form', locals: {type: 'create'}) %>")
$(".site-change-modal").modal('show');

View File

@ -1,27 +0,0 @@
<%= form_with(model: edu_setting, local: true) do |form| %>
<% if edu_setting.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(edu_setting.errors.count, "error") %> prohibited this edu_setting from being saved:</h2>
<ul>
<% edu_setting.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label :name %>
<%= form.text_field :name %>
</div>
<div class="field">
<%= form.label :value %>
<%= form.text_field :value %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>

View File

@ -1,6 +0,0 @@
<h1>Editing Edu Setting</h1>
<%= render 'form', edu_setting: @edu_setting %>
<%= link_to 'Show', @edu_setting %> |
<%= link_to 'Back', edu_settings_path %>

View File

@ -1,30 +0,0 @@
<p id="notice"><%= notice %></p>
<h1>EduCoder公共配置</h1>
<p>说明:该界面适用于存储全局变量</p>
<table>
<thead>
<tr>
<th>变量名</th>
<th>变量值</th>
<th colspan="3"></th>
</tr>
</thead>
<tbody>
<% @edu_settings.each do |edu_setting| %>
<tr>
<td><%= edu_setting.name %></td>
<td><%= edu_setting.value %></td>
<td><%= link_to 'Show', edu_setting %></td>
<td><%= link_to 'Edit', edit_edu_setting_path(edu_setting) %></td>
<td><%= link_to 'Destroy', edu_setting, method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</tbody>
</table>
<br>
<%= link_to 'New Edu Setting', new_edu_setting_path %>

View File

@ -1,5 +0,0 @@
<h1>New Edu Setting</h1>
<%= render 'form', edu_setting: @edu_setting %>
<%= link_to 'Back', edu_settings_path %>

View File

@ -1,14 +0,0 @@
<p id="notice"><%= notice %></p>
<p>
<strong>Name:</strong>
<%= @edu_setting.name %>
</p>
<p>
<strong>Value:</strong>
<%= @edu_setting.value %>
</p>
<%= link_to 'Edit', edit_edu_setting_path(@edu_setting) %> |
<%= link_to 'Back', edu_settings_path %>

View File

@ -651,6 +651,8 @@ Rails.application.routes.draw do
get :visits_static
end
end
resources :sites
resources :edu_settings
resources :project_languages
resources :project_categories
resources :project_licenses

View File

@ -0,0 +1,47 @@
require 'rails_helper'
RSpec.describe Admins::EduSettingsController, type: :controller do
describe "GET #index" do
it "returns http success" do
get :index
expect(response).to have_http_status(:success)
end
end
describe "GET #new" do
it "returns http success" do
get :new
expect(response).to have_http_status(:success)
end
end
describe "GET #update" do
it "returns http success" do
get :update
expect(response).to have_http_status(:success)
end
end
describe "GET #edit" do
it "returns http success" do
get :edit
expect(response).to have_http_status(:success)
end
end
describe "GET #create" do
it "returns http success" do
get :create
expect(response).to have_http_status(:success)
end
end
describe "GET #destroy" do
it "returns http success" do
get :destroy
expect(response).to have_http_status(:success)
end
end
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe Admins::SitesController, type: :controller do
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/create.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/destroy.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/edit.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/index.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/new.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end

View File

@ -0,0 +1,5 @@
require 'rails_helper'
RSpec.describe "edu_settings/update.html.erb", type: :view do
pending "add some examples to (or delete) #{__FILE__}"
end