forked from Gitlink/forgeplus
FIX 解决featrue_homepage分支代码冲突
This commit is contained in:
commit
9d05973700
|
@ -51,6 +51,51 @@ http://localhost:3000/api/accounts/remote_register | jq
|
|||
|-- token |string|用户token|
|
||||
|
||||
|
||||
返回值
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success",
|
||||
"user": {
|
||||
"id": 36400,
|
||||
"token": "8c87a80d9cfacc92fcb2451845104f35119eda96"
|
||||
}
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
#### 独立注册接口
|
||||
```
|
||||
POST accounts/register
|
||||
```
|
||||
*示例*
|
||||
```bash
|
||||
curl -X POST \
|
||||
-d "login=2456233122@qq.com" \
|
||||
-d "password=djs_D_00001" \
|
||||
-d "namespace=16895620" \
|
||||
-d "code=forge" \
|
||||
http://localhost:3000/api/accounts/remote_register | jq
|
||||
```
|
||||
*请求参数说明:*
|
||||
|
||||
|参数名|必选|类型|说明|
|
||||
|-|-|-|-|
|
||||
|login |是|string |邮箱或者手机号 |
|
||||
|namespace |是|string |登录名 |
|
||||
|password |是|string |密码 |
|
||||
|code |是|string |验证码 |
|
||||
|
||||
|
||||
*返回参数说明:*
|
||||
|
||||
|参数名|类型|说明|
|
||||
|-|-|-|
|
||||
|user|json object |返回数据|
|
||||
|-- id |int |用户id |
|
||||
|-- token |string|用户token|
|
||||
|
||||
|
||||
返回值
|
||||
```json
|
||||
{
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 9.8 KiB |
|
@ -1,4 +1,5 @@
|
|||
class AccountsController < ApplicationController
|
||||
include ApplicationHelper
|
||||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
|
@ -9,7 +10,7 @@ class AccountsController < ApplicationController
|
|||
# 其他平台同步注册的用户
|
||||
def remote_register
|
||||
username = params[:username]&.gsub(/\s+/, "")
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.is_reversed(username).present?
|
||||
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
|
||||
email = params[:email]&.gsub(/\s+/, "")
|
||||
password = params[:password]
|
||||
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
|
||||
|
@ -109,67 +110,46 @@ class AccountsController < ApplicationController
|
|||
# 用户注册
|
||||
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
|
||||
# params[:login] 邮箱或者手机号
|
||||
# params[:namespace] 登录名
|
||||
# params[:code] 验证码
|
||||
# code_type 1:注册手机验证码 8:邮箱注册验证码
|
||||
# 本地forge注册入口
|
||||
# 本地forge注册入口需要重新更改逻辑
|
||||
def register
|
||||
# type只可能是1或者8
|
||||
user = nil
|
||||
begin
|
||||
# 查询验证码是否正确;type只可能是1或者8
|
||||
type = phone_mail_type(params[:login].strip)
|
||||
# code = params[:code].strip
|
||||
Register::Form.new(register_params).validate!
|
||||
|
||||
if type == 1
|
||||
uid_logger("start register by phone: type is #{type}")
|
||||
pre = 'p'
|
||||
email = nil
|
||||
phone = params[:login]
|
||||
# verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last
|
||||
# TODO: 暂时限定邮箱注册
|
||||
return normal_status(-1, '只支持邮箱注册')
|
||||
else
|
||||
uid_logger("start register by email: type is #{type}")
|
||||
pre = 'm'
|
||||
email = params[:login]
|
||||
phone = nil
|
||||
return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login])
|
||||
return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL
|
||||
# verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last
|
||||
end
|
||||
# uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}")
|
||||
# check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60)
|
||||
# todo 上线前请删除万能验证码"513231"
|
||||
return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD
|
||||
user = Users::RegisterService.call(register_params)
|
||||
password = register_params[:password].strip
|
||||
|
||||
code = generate_identifier User, 8, pre
|
||||
login = pre + code
|
||||
|
||||
is_admin = !User.exists?(type: 'User')
|
||||
@user = User.new(admin: is_admin, login: login, mail: email, phone: phone, type: "User")
|
||||
@user.password = params[:password]
|
||||
# 现在因为是验证码,所以在注册的时候就可以激活
|
||||
@user.activate
|
||||
# 必须要用save操作,密码的保存是在users中
|
||||
|
||||
interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]})
|
||||
# gitea用户注册, email, username, password
|
||||
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
|
||||
if interactor.success?
|
||||
gitea_user = interactor.result
|
||||
result = Gitea::User::GenerateTokenService.new(login, params[:password]).call
|
||||
@user.gitea_token = result['sha1']
|
||||
@user.gitea_uid = gitea_user[:body]['id']
|
||||
if @user.save!
|
||||
# set user for admin role
|
||||
if @user.admin?
|
||||
sync_params = { email: @user.mail, admin: true }
|
||||
Gitea::User::UpdateInteractor.call(@user.login, sync_params)
|
||||
end
|
||||
UserExtension.create!(user_id: @user.id)
|
||||
successful_authentication(@user)
|
||||
normal_status("注册成功")
|
||||
result = Gitea::User::GenerateTokenService.call(user.login, password)
|
||||
user.gitea_token = result['sha1']
|
||||
user.gitea_uid = gitea_user[:body]['id']
|
||||
if user.save!
|
||||
UserExtension.create!(user_id: user.id)
|
||||
successful_authentication(user)
|
||||
render_ok
|
||||
end
|
||||
else
|
||||
tip_exception(-1, interactor.error)
|
||||
end
|
||||
rescue Register::BaseForm::EmailError => e
|
||||
render_error(-2, e.message)
|
||||
rescue Register::BaseForm::LoginError => e
|
||||
render_error(-3, e.message)
|
||||
rescue Register::BaseForm::PhoneError => e
|
||||
render_error(-4, e.message)
|
||||
rescue Register::BaseForm::PasswordFormatError => e
|
||||
render_error(-5, e.message)
|
||||
rescue Register::BaseForm::VerifiCodeError => e
|
||||
render_error(-6, e.message)
|
||||
rescue Exception => e
|
||||
Gitea::User::DeleteService.call(user.login) unless user.nil?
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
|
@ -304,7 +284,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
# 发送验证码
|
||||
# params[:login] 手机号或者邮箱号
|
||||
# params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
|
||||
# params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
|
||||
# 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱
|
||||
# 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效
|
||||
def get_verification_code
|
||||
|
@ -318,19 +298,22 @@ class AccountsController < ApplicationController
|
|||
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
|
||||
tip_exception(501, "请求不合理") if sign != params[:smscode]
|
||||
|
||||
logger.info "########### 验证码:#{verification_code}"
|
||||
logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ")
|
||||
|
||||
# 记录验证码
|
||||
check_verification_code(verification_code, send_type, value)
|
||||
sucess_status
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 1 手机类型;0 邮箱类型
|
||||
# 注意新版的login是自动名生成的
|
||||
def phone_mail_type value
|
||||
value =~ /^1\d{10}$/ ? 1 : 0
|
||||
# check user's login or email or phone is used
|
||||
# params[:value] 手机号或者邮箱号或者登录名
|
||||
# params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号)
|
||||
def check
|
||||
Register::CheckColumnsForm.new(check_params).validate!
|
||||
render_ok
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
|
@ -376,4 +359,13 @@ class AccountsController < ApplicationController
|
|||
def account_params
|
||||
params.require(:account).permit(:login, :password)
|
||||
end
|
||||
|
||||
def check_params
|
||||
params.permit(:type, :value)
|
||||
end
|
||||
|
||||
def register_params
|
||||
params.permit(:login, :namespace, :password, :code)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -10,6 +10,10 @@ class Admins::SystemNotificationsController < Admins::BaseController
|
|||
@notifications = paginate(notifications)
|
||||
end
|
||||
|
||||
def history
|
||||
@users = @notification.users
|
||||
end
|
||||
|
||||
def new
|
||||
@notification = SystemNotification.new
|
||||
end
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController
|
||||
before_action :find_activity_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ActivityForum.ransack(title_cont: params[:search])
|
||||
activity_forums = q.result(distinct: true)
|
||||
@activity_forums = paginate(activity_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@activity_forum = ::Topic::ActivityForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@activity_forum = ::Topic::ActivityForum.new(activity_forum_params)
|
||||
if @activity_forum.save
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "新增平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "新增平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@activity_forum.attributes = activity_forum_params
|
||||
if @activity_forum.save
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "更新平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "更新平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @activity_forum.destroy
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:success] = "删除平台动态成功"
|
||||
else
|
||||
redirect_to admins_topic_activity_forums_path
|
||||
flash[:danger] = "删除平台动态失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_activity_forum
|
||||
@activity_forum = ::Topic::ActivityForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def activity_forum_params
|
||||
params.require(:topic_activity_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::BannersController < Admins::Topic::BaseController
|
||||
before_action :find_banner, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@banners = paginate(::Topic::Banner)
|
||||
end
|
||||
|
||||
def new
|
||||
@banner = ::Topic::Banner.new
|
||||
end
|
||||
|
||||
def create
|
||||
@banner = ::Topic::Banner.new(banner_params)
|
||||
if @banner.save
|
||||
save_image_file(params[:image], @banner)
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "新增banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "新增banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@banner.attributes = banner_params
|
||||
if @banner.save
|
||||
save_image_file(params[:image], @banner)
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "更新banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "更新banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @banner.destroy
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:success] = "删除banner成功"
|
||||
else
|
||||
redirect_to admins_topic_banners_path
|
||||
flash[:danger] = "删除banner失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_banner
|
||||
@banner = ::Topic::Banner.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def banner_params
|
||||
params.require(:topic_banner).permit(:title, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Admins::Topic::BaseController < Admins::BaseController
|
||||
|
||||
protected
|
||||
def save_image_file(file, topic)
|
||||
return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
|
||||
|
||||
file_path = Util::FileManage.source_disk_filename(topic, 'image')
|
||||
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
|
||||
Util.write_file(file, file_path)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::CardsController < Admins::Topic::BaseController
|
||||
before_action :find_card, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::Card.ransack(title_cont: params[:search])
|
||||
cards = q.result(distinct: true)
|
||||
@cards = paginate(cards)
|
||||
end
|
||||
|
||||
def new
|
||||
@card = ::Topic::Card.new
|
||||
end
|
||||
|
||||
def create
|
||||
@card = ::Topic::Card.new(card_params)
|
||||
if @card.save
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "新增合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "新增合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@card.attributes = card_params
|
||||
if @card.save
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "更新合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "更新合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @card.destroy
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:success] = "删除合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cards_path
|
||||
flash[:danger] = "删除合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_card
|
||||
@card = ::Topic::Card.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def card_params
|
||||
params.require(:topic_card).permit(:title, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::CooperatorsController < Admins::Topic::BaseController
|
||||
before_action :find_cooperator, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
@cooperators = paginate(::Topic::Cooperator)
|
||||
end
|
||||
|
||||
def new
|
||||
@cooperator = ::Topic::Cooperator.new
|
||||
end
|
||||
|
||||
def create
|
||||
@cooperator = ::Topic::Cooperator.new(cooperator_params)
|
||||
if @cooperator.save
|
||||
save_image_file(params[:image], @cooperator)
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "新增合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "新增合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@cooperator.attributes = cooperator_params
|
||||
if @cooperator.save
|
||||
save_image_file(params[:image], @cooperator)
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "更新合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "更新合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @cooperator.destroy
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:success] = "删除合作单位成功"
|
||||
else
|
||||
redirect_to admins_topic_cooperators_path
|
||||
flash[:danger] = "删除合作单位失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_cooperator
|
||||
@cooperator = ::Topic::Cooperator.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def cooperator_params
|
||||
params.require(:topic_cooperator).permit(:title, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController
|
||||
before_action :find_excellent_project, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ExcellentProject.ransack(title_cont: params[:search])
|
||||
excellent_projects = q.result(distinct: true)
|
||||
@excellent_projects = paginate(excellent_projects)
|
||||
end
|
||||
|
||||
def new
|
||||
@excellent_project = ::Topic::ExcellentProject.new
|
||||
end
|
||||
|
||||
def create
|
||||
@excellent_project = ::Topic::ExcellentProject.new(excellent_project_params)
|
||||
if @excellent_project.save
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "新增优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "新增优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@excellent_project.attributes = excellent_project_params
|
||||
if @excellent_project.save
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "更新优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "更新优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @excellent_project.destroy
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:success] = "删除优秀仓库成功"
|
||||
else
|
||||
redirect_to admins_topic_excellent_projects_path
|
||||
flash[:danger] = "删除优秀仓库失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_excellent_project
|
||||
@excellent_project = ::Topic::ExcellentProject.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def excellent_project_params
|
||||
params.require(:topic_excellent_project).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController
|
||||
before_action :find_experience_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::ExperienceForum.ransack(title_cont: params[:search])
|
||||
experience_forums = q.result(distinct: true)
|
||||
@experience_forums = paginate(experience_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@experience_forum = ::Topic::ExperienceForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@experience_forum = ::Topic::ExperienceForum.new(experience_forum_params)
|
||||
if @experience_forum.save
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "新增经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "新增经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@experience_forum.attributes = experience_forum_params
|
||||
if @experience_forum.save
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "更新经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "更新经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @experience_forum.destroy
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:success] = "删除经验分享成功"
|
||||
else
|
||||
redirect_to admins_topic_experience_forums_path
|
||||
flash[:danger] = "删除经验分享失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_experience_forum
|
||||
@experience_forum = ::Topic::ExperienceForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def experience_forum_params
|
||||
params.require(:topic_experience_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,57 @@
|
|||
class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController
|
||||
before_action :find_pinned_forum, only: [:edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
q = ::Topic::PinnedForum.ransack(title_cont: params[:search])
|
||||
pinned_forums = q.result(distinct: true)
|
||||
@pinned_forums = paginate(pinned_forums)
|
||||
end
|
||||
|
||||
def new
|
||||
@pinned_forum = ::Topic::PinnedForum.new
|
||||
end
|
||||
|
||||
def create
|
||||
@pinned_forum = ::Topic::PinnedForum.new(pinned_forum_params)
|
||||
if @pinned_forum.save
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "新增精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "新增精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
end
|
||||
|
||||
def update
|
||||
@pinned_forum.attributes = pinned_forum_params
|
||||
if @pinned_forum.save
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "更新精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "更新精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @pinned_forum.destroy
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:success] = "删除精选文章成功"
|
||||
else
|
||||
redirect_to admins_topic_pinned_forums_path
|
||||
flash[:danger] = "删除精选文章失败"
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def find_pinned_forum
|
||||
@pinned_forum = ::Topic::PinnedForum.find_by_id(params[:id])
|
||||
end
|
||||
|
||||
def pinned_forum_params
|
||||
params.require(:topic_pinned_forum).permit(:title, :uuid, :url, :order_index)
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
class Admins::UsersController < Admins::BaseController
|
||||
before_action :finder_user, except: [:index]
|
||||
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
|
@ -8,12 +10,9 @@ class Admins::UsersController < Admins::BaseController
|
|||
end
|
||||
|
||||
def edit
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find(params[:id])
|
||||
|
||||
Admins::UpdateUserService.call(@user, update_params)
|
||||
flash[:success] = '保存成功'
|
||||
redirect_to edit_admins_user_path(@user)
|
||||
|
@ -26,43 +25,47 @@ class Admins::UsersController < Admins::BaseController
|
|||
end
|
||||
|
||||
def destroy
|
||||
User.find(params[:id]).destroy!
|
||||
@user.destroy!
|
||||
Gitea::User::DeleteService.call(@user.login)
|
||||
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
def lock
|
||||
User.find(params[:id]).lock!
|
||||
@user.lock!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def unlock
|
||||
User.find(params[:id]).activate!
|
||||
@user.activate!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
def reward_grade
|
||||
user = User.find(params[:user_id])
|
||||
return render_unprocessable_entity('金币数量必须大于0') if params[:grade].to_i <= 0
|
||||
|
||||
RewardGradeService.call(user, container_id: user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true)
|
||||
RewardGradeService.call(@user, container_id: @user.id, container_type: 'Feedback', score: params[:grade].to_i, not_unique: true)
|
||||
|
||||
render_ok(grade: user.grade)
|
||||
render_ok(grade: @user.grade)
|
||||
end
|
||||
|
||||
def reset_login_times
|
||||
User.find(params[:id]).reset_login_times!
|
||||
@user.reset_login_times!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def finder_user
|
||||
@user = User.find(params[:id])
|
||||
end
|
||||
|
||||
def update_params
|
||||
params.require(:user).permit(%i[lastname nickname gender identity technical_title student_id is_shixun_marker
|
||||
mail phone location location_city school_id department_id admin business is_test
|
||||
password professional_certification authentication])
|
||||
password professional_certification authentication login])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -70,49 +70,11 @@ class ApplicationController < ActionController::Base
|
|||
(current_user.professional_certification && (ue.teacher? || ue.professional?))
|
||||
end
|
||||
|
||||
def shixun_marker
|
||||
unless current_user.is_shixun_marker? || current_user.admin_or_business?
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
# 实训的访问权限
|
||||
def shixun_access_allowed
|
||||
if !current_user.shixun_permission(@shixun)
|
||||
tip_exception(403, "..")
|
||||
end
|
||||
end
|
||||
|
||||
def admin_or_business?
|
||||
User.current.admin? || User.current.business?
|
||||
end
|
||||
|
||||
# 访问课堂时没权限直接弹加入课堂的弹框 :409
|
||||
def user_course_identity
|
||||
@user_course_identity = current_user.course_identity(@course)
|
||||
if @user_course_identity > Course::STUDENT && @course.is_public == 0
|
||||
tip_exception(401, "..") unless User.current.logged?
|
||||
check_account
|
||||
tip_exception(@course.excellent ? 410 : 409, "您没有权限进入")
|
||||
end
|
||||
if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT && @course.tea_id != current_user.id
|
||||
# 实名认证和职业认证的身份判断
|
||||
tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication &&
|
||||
@course.professional_certification && (!current_user.authentication && !current_user.professional_certification)
|
||||
tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication
|
||||
tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification
|
||||
end
|
||||
uid_logger("###############user_course_identity:#{@user_course_identity}")
|
||||
end
|
||||
|
||||
# 题库的访问权限
|
||||
def bank_visit_auth
|
||||
tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public
|
||||
tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? ||
|
||||
(current_user.certification_teacher? && @bank.is_public)
|
||||
end
|
||||
|
||||
|
||||
# 判断用户的邮箱或者手机是否可用
|
||||
# params[:type] 1: 注册;2:忘记密码;3:绑定
|
||||
def check_mail_and_phone_valid login, type
|
||||
|
@ -120,16 +82,16 @@ class ApplicationController < ActionController::Base
|
|||
login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/
|
||||
tip_exception(-2, "请输入正确的手机号或邮箱")
|
||||
end
|
||||
# 考虑到安全参数问题,多一次查询,去掉Union
|
||||
user = User.where(phone: login).first || User.where(mail: login).first
|
||||
if type.to_i == 1 && !user.nil?
|
||||
|
||||
user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login)
|
||||
if user_exist && type.to_i == 1
|
||||
tip_exception(-2, "该手机号码或邮箱已被注册")
|
||||
elsif type.to_i == 2 && user.nil?
|
||||
elsif type.to_i == 2 && !user_exist
|
||||
tip_exception(-2, "该手机号码或邮箱未注册")
|
||||
elsif type.to_i == 3 && user.present?
|
||||
elsif type.to_i == 3 && user_exist
|
||||
tip_exception(-2, "该手机号码或邮箱已绑定")
|
||||
end
|
||||
sucess_status
|
||||
render_ok
|
||||
end
|
||||
|
||||
# 发送及记录激活码
|
||||
|
@ -186,26 +148,6 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
end
|
||||
|
||||
def find_course
|
||||
return normal_status(2, '缺少course_id参数!') if params[:course_id].blank?
|
||||
@course = Course.find(params[:course_id])
|
||||
tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business?
|
||||
rescue Exception => e
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def course_manager
|
||||
return normal_status(403, '只有课堂管理员才有权限') if @user_course_identity > Course::CREATOR
|
||||
end
|
||||
|
||||
def find_board
|
||||
return normal_status(2, "缺少board_id参数") if params[:board_id].blank?
|
||||
@board = Board.find(params[:board_id])
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
|
||||
def validate_type(object_type)
|
||||
normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip)
|
||||
end
|
||||
|
@ -215,21 +157,6 @@ class ApplicationController < ActionController::Base
|
|||
@page_size = params[:page_size] || 15
|
||||
end
|
||||
|
||||
# 课堂教师权限
|
||||
def teacher_allowed
|
||||
logger.info("#####identity: #{current_user.course_identity(@course)}")
|
||||
unless current_user.course_identity(@course) < Course::STUDENT
|
||||
normal_status(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
# 课堂教师、课堂管理员、超级管理员的权限(不包含助教)
|
||||
def teacher_or_admin_allowed
|
||||
unless current_user.course_identity(@course) < Course::ASSISTANT_PROFESSOR
|
||||
normal_status(403, "")
|
||||
end
|
||||
end
|
||||
|
||||
def require_admin
|
||||
normal_status(403, "") unless User.current.admin?
|
||||
end
|
||||
|
@ -681,7 +608,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def kaminari_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
|
@ -689,7 +616,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def kaminari_array_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
Kaminari.paginate_array(relation).page(page).per(limit)
|
||||
|
|
|
@ -3,8 +3,8 @@ module RenderHelper
|
|||
render json: { status: 0, message: 'success' }.merge(data)
|
||||
end
|
||||
|
||||
def render_error(message = '')
|
||||
render json: { status: -1, message: message }
|
||||
def render_error(status = -1, message = '')
|
||||
render json: { status: status, message: message }
|
||||
end
|
||||
|
||||
def render_not_acceptable(message = '请求已拒绝')
|
||||
|
|
|
@ -27,7 +27,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.is_reversed(organization_params[:name]).present?
|
||||
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
|
||||
Organizations::CreateForm.new(organization_params).validate!
|
||||
@organization = Organizations::CreateService.call(current_user, organization_params)
|
||||
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
class TopicsController < ApplicationController
|
||||
|
||||
def index
|
||||
return render_not_found("请输入正确的数据类型") unless params[:topic_type].present?
|
||||
scope = Topic.with_single_type(params[:topic_type])
|
||||
@topics = kaminari_paginate(scope)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class Users::SystemNotificationHistoriesController < Users::BaseController
|
||||
before_action :private_user_resources!, only: [:create]
|
||||
def create
|
||||
@history = observed_user.system_notification_histories.new(system_notification_id: params[:system_notification_id])
|
||||
if @history.save
|
||||
render_ok
|
||||
else
|
||||
Rails.logger.info @history.errors.as_json
|
||||
render_error(@history.errors.full_messages.join(","))
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
end
|
||||
end
|
|
@ -199,6 +199,36 @@ await octokit.request('GET /api/users/:login/messages.json')
|
|||
Success Data.
|
||||
</aside>
|
||||
|
||||
## 用户阅读系统通知
|
||||
用户阅读系统通知
|
||||
|
||||
> 示例:
|
||||
|
||||
```shell
|
||||
curl -X POST http://localhost:3000/api/users/yystopf/system_notification_histories.json
|
||||
```
|
||||
|
||||
```javascript
|
||||
await octokit.request('GET /api/users/:login/system_notification_histories.json')
|
||||
```
|
||||
|
||||
### HTTP 请求
|
||||
`POST /api/users/:login/system_notification_histories.json`
|
||||
|
||||
### 请求字段说明:
|
||||
参数 | 类型 | 字段说明
|
||||
--------- | ----------- | -----------
|
||||
|system_notification_id |integer |阅读的系统通知id |
|
||||
|
||||
> 返回的JSON示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": 0,
|
||||
"message": "success"
|
||||
}
|
||||
```
|
||||
|
||||
## 发送消息
|
||||
发送消息, 目前只支持atme
|
||||
|
||||
|
|
|
@ -23,7 +23,11 @@ class BaseForm
|
|||
end
|
||||
|
||||
def check_reversed_keyword(repository_name)
|
||||
raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists?
|
||||
raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name)
|
||||
end
|
||||
|
||||
private
|
||||
def strip(str)
|
||||
str.to_s.strip.presence
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
module Register
|
||||
class BaseForm < ::BaseForm
|
||||
include ActiveModel::Model
|
||||
|
||||
Error = Class.new(StandardError)
|
||||
EmailError = Class.new(Error)
|
||||
LoginError = Class.new(Error)
|
||||
PhoneError = Class.new(Error)
|
||||
PasswordFormatError = Class.new(Error)
|
||||
VerifiCodeError = Class.new(Error)
|
||||
|
||||
private
|
||||
def check_login(login)
|
||||
login = strip(login)
|
||||
raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN
|
||||
|
||||
login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login)
|
||||
raise LoginError, '登录名已被使用' if login_exist
|
||||
end
|
||||
|
||||
def check_mail(mail)
|
||||
mail = strip(mail)
|
||||
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
|
||||
|
||||
mail_exist = Owner.exists?(mail: mail)
|
||||
raise EmailError, '邮箱已被使用' if mail_exist
|
||||
end
|
||||
|
||||
def check_phone(phone)
|
||||
phone = strip(phone)
|
||||
raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE
|
||||
|
||||
phone_exist = Owner.exists?(phone: phone)
|
||||
raise PhoneError, '手机号已被使用' if phone_exist
|
||||
end
|
||||
|
||||
def check_password(password)
|
||||
password = strip(password)
|
||||
raise PasswordFormatError, "8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
|
||||
end
|
||||
|
||||
def check_verifi_code(verifi_code, code)
|
||||
code = strip(code)
|
||||
# return if code == "123123" # TODO 万能验证码,用于测试
|
||||
|
||||
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
|
||||
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
module Register
|
||||
class CheckColumnsForm < Register::BaseForm
|
||||
attr_accessor :type, :value
|
||||
|
||||
validates :type, presence: true, numericality: true
|
||||
validates :value, presence: true
|
||||
validate :check!
|
||||
|
||||
def check!
|
||||
# params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号)
|
||||
case strip(type).to_i
|
||||
when 1 then check_login(strip(value))
|
||||
when 2 then check_mail(strip(value))
|
||||
when 3 then check_phone(strip(value))
|
||||
else raise("type值无效")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
module Register
|
||||
class Form < Register::BaseForm
|
||||
# login 登陆方式,支持邮箱、登陆、手机号等
|
||||
# namespace 用户空间地址
|
||||
# type: 1:手机号注册;2:邮箱注册
|
||||
attr_accessor :login, :namespace, :password, :code, :type
|
||||
|
||||
validates :login, :code, :password, :namespace, presence: true
|
||||
validate :check!
|
||||
|
||||
def check!
|
||||
Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}"
|
||||
db_verifi_code =
|
||||
if type == 1
|
||||
check_phone(login)
|
||||
VerificationCode.where(phone: login, code: code, code_type: 1).last
|
||||
elsif type == 0
|
||||
check_mail(login)
|
||||
VerificationCode.where(email: login, code: code, code_type: 8).last
|
||||
end
|
||||
|
||||
check_login(namespace)
|
||||
check_verifi_code(db_verifi_code, code)
|
||||
check_password(password)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -463,5 +463,11 @@ module ApplicationHelper
|
|||
sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root')
|
||||
end
|
||||
end
|
||||
|
||||
# 1 手机类型;0 邮箱类型
|
||||
# 注意新版的login是自动名生成的
|
||||
def phone_mail_type value
|
||||
value =~ /^1\d{10}$/ ? 1 : 0
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
module CustomRegexp
|
||||
PHONE = /1\d{10}/
|
||||
EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/
|
||||
LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/
|
||||
NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/
|
||||
PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
module Forum
|
||||
class << self
|
||||
def forum_config
|
||||
forum_config = {}
|
||||
|
||||
begin
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
forum_config = config[:forum].symbolize_keys!
|
||||
raise 'forum config missing' if forum_config.blank?
|
||||
rescue => ex
|
||||
raise ex if Rails.env.production?
|
||||
|
||||
puts %Q{\033[33m [warning] forum config or configuration.yml missing,
|
||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||
forum_config = {}
|
||||
end
|
||||
forum_config
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,17 +1,11 @@
|
|||
class UserMailer < ApplicationMailer
|
||||
# 注意:这个地方一定要和你的邮箱服务域名一致
|
||||
default from: 'educoder@trustie.org'
|
||||
default from: 'notification@trustie.org'
|
||||
|
||||
# 用户注册验证码
|
||||
def register_email(mail, code)
|
||||
@code = code
|
||||
mail(to: mail, subject: '验证你的电子邮件')
|
||||
mail(to: mail, subject: 'Gitink | 注册验证码')
|
||||
end
|
||||
|
||||
# 课堂讨论区的邮件通知
|
||||
def course_message_email(mail, message_id)
|
||||
@message = Message.find_by(id: message_id)
|
||||
@course = @message&.board&.course
|
||||
mail(to: mail, subject: '课堂发布了新的帖子') if @message.present? && @course.present?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,6 +18,10 @@ class ReversedKeyword < ApplicationRecord
|
|||
|
||||
before_validation :set_identifier
|
||||
|
||||
def self.check_exists?(identifier)
|
||||
self.is_reversed(identifier).exists?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_identifier
|
||||
|
|
|
@ -15,6 +15,13 @@ class SystemNotification < ApplicationRecord
|
|||
|
||||
default_scope { order(created_at: :desc)}
|
||||
|
||||
has_many :system_notification_histories
|
||||
has_many :users, through: :system_notification_histories
|
||||
|
||||
scope :is_top, lambda { where(is_top: true) }
|
||||
|
||||
def read_member?(user_id)
|
||||
self.system_notification_histories.where(user_id: user_id).present? ? true : false
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: system_notification_histories
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# system_message_id :integer
|
||||
# user_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_system_notification_histories_on_system_message_id (system_message_id)
|
||||
# index_system_notification_histories_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class SystemNotificationHistory < ApplicationRecord
|
||||
|
||||
belongs_to :system_notification
|
||||
belongs_to :user
|
||||
|
||||
validates :system_notification_id, uniqueness: { scope: :user_id, message: '只能阅读一次'}
|
||||
end
|
|
@ -0,0 +1,50 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
class Topic < ApplicationRecord
|
||||
|
||||
default_scope { order(order_index: :desc)}
|
||||
|
||||
scope :with_single_type, ->(type){where(type: trans_simpletype_to_classtype(type))}
|
||||
|
||||
def image
|
||||
image_url('image')
|
||||
end
|
||||
|
||||
def self.trans_simpletype_to_classtype(type)
|
||||
case type
|
||||
when 'activity_forum'
|
||||
'Topic::ActivityForum'
|
||||
when 'banner'
|
||||
'Topic::Banner'
|
||||
when 'card'
|
||||
'Topic::Card'
|
||||
when 'cooperator'
|
||||
'Topic::Cooperator'
|
||||
when 'excellent_project'
|
||||
'Topic::ExcellentProject'
|
||||
when 'experience_forum'
|
||||
'Topic::ExperienceForum'
|
||||
when 'pinned_forum'
|
||||
'Topic::PinnedForum'
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def image_url(type)
|
||||
return nil unless Util::FileManage.exists?(self, type)
|
||||
Util::FileManage.source_disk_file_url(self, type)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页平台动态
|
||||
class Topic::ActivityForum < Topic
|
||||
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页banner
|
||||
class Topic::Banner < Topic
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页卡片内容
|
||||
class Topic::Card < Topic
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页合作伙伴
|
||||
class Topic::Cooperator < Topic
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页优秀项目
|
||||
class Topic::ExcellentProject < Topic
|
||||
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页经验分享
|
||||
class Topic::ExperienceForum < Topic
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: topics
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# title :string(255)
|
||||
# uuid :integer
|
||||
# image_url :string(255)
|
||||
# url :string(255)
|
||||
# order_index :integer
|
||||
#
|
||||
|
||||
# 首页精选文章
|
||||
class Topic::PinnedForum < Topic
|
||||
end
|
|
@ -117,8 +117,6 @@ class User < Owner
|
|||
enumerize :platform, in: [:forge, :educoder, :trustie, :military], default: :forge, scope: :shallow
|
||||
|
||||
belongs_to :laboratory, optional: true
|
||||
has_many :composes, dependent: :destroy
|
||||
has_many :compose_users, dependent: :destroy
|
||||
has_one :user_extension, dependent: :destroy
|
||||
has_many :open_users, dependent: :destroy
|
||||
has_one :wechat_open_user, class_name: 'OpenUsers::Wechat'
|
||||
|
@ -174,6 +172,9 @@ class User < Owner
|
|||
|
||||
has_one :user_template_message_setting, dependent: :destroy
|
||||
|
||||
has_many :system_notification_histories
|
||||
has_many :system_notifications, through: :system_notification_histories
|
||||
|
||||
# Groups and active users
|
||||
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
|
||||
scope :like, lambda { |keywords|
|
||||
|
@ -440,6 +441,7 @@ class User < Owner
|
|||
|
||||
def activate!
|
||||
update_attribute(:status, STATUS_ACTIVE)
|
||||
prohibit_gitea_user_login!(false)
|
||||
end
|
||||
|
||||
def register!
|
||||
|
@ -448,6 +450,12 @@ class User < Owner
|
|||
|
||||
def lock!
|
||||
update_attribute(:status, STATUS_LOCKED)
|
||||
prohibit_gitea_user_login!
|
||||
end
|
||||
|
||||
def prohibit_gitea_user_login!(prohibit_login = true)
|
||||
Gitea::User::UpdateInteractor.call(self.login,
|
||||
{email: self.mail, prohibit_login: prohibit_login})
|
||||
end
|
||||
|
||||
def need_edit_info!
|
||||
|
|
|
@ -11,20 +11,45 @@ class Projects::ListQuery < ApplicationQuery
|
|||
end
|
||||
|
||||
def call
|
||||
q = params[:pinned].present? ? Project.pinned : Project
|
||||
q = q.visible.by_name_or_identifier(params[:search])
|
||||
|
||||
scope = q
|
||||
.with_project_type(params[:project_type])
|
||||
.with_project_category(params[:category_id])
|
||||
.with_project_language(params[:language_id])
|
||||
collection = Project.all
|
||||
collection = filter_projects(collection)
|
||||
|
||||
sort = params[:sort_by] || "updated_on"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
|
||||
custom_sort(scope, sort, sort_direction)
|
||||
custom_sort(collection, sort, sort_direction)
|
||||
|
||||
# scope = scope.reorder("projects.#{sort} #{sort_direction}")
|
||||
# scope
|
||||
end
|
||||
|
||||
def filter_projects(collection)
|
||||
collection = by_pinned(collection)
|
||||
collection = by_search(collection)
|
||||
collection = by_project_type(collection)
|
||||
collection = by_project_category(collection)
|
||||
collection = by_project_language(collection)
|
||||
collection
|
||||
end
|
||||
|
||||
def by_search(items)
|
||||
items.visible.by_name_or_identifier(params[:search])
|
||||
end
|
||||
|
||||
def by_project_type(items)
|
||||
items.with_project_type(params[:project_type])
|
||||
end
|
||||
|
||||
def by_project_category(items)
|
||||
items.with_project_category(params[:category_id])
|
||||
end
|
||||
|
||||
def by_project_language(items)
|
||||
items.with_project_language(params[:language_id])
|
||||
end
|
||||
|
||||
def by_pinned(items)
|
||||
(params[:pinned].present? && params[:category_id].present?) ? items.pinned : items
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,19 +15,13 @@ class Admins::UpdateUserService < ApplicationService
|
|||
user.firstname = ''
|
||||
user.password = params[:password] if params[:password].present?
|
||||
|
||||
if params[:identity].to_s == 'student'
|
||||
params[:technical_title] = nil
|
||||
else
|
||||
params[:student_id] = nil
|
||||
end
|
||||
user.user_extension.assign_attributes(user_extension_attributes)
|
||||
|
||||
old_login = user.login
|
||||
ActiveRecord::Base.transaction do
|
||||
user.save!
|
||||
user.user_extension.save!
|
||||
user.update!(is_shixun_marker: true) if user.is_certification_teacher
|
||||
|
||||
update_gitlab_password if params[:password].present?
|
||||
update_gitea_user(old_login)
|
||||
end
|
||||
|
||||
user
|
||||
|
@ -36,7 +30,7 @@ class Admins::UpdateUserService < ApplicationService
|
|||
private
|
||||
|
||||
def user_attributes
|
||||
params.slice(*%i[lastname nickname mail phone admin business is_test
|
||||
params.slice(*%i[lastname nickname mail phone admin business is_test login
|
||||
professional_certification authentication is_shixun_marker])
|
||||
end
|
||||
|
||||
|
@ -44,10 +38,29 @@ class Admins::UpdateUserService < ApplicationService
|
|||
params.slice(*%i[gender identity technical_title student_id location location_city school_id department_id])
|
||||
end
|
||||
|
||||
def update_gitlab_password
|
||||
return if user.gid.blank?
|
||||
# 同步修改gitlab密码
|
||||
Gitlab.client.edit_user(user.gid, password: params[:password])
|
||||
def gitea_user_params
|
||||
hash = {
|
||||
password: params[:password].to_s.presence,
|
||||
email: user.mail,
|
||||
login_name: params[:login].to_s.presence,
|
||||
admin: boolean_admin
|
||||
}.compact
|
||||
|
||||
hash.delete_if {|_,v| v.to_s.strip == ''}
|
||||
end
|
||||
|
||||
def boolean_admin
|
||||
admin = params[:admin].to_s.presence
|
||||
case admin
|
||||
when "0" then false
|
||||
when "1" then true
|
||||
end
|
||||
end
|
||||
|
||||
def update_gitea_user(old_login)
|
||||
return if user.gitea_uid.blank?
|
||||
|
||||
Gitea::User::UpdateInteractor.call(old_login, gitea_user_params)
|
||||
rescue Exception => ex
|
||||
Util.logger_error(ex)
|
||||
raise Error, '保存失败'
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
class Forum::ClientService < ApplicationService
|
||||
attr_reader :url, :params
|
||||
|
||||
PAGINATE_DEFAULT_PAGE = 1
|
||||
PAGINATE_DEFAULT_LIMIT = 20
|
||||
|
||||
def initialize(options={})
|
||||
@url = options[:url]
|
||||
@params = options[:params]
|
||||
end
|
||||
|
||||
def get(url, params={})
|
||||
conn(params).get do |req|
|
||||
req.url full_url(url, 'get')
|
||||
params.except(:token).each_pair do |key, value|
|
||||
req.params["#{key}"] = value
|
||||
end
|
||||
end
|
||||
|
||||
# response.headers.each do |k,v|
|
||||
# puts "#{k}:#{v}"
|
||||
# end #=> 响应头
|
||||
end
|
||||
|
||||
private
|
||||
def conn(auth={})
|
||||
@client ||= begin
|
||||
Faraday.new(url: domain) do |req|
|
||||
req.request :url_encoded
|
||||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
end
|
||||
end
|
||||
@client
|
||||
end
|
||||
|
||||
def base_url
|
||||
Forum.forum_config[:base_url]
|
||||
end
|
||||
|
||||
def domain
|
||||
Forum.forum_config[:domain]
|
||||
end
|
||||
|
||||
def api_url
|
||||
[domain, base_url].join('')
|
||||
end
|
||||
|
||||
def full_url(api_rest, action='post')
|
||||
url = [api_url, api_rest].join('').freeze
|
||||
url = action === 'get' ? url : URI.escape(url)
|
||||
url = URI.escape(url) unless url.ascii_only?
|
||||
puts "[forum] request url: #{url}"
|
||||
return url
|
||||
end
|
||||
|
||||
def render_response(response)
|
||||
status = response.status
|
||||
body = response&.body
|
||||
|
||||
# log_error(status, body)
|
||||
|
||||
body, message = get_body_by_status(status, body)
|
||||
|
||||
[status, message, body]
|
||||
end
|
||||
|
||||
def get_body_by_status(status, body)
|
||||
body, message =
|
||||
case status
|
||||
when 401 then [nil, "401"]
|
||||
when 404 then [nil, "404"]
|
||||
when 403 then [nil, "403"]
|
||||
when 500 then [nil, "500"]
|
||||
else
|
||||
if body.present?
|
||||
body = JSON.parse(body)
|
||||
fix_body(body)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
[body, message]
|
||||
end
|
||||
|
||||
def fix_body(body)
|
||||
return [body, nil] if body.is_a?(Array) || body.is_a?(Hash)
|
||||
|
||||
body['message'].blank? ? [body, nil] : [nil, body['message']]
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,21 @@
|
|||
class Forum::Memos::GetService < Forum::ClientService
|
||||
attr_reader :memo_id
|
||||
|
||||
def initialize(memo_id)
|
||||
@memo_id = memo_id
|
||||
end
|
||||
|
||||
def call
|
||||
response = get(url)
|
||||
code, message, body = render_response(response)
|
||||
if code == 200 && body["status"] == 0
|
||||
return body
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
def url
|
||||
"/memos/#{memo_id}.json".freeze
|
||||
end
|
||||
end
|
|
@ -82,6 +82,8 @@ class Gitea::ClientService < ApplicationService
|
|||
req.headers['Content-Type'] = 'application/json'
|
||||
req.response :logger # 显示日志
|
||||
req.adapter Faraday.default_adapter
|
||||
req.options.timeout = 100 # open/read timeout in seconds
|
||||
req.options.open_timeout = 10 # connection open timeout in seconds
|
||||
if token.blank?
|
||||
req.basic_auth(username, secret)
|
||||
else
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
class Gitea::User::DeleteService < Gitea::ClientService
|
||||
attr_reader :username
|
||||
|
||||
def initialize(username)
|
||||
@username = username
|
||||
end
|
||||
|
||||
def call
|
||||
response = delete(request_url, params)
|
||||
|
||||
render_status(response)
|
||||
end
|
||||
|
||||
private
|
||||
def token
|
||||
{
|
||||
username: Gitea.gitea_config[:access_key_id],
|
||||
password: Gitea.gitea_config[:access_key_secret]
|
||||
}
|
||||
end
|
||||
|
||||
def request_url
|
||||
"/admin/users/#{username}"
|
||||
end
|
||||
|
||||
def params
|
||||
Hash.new.merge(token: token)
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1,58 @@
|
|||
class Users::RegisterService < ApplicationService
|
||||
def initialize(params)
|
||||
@login = params[:login]
|
||||
@namespace = params[:namespace]
|
||||
@password = params[:password]
|
||||
@code = params[:code]
|
||||
end
|
||||
|
||||
def call
|
||||
code = strip(@code)
|
||||
login = strip(@login)
|
||||
namespace = strip(@namespace)
|
||||
password = strip(@password)
|
||||
|
||||
Rails.logger.info "Users::RegisterService params: ##### #{params} "
|
||||
|
||||
email, phone =
|
||||
if register_type == 1
|
||||
phone_register(login, code)
|
||||
elsif register_type == 0
|
||||
mail_register(login, code)
|
||||
end
|
||||
|
||||
user = User.new(admin: false, login: namespace, mail: email, phone: phone, type: "User")
|
||||
user.password = password
|
||||
user.activate # 现在因为是验证码,所以在注册的时候就可以激活
|
||||
|
||||
user
|
||||
end
|
||||
|
||||
private
|
||||
# 手机注册
|
||||
def phone_register(login, code)
|
||||
Rails.logger.info("start register by phone: phone is #{login}")
|
||||
email = nil
|
||||
phone = login
|
||||
|
||||
[email, phone]
|
||||
end
|
||||
|
||||
# 邮箱注册
|
||||
def mail_register(login, code)
|
||||
Rails.logger.info("start register by email: email is #{login}")
|
||||
email = login
|
||||
phone = nil
|
||||
|
||||
[email, phone]
|
||||
end
|
||||
|
||||
def register_type
|
||||
phone_mail_type(@login)
|
||||
end
|
||||
|
||||
def phone_mail_type value
|
||||
value =~ /^1\d{10}$/ ? 1 : 0
|
||||
end
|
||||
|
||||
end
|
|
@ -31,17 +31,30 @@
|
|||
|
||||
<li><%= sidebar_item(admins_reversed_keywords_path, '系统保留关键词', icon: 'key', controller: 'admins-reversed_keywords') %></li>
|
||||
<li><%= sidebar_item(admins_laboratories_path, '云上实验室', icon: 'cloud', controller: 'admins-laboratories') %></li>
|
||||
|
||||
<!-- <li>
|
||||
<li>
|
||||
<%= sidebar_item_group('#setting-index', '首页配置', icon: 'file') do %>
|
||||
<li><%= sidebar_item(admins_topic_banners_path, 'banner管理', icon: 'image', controller: 'admins-topic-banners') %></li>
|
||||
<li><%= sidebar_item(admins_topic_cards_path, '卡片管理', icon: 'archive', controller: 'admins-topic-cards') %></li>
|
||||
<li><%= sidebar_item(admins_topic_activity_forums_path, '平台动态管理', icon: 'bell', controller: 'admins-topic-activity_forums') %></li>
|
||||
<li><%= sidebar_item(admins_topic_excellent_projects_path, '优秀仓库管理', icon: 'git', controller: 'admins-topic-excellent_projects') %></li>
|
||||
<li><%= sidebar_item(admins_topic_pinned_forums_path, '精选文章管理', icon: 'edit', controller: 'admins-topic-pinned_forums') %></li>
|
||||
<li><%= sidebar_item(admins_topic_experience_forums_path, '经验分享管理', icon: 'edit', controller: 'admins-topic-experience_forums') %></li>
|
||||
<li><%= sidebar_item(admins_topic_cooperators_path, '合作伙伴管理', icon: 'user', controller: 'admins-topic-cooperators') %></li>
|
||||
<% end %>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
|
||||
<!-- >
|
||||
<li><%= sidebar_item(edit_admins_about_path, '关于我们', icon: 'smile-o', controller: 'admins-abouts') %></li>
|
||||
<li><%= sidebar_item(edit_admins_contact_us_path, '联系我们', icon: 'commenting-o', controller: 'admins-contact_us') %></li>
|
||||
<li><%= sidebar_item(admins_cooperatives_path, '合作伙伴', icon: 'handshake-o', controller: 'admins-cooperatives') %></li>
|
||||
<li><%= sidebar_item(edit_admins_agreement_path, '服务协议', icon: 'file-text-o', controller: 'admins-agreements') %></li>
|
||||
<li><%= sidebar_item(edit_admins_help_center_path, '帮助中心', icon: 'question-circle-o', controller: 'admins-help_centers') %></li>
|
||||
-->
|
||||
<li><%= sidebar_item(admins_faqs_path, 'FAQ', icon: 'question-circle', controller: 'admins-faqs') %></li>
|
||||
<% end %>
|
||||
</li> -->
|
||||
</li>
|
||||
<li>
|
||||
<%= sidebar_item_group('#setting-system', '系统配置', icon: 'wrench') do %>
|
||||
<li><%= sidebar_item(admins_sites_path, 'setting接口配置', icon: 'deaf', controller: 'admins-sites') %></li>
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<div class="modal fade activity-forum-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @activity_forum, url: {controller: "topic/activity_forums", action: "#{type}"} do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
帖子ID <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :uuid,class: "form-control input-lg",required: true%>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, 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>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="10%">帖子ID</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if activity_forums.present? %>
|
||||
<% activity_forums.each_with_index do |activity_forum, index| %>
|
||||
<tr class="activity-forum-item-<%= activity_forum.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= activity_forum.title %></td>
|
||||
<td><%= activity_forum.url %></td>
|
||||
<td><%= activity_forum.uuid %></td>
|
||||
<td><%= activity_forum.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_activity_forum_path(activity_forum), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_activity_forum_path(activity_forum), 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: activity_forums } %>
|
|
@ -0,0 +1,2 @@
|
|||
$("#activity-forum-modals").html("<%= j render(partial: 'admins/topic/activity_forums/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".activity-forum-change-modal").modal('show');
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('平台动态管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_activity_forums_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_topic_activity_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container activity-forum-list-container">
|
||||
<%= render partial: 'admins/topic/activity_forums/list', locals: { activity_forums: @activity_forums } %>
|
||||
</div>
|
||||
<div id="activity-forum-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.activity-forum-list-container').html("<%= j( render partial: 'admins/topic/activity_forums/list', locals: { activity_forums: @activity_forums } ) %>");
|
|
@ -0,0 +1,2 @@
|
|||
$("#activity-forum-modals").html("<%= j render(partial: 'admins/topic/activity_forums/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".activity-forum-change-modal").modal('show');
|
|
@ -0,0 +1,45 @@
|
|||
<div class="modal fade banner-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @banner, url: {controller: "topic/banners", action: "#{type}"}, html: { enctype: 'multipart/form-data' } do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,class: "form-control input-lg",required: true%>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, class: "form-control",placeholder: ""%>
|
||||
</div>
|
||||
<div class="logo-item">
|
||||
<% logo_img = @banner.image %>
|
||||
<div class="logo-item-left mr-3 <%= logo_img ? 'has-img' : '' %>">
|
||||
<img class="logo-item-img nav-logo-img" src="<%= logo_img %>" style="<%= logo_img.present? ? '' : 'display: none' %>"/>
|
||||
<%= file_field_tag(:image, accept: 'image/png,image/jpg,image/jpeg',style: "display: none", value: params[:image]) %>
|
||||
<label for="image" class="logo-item-upload" data-toggle="tooltip" data-title="选择图片"></label>
|
||||
</div>
|
||||
<div class="logo-item-right">
|
||||
<div class="logo-item-title flex-1">logo</div>
|
||||
<div>格式:PNG、JPG</div>
|
||||
<div>尺寸:高度38px以内,宽等比例缩放</div>
|
||||
</div>
|
||||
</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>
|
|
@ -0,0 +1,31 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">图片</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if banners.present? %>
|
||||
<% banners.each_with_index do |banner, index| %>
|
||||
<tr class="banner-item-<%= banner.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= banner.title %></td>
|
||||
<td><img style="width:150px" src="<%= banner.image %>" /></td>
|
||||
<td><%= banner.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_banner_path(banner), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_banner_path(banner), 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: banners } %>
|
|
@ -0,0 +1,18 @@
|
|||
$("#banner-modals").html("<%= j render(partial: 'admins/topic/banners/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".banner-change-modal").modal('show');
|
||||
|
||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||
var $fileInput = $(this);
|
||||
var file = this.files[0];
|
||||
var imageType = /image.*/;
|
||||
if (file && file.type.match(imageType)) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
var $box = $fileInput.parent();
|
||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||
$box.addClass('has-img');
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
}
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('卡片管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_banners_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_topic_banner_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container banner-list-container">
|
||||
<%= render partial: 'admins/topic/banners/list', locals: { banners: @banners } %>
|
||||
</div>
|
||||
<div id="banner-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.banner-list-container').html("<%= j( render partial: 'admins/topic/banners/list', locals: { banners: @banners } ) %>");
|
|
@ -0,0 +1,18 @@
|
|||
$("#banner-modals").html("<%= j render(partial: 'admins/topic/banners/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".banner-change-modal").modal('show');
|
||||
|
||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||
var $fileInput = $(this);
|
||||
var file = this.files[0];
|
||||
var imageType = /image.*/;
|
||||
if (file && file.type.match(imageType)) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
var $box = $fileInput.parent();
|
||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||
$box.addClass('has-img');
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
}
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
<div class="modal fade card-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @card, url: {controller: "topic/cards", action: "#{type}"} do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, 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>
|
|
@ -0,0 +1,31 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if cards.present? %>
|
||||
<% cards.each_with_index do |card, index| %>
|
||||
<tr class="card-item-<%= card.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= card.title %></td>
|
||||
<td><%= card.url %></td>
|
||||
<td><%= card.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_card_path(card), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_card_path(card), 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: cards } %>
|
|
@ -0,0 +1,2 @@
|
|||
$("#card-modals").html("<%= j render(partial: 'admins/topic/cards/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".card-change-modal").modal('show');
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('卡片管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_cards_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_topic_card_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container card-list-container">
|
||||
<%= render partial: 'admins/topic/cards/list', locals: { cards: @cards } %>
|
||||
</div>
|
||||
<div id="card-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.card-list-container').html("<%= j( render partial: 'admins/topic/cards/list', locals: { cards: @cards } ) %>");
|
|
@ -0,0 +1,2 @@
|
|||
$("#card-modals").html("<%= j render(partial: 'admins/topic/cards/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".card-change-modal").modal('show');
|
|
@ -0,0 +1,51 @@
|
|||
<div class="modal fade cooperator-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @cooperator, url: {controller: "topic/cooperators", action: "#{type}"}, html: { enctype: 'multipart/form-data' } do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, class: "form-control",placeholder: ""%>
|
||||
</div>
|
||||
<div class="logo-item">
|
||||
<% logo_img = @cooperator.image %>
|
||||
<div class="logo-item-left mr-3 <%= logo_img ? 'has-img' : '' %>">
|
||||
<img class="logo-item-img nav-logo-img" src="<%= logo_img %>" style="<%= logo_img.present? ? '' : 'display: none' %>"/>
|
||||
<%= file_field_tag(:image, accept: 'image/png,image/jpg,image/jpeg',style: "display: none", value: params[:image]) %>
|
||||
<label for="image" class="logo-item-upload" data-toggle="tooltip" data-title="选择图片"></label>
|
||||
</div>
|
||||
<div class="logo-item-right">
|
||||
<div class="logo-item-title flex-1">logo</div>
|
||||
<div>格式:PNG、JPG</div>
|
||||
<div>尺寸:高度38px以内,宽等比例缩放</div>
|
||||
</div>
|
||||
</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>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="20%">图片</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if cooperators.present? %>
|
||||
<% cooperators.each_with_index do |cooperator, index| %>
|
||||
<tr class="cooperator-item-<%= cooperator.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= cooperator.title %></td>
|
||||
<td><%= cooperator.url %></td>
|
||||
<td><img style="width:150px" src="<%= cooperator.image %>" /></td>
|
||||
<td><%= cooperator.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_cooperator_path(cooperator), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_cooperator_path(cooperator), 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: cooperators } %>
|
|
@ -0,0 +1,18 @@
|
|||
$("#cooperator-modals").html("<%= j render(partial: 'admins/topic/cooperators/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".cooperator-change-modal").modal('show');
|
||||
|
||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||
var $fileInput = $(this);
|
||||
var file = this.files[0];
|
||||
var imageType = /image.*/;
|
||||
if (file && file.type.match(imageType)) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
var $box = $fileInput.parent();
|
||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||
$box.addClass('has-img');
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
}
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('卡片管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_cooperators_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_topic_cooperator_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container cooperator-list-container">
|
||||
<%= render partial: 'admins/topic/cooperators/list', locals: { cooperators: @cooperators } %>
|
||||
</div>
|
||||
<div id="cooperator-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.cooperator-list-container').html("<%= j( render partial: 'admins/topic/cooperators/list', locals: { cooperators: @cooperators } ) %>");
|
|
@ -0,0 +1,18 @@
|
|||
$("#cooperator-modals").html("<%= j render(partial: 'admins/topic/cooperators/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".cooperator-change-modal").modal('show');
|
||||
|
||||
$('.logo-item-left').on("change", 'input[type="file"]', function () {
|
||||
var $fileInput = $(this);
|
||||
var file = this.files[0];
|
||||
var imageType = /image.*/;
|
||||
if (file && file.type.match(imageType)) {
|
||||
var reader = new FileReader();
|
||||
reader.onload = function () {
|
||||
var $box = $fileInput.parent();
|
||||
$box.find('img').attr('src', reader.result).css('display', 'block');
|
||||
$box.addClass('has-img');
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
} else {
|
||||
}
|
||||
});
|
|
@ -0,0 +1,44 @@
|
|||
<div class="modal fade excellent-project-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @excellent_project, url: {controller: "topic/excellent_projects", action: "#{type}"} do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
项目ID <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.number_field :uuid,class: "form-control input-lg",required: true%>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, 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>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="10%">项目ID</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if excellent_projects.present? %>
|
||||
<% excellent_projects.each_with_index do |excellent_project, index| %>
|
||||
<tr class="excellent-project-item-<%= excellent_project.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= excellent_project.title %></td>
|
||||
<td><%= excellent_project.url %></td>
|
||||
<td><%= excellent_project.uuid %></td>
|
||||
<td><%= excellent_project.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_excellent_project_path(excellent_project), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_excellent_project_path(excellent_project), 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: excellent_projects } %>
|
|
@ -0,0 +1,2 @@
|
|||
$("#excellent-project-modals").html("<%= j render(partial: 'admins/topic/excellent_projects/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".excellent-project-change-modal").modal('show');
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('优秀仓库管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_excellent_projects_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_topic_excellent_project_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container excellent-project-list-container">
|
||||
<%= render partial: 'admins/topic/excellent_projects/list', locals: { excellent_projects: @excellent_projects } %>
|
||||
</div>
|
||||
<div id="excellent-project-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.excellent-project-list-container').html("<%= j( render partial: 'admins/topic/excellent_projects/list', locals: { excellent_projects: @excellent_projects } ) %>");
|
|
@ -0,0 +1,2 @@
|
|||
$("#excellent-project-modals").html("<%= j render(partial: 'admins/topic/excellent_projects/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".excellent-project-change-modal").modal('show');
|
|
@ -0,0 +1,44 @@
|
|||
<div class="modal fade experience-forum-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @experience_forum, url: {controller: "topic/experience_forums", action: "#{type}"} do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
帖子ID <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.number_field :uuid,class: "form-control input-lg",required: true%>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, 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>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="10%">帖子ID</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if experience_forums.present? %>
|
||||
<% experience_forums.each_with_index do |experience_forum, index| %>
|
||||
<tr class="experience-forum-item-<%= experience_forum.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= experience_forum.title %></td>
|
||||
<td><%= experience_forum.url %></td>
|
||||
<td><%= experience_forum.uuid %></td>
|
||||
<td><%= experience_forum.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_experience_forum_path(experience_forum), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_experience_forum_path(experience_forum), 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: experience_forums } %>
|
|
@ -0,0 +1,2 @@
|
|||
$("#experience-forum-modals").html("<%= j render(partial: 'admins/topic/experience_forums/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".experience-forum-change-modal").modal('show');
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('经验分享管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_experience_forums_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_topic_experience_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container experience-forum-list-container">
|
||||
<%= render partial: 'admins/topic/experience_forums/list', locals: { experience_forums: @experience_forums } %>
|
||||
</div>
|
||||
<div id="experience-forum-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.experience-forum-list-container').html("<%= j( render partial: 'admins/topic/experience_forums/list', locals: { experience_forums: @experience_forums } ) %>");
|
|
@ -0,0 +1,2 @@
|
|||
$("#experience-forum-modals").html("<%= j render(partial: 'admins/topic/experience_forums/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".experience-forum-change-modal").modal('show');
|
|
@ -0,0 +1,44 @@
|
|||
<div class="modal fade pinned-forum-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">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<%= form_for @pinned_forum, url: {controller: "topic/pinned_forums", action: "#{type}"} do |p| %>
|
||||
<div class="modal-body">
|
||||
<div class="form-group">
|
||||
<label>
|
||||
标题 <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.text_field :title,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>
|
||||
帖子ID <span class="ml10 color-orange mr20">*</span>
|
||||
</label>
|
||||
<%= p.number_field :uuid,class: "form-control input-lg",required: true%>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
排序等级
|
||||
</label>
|
||||
<%= p.number_field :order_index, 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>
|
|
@ -0,0 +1,33 @@
|
|||
<table class="table table-hover text-center subject-list-table">
|
||||
<thead class="thead-light">
|
||||
<tr>
|
||||
<th width="5%">序号</th>
|
||||
<th width="20%">标题</th>
|
||||
<th width="20%">跳转地址</th>
|
||||
<th width="10%">帖子ID</th>
|
||||
<th width="20%">排序等级</th>
|
||||
<th width="25%">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% if pinned_forums.present? %>
|
||||
<% pinned_forums.each_with_index do |pinned_forum, index| %>
|
||||
<tr class="pinned-forum-item-<%= pinned_forum.id %>">
|
||||
<td><%= list_index_no((params[:page] || 1).to_i, index) %></td>
|
||||
<td><%= pinned_forum.title %></td>
|
||||
<td><%= pinned_forum.url %></td>
|
||||
<td><%= pinned_forum.uuid %></td>
|
||||
<td><%= pinned_forum.order_index %></td>
|
||||
<td class="action-container">
|
||||
<%= link_to "编辑", edit_admins_topic_pinned_forum_path(pinned_forum), remote: true, class: "action" %>
|
||||
<%= link_to "删除", admins_topic_pinned_forum_path(pinned_forum), 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: pinned_forums } %>
|
|
@ -0,0 +1,2 @@
|
|||
$("#pinned-forum-modals").html("<%= j render(partial: 'admins/topic/pinned_forums/form_modal', locals: {type: 'update'}) %>")
|
||||
$(".pinned-forum-change-modal").modal('show');
|
|
@ -0,0 +1,18 @@
|
|||
<% define_admin_breadcrumbs do %>
|
||||
<% add_admin_breadcrumb('精选文章管理') %>
|
||||
<% end %>
|
||||
|
||||
<div class="box search-form-container project-list-form">
|
||||
<%= form_tag(admins_topic_pinned_forums_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_topic_pinned_forum_path, remote: true, class: "btn btn-primary pull-right", "data-disabled-with":"...新增" %>
|
||||
</div>
|
||||
|
||||
<div class="box admin-list-container pinned-forum-list-container">
|
||||
<%= render partial: 'admins/topic/pinned_forums/list', locals: { pinned_forums: @pinned_forums } %>
|
||||
</div>
|
||||
<div id="pinned-forum-modals">
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
$('.pinned-forum-list-container').html("<%= j( render partial: 'admins/topic/pinned_forums/list', locals: { pinned_forums: @pinned_forums } ) %>");
|
|
@ -0,0 +1,2 @@
|
|||
$("#pinned-forum-modals").html("<%= j render(partial: 'admins/topic/pinned_forums/form_modal', locals: {type: 'create'}) %>")
|
||||
$(".pinned-forum-change-modal").modal('show');
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
<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" />
|
||||
<%= link_to "/#{@user.login}", class: 'user-info-avatar col-md-1', target: '_blank', data: { toggle: 'tooltip', title: '个人中心' } do %>
|
||||
<img src="/<%= 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>
|
||||
|
@ -50,6 +50,10 @@
|
|||
|
||||
<div><h6>基本信息</h6></div>
|
||||
<div class="form-group px-2">
|
||||
<div class="form-row">
|
||||
<%= f.input :login, label: '登录名', wrapper_html: { class: 'col-md-3' }, input_html: { readonly: true, class: 'col-md-11', value: @user.login } %>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
|
@ -109,7 +113,6 @@
|
|||
<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>
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<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 %>
|
||||
<%= link_to "/#{user.login}", target: '_blank' do %>
|
||||
<%= overflow_hidden_span user.real_name, width: 100 %>
|
||||
<% end %>
|
||||
</td>
|
||||
|
@ -44,7 +44,6 @@
|
|||
<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 } %>
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ json.setting do
|
|||
if @top_system_notification.present?
|
||||
json.system_notification do
|
||||
json.(@top_system_notification, :id, :subject, :sub_subject, :content)
|
||||
json.is_read @top_system_notification.read_member?(current_user&.id)
|
||||
end
|
||||
else
|
||||
json.system_notification nil
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
json.(activity_forum, :id, :title, :url)
|
||||
request_memo = Forum::Memos::GetService.call(activity_forum&.uuid)
|
||||
json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"]
|
||||
json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"]
|
|
@ -0,0 +1 @@
|
|||
json.(banner, :id, :title, :image)
|
|
@ -0,0 +1 @@
|
|||
json.(card, :id, :title, :url)
|
|
@ -0,0 +1 @@
|
|||
json.(cooperator, :id, :title, :image, :url)
|
|
@ -0,0 +1,3 @@
|
|||
json.(excellent_project, :id, :title, :url)
|
||||
project_common = $redis_cache.hgetall("v2-project-common:#{excellent_project&.uuid}")
|
||||
json.visits (project_common['visits'] || 0).to_i
|
|
@ -0,0 +1,4 @@
|
|||
json.(experience_forum, :id, :title, :url)
|
||||
request_memo = Forum::Memos::GetService.call(experience_forum&.uuid)
|
||||
json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"]
|
||||
json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"]
|
|
@ -0,0 +1,4 @@
|
|||
json.(pinned_forum, :id, :title, :url)
|
||||
request_memo = Forum::Memos::GetService.call(pinned_forum&.uuid)
|
||||
json.visits request_memo.nil? ? 0 : request_memo["memo"]["viewed_count"]
|
||||
json.created_time request_memo.nil? ? format_time(Time.now) : request_memo["memo"]["published_time"]
|
|
@ -0,0 +1,49 @@
|
|||
json.partial! "commons/success"
|
||||
json.total_count @topics.total_count
|
||||
json.topics do
|
||||
if params[:group_size].present?
|
||||
json.array! @topics.to_a.each_slice(params[:group_size].to_i).to_a.each do |group|
|
||||
json.array! group.each do |topic|
|
||||
case topic.type
|
||||
when "Topic::ActivityForum"
|
||||
json.partial! "activity_forum", locals: {activity_forum: topic}
|
||||
when "Topic::Banner"
|
||||
json.partial! "banner", locals: {banner: topic}
|
||||
when "Topic::Card"
|
||||
json.partial! "card", locals: {card: topic}
|
||||
when "Topic::Cooperator"
|
||||
json.partial! "cooperator", locals: {cooperator: topic}
|
||||
when "Topic::ExcellentProject"
|
||||
json.partial! "excellent_project", locals: {excellent_project: topic}
|
||||
when "Topic::ExperienceForum"
|
||||
json.partial! "experience_forum", locals: {experience_forum: topic}
|
||||
when "Topic::PinnedForum"
|
||||
json.partial! "pinned_forum", locals: {pinned_forum: topic}
|
||||
else
|
||||
json.nil!
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
json.array! @topics.each do |topic|
|
||||
case topic.type
|
||||
when "Topic::ActivityForum"
|
||||
json.partial! "activity_forum", locals: {activity_forum: topic}
|
||||
when "Topic::Banner"
|
||||
json.partial! "banner", locals: {banner: topic}
|
||||
when "Topic::Card"
|
||||
json.partial! "card", locals: {card: topic}
|
||||
when "Topic::Cooperator"
|
||||
json.partial! "cooperator", locals: {cooperator: topic}
|
||||
when "Topic::ExcellentProject"
|
||||
json.partial! "excellent_project", locals: {excellent_project: topic}
|
||||
when "Topic::ExperienceForum"
|
||||
json.partial! "experience_forum", locals: {experience_forum: topic}
|
||||
when "Topic::PinnedForum"
|
||||
json.partial! "pinned_forum", locals: {pinned_forum: topic}
|
||||
else
|
||||
json.nil!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue