forked from Gitlink/forgeplus
Compare commits
49 Commits
master
...
integrated
| Author | SHA1 | Date |
|---|---|---|
|
|
9314d134be | |
|
|
b524111ae6 | |
|
|
244c1b865a | |
|
|
dafdbadb6b | |
|
|
2b0c987558 | |
|
|
6796805b21 | |
|
|
5752f19b2f | |
|
|
eb52f05417 | |
|
|
786629dbff | |
|
|
7a00541375 | |
|
|
1d832a1723 | |
|
|
80ce40e492 | |
|
|
91f6dae56a | |
|
|
8c5a834b14 | |
|
|
57f420848e | |
|
|
fba58800a7 | |
|
|
c4a43c4392 | |
|
|
1153bd5ab6 | |
|
|
f732b0374c | |
|
|
0d97d7d4f0 | |
|
|
bf68c1c544 | |
|
|
6de617d898 | |
|
|
5addece8d5 | |
|
|
ffbe4942b7 | |
|
|
c963a80e8c | |
|
|
01f15da5ed | |
|
|
cd595646d8 | |
|
|
1ac5498091 | |
|
|
faf2302b8e | |
|
|
5433920724 | |
|
|
0e33b12989 | |
|
|
1c45b48063 | |
|
|
80d6cbf823 | |
|
|
0ebcf3d7f7 | |
|
|
0f69255422 | |
|
|
d480deee64 | |
|
|
50bef66261 | |
|
|
9915c10bcf | |
|
|
c546eda537 | |
|
|
769bf2b90e | |
|
|
94ad4ce56c | |
|
|
98176f839d | |
|
|
33951af37d | |
|
|
46b906d2ac | |
|
|
0a460d1d37 | |
|
|
cb089b1bb8 | |
|
|
8e2cf4ecc0 | |
|
|
38193dff54 | |
|
|
e07dddde98 |
|
|
@ -36,7 +36,6 @@ public/react/yarn.lock
|
|||
/.idea/*
|
||||
|
||||
# Ignore react node_modules
|
||||
public/system/*
|
||||
public/react/*
|
||||
/public/react/.cache
|
||||
/public/react/node_modules/
|
||||
|
|
@ -83,5 +82,4 @@ docker/
|
|||
educoder.sql
|
||||
redis_data/
|
||||
Dockerfile
|
||||
dump.rdb
|
||||
.tags*
|
||||
dump.rdb
|
||||
27
CHANGELOG.md
27
CHANGELOG.md
|
|
@ -1,32 +1,5 @@
|
|||
# Changelog
|
||||
|
||||
## [v3.0.2](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-04-23
|
||||
|
||||
* BUGFIXES
|
||||
* Fix 解决部分用户头像不显示问题
|
||||
* Fix 解决代码库模块中最左侧目录中的文件定位加载不准确的问题
|
||||
* FIX 解决团队管理页面中项目链接错误问题
|
||||
* Fix 解决markdown格式文件显示问题
|
||||
* Fix 解决组织名下创建项目报错的问题
|
||||
* Fix 解决组织名下的项目,创建issue报错的问题
|
||||
* Fix 解决组织名下创建团队提示信息信息显示错误问题
|
||||
* Fix 解决点击组织图片时,链接加载错误问题
|
||||
* Fix 修复查询版本库信息安全漏洞
|
||||
* Fix 解决修复团队成员操作访问组织仓库报403错误的问题
|
||||
* Fix 解决owners团队成员对仓库添加成功失败的问题
|
||||
|
||||
* ENHANCEMENTS
|
||||
* ADD 自动生产用户头像功能
|
||||
* ADD 创建组织支持中文名称
|
||||
* ADD 创建团建支持中文名称
|
||||
* ADD 组织名称统一显示中文名
|
||||
* ADD 团队名称统一显示中文名
|
||||
* ADD 用户头像悬浮时展示相关信息
|
||||
* ADD 项目详情页添加实践课程链接入口
|
||||
* ADD README文件页面添加添加目录导航功能
|
||||
* UPDATE 升级改版底部footer信息
|
||||
* UPDATE 升级用户操作版本库权限
|
||||
|
||||
## [v3.0.1](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-03-19
|
||||
|
||||
* BUGFIXES
|
||||
|
|
|
|||
5
Gemfile
5
Gemfile
|
|
@ -100,6 +100,7 @@ gem 'rails-i18n', '~> 5.1'
|
|||
# job
|
||||
gem 'sidekiq'
|
||||
gem 'sinatra'
|
||||
gem 'whenever'
|
||||
gem "sidekiq-cron", "~> 1.1"
|
||||
|
||||
# batch insert
|
||||
|
|
@ -127,4 +128,6 @@ gem 'harmonious_dictionary', '~> 0.0.1'
|
|||
|
||||
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
||||
|
||||
gem 'letter_avatar'
|
||||
# log
|
||||
gem 'multi_logger'
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ GEM
|
|||
chromedriver-helper (2.1.1)
|
||||
archive-zip (~> 0.10)
|
||||
nokogiri (~> 1.8)
|
||||
chronic (0.10.2)
|
||||
chunky_png (1.3.11)
|
||||
concurrent-ruby (1.1.6)
|
||||
connection_pool (2.2.2)
|
||||
|
|
@ -162,7 +163,6 @@ GEM
|
|||
activerecord
|
||||
kaminari-core (= 1.2.0)
|
||||
kaminari-core (1.2.0)
|
||||
letter_avatar (0.3.8)
|
||||
listen (3.1.5)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
|
|
@ -182,6 +182,8 @@ GEM
|
|||
minitest (5.14.0)
|
||||
msgpack (1.3.3)
|
||||
multi_json (1.14.1)
|
||||
multi_logger (0.2.0)
|
||||
railties
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.1.1)
|
||||
mustermann (1.1.1)
|
||||
|
|
@ -421,6 +423,8 @@ GEM
|
|||
websocket-driver (0.7.1)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.4)
|
||||
whenever (1.0.0)
|
||||
chronic (>= 0.6.3)
|
||||
wkhtmltopdf-binary (0.12.5.4)
|
||||
xpath (3.2.0)
|
||||
nokogiri (~> 1.8)
|
||||
|
|
@ -457,8 +461,8 @@ DEPENDENCIES
|
|||
jbuilder (~> 2.5)
|
||||
jquery-rails
|
||||
kaminari (~> 1.1, >= 1.1.1)
|
||||
letter_avatar
|
||||
listen (>= 3.0.5, < 3.2)
|
||||
multi_logger
|
||||
mysql2 (>= 0.4.4, < 0.6.0)
|
||||
oauth2
|
||||
omniauth (~> 1.9.0)
|
||||
|
|
@ -500,6 +504,7 @@ DEPENDENCIES
|
|||
tzinfo-data
|
||||
uglifier (>= 1.3.0)
|
||||
web-console (>= 3.3.0)
|
||||
whenever
|
||||
wkhtmltopdf-binary
|
||||
|
||||
BUNDLED WITH
|
||||
|
|
|
|||
36
README.md
36
README.md
|
|
@ -21,7 +21,7 @@ Trustie (确实)是一个以大众化协同开发、开放式资源共享、
|
|||
|
||||
* Redis 5+
|
||||
|
||||
* imagemagick
|
||||
* NodeJS > 13.0.0
|
||||
|
||||
### Steps
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ default: &default
|
|||
|
||||
**因目前gitea平台api受限,暂时推荐从forge平台获取gitea部署文件进行部署:https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
|
||||
|
||||
**配置gitea服务步骤**
|
||||
#### 配置gitea服务步骤
|
||||
1. 部署gitea服务,并注册root账户
|
||||
2. 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||
|
||||
|
|
@ -80,64 +80,60 @@ gitea:
|
|||
#### 6. 安装redis环境
|
||||
**请自行搜索各平台如何安装部署redis环境**
|
||||
|
||||
#### 7. 安装imagemagick插件
|
||||
- Mac OS X
|
||||
```bash
|
||||
brew install imagemagick ghostscript
|
||||
```
|
||||
|
||||
- Linux
|
||||
```bash
|
||||
sudo apt-get install -y imagemagick
|
||||
```
|
||||
|
||||
#### 8. 创建数据库
|
||||
#### 7. 创建数据库
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:create RAILS_ENV=development
|
||||
```
|
||||
|
||||
#### 9. 导入数据表结构
|
||||
#### 8. 导入数据表结构
|
||||
|
||||
```bash
|
||||
bundle exec rake sync_table_structure:import_csv
|
||||
```
|
||||
|
||||
#### 10. 执行migrate迁移文件
|
||||
#### 9. 执行migrate迁移文件
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:migrate RAILS_ENV=development
|
||||
```
|
||||
|
||||
#### 11. clone前端代码
|
||||
#### 10. clone前端代码
|
||||
**将前端代码克隆到public/react目录下,目录结构应该是: public/react/build**
|
||||
```bash
|
||||
git clone -b standalone https://git.trustie.net/jasder/build.git
|
||||
```
|
||||
|
||||
#### 12. 启动redis(此处已mac系统为例)
|
||||
#### 11. 启动redis(此处已mac系统为例)
|
||||
```bash
|
||||
redis-server&
|
||||
```
|
||||
|
||||
#### 13. 启动sidekiq
|
||||
#### 12. 启动sidekiq
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
bundle exec sidekiq -C config/sidekiq.yml -e production -d
|
||||
```
|
||||
|
||||
#### 14. 启动rails服务
|
||||
#### 13. 启动rails服务
|
||||
```bash
|
||||
rails s
|
||||
```
|
||||
|
||||
#### 14. 浏览器访问
|
||||
在浏览器中输入如下地址访问:
|
||||
```bash
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
#### 15. 浏览器访问
|
||||
在浏览器中输入如下地址访问:
|
||||
```bash
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
#### 16. 其他说明
|
||||
#### 15. 其他说明
|
||||
通过页面注册都第一个用户为平台管理员用户
|
||||
|
||||
## 页面展示
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the log controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
body {
|
||||
background-color: #fff;
|
||||
color: #333;
|
||||
margin: 33px;
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
p, ol, ul, td {
|
||||
font-family: verdana, arial, helvetica, sans-serif;
|
||||
font-size: 13px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #eee;
|
||||
padding: 10px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
|
||||
&:visited {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background-color: #000;
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 0 5px 7px;
|
||||
}
|
||||
|
||||
div {
|
||||
&.field, &.actions {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
#notice {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.field_with_errors {
|
||||
padding: 2px;
|
||||
background-color: red;
|
||||
display: table;
|
||||
}
|
||||
|
||||
#error_explanation {
|
||||
width: 450px;
|
||||
border: 2px solid red;
|
||||
padding: 7px 7px 0;
|
||||
margin-bottom: 20px;
|
||||
background-color: #f0f0f0;
|
||||
|
||||
h2 {
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
padding: 5px 5px 5px 15px;
|
||||
font-size: 12px;
|
||||
margin: -7px -7px 0;
|
||||
background-color: #c00;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul li {
|
||||
font-size: 12px;
|
||||
list-style: square;
|
||||
}
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the SponsorTiers controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the Sponsorships controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the Wallets controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
|
|
@ -234,6 +234,7 @@ class AccountsController < ApplicationController
|
|||
|
||||
set_autologin_cookie(user)
|
||||
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
|
||||
# user.daily_reward
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
session[:"#{default_yun_session}"] = user.id
|
||||
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
require 'oauth2'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
|
||||
include CodeExample
|
||||
include RenderExpand
|
||||
include RenderHelper
|
||||
|
|
@ -10,12 +11,14 @@ class ApplicationController < ActionController::Base
|
|||
include LoggerHelper
|
||||
include LoginHelper
|
||||
include RegisterHelper
|
||||
include UpdateHelper
|
||||
|
||||
protect_from_forgery prepend: true, unless: -> { request.format.json? }
|
||||
|
||||
before_action :check_sign
|
||||
before_action :user_setup
|
||||
#before_action :check_account
|
||||
after_action :user_trace_log
|
||||
|
||||
# TODO
|
||||
# check sql query time
|
||||
|
|
@ -28,7 +31,7 @@ class ApplicationController < ActionController::Base
|
|||
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
|
||||
OPENKEY = "79e33abd4b6588941ab7622aed1e67e8"
|
||||
|
||||
helper_method :current_user, :base_url
|
||||
helper_method :current_user
|
||||
|
||||
# 所有请求必须合法签名
|
||||
def check_sign
|
||||
|
|
@ -329,7 +332,6 @@ class ApplicationController < ActionController::Base
|
|||
User.current = user
|
||||
end
|
||||
end
|
||||
|
||||
# if !User.current.logged? && Rails.env.development?
|
||||
# User.current = User.find 1
|
||||
# end
|
||||
|
|
@ -344,7 +346,8 @@ class ApplicationController < ActionController::Base
|
|||
User.current = User.find 8686
|
||||
elsif params[:debug] == 'admin'
|
||||
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
|
||||
user = User.find 36480
|
||||
# user = User.find 36480
|
||||
user = User.find 5
|
||||
User.current = user
|
||||
cookies.signed[:user_id] = user.id
|
||||
end
|
||||
|
|
@ -367,7 +370,19 @@ class ApplicationController < ActionController::Base
|
|||
# RSS key authentication does not start a session
|
||||
User.find_by_rss_key(params[:key])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def user_trace_log
|
||||
user = current_user
|
||||
# print("*********************url:", request.url, "****routes", request.request_method)
|
||||
Rails.logger.user_trace.info("{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params}, response_code: #{response.code}, time: #{Time.now}}")
|
||||
end
|
||||
|
||||
def user_trace_update_log(old_value_hash)
|
||||
user = current_user
|
||||
str = "{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params.merge(old_value: old_value_hash)}, response_code: #{response.code}, time: #{Time.now}}"
|
||||
Rails.logger.user_trace.info(str)
|
||||
end
|
||||
|
||||
def try_to_autologin
|
||||
if cookies[autologin_cookie_name]
|
||||
|
|
@ -393,291 +408,291 @@ class ApplicationController < ActionController::Base
|
|||
respond_to do |format|
|
||||
format.json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## 输出错误信息
|
||||
def error_status(message = nil)
|
||||
@status = -1
|
||||
@message = message
|
||||
end
|
||||
## 输出错误信息
|
||||
def error_status(message = nil)
|
||||
@status = -1
|
||||
@message = message
|
||||
end
|
||||
|
||||
# 实训等对应的仓库地址
|
||||
def repo_ip_url(repo_path)
|
||||
"#{edu_setting('git_address_ip')}/#{repo_path}"
|
||||
end
|
||||
# 实训等对应的仓库地址
|
||||
def repo_ip_url(repo_path)
|
||||
"#{edu_setting('git_address_ip')}/#{repo_path}"
|
||||
end
|
||||
|
||||
def repo_url(repo_path)
|
||||
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
||||
end
|
||||
def repo_url(repo_path)
|
||||
"#{edu_setting('git_address_domain')}/#{repo_path}"
|
||||
end
|
||||
|
||||
# 通关后,把最后一次成功的代码存到数据库
|
||||
# type 0 创始内容, 1 最新内容
|
||||
# def game_passed_code(path, myshixun, game_id)
|
||||
# # 如果代码窗口是隐藏的,则不用保存代码
|
||||
# return if myshixun.shixun.hide_code || myshixun.shixun.vnc
|
||||
# file_content = git_fle_content myshixun.repo_path, path
|
||||
# #unless file_content.present?
|
||||
# # raise("获取文件代码异常")
|
||||
# #end
|
||||
# logger.info("#######game_id:#{game_id}, file_content:#{file_content}")
|
||||
# game_code = GameCode.where(:game_id => game_id, :path => path).first
|
||||
# if game_code.nil?
|
||||
# GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path)
|
||||
# else
|
||||
# game_code.update_attributes!(:new_code => file_content)
|
||||
# end
|
||||
# 通关后,把最后一次成功的代码存到数据库
|
||||
# type 0 创始内容, 1 最新内容
|
||||
# def game_passed_code(path, myshixun, game_id)
|
||||
# # 如果代码窗口是隐藏的,则不用保存代码
|
||||
# return if myshixun.shixun.hide_code || myshixun.shixun.vnc
|
||||
# file_content = git_fle_content myshixun.repo_path, path
|
||||
# #unless file_content.present?
|
||||
# # raise("获取文件代码异常")
|
||||
# #end
|
||||
# logger.info("#######game_id:#{game_id}, file_content:#{file_content}")
|
||||
# game_code = GameCode.where(:game_id => game_id, :path => path).first
|
||||
# if game_code.nil?
|
||||
# GameCode.create!(:game_id => game_id, :new_code => file_content, :path => path)
|
||||
# else
|
||||
# game_code.update_attributes!(:new_code => file_content)
|
||||
# end
|
||||
# end
|
||||
|
||||
# Post请求
|
||||
def uri_post(uri, params)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
JSON.parse(res)
|
||||
rescue Exception => e
|
||||
uid_logger_error("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)")
|
||||
end
|
||||
end
|
||||
# Post请求
|
||||
def uri_post(uri, params)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
JSON.parse(res)
|
||||
rescue Exception => e
|
||||
uid_logger_error("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("实训平台繁忙(繁忙等级:84)")
|
||||
end
|
||||
end
|
||||
|
||||
# 处理返回非0就报错的请求
|
||||
def interface_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
res = JSON.parse(res)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new(message)
|
||||
end
|
||||
end
|
||||
# 处理返回非0就报错的请求
|
||||
def interface_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.post_form(uri, params).body
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res}")
|
||||
res = JSON.parse(res)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new(message)
|
||||
end
|
||||
end
|
||||
|
||||
# json格式请求
|
||||
def interface_json_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||
req = Net::HTTP::Post.new(uri)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = params.to_json
|
||||
http.request(req)
|
||||
end
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res.body}")
|
||||
res = JSON.parse(res.body)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("服务器繁忙")
|
||||
end
|
||||
end
|
||||
# json格式请求
|
||||
def interface_json_post(uri, params, status, message)
|
||||
begin
|
||||
uid_logger_dubug("--uri_exec: params is #{params}, url is #{uri}")
|
||||
uri = URI.parse(URI.encode(uri.strip))
|
||||
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||
req = Net::HTTP::Post.new(uri)
|
||||
req['Content-Type'] = 'application/json'
|
||||
req.body = params.to_json
|
||||
http.request(req)
|
||||
end
|
||||
uid_logger_dubug("--uri_exec: .....res is #{res.body}")
|
||||
res = JSON.parse(res.body)
|
||||
if (res && res['code'] != 0)
|
||||
tip_exception(status, message)
|
||||
else
|
||||
res
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger("--uri_exec: exception #{e.message}")
|
||||
raise Educoder::TipException.new("服务器繁忙")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# 适用与已经用url_safe编码后,回调字符串形式
|
||||
def tran_base64_decode64(str)
|
||||
s_size = str.size % 4
|
||||
if s_size != 0
|
||||
str += "=" * (4 - s_size)
|
||||
end
|
||||
if str.blank?
|
||||
str
|
||||
else
|
||||
Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
|
||||
end
|
||||
end
|
||||
# 适用与已经用url_safe编码后,回调字符串形式
|
||||
def tran_base64_decode64(str)
|
||||
s_size = str.size % 4
|
||||
if s_size != 0
|
||||
str += "=" * (4 - s_size)
|
||||
end
|
||||
if str.blank?
|
||||
str
|
||||
else
|
||||
Base64.decode64(str.tr("-_", "+/")).force_encoding("utf-8")
|
||||
end
|
||||
end
|
||||
|
||||
def sucess_status(message = 'success')
|
||||
render :json => { status: 1, message: message }
|
||||
end
|
||||
def sucess_status(message = 'success')
|
||||
render :json => { status: 1, message: message }
|
||||
end
|
||||
|
||||
# 随机生成字符
|
||||
def generate_identifier(container, num, pre='')
|
||||
code = DCODES.sample(num).join
|
||||
if container == User
|
||||
while container.exists?(login: pre+code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
else
|
||||
while container.exists?(identifier: code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
end
|
||||
code
|
||||
end
|
||||
# 随机生成字符
|
||||
def generate_identifier(container, num, pre='')
|
||||
code = DCODES.sample(num).join
|
||||
if container == User
|
||||
while container.exists?(login: pre+code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
else
|
||||
while container.exists?(identifier: code) do
|
||||
code = DCODES.sample(num).join
|
||||
end
|
||||
end
|
||||
code
|
||||
end
|
||||
|
||||
|
||||
# 实训主类别列表,自带描述
|
||||
def shixun_main_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
# 实训主类别列表,自带描述
|
||||
def shixun_main_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_main_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.try(:description), mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
# 小类别列表
|
||||
def shixun_small_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
# 小类别列表
|
||||
def shixun_small_type
|
||||
list = []
|
||||
mirrors = MirrorRepository.select([:id, :type_name, :description, :name]).published_small_mirror
|
||||
mirrors.try(:each) do |mirror|
|
||||
list << {id: mirror.id, type_name: mirror.type_name, description: mirror.description, mirror_name: mirror.name}
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
def container_limit(mirror_repositories)
|
||||
container = []
|
||||
mirror_repositories.each do |mr|
|
||||
if mr.name.present?
|
||||
container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
def container_limit(mirror_repositories)
|
||||
container = []
|
||||
mirror_repositories.each do |mr|
|
||||
if mr.name.present?
|
||||
container << {:image => mr.name, :cpuLimit => mr.cpu_limit, :memoryLimit => "#{mr.memory_limit}M", :type => mr.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
|
||||
# 实训中间层pod配置
|
||||
def shixun_container_limit shixun
|
||||
container = []
|
||||
shixun.shixun_service_configs.each do |config|
|
||||
mirror = config.mirror_repository
|
||||
if mirror.name.present?
|
||||
# 资源限制没有就传默认值。
|
||||
cpu_limit = config.cpu_limit.presence || 1
|
||||
cpu_request = config.lower_cpu_limit.presence || 0.1
|
||||
memory_limit = config.memory_limit.presence || 1024
|
||||
request_limit = config.request_limit.presence || 10
|
||||
resource_limit = config.resource_limit.presence || 10000
|
||||
container << {:image => mirror.name,
|
||||
:cpuLimit => cpu_limit,
|
||||
:cpuRequest => cpu_request,
|
||||
:memoryLimit => "#{memory_limit}M",
|
||||
:memoryRequest => "#{request_limit}M",
|
||||
:resourceLimit => "#{resource_limit}K",
|
||||
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
# 实训中间层pod配置
|
||||
def shixun_container_limit shixun
|
||||
container = []
|
||||
shixun.shixun_service_configs.each do |config|
|
||||
mirror = config.mirror_repository
|
||||
if mirror.name.present?
|
||||
# 资源限制没有就传默认值。
|
||||
cpu_limit = config.cpu_limit.presence || 1
|
||||
cpu_request = config.lower_cpu_limit.presence || 0.1
|
||||
memory_limit = config.memory_limit.presence || 1024
|
||||
request_limit = config.request_limit.presence || 10
|
||||
resource_limit = config.resource_limit.presence || 10000
|
||||
container << {:image => mirror.name,
|
||||
:cpuLimit => cpu_limit,
|
||||
:cpuRequest => cpu_request,
|
||||
:memoryLimit => "#{memory_limit}M",
|
||||
:memoryRequest => "#{request_limit}M",
|
||||
:resourceLimit => "#{resource_limit}K",
|
||||
:type => mirror.try(:main_type) == "1" ? "main" : "sub"}
|
||||
end
|
||||
end
|
||||
container.to_json
|
||||
end
|
||||
|
||||
# 毕设任务列表的赛选
|
||||
def course_work(task, **option)
|
||||
logger.info("#############{option}")
|
||||
course = task.course
|
||||
work_list = task.graduation_works.includes(user: [:user_extension])
|
||||
# 教师评阅搜索 0: 未评, 1 已评
|
||||
if option[:teacher_comment]
|
||||
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id)
|
||||
if option[:teacher_comment].zero?
|
||||
work_list = work_list.where.not(id: graduation_work_ids)
|
||||
elsif option[:teacher_comment] == 1
|
||||
work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0)
|
||||
end
|
||||
end
|
||||
# 毕设任务列表的赛选
|
||||
def course_work(task, **option)
|
||||
logger.info("#############{option}")
|
||||
course = task.course
|
||||
work_list = task.graduation_works.includes(user: [:user_extension])
|
||||
# 教师评阅搜索 0: 未评, 1 已评
|
||||
if option[:teacher_comment]
|
||||
graduation_work_ids = GraduationWorkScore.where(graduation_work_id: work_list.map(&:id)).pluck(:graduation_work_id)
|
||||
if option[:teacher_comment].zero?
|
||||
work_list = work_list.where.not(id: graduation_work_ids)
|
||||
elsif option[:teacher_comment] == 1
|
||||
work_list = work_list.where(id: graduation_work_ids).where.not(work_status: 0)
|
||||
end
|
||||
end
|
||||
|
||||
# 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
|
||||
if option[:task_status]
|
||||
work_list = work_list.where(work_status: option[:task_status])
|
||||
end
|
||||
# 作品状态 0: 未提交, 1 按时提交, 2 延迟提交
|
||||
if option[:task_status]
|
||||
work_list = work_list.where(work_status: option[:task_status])
|
||||
end
|
||||
|
||||
# 分班情况
|
||||
if option[:course_group]
|
||||
group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id)
|
||||
# 有分组只可能是老师身份查看列表
|
||||
work_list = work_list.where(user_id: group_user_ids)
|
||||
end
|
||||
# 分班情况
|
||||
if option[:course_group]
|
||||
group_user_ids = course.course_members.where(course_group_id: option[:course_group]).pluck(:user_id)
|
||||
# 有分组只可能是老师身份查看列表
|
||||
work_list = work_list.where(user_id: group_user_ids)
|
||||
end
|
||||
|
||||
# 只看我的交叉评阅
|
||||
if option[:cross_comment]
|
||||
graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id)
|
||||
.pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations
|
||||
work_list = work_list.where(id: graduation_work_id)
|
||||
end
|
||||
# 只看我的交叉评阅
|
||||
if option[:cross_comment]
|
||||
graduation_work_id = task.graduation_work_comment_assignations.where(:user_id => current_user.id)
|
||||
.pluck(:graduation_work_id).uniq if task.graduation_work_comment_assignations
|
||||
work_list = work_list.where(id: graduation_work_id)
|
||||
end
|
||||
|
||||
# 输入姓名和学号搜索
|
||||
# TODO user_extension 如果修改 请调整
|
||||
if option[:search]
|
||||
work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
|
||||
# 输入姓名和学号搜索
|
||||
# TODO user_extension 如果修改 请调整
|
||||
if option[:search]
|
||||
work_list = work_list.joins(user: :user_extension).where("concat(lastname, firstname) like ?
|
||||
or student_id like ?", "%#{option[:search]}%", "%#{option[:search]}%")
|
||||
end
|
||||
end
|
||||
|
||||
# 排序
|
||||
rorder = option[:order] || "updated_at"
|
||||
b_order = option[:b_order] || "desc"
|
||||
if rorder == "created_at" || rorder == "work_score"
|
||||
work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
|
||||
elsif rorder == "student_id"
|
||||
work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
|
||||
end
|
||||
work_list
|
||||
end
|
||||
# 排序
|
||||
rorder = option[:order] || "updated_at"
|
||||
b_order = option[:b_order] || "desc"
|
||||
if rorder == "created_at" || rorder == "work_score"
|
||||
work_list = work_list.order("graduation_works.#{rorder} #{b_order}")
|
||||
elsif rorder == "student_id"
|
||||
work_list = work_list.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}")
|
||||
end
|
||||
work_list
|
||||
end
|
||||
|
||||
def strip_html(text, len=0, endss="...")
|
||||
ss = ""
|
||||
if !text.nil? && text.length>0
|
||||
ss=text.gsub(/<\/?.*?>/, '').strip
|
||||
ss = ss.gsub(/ */, '')
|
||||
ss = ss.gsub(/\r\n/,'') #新增
|
||||
ss = ss.gsub(/\n/,'') #新增
|
||||
if len > 0 && ss.length > len
|
||||
ss = ss[0, len] + endss
|
||||
elsif len > 0 && ss.length <= len
|
||||
ss = ss
|
||||
#ss = truncate(ss, :length => len)
|
||||
end
|
||||
end
|
||||
ss
|
||||
end
|
||||
def strip_html(text, len=0, endss="...")
|
||||
ss = ""
|
||||
if !text.nil? && text.length>0
|
||||
ss=text.gsub(/<\/?.*?>/, '').strip
|
||||
ss = ss.gsub(/ */, '')
|
||||
ss = ss.gsub(/\r\n/,'') #新增
|
||||
ss = ss.gsub(/\n/,'') #新增
|
||||
if len > 0 && ss.length > len
|
||||
ss = ss[0, len] + endss
|
||||
elsif len > 0 && ss.length <= len
|
||||
ss = ss
|
||||
#ss = truncate(ss, :length => len)
|
||||
end
|
||||
end
|
||||
ss
|
||||
end
|
||||
|
||||
# Returns a string that can be used as filename value in Content-Disposition header
|
||||
def filename_for_content_disposition(name)
|
||||
request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name
|
||||
end
|
||||
# Returns a string that can be used as filename value in Content-Disposition header
|
||||
def filename_for_content_disposition(name)
|
||||
request.env['HTTP_USER_AGENT'] =~ %r{MSIE|Trident|Edge} ? ERB::Util.url_encode(name) : name
|
||||
end
|
||||
|
||||
def format_time(time)
|
||||
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M")
|
||||
end
|
||||
def format_time(time)
|
||||
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M")
|
||||
end
|
||||
|
||||
# 获取Oauth Client
|
||||
def get_client(site)
|
||||
client_id = Rails.configuration.educoder['client_id']
|
||||
client_secret = Rails.configuration.educoder['client_secret']
|
||||
# 获取Oauth Client
|
||||
def get_client(site)
|
||||
client_id = Rails.configuration.educoder['client_id']
|
||||
client_secret = Rails.configuration.educoder['client_secret']
|
||||
|
||||
OAuth2::Client.new(client_id, client_secret, site: site)
|
||||
end
|
||||
OAuth2::Client.new(client_id, client_secret, site: site)
|
||||
end
|
||||
|
||||
def paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
offset = (page - 1) * limit
|
||||
def paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
offset = (page - 1) * limit
|
||||
|
||||
if relation.is_a?(Array)
|
||||
relation[offset, limit]
|
||||
else
|
||||
relation.limit(limit).offset(offset)
|
||||
end
|
||||
end
|
||||
if relation.is_a?(Array)
|
||||
relation[offset, limit]
|
||||
else
|
||||
relation.limit(limit).offset(offset)
|
||||
end
|
||||
end
|
||||
|
||||
def kaminari_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
def kaminari_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
relation.page(page).per(limit)
|
||||
end
|
||||
|
||||
def kaminari_array_paginate(relation)
|
||||
|
|
@ -692,29 +707,30 @@ class ApplicationController < ActionController::Base
|
|||
time.blank? ? '' : time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
end
|
||||
|
||||
def strf_date(date)
|
||||
date.blank? ? '' : date.to_date.strftime("%Y-%m-%d")
|
||||
end
|
||||
def strf_date(date)
|
||||
date.blank? ? '' : date.to_date.strftime("%Y-%m-%d")
|
||||
end
|
||||
|
||||
def logger_error(error)
|
||||
Rails.logger.error(error.message)
|
||||
error.backtrace.each { |msg| Rails.logger.error(msg) }
|
||||
end
|
||||
def logger_error(error)
|
||||
Rails.logger.error(error.message)
|
||||
error.backtrace.each { |msg| Rails.logger.error(msg) }
|
||||
end
|
||||
|
||||
def find_user
|
||||
@user = User.find_by_login params[:login]
|
||||
def find_user
|
||||
@user = User.find_by_login params[:login]
|
||||
render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||
end
|
||||
end
|
||||
|
||||
def find_user_with_id
|
||||
@user = User.find_by_id params[:user_id]
|
||||
def find_user_with_id
|
||||
@user = User.find_by_id params[:user_id]
|
||||
# render_not_found("未找到’#{params[:login]}’相关的用户") unless @user
|
||||
render_error("未找到相关的用户") unless @user
|
||||
end
|
||||
render_error("未找到相关的用户") unless @user
|
||||
end
|
||||
|
||||
def find_repository
|
||||
@repo = @user.repositories.find_by_identifier params[:repo_identifier]
|
||||
def find_repository
|
||||
@repo = @user.repositories.find_by_identifier params[:repo_identifier]
|
||||
render_not_found("未找到’#{params[:repo_identifier]}’相关的项目") unless @repo
|
||||
|
||||
end
|
||||
|
||||
def find_repository_by_id
|
||||
|
|
@ -770,61 +786,56 @@ class ApplicationController < ActionController::Base
|
|||
@repository ||= load_project&.repository
|
||||
end
|
||||
|
||||
def base_url
|
||||
request.base_url
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def object_not_found
|
||||
uid_logger("Missing template or cant't find record, responding with 404")
|
||||
render json: {message: "您访问的页面不存在或已被删除", status: 404}
|
||||
false
|
||||
end
|
||||
def object_not_found
|
||||
uid_logger("Missing template or cant't find record, responding with 404")
|
||||
render json: {message: "您访问的页面不存在或已被删除", status: 404}
|
||||
false
|
||||
end
|
||||
|
||||
def tip_show(exception)
|
||||
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
|
||||
render json: exception.tip_json
|
||||
end
|
||||
def tip_show(exception)
|
||||
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
|
||||
render json: exception.tip_json
|
||||
end
|
||||
|
||||
def render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
end
|
||||
def render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
end
|
||||
|
||||
def set_export_cookies
|
||||
cookies[:fileDownload] = true
|
||||
end
|
||||
def set_export_cookies
|
||||
cookies[:fileDownload] = true
|
||||
end
|
||||
|
||||
# 149课程的评审用户数据创建(包含创建课堂学生)
|
||||
def open_class_user
|
||||
user = User.find_by(login: "OpenClassUser")
|
||||
unless user
|
||||
ActiveRecord::Base.transaction do
|
||||
user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
|
||||
nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
|
||||
password: "12345678", phone: "11122223333", profile_completed: 1}
|
||||
user = User.create!(user_params)
|
||||
# 149课程的评审用户数据创建(包含创建课堂学生)
|
||||
def open_class_user
|
||||
user = User.find_by(login: "OpenClassUser")
|
||||
unless user
|
||||
ActiveRecord::Base.transaction do
|
||||
user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
|
||||
nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
|
||||
password: "12345678", phone: "11122223333", profile_completed: 1}
|
||||
user = User.create!(user_params)
|
||||
|
||||
UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396
|
||||
UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396
|
||||
|
||||
subject = Subject.find_by(id: 149)
|
||||
if subject
|
||||
subject.courses.each do |course|
|
||||
CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
user
|
||||
end
|
||||
subject = Subject.find_by(id: 149)
|
||||
if subject
|
||||
subject.courses.each do |course|
|
||||
CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
user
|
||||
end
|
||||
|
||||
# 记录热门搜索关键字
|
||||
def record_search_keyword
|
||||
keyword = params[:keyword].to_s.strip
|
||||
return if keyword.blank? || keyword.size <= 1
|
||||
return unless HotSearchKeyword.available?
|
||||
# 记录热门搜索关键字
|
||||
def record_search_keyword
|
||||
keyword = params[:keyword].to_s.strip
|
||||
return if keyword.blank? || keyword.size <= 1
|
||||
return unless HotSearchKeyword.available?
|
||||
|
||||
HotSearchKeyword.add(keyword)
|
||||
end
|
||||
HotSearchKeyword.add(keyword)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -44,6 +44,7 @@ module LoginHelper
|
|||
set_autologin_cookie(user)
|
||||
|
||||
UserAction.create(action_id: user&.id, action_type: 'Login', user_id: user&.id, ip: request.remote_ip)
|
||||
# user.daily_reward
|
||||
user.update_column(:last_login_on, Time.now)
|
||||
# 注册完成后有一天的试用申请(先去掉)
|
||||
# UserDayCertification.create(user_id: user.id, status: 1)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
module RegisterHelper
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def autologin_register(username, email, password, platform= 'forge')
|
||||
def autologin_register(username, email, password, platform= 'forge', need_edit_info = false)
|
||||
result = {message: nil, user: nil}
|
||||
|
||||
user = User.new(admin: false, login: username, mail: email, type: "User")
|
||||
user.password = password
|
||||
user.platform = platform
|
||||
user.activate
|
||||
if need_edit_info
|
||||
user.need_edit_info
|
||||
else
|
||||
user.activate
|
||||
end
|
||||
|
||||
return unless user.valid?
|
||||
|
||||
|
|
@ -27,4 +31,30 @@ module RegisterHelper
|
|||
result
|
||||
end
|
||||
|
||||
def autosync_register_trustie(username, password, email)
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
|
||||
api_host = config[:sync_url]
|
||||
|
||||
return if api_host.blank?
|
||||
|
||||
url = "#{api_host}/api/v1/users/common"
|
||||
sync_json = {
|
||||
"mail": email,
|
||||
"password": password,
|
||||
"login": username
|
||||
}
|
||||
uri = URI.parse(url)
|
||||
|
||||
if api_host
|
||||
http = Net::HTTP.new(uri.hostname, uri.port)
|
||||
|
||||
if api_host.include?("https://")
|
||||
http.use_ssl = true
|
||||
end
|
||||
|
||||
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,9 +2,12 @@ class ForksController < ApplicationController
|
|||
before_action :require_login
|
||||
before_action :load_project
|
||||
before_action :authenticate_project!, :authenticate_user!
|
||||
skip_after_action :user_trace_log, only: [:create]
|
||||
|
||||
def create
|
||||
@new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call
|
||||
user = current_user
|
||||
Rails.logger.user_trace.info("{id: #{user.id}, login: #{user.login}, url: #{request.url}, method: #{request.method}, params: #{params.merge(forkee: @new_project.id)}, response_code: #{response.code}, time: #{Time.now}}")
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class IssuesController < ApplicationController
|
|||
before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue]
|
||||
before_action :check_token_enough, only: [:create, :update]
|
||||
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
include ApplicationHelper
|
||||
include TagChosenHelper
|
||||
|
||||
|
|
@ -194,6 +196,7 @@ class IssuesController < ApplicationController
|
|||
# end
|
||||
# end
|
||||
# end
|
||||
issue_hash = old_value_to_hash(@issue, params)
|
||||
|
||||
if @issue.issue_type.to_s == "2" && params[:status_id].to_i == 5 && @issue.author_id != current_user.try(:id)
|
||||
normal_status(-1, "不允许修改为关闭状态")
|
||||
|
|
@ -201,6 +204,7 @@ class IssuesController < ApplicationController
|
|||
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
||||
|
||||
if @issue.update_attributes(issue_params)
|
||||
user_trace_update_log(issue_hash)
|
||||
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
|
||||
@issue.issue_times.update_all(end_time: Time.now)
|
||||
@issue.update_closed_issues_count_in_project!
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ class JournalsController < ApplicationController
|
|||
before_action :set_issue
|
||||
before_action :check_issue_permission
|
||||
before_action :set_journal, only: [:destroy, :edit, :update]
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
def index
|
||||
@page = params[:page] || 1
|
||||
|
|
@ -67,7 +68,9 @@ class JournalsController < ApplicationController
|
|||
def update
|
||||
content = params[:content]
|
||||
if content.present?
|
||||
old_value = old_value_to_hash(@journal, params)
|
||||
if @journal.update_attribute(:notes, content)
|
||||
user_trace_update_log(old_value)
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
normal_status(-1, "更新失败")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
class LogController < ApplicationController
|
||||
def list
|
||||
path = "#{Rails.root}/log"
|
||||
@file_list = []
|
||||
Dir.foreach(path) do |file|
|
||||
@file_list << file
|
||||
end
|
||||
@file_list = @file_list.sort
|
||||
end
|
||||
|
||||
def download
|
||||
path = "#{Rails.root}/log/#{params[:filename]}"
|
||||
if params[:filename] && File.exist?(path) && File.file?(path)
|
||||
send_file(path, filename: params[:filename])
|
||||
else
|
||||
render json: { message: 'no such file!' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@ class MembersController < ApplicationController
|
|||
before_action :operate!, except: %i[index]
|
||||
before_action :check_member_exists!, only: %i[create]
|
||||
before_action :check_member_not_exists!, only: %i[remove change_role]
|
||||
skip_after_action :user_trace_log, only: [:change_role]
|
||||
|
||||
def create
|
||||
interactor = Projects::AddMemberInteractor.call(@project.owner, @project, @user)
|
||||
|
|
@ -34,7 +35,9 @@ class MembersController < ApplicationController
|
|||
end
|
||||
|
||||
def change_role
|
||||
old_value = @project.members.where(user_id: params[:user_id])[0].roles.last.name
|
||||
interactor = Projects::ChangeMemberRoleInteractor.call(@project.owner, @project, @user, params[:role])
|
||||
user_trace_update_log(old_value)
|
||||
render_response(interactor)
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
|
|
@ -47,7 +50,7 @@ class MembersController < ApplicationController
|
|||
end
|
||||
|
||||
def member_exists?
|
||||
@project.members.exists?(params[:user_id])
|
||||
@project.member?(params[:user_id])
|
||||
end
|
||||
|
||||
def operate!
|
||||
|
|
@ -59,6 +62,6 @@ class MembersController < ApplicationController
|
|||
end
|
||||
|
||||
def check_member_not_exists!
|
||||
return render_result(1, "user_id为#{params[:user_id]}的用户还不是项目成员") unless @project.member?(params[:user_id])
|
||||
return render_result(1, "user_id为#{params[:user_id]}的用户还不是项目成员") unless member_exists?
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base
|
|||
include RenderHelper
|
||||
include LoginHelper
|
||||
include ControllerRescueHandler
|
||||
include LoggerHelper
|
||||
# include LaboratoryHelper
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
|
|
@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base
|
|||
end
|
||||
|
||||
private
|
||||
def tip_exception(status = -1, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def tip_show_exception(status = -2, message)
|
||||
raise Educoder::TipException.new(status, message)
|
||||
end
|
||||
|
||||
def tip_show(exception)
|
||||
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
|
||||
render json: exception.tip_json
|
||||
end
|
||||
|
||||
def session_user_id
|
||||
# session[:user_id]
|
||||
|
|
@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base
|
|||
Rails.logger.info("[wechat] set session unionid: #{unionid}")
|
||||
session[:unionid] = unionid
|
||||
end
|
||||
|
||||
def session_edulogin
|
||||
session[:edulogin]
|
||||
end
|
||||
|
||||
def set_session_edulogin(login)
|
||||
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
|
||||
session[:edulogin] = login
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
class Oauth::EducoderController < Oauth::BaseController
|
||||
include RegisterHelper
|
||||
|
||||
def bind
|
||||
begin
|
||||
login = params[:login]
|
||||
|
|
@ -32,4 +34,41 @@ class Oauth::EducoderController < Oauth::BaseController
|
|||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
|
||||
# 需要educoder那边设置回调地址
|
||||
def create
|
||||
begin
|
||||
code = params['code'].to_s.strip
|
||||
tip_exception("code不能为空") if code.blank?
|
||||
|
||||
new_user = false
|
||||
result = EducoderOauth::Service.access_token(code)
|
||||
result = EducoderOauth::Service.user_info(result[:access_token])
|
||||
|
||||
# 存在该用户
|
||||
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
|
||||
if open_user.present? && open_user.user.present?
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
if current_user.blank? || !current_user.logged?
|
||||
new_user = true
|
||||
login = User.generate_login('E')
|
||||
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
|
||||
if reg_result[:message].blank?
|
||||
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
|
||||
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
|
||||
successful_authentication(open_user.user)
|
||||
else
|
||||
render_error(reg_result[:message])
|
||||
end
|
||||
else
|
||||
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
|
||||
end
|
||||
end
|
||||
|
||||
redirect_to root_path(new_user: new_user)
|
||||
rescue Exception => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ class Organizations::BaseController < ApplicationController
|
|||
end
|
||||
|
||||
def team_not_found_condition
|
||||
!current_user&.admin? && @team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user.id)
|
||||
@team.team_users.where(user_id: current_user.id).blank? && !@organization.is_owner?(current_user.id)
|
||||
end
|
||||
|
||||
def user_mark
|
||||
|
|
@ -31,4 +31,4 @@ class Organizations::BaseController < ApplicationController
|
|||
def project_mark
|
||||
params[:repo_name] || params[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -25,7 +25,6 @@ class Organizations::OrganizationsController < Organizations::BaseController
|
|||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
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?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,10 +33,7 @@ class Organizations::TeamsController < Organizations::BaseController
|
|||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
Organizations::CreateTeamForm.new(team_params).validate!
|
||||
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
|
||||
end
|
||||
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
tip_exception(e.message)
|
||||
|
|
@ -63,7 +60,7 @@ class Organizations::TeamsController < Organizations::BaseController
|
|||
|
||||
private
|
||||
def team_params
|
||||
params.permit(:name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types => [])
|
||||
params.permit(:name, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types => [])
|
||||
end
|
||||
|
||||
def load_organization
|
||||
|
|
|
|||
|
|
@ -183,7 +183,7 @@ class ProjectsController < ApplicationController
|
|||
|
||||
private
|
||||
def project_params
|
||||
params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url,
|
||||
params.permit(:user_id, :name, :description, :repository_name, :website,
|
||||
:project_category_id, :project_language_id, :license_id, :ignore_id, :private)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
class PullRequestsController < ApplicationController
|
||||
|
||||
before_action :require_login, except: [:index, :show, :files, :commits]
|
||||
before_action :load_repository
|
||||
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits]
|
||||
before_action :load_pull_request, only: [:files, :commits]
|
||||
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
include TagChosenHelper
|
||||
include ApplicationHelper
|
||||
|
||||
|
|
@ -86,8 +89,14 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
old_issue_value = old_value_to_hash(@issue, @issue_params)
|
||||
old_pr_value = old_value_to_hash(@pull_request, @local_params.compact)
|
||||
old_value = {issue: old_issue_value, pull_request: old_pr_value}
|
||||
|
||||
if @issue.update_attributes(@issue_params)
|
||||
if @pull_request.update_attributes(@local_params.compact)
|
||||
|
||||
user_trace_update_log(old_value)
|
||||
gitea_pull = Gitea::PullRequest::UpdateService.call(@owner.login, @repository.identifier,
|
||||
@pull_request.gpid, @requests_params, current_user.gitea_token)
|
||||
|
||||
|
|
@ -140,7 +149,7 @@ class PullRequestsController < ApplicationController
|
|||
end
|
||||
|
||||
def pr_merge
|
||||
return render_forbidden("你没有权限操作.") unless current_user.project_manager?(@project)
|
||||
return render_forbidden("你没有权限操作.") if @project.reporter?(current_user)
|
||||
|
||||
if params[:do].blank?
|
||||
normal_status(-1, "请选择合并方式")
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
class SettingsController < ApplicationController
|
||||
def show
|
||||
@old_projects_url = nil
|
||||
@old_projects_url = "https://www.trustie.net/users/#{current_user.try(:login)}/projects" if User.current.logged?
|
||||
get_add_menu
|
||||
get_common_menu
|
||||
get_personal_menu
|
||||
|
||||
get_third_party
|
||||
end
|
||||
|
||||
private
|
||||
|
|
@ -40,6 +41,14 @@ class SettingsController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def get_third_party
|
||||
@third_party = []
|
||||
@third_party << {
|
||||
name: 'educoder',
|
||||
url: EducoderOauth.oauth_url
|
||||
}
|
||||
end
|
||||
|
||||
def get_site_url(key, value)
|
||||
key.to_s === "url" ? append_http(reset_site_url(value)) : reset_site_url(value)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,90 @@
|
|||
class SponsorTiersController < ApplicationController
|
||||
before_action :set_sponsor_tier, only: [:show, :edit, :update, :destroy]
|
||||
before_action :check_sponsor, only: [:show]
|
||||
before_action :require_login, only: [:create, :update, :destroy]
|
||||
|
||||
# GET /sponsor_tiers
|
||||
# GET /sponsor_tiers.json
|
||||
def index
|
||||
# @sponsor_tiers = SponsorTier.all
|
||||
user = User.find_by_login(params[:login])
|
||||
@sponsor_tiers = user.sponsor_tier
|
||||
end
|
||||
|
||||
# GET /sponsor_tiers/1
|
||||
# GET /sponsor_tiers/1.json
|
||||
def show
|
||||
|
||||
end
|
||||
|
||||
# POST /sponsor_tiers
|
||||
# POST /sponsor_tiers.json
|
||||
def create
|
||||
# print("------------\n", sponsor_tier_params, "\n------------\n")
|
||||
@check_sponsorship = nil
|
||||
@sponsor_tier = SponsorTier.new(sponsor_tier_params)
|
||||
respond_to do |format|
|
||||
if @sponsor_tier.user_id == User.current.id && @sponsor_tier.save
|
||||
format.html { redirect_to @sponsor_tier, notice: 'Sponsor tier was successfully created.' }
|
||||
format.json { render :show, status: :created, location: @sponsor_tier }
|
||||
# render json: {status: 1, message: '创建成功' }
|
||||
else
|
||||
format.html { render :new }
|
||||
format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# PATCH/PUT /sponsor_tiers/1
|
||||
# PATCH/PUT /sponsor_tiers/1.json
|
||||
def update
|
||||
@check_sponsorship = nil
|
||||
old_value = old_value_to_hash(@sponsor_tier, params)
|
||||
respond_to do |format|
|
||||
if User.current.id == @sponsor_tier.user_id && @sponsor_tier.update(sponsor_tier_update_params)
|
||||
user_trace_update_log(old_value)
|
||||
format.html { redirect_to @sponsor_tier, notice: 'Sponsor tier was successfully updated.' }
|
||||
format.json { render :show, status: :ok, location: @sponsor_tier }
|
||||
# render json: {status: 1, message: '修改成功' }
|
||||
else
|
||||
format.html { render :edit }
|
||||
format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity }
|
||||
# format.json { render status: :unprocessable_entity }
|
||||
# render json: {status: -1, message: '修改失败' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /sponsor_tiers/1
|
||||
# DELETE /sponsor_tiers/1.json
|
||||
def destroy
|
||||
if User.current.id == @sponsor_tier.user_id
|
||||
@sponsor_tier.destroy
|
||||
respond_to do |format|
|
||||
format.html { redirect_to sponsor_tiers_url, notice: 'Sponsor tier was successfully destroyed.' }
|
||||
format.json { head :no_content }
|
||||
end
|
||||
else
|
||||
format.json { render json: @sponsor_tier.errors, status: :unprocessable_entity }
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def check_sponsor
|
||||
@check_sponsorship = Sponsorship.where("sponsor_id=? AND developer_id=?", current_user.id, @sponsor_tier.user.id)
|
||||
end
|
||||
|
||||
def set_sponsor_tier
|
||||
@sponsor_tier = SponsorTier.find(params[:id])
|
||||
end
|
||||
|
||||
def sponsor_tier_update_params
|
||||
params.require(:sponsor_tier).permit(:tier, :description)
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def sponsor_tier_params
|
||||
params.require(:sponsor_tier).permit(:tier, :user_id, :description)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
class SponsorshipsController < ApplicationController
|
||||
before_action :set_sponsorship, only: [:show, :edit, :update, :destroy]
|
||||
# before_action :require_login, except: [:index, :stopped, :sponsored, :sponsoring, :stopped_sponsored, :stopped_sponsoring]
|
||||
before_action :require_login, only: [:create, :edit, :update, :destroy]
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
# GET /sponsorships
|
||||
# GET /sponsorships.json
|
||||
def index
|
||||
@sponsorships = Sponsorship.all
|
||||
end
|
||||
|
||||
def stopped
|
||||
@stopped_sponsorships = StoppedSponsorship.all
|
||||
end
|
||||
|
||||
def sponsored
|
||||
if User.current.id == Integer(params[:id])
|
||||
@sponsorships = Sponsorship.where("developer_id=?", params[:id])
|
||||
else
|
||||
@sponsorships = Sponsorship.where("developer_id=? AND visible=1", params[:id])
|
||||
end
|
||||
sort = params[:sort_by] || "created_at"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
@sponsorships = @sponsorships.reorder("#{sort} #{sort_direction}")
|
||||
@total = @sponsorships.length
|
||||
@sponsorships = kaminari_paginate(@sponsorships)
|
||||
end
|
||||
|
||||
def sponsoring
|
||||
if User.current.id == Integer(params[:id])
|
||||
@sponsorships = Sponsorship.where("sponsor_id=?", params[:id])
|
||||
else
|
||||
@sponsorships = Sponsorship.where("sponsor_id=? AND visible=1", params[:id])
|
||||
end
|
||||
sort = params[:sort_by] || "created_at"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
@sponsorships = @sponsorships.reorder("#{sort} #{sort_direction}")
|
||||
@total = @sponsorships.length
|
||||
@sponsorships = kaminari_paginate(@sponsorships)
|
||||
end
|
||||
|
||||
def stopped_sponsored
|
||||
if User.current.id == Integer(params[:id])
|
||||
@stopped_sponsorships = StoppedSponsorship.where("developer_id=?", params[:id])
|
||||
else
|
||||
@stopped_sponsorships = StoppedSponsorship.where("developer_id=? AND visible=1", params[:id])
|
||||
end
|
||||
sort = params[:sort_by] || "created_at"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
@stopped_sponsorships = @stopped_sponsorships.reorder("#{sort} #{sort_direction}")
|
||||
@total = @stopped_sponsorships.length
|
||||
@stopped_sponsorships = kaminari_paginate(@stopped_sponsorships)
|
||||
end
|
||||
|
||||
def stopped_sponsoring
|
||||
if User.current.id == Integer(params[:id])
|
||||
@stopped_sponsorships = StoppedSponsorship.where("sponsor_id=?", params[:id])
|
||||
else
|
||||
@stopped_sponsorships = StoppedSponsorship.where("sponsor_id=? AND visible=1", params[:id])
|
||||
end
|
||||
sort = params[:sort_by] || "created_at"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
@stopped_sponsorships = @stopped_sponsorships.reorder("#{sort} #{sort_direction}")
|
||||
@total = @stopped_sponsorships.length
|
||||
@stopped_sponsorships = kaminari_paginate(@stopped_sponsorships)
|
||||
end
|
||||
|
||||
# GET /sponsorships/1
|
||||
# GET /sponsorships/1.json
|
||||
def show
|
||||
end
|
||||
|
||||
# POST /sponsorships
|
||||
# POST /sponsorships.json
|
||||
def create
|
||||
sponsor_id = User.current.id
|
||||
check_sponsorship = Sponsorship.where("sponsor_id=? AND developer_id=?", sponsor_id, params[:developer_id])
|
||||
|
||||
@sponsorship = Sponsorship.new(sponsorship_params.merge({sponsor_id: sponsor_id}))
|
||||
|
||||
unless check_sponsorship.length.zero?
|
||||
return render json: {status: -1, message: '您已经赞助了TA' }
|
||||
end
|
||||
|
||||
if @sponsorship.pay && @sponsorship.save
|
||||
if params[:single] && @sponsorship.stop
|
||||
return render json: { status: 1, message: '赞助成功' }
|
||||
elsif !params[:single]
|
||||
User.current.update(sponsor_num: User.current.sponsor_num+1)
|
||||
@sponsorship.developer.update(sponsored_num: @sponsorship.developer.sponsored_num + 1)
|
||||
return render json: { status: 1, message: '赞助成功' }
|
||||
else
|
||||
return render json: { status: -1, message: '赞助失败' }
|
||||
end
|
||||
end
|
||||
# return render_result message: '赞助成功' if @sponsorship.save
|
||||
# respond_to do |format|
|
||||
# if check_sponsorship.length.zero? && @sponsorship.save
|
||||
# format.html { redirect_to @sponsorship, notice: 'Sponsorship was successfully created.' }
|
||||
# format.json { render :show, status: :created, location: @sponsorship }
|
||||
# # render_result status=0, message="赞助成功"
|
||||
# else
|
||||
# format.html { render :new }
|
||||
# format.json { render json: @sponsorship.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
||||
# PATCH/PUT /sponsorships/1
|
||||
# PATCH/PUT /sponsorships/1.json
|
||||
def update
|
||||
# respond_to do |format|
|
||||
# if @sponsorship.update(sponsorship_params)
|
||||
# format.html { redirect_to @sponsorship, notice: 'Sponsorship was successfully updated.' }
|
||||
# format.json { render :show, status: :ok, location: @sponsorship }
|
||||
# else
|
||||
# format.html { render :edit }
|
||||
# format.json { render json: @sponsorship.errors, status: :unprocessable_entity }
|
||||
# end
|
||||
# end
|
||||
|
||||
if @sponsorship.sponsor.id != current_user.id
|
||||
return render json: {status: 401, message: '没有权限' }
|
||||
end
|
||||
old_value = old_value_to_hash(@sponsorship, params)
|
||||
|
||||
if @sponsorship.update(sponsorship_params)
|
||||
user_trace_update_log(old_value)
|
||||
render json: {status: 1, message: '修改成功' }
|
||||
else
|
||||
render json: {status: -1, message: '修改失败' }
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /sponsorships/1
|
||||
# DELETE /sponsorships/1.json
|
||||
def destroy
|
||||
# @sponsorship.destroy
|
||||
# respond_to do |format|
|
||||
# format.html { redirect_to sponsorships_url, notice: 'Sponsorship was successfully destroyed.' }
|
||||
# format.json { head :no_content }
|
||||
# end
|
||||
developer = @sponsorship.developer
|
||||
sponsor = @sponsorship.sponsor
|
||||
if (User.current.id == developer.id || User.current.id == sponsor.id) && developer.update(sponsored_num: developer.sponsored_num-1) && sponsor.update(sponsor_num: sponsor.sponsor_num-1) && @sponsorship.stop
|
||||
render json: {status: 1, message: "终止成功"}
|
||||
else
|
||||
render json: {status: -1, message: "失败"}
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
# Use callbacks to share common setup or constraints between actions.
|
||||
def set_sponsorship
|
||||
@sponsorship = Sponsorship.find(params[:id])
|
||||
end
|
||||
|
||||
# Only allow a list of trusted parameters through.
|
||||
def sponsorship_params
|
||||
params.require(:sponsorship).permit(:amount, :visible, :sponsor_id, :developer_id, :single, :page, :limit, :sort_by, :search)
|
||||
end
|
||||
end
|
||||
|
|
@ -2,8 +2,8 @@ class UsersController < ApplicationController
|
|||
include ApplicationHelper
|
||||
include Ci::DbConnectable
|
||||
|
||||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard]
|
||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
|
||||
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users]
|
||||
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users]
|
||||
before_action :require_login, only: %i[me list sync_user_info]
|
||||
before_action :connect_to_ci_db, only: [:get_user_info]
|
||||
skip_before_action :check_sign, only: [:attachment_show]
|
||||
|
|
@ -56,9 +56,6 @@ class UsersController < ApplicationController
|
|||
@watchers = paginate(watchers)
|
||||
end
|
||||
|
||||
def hovercard
|
||||
end
|
||||
|
||||
def update
|
||||
@user = User.find params[:id]
|
||||
@user.update!(user_params)
|
||||
|
|
@ -75,6 +72,10 @@ class UsersController < ApplicationController
|
|||
@user = current_user
|
||||
# TODO 等消息上线再打开注释
|
||||
#@tidding_count = unviewed_tiddings(current_user) if current_user.present?
|
||||
#
|
||||
if(@user.logged?)
|
||||
@user.daily_reward
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
missing_template
|
||||
|
|
@ -236,6 +237,15 @@ class UsersController < ApplicationController
|
|||
render_ok
|
||||
end
|
||||
|
||||
def update_description
|
||||
@user = User.find params[:id]
|
||||
if @user.id == User.current.id && @user.update(description: params[:description])
|
||||
render_ok
|
||||
else
|
||||
render_error
|
||||
end
|
||||
end
|
||||
|
||||
def sync_user_info
|
||||
user = User.find_by_login params[:login]
|
||||
return render_forbidden unless user === current_user
|
||||
|
|
@ -249,7 +259,7 @@ class UsersController < ApplicationController
|
|||
|
||||
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
|
||||
if interactor.success?
|
||||
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_EDIT_INFO)
|
||||
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_ACTIVE)
|
||||
render_ok
|
||||
else
|
||||
render_error(interactor.error)
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@ class VersionReleasesController < ApplicationController
|
|||
before_action :set_user
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :find_version , only: [:edit, :update, :destroy]
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
def index
|
||||
version_releases = Gitea::Versions::ListService.new(@user.gitea_token, @user.try(:login), @repository.try(:identifier)).call
|
||||
@version_releases = version_releases
|
||||
@user_permission = current_user.present? && (current_user == @user || current_user.admin?)
|
||||
@forge_releases = @repository.version_releases.select(:id,:version_gid, :created_at).includes(:attachments)
|
||||
@forge_releases = @repository.version_releases.select(:id,:version_gid).includes(:attachments)
|
||||
end
|
||||
|
||||
def new
|
||||
|
|
@ -78,14 +79,14 @@ class VersionReleasesController < ApplicationController
|
|||
ActiveRecord::Base.transaction do
|
||||
begin
|
||||
version_params = releases_params
|
||||
|
||||
old_value = old_value_to_hash(@version, version_params)
|
||||
if @version.update_attributes!(version_params)
|
||||
create_attachments(params[:attachment_ids], @version) if params[:attachment_ids].present?
|
||||
git_version_release = Gitea::Versions::UpdateService.new(@user.gitea_token, @user.try(:login), @repository.try(:identifier), version_params, @version.try(:version_gid)).call
|
||||
unless git_version_release
|
||||
raise Error, "更新失败"
|
||||
end
|
||||
|
||||
user_trace_update_log(old_value)
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
normal_status(-1, "更新失败")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
class WalletsController < ApplicationController
|
||||
before_action :require_login
|
||||
|
||||
def balance
|
||||
user = User.find_by_id(params[:id])
|
||||
@wallet = user.get_wallet
|
||||
end
|
||||
|
||||
def coin_changes
|
||||
user = User.find_by_id(params[:id])
|
||||
@wallet = user.get_wallet
|
||||
if params[:category] == 'all'
|
||||
scope = CoinChange.where('to_wallet_id = ? OR from_wallet_id = ?', @wallet.id, @wallet.id)
|
||||
elsif params[:category] == 'income'
|
||||
# @coin_changes = CoinChange.where('to_wallet_id = ?', @wallet.id).limit(100)
|
||||
scope = @wallet.income
|
||||
elsif params[:category] == 'outcome'
|
||||
scope = @wallet.outcome
|
||||
end
|
||||
|
||||
sort = params[:sort_by] || "created_at"
|
||||
sort_direction = params[:sort_direction] || "desc"
|
||||
scope = scope.reorder("#{sort} #{sort_direction}")
|
||||
|
||||
@total = scope.length
|
||||
@coin_changes = kaminari_paginate(scope)
|
||||
end
|
||||
end
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
class Organizations::CreateForm < BaseForm
|
||||
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
attr_accessor :name, :description, :website, :location, :repo_admin_change_team_access, :visibility, :max_repo_creation, :nickname
|
||||
|
||||
validates :name, :nickname, :visibility, presence: true
|
||||
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||
|
||||
end
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
class Organizations::CreateTeamForm < BaseForm
|
||||
NAME_REGEX = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾
|
||||
attr_accessor :name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project, :unit_types
|
||||
|
||||
validates :name, :nickname, :authorize, presence: true
|
||||
validates :name, format: { with: NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||
|
||||
end
|
||||
|
|
@ -35,6 +35,12 @@ module ApplicationHelper
|
|||
course.course_modules.find_by(module_type: "graduation").try(:id)
|
||||
end
|
||||
|
||||
# 是否关注
|
||||
# from_user_id为被关注的用户
|
||||
def follow?(from_user_id, user_id)
|
||||
Watcher.where(watchable_type: 'Principal', watchable_id: from_user_id, user_id: user_id).exists?
|
||||
end
|
||||
|
||||
# git用户
|
||||
# git用户命名规则:login+"@educoder.net"
|
||||
def git_username(email)
|
||||
|
|
@ -138,12 +144,17 @@ module ApplicationHelper
|
|||
if File.exist?(disk_filename(source&.class, source&.id))
|
||||
ctime = File.ctime(disk_filename(source.class, source.id)).to_i
|
||||
if %w(User Organization).include?(source.class.to_s)
|
||||
File.join("images", relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
|
||||
File.join(relative_path, ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
|
||||
else
|
||||
File.join("images/avatars", ["#{source.class}", "#{source.id}"]) + "?t=#{ctime}"
|
||||
end
|
||||
elsif source.class.to_s == 'User'
|
||||
source.get_letter_avatar_url
|
||||
str = source.user_extension.try(:gender).to_i == 0 ? "b" : "g"
|
||||
File.join(relative_path, "#{source.class}", str)
|
||||
elsif source.class.to_s == 'Subject'
|
||||
File.join("images","educoder", "index", "subject", "subject#{rand(17)}.jpg")
|
||||
elsif source.class.to_s == 'Shixun'
|
||||
File.join("images","educoder", "index", "shixun", "shixun#{rand(23)}.jpg")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
module LogHelper
|
||||
end
|
||||
|
|
@ -90,4 +90,8 @@ module ProjectsHelper
|
|||
def render_educoder_avatar_url(project_educoder)
|
||||
[Rails.application.config_for(:configuration)['educoder']['cdn_url'], project_educoder&.image_url].join('/')
|
||||
end
|
||||
|
||||
def render_avatar_url(owner)
|
||||
['images', url_to_avatar(owner)].join('/')
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
module SponsorTiersHelper
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
module SponsorshipsHelper
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
module UpdateHelper
|
||||
def old_value_to_hash(old_value, params)
|
||||
params = params.dup.stringify_keys
|
||||
old_value.attributes.select { |key, value| params.key?(key) }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
module WalletsHelper
|
||||
end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
class MonthlyPaymentWorker
|
||||
include Sidekiq::Worker
|
||||
include Sidetiq::Schedulable
|
||||
|
||||
recurrence do
|
||||
minutely(2)
|
||||
# monthly.day_of_month(12) #每月的12号0点执行
|
||||
# monthly.day_of_month(23).hour_of_day(20) #每月的12号1点执行
|
||||
end
|
||||
|
||||
def perform(*args)
|
||||
Sponsorship.monthly_payment
|
||||
puts Time.now, 'sponsor payment done'
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
module EducoderOauth
|
||||
class << self
|
||||
attr_accessor :client_id, :client_secret, :base_url, :redirect_uri
|
||||
|
||||
def logger
|
||||
@_logger ||= STDOUT
|
||||
end
|
||||
|
||||
def logger=(l)
|
||||
@_logger = l
|
||||
end
|
||||
|
||||
def oauth_url
|
||||
"#{base_url}/oauth2?call_url=/oauth/authorize?client_id=#{client_id}&redirect_uri=#{URI.encode_www_form_component(redirect_uri)}&response_type=code"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
require 'oauth2'
|
||||
|
||||
module EducoderOauth::Service
|
||||
module_function
|
||||
|
||||
def request(method, url, params)
|
||||
begin
|
||||
Rails.logger.info("[EducoderOauth] [#{method.to_s.upcase}] #{url} || #{params}")
|
||||
|
||||
client = Faraday.new(url: EducoderOauth.base_url)
|
||||
response = client.public_send(method, url, params)
|
||||
result = JSON.parse(response.body)
|
||||
|
||||
Rails.logger.info("[EducoderOauth] [#{response.status}] #{result}")
|
||||
|
||||
result
|
||||
rescue Exception => e
|
||||
raise Educoder::TipException.new(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def access_token(code)
|
||||
begin
|
||||
Rails.logger.info("[EducoderOauth] [code] #{code} ")
|
||||
Rails.logger.info("[EducoderOauth] [redirect_uri] #{EducoderOauth.redirect_uri} ")
|
||||
client = OAuth2::Client.new(EducoderOauth.client_id, EducoderOauth.client_secret, site: EducoderOauth.base_url)
|
||||
result = client.auth_code.get_token(code, redirect_uri: EducoderOauth.redirect_uri).to_hash
|
||||
return result
|
||||
rescue Exception => e
|
||||
raise Educoder::TipException.new(e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def user_info(access_token)
|
||||
request(:get, '/api/users/info.json', {access_token: access_token})
|
||||
end
|
||||
end
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
# disk_directory :string(255)
|
||||
# attachtype :integer default("1")
|
||||
# is_public :integer default("1")
|
||||
# copy_from :string(255)
|
||||
# copy_from :integer
|
||||
# quotes :integer default("0")
|
||||
# is_publish :integer default("1")
|
||||
# publish_time :datetime
|
||||
|
|
@ -26,15 +26,15 @@
|
|||
# cloud_url :string(255) default("")
|
||||
# course_second_category_id :integer default("0")
|
||||
# delay_publish :boolean default("0")
|
||||
# link :string(255)
|
||||
# clone_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_attachments_on_author_id (author_id)
|
||||
# index_attachments_on_clone_id (clone_id)
|
||||
# index_attachments_on_container_id_and_container_type (container_id,container_type)
|
||||
# index_attachments_on_course_second_category_id (course_second_category_id)
|
||||
# index_attachments_on_created_on (created_on)
|
||||
# index_attachments_on_is_public (is_public)
|
||||
# index_attachments_on_quotes (quotes)
|
||||
#
|
||||
|
||||
class Attachment < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -1,21 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: chart_rules
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# rule_type :string(255)
|
||||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# competition_id :integer
|
||||
# competition_stage_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_chart_rules_on_competition_id (competition_id)
|
||||
# index_chart_rules_on_competition_stage_id (competition_stage_id)
|
||||
#
|
||||
|
||||
class ChartRule < ApplicationRecord
|
||||
|
||||
validates :content, length: { maximum: 1000, too_long: "不能超过1000个字符" }
|
||||
|
|
|
|||
|
|
@ -1,22 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: stages
|
||||
#
|
||||
# id :integer not null
|
||||
# subject_id :integer
|
||||
# name :string(255)
|
||||
# description :text(65535)
|
||||
# user_id :integer
|
||||
# position :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# shixuns_count :integer default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_stages_on_subject_id (subject_id)
|
||||
#
|
||||
|
||||
class Ci::Stage < Ci::RemoteBase
|
||||
self.primary_key = 'stage_id'
|
||||
|
||||
|
|
|
|||
|
|
@ -39,14 +39,18 @@
|
|||
# business :boolean default("0")
|
||||
# profile_completed :boolean default("0")
|
||||
# laboratory_id :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# admin_visitable :boolean default("0")
|
||||
# collaborator :boolean default("0")
|
||||
# platform :string(255) default("0")
|
||||
# gitea_token :string(255)
|
||||
# gitea_uid :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# is_sync_pwd :boolean default("1")
|
||||
# watchers_count :integer default("0")
|
||||
# sponsor_certification :integer default("0")
|
||||
# sponsor_num :integer default("0")
|
||||
# sponsored_num :integer default("0")
|
||||
# description :text(65535)
|
||||
# devops_step :integer default("0")
|
||||
# gitea_token :string(255)
|
||||
# award_time :datetime
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
@ -54,9 +58,8 @@
|
|||
# index_users_on_homepage_engineer (homepage_engineer)
|
||||
# index_users_on_homepage_teacher (homepage_teacher)
|
||||
# index_users_on_laboratory_id (laboratory_id)
|
||||
# index_users_on_login (login) UNIQUE
|
||||
# index_users_on_mail (mail) UNIQUE
|
||||
# index_users_on_phone (phone) UNIQUE
|
||||
# index_users_on_login (login)
|
||||
# index_users_on_mail (mail)
|
||||
# index_users_on_type (type)
|
||||
#
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: coin_changes
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# amount :integer
|
||||
# description :string(255)
|
||||
# reason :string(255)
|
||||
# to_wallet_id :integer
|
||||
# from_wallet_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class CoinChange < ApplicationRecord
|
||||
belongs_to :to_wallet, class_name: 'Wallet'
|
||||
belongs_to :from_wallet, class_name: 'Wallet', optional: true
|
||||
validates :amount, presence: true
|
||||
end
|
||||
|
|
@ -6,7 +6,6 @@ module Watchable
|
|||
has_many :watcher_users, through: :watchers, source: :user, validate: false
|
||||
|
||||
scope :watched_by, -> (user_id) { includes(:watchers).where(watchers: { user_id: user_id }) }
|
||||
scope :following, -> (user_id) { watched_by(user_id) }
|
||||
end
|
||||
|
||||
def watched?(watchable)
|
||||
|
|
@ -22,24 +21,6 @@ module Watchable
|
|||
obj.destroy! if obj.present?
|
||||
end
|
||||
|
||||
# 我正在关注的、我追随的
|
||||
def following
|
||||
User.following(self.id)
|
||||
end
|
||||
|
||||
def following_count
|
||||
following.size
|
||||
end
|
||||
|
||||
# 关注我的、我的粉丝、我的追随者
|
||||
def followers
|
||||
watcher_users
|
||||
end
|
||||
|
||||
def followers_count
|
||||
followers.size
|
||||
end
|
||||
|
||||
module ClassMethods
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,38 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: discusses
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# dis_type :string(255)
|
||||
# dis_id :integer
|
||||
# content :text(65535)
|
||||
# parent_id :integer
|
||||
# root_id :integer
|
||||
# praise_count :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# challenge_id :integer
|
||||
# reward :integer
|
||||
# hidden :boolean default("0")
|
||||
# last_reply_id :integer
|
||||
# position :integer
|
||||
# praises_count :integer default("0")
|
||||
# sticky :boolean default("0")
|
||||
# course_sticky :boolean default("0")
|
||||
# course_hidden :boolean default("0")
|
||||
# copy_message_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_discusses_on_challenge_id (challenge_id)
|
||||
# index_discusses_on_copy_message_id (copy_message_id)
|
||||
# index_discusses_on_course_hidden (course_hidden)
|
||||
# index_discusses_on_course_sticky (course_sticky)
|
||||
# index_discusses_on_dis_id_and_dis_type (dis_id,dis_type)
|
||||
# index_discusses_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class Discuss < ApplicationRecord
|
||||
default_scope { order(created_at: :desc) }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,5 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: forge_activities
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer
|
||||
# project_id :integer
|
||||
# forge_act_id :integer
|
||||
# forge_act_type :string(255)
|
||||
# org_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# forge_act_index (project_id,forge_act_id,created_at,forge_act_type)
|
||||
# index_forge_activities_on_forge_act_id (forge_act_id)
|
||||
#
|
||||
|
||||
class ForgeActivity < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :project
|
||||
belongs_to :forge_act, polymorphic: true
|
||||
end
|
||||
end
|
||||
|
|
@ -1,17 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: helps
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# about_us :text(65535)
|
||||
# agreement :text(65535)
|
||||
# status :text(65535)
|
||||
# help_center :text(65535)
|
||||
# join_us :text(65535)
|
||||
#
|
||||
|
||||
class Help < ApplicationRecord
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -10,12 +10,6 @@
|
|||
# sync_course :boolean default("0")
|
||||
# sync_subject :boolean default("0")
|
||||
# sync_shixun :boolean default("0")
|
||||
# is_local :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_laboratories_on_identifier (identifier) UNIQUE
|
||||
# index_laboratories_on_school_id (school_id)
|
||||
#
|
||||
|
||||
class Laboratory < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@
|
|||
# laboratory_id :integer
|
||||
# config :text(65535)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_laboratory_settings_on_laboratory_id (laboratory_id)
|
||||
#
|
||||
|
||||
class LaboratorySetting < ApplicationRecord
|
||||
belongs_to :laboratory
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
# content :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# is_secret :boolean default("0")
|
||||
#
|
||||
|
||||
class License < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -1,27 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: live_links
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# course_id :integer
|
||||
# user_id :integer
|
||||
# url :string(255)
|
||||
# description :text(65535)
|
||||
# on_status :boolean default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# course_name :string(255)
|
||||
# platform :string(255)
|
||||
# live_time :datetime
|
||||
# duration :integer
|
||||
# position :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_live_links_on_course_id (course_id)
|
||||
# index_live_links_on_user_id (user_id)
|
||||
#
|
||||
|
||||
class LiveLink < ApplicationRecord
|
||||
# belongs_to :course
|
||||
belongs_to :user
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
# course_group_id :integer default("0")
|
||||
# is_collect :integer default("1")
|
||||
# graduation_group_id :integer default("0")
|
||||
# is_apply_signature :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,18 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_details
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# content :text(4294967295)
|
||||
# message_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_message_details_on_message_id (message_id)
|
||||
#
|
||||
|
||||
class MessageDetail < ApplicationRecord
|
||||
# belongs_to :message, :touch => true
|
||||
validates :content, length: { maximum: 10000, too_long: "内容不能超过10000个字符" }
|
||||
|
|
|
|||
|
|
@ -39,14 +39,13 @@
|
|||
# business :boolean default("0")
|
||||
# profile_completed :boolean default("0")
|
||||
# laboratory_id :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# admin_visitable :boolean default("0")
|
||||
# collaborator :boolean default("0")
|
||||
# platform :string(255) default("0")
|
||||
# gitea_token :string(255)
|
||||
# gitea_uid :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# is_sync_pwd :boolean default("1")
|
||||
# watchers_count :integer default("0")
|
||||
# devops_step :integer default("0")
|
||||
# gitea_token :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
@ -54,9 +53,8 @@
|
|||
# index_users_on_homepage_engineer (homepage_engineer)
|
||||
# index_users_on_homepage_teacher (homepage_teacher)
|
||||
# index_users_on_laboratory_id (laboratory_id)
|
||||
# index_users_on_login (login) UNIQUE
|
||||
# index_users_on_mail (mail) UNIQUE
|
||||
# index_users_on_phone (phone) UNIQUE
|
||||
# index_users_on_login (login)
|
||||
# index_users_on_mail (mail)
|
||||
# index_users_on_type (type)
|
||||
#
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: passed_waitlists
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# applicant_id :string(255)
|
||||
# integer :string(255)
|
||||
# reviewer_id :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class PassedWaitlist < ApplicationRecord
|
||||
belongs_to :applicant, class_name: 'User'
|
||||
belongs_to :reviewer, class_name: 'User'
|
||||
end
|
||||
|
|
@ -37,6 +37,8 @@
|
|||
# rep_identifier :string(255)
|
||||
# project_category_id :integer
|
||||
# project_language_id :integer
|
||||
# license_id :integer
|
||||
# ignore_id :integer
|
||||
# praises_count :integer default("0")
|
||||
# watchers_count :integer default("0")
|
||||
# issues_count :integer default("0")
|
||||
|
|
@ -50,11 +52,8 @@
|
|||
# open_devops_count :integer default("0")
|
||||
# recommend :boolean default("0")
|
||||
# platform :integer default("0")
|
||||
# license_id :integer
|
||||
# ignore_id :integer
|
||||
# default_branch :string(255) default("master")
|
||||
# website :string(255)
|
||||
# lesson_url :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
@ -71,6 +70,10 @@
|
|||
# index_projects_on_updated_on (updated_on)
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Project < ApplicationRecord
|
||||
include Matchable
|
||||
include Publicable
|
||||
|
|
@ -158,7 +161,6 @@ class Project < ApplicationRecord
|
|||
|
||||
#创建项目管理员
|
||||
def check_project_members
|
||||
return if owner.is_a?(Organization)
|
||||
unless members.present? && members.exists?(user_id: self.user_id)
|
||||
member_params = {
|
||||
user_id: self.user_id,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@
|
|||
# projects_count :integer default("0")
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# ancestry :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_project_categories_on_ancestry (ancestry)
|
||||
#
|
||||
|
||||
class ProjectCategory < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_repositories_on_identifier (identifier)
|
||||
# index_repositories_on_project_id (project_id)
|
||||
# index_repositories_on_user_id (user_id)
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,39 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: schools
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# province :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# logo_link :string(255)
|
||||
# pinyin :string(255)
|
||||
# school_type :integer default("0")
|
||||
# city :string(255)
|
||||
# address :string(255)
|
||||
# auto_users_trial :boolean default("0")
|
||||
# shool_code :string(255)
|
||||
# authorization_time :datetime
|
||||
# ec_auth :integer default("0")
|
||||
# identifier :string(255)
|
||||
# is_online :boolean default("0")
|
||||
# video_name :string(255)
|
||||
# video_desc :string(255)
|
||||
# course_link :string(255)
|
||||
# course_name :string(255)
|
||||
# partner_id :integer
|
||||
# customer_id :integer
|
||||
# school_property_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_schools_on_customer_id (customer_id)
|
||||
# index_schools_on_identifier (identifier)
|
||||
# index_schools_on_partner_id (partner_id)
|
||||
# index_schools_on_school_property_id (school_property_id)
|
||||
#
|
||||
|
||||
class School < ApplicationRecord
|
||||
has_many :departments, dependent: :destroy
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: sponsor_tiers
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# tier :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# description :string(255) default("")
|
||||
# user_id :integer
|
||||
#
|
||||
|
||||
class SponsorTier < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: sponsorships
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# amount :integer
|
||||
# visible :integer
|
||||
# sponsor_id :integer
|
||||
# developer_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# accumulate :integer default("0")
|
||||
#
|
||||
|
||||
class Sponsorship < ApplicationRecord
|
||||
belongs_to :sponsor, class_name: 'User'
|
||||
belongs_to :developer, class_name: 'User'
|
||||
validates :amount, presence: true
|
||||
|
||||
def stop
|
||||
stopped_sponsorship = StoppedSponsorship.new(developer_id: developer_id, sponsor_id: sponsor_id, start_time: created_at, amount: amount, visible: visible, accumulate: accumulate)
|
||||
stopped_sponsorship.save && destroy
|
||||
end
|
||||
|
||||
def pay
|
||||
sponsor_wallet = sponsor.get_wallet
|
||||
developer_wallet = developer.get_wallet
|
||||
|
||||
Wallet.transaction do
|
||||
return false if sponsor.wallet.balance < amount
|
||||
|
||||
sponsor_wallet.update(balance: sponsor_wallet.balance -= amount)
|
||||
developer_wallet.update(balance: developer_wallet.balance += amount)
|
||||
update(accumulate: self.accumulate += amount)
|
||||
end
|
||||
reason = "#{sponsor.full_name}向#{developer.full_name}的赞助支付。"
|
||||
coinchange = CoinChange.new(amount: amount, reason: reason, to_wallet_id: developer_wallet.id, from_wallet_id: sponsor_wallet.id)
|
||||
if coinchange.save
|
||||
return true
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def self.monthly_payment
|
||||
sponsorships = Sponsorship.all
|
||||
sponsorships.each do |s|
|
||||
s.stop unless s.pay
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: stopped_sponsorships
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# amount :integer
|
||||
# sponsor_id :integer
|
||||
# developer_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# start_time :datetime
|
||||
# visible :integer
|
||||
# accumulate :integer default("0")
|
||||
#
|
||||
|
||||
class StoppedSponsorship < ApplicationRecord
|
||||
belongs_to :sponsor, class_name: 'User'
|
||||
belongs_to :developer, class_name: 'User'
|
||||
validates :amount, presence: true
|
||||
end
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
# gtid :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# nickname :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
|||
|
|
@ -1,19 +1,19 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: tokens
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# user_id :integer default("0"), not null
|
||||
# action :string(30) default(""), not null
|
||||
# value :string(40) default(""), not null
|
||||
# created_on :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_tokens_on_user_id (user_id)
|
||||
# tokens_value (value) UNIQUE
|
||||
#
|
||||
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
|
|
@ -76,7 +76,7 @@ class Token < ActiveRecord::Base
|
|||
# Returns the active user who owns the key for the given action
|
||||
def self.find_active_user(action, key, validity_days=nil)
|
||||
user = find_user(action, key, validity_days)
|
||||
if user && user.active?
|
||||
if user && (user.active? || user.need_edit_info?)
|
||||
user
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,87 +1,4 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: courses
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# tea_id :integer
|
||||
# name :string(255)
|
||||
# state :integer
|
||||
# code :string(255)
|
||||
# time :integer
|
||||
# extra :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# location :string(255)
|
||||
# term :string(255)
|
||||
# string :string(255)
|
||||
# password :string(255)
|
||||
# setup_time :string(255)
|
||||
# endup_time :string(255)
|
||||
# class_period :integer default("0")
|
||||
# school_id :integer
|
||||
# description :text(65535)
|
||||
# status :integer default("1")
|
||||
# attachmenttype :integer default("2")
|
||||
# lft :integer
|
||||
# rgt :integer
|
||||
# is_public :integer default("1")
|
||||
# inherit_members :integer default("1")
|
||||
# open_student :integer default("0")
|
||||
# outline :integer default("0")
|
||||
# publish_resource :integer default("0")
|
||||
# is_delete :integer default("0")
|
||||
# end_time :integer
|
||||
# end_term :string(255)
|
||||
# is_excellent :integer default("0")
|
||||
# excellent_option :integer default("0")
|
||||
# is_copy :integer default("0")
|
||||
# visits :integer default("0")
|
||||
# syllabus_id :integer
|
||||
# invite_code :string(255)
|
||||
# qrcode :string(255)
|
||||
# qrcode_expiretime :integer default("0")
|
||||
# invite_code_halt :integer default("0")
|
||||
# os_allow :integer default("0")
|
||||
# credit :float(24)
|
||||
# is_end :boolean default("0")
|
||||
# end_date :date
|
||||
# choose_group_allow :boolean default("0")
|
||||
# homepage_show :boolean default("0")
|
||||
# course_list_id :integer
|
||||
# members_count :integer default("0")
|
||||
# homework_commons_count :integer default("0")
|
||||
# show_unit :boolean default("0")
|
||||
# teacher_list :string(255) default("老师")
|
||||
# student_list :string(255) default("学生")
|
||||
# is_hidden :boolean default("0")
|
||||
# course_members_count :integer default("0")
|
||||
# course_groups_count :integer default("0")
|
||||
# authentication :boolean default("0")
|
||||
# professional_certification :boolean default("0")
|
||||
# graduation_topics_count :integer default("0")
|
||||
# graduation_tasks_count :integer default("0")
|
||||
# polls_count :integer default("0")
|
||||
# exercises_count :integer default("0")
|
||||
# start_date :date
|
||||
# subject_id :integer default("0")
|
||||
# excellent :boolean default("0")
|
||||
# email_notify :boolean default("0")
|
||||
# sticky :boolean default("0")
|
||||
# sticky_time :datetime
|
||||
# laboratory_id :integer
|
||||
# mooc_course_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_courses_on_invite_code (invite_code) UNIQUE
|
||||
# index_courses_on_laboratory_id (laboratory_id)
|
||||
# index_courses_on_mooc_course_id (mooc_course_id)
|
||||
# index_courses_on_school_id_and_is_delete (school_id,is_delete)
|
||||
# index_courses_on_subject_id (subject_id)
|
||||
# index_courses_on_tea_id (tea_id)
|
||||
#
|
||||
|
||||
class Trustie::Course < Trustie::Database
|
||||
has_many :course_groups, class_name: "Trustie::CourseGroup"
|
||||
has_many :homework_commons, class_name: "Trustie::HomeworkCommon"
|
||||
end
|
||||
end
|
||||
|
|
@ -1,25 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: course_groups
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# course_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# members_count :integer
|
||||
# invite_code :string(255)
|
||||
# position :integer default("0")
|
||||
# course_members_count :integer default("0")
|
||||
# invite_code_halt :boolean default("0")
|
||||
# invite_code_set :integer default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_course_groups_on_course_id (course_id)
|
||||
# index_course_groups_on_invite_code (invite_code) UNIQUE
|
||||
#
|
||||
|
||||
class Trustie::CourseGroup < Trustie::Database
|
||||
belongs_to :course, class_name: "Trustie::Course"
|
||||
end
|
||||
end
|
||||
|
|
@ -1,54 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: homework_commons
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# user_id :integer
|
||||
# description :text(65535)
|
||||
# publish_time :datetime
|
||||
# end_time :datetime
|
||||
# homework_type :integer default("1")
|
||||
# late_penalty :string(255) default("0")
|
||||
# course_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# teacher_priority :integer default("1")
|
||||
# anonymous_comment :boolean default("0")
|
||||
# quotes :integer default("0")
|
||||
# is_open :integer default("0")
|
||||
# simi_time :datetime
|
||||
# score_open :boolean default("0")
|
||||
# anonymous_appeal :boolean default("0")
|
||||
# homework_bank_id :integer
|
||||
# is_update :boolean default("0")
|
||||
# is_public :boolean default("0")
|
||||
# reference_answer :text(65535)
|
||||
# answer_public :boolean default("0")
|
||||
# archive_time :datetime
|
||||
# allow_late :boolean default("0")
|
||||
# late_time :datetime
|
||||
# work_public :boolean default("0")
|
||||
# explanation :text(65535)
|
||||
# unified_setting :boolean default("1")
|
||||
# comment_public :boolean default("1")
|
||||
# course_homework_category_id :integer
|
||||
# work_efficiency :boolean default("0")
|
||||
# eff_score :float(24) default("0")
|
||||
# max_efficiency :float(24) default("0")
|
||||
# course_second_category_id :integer default("0")
|
||||
# calculation_time :datetime
|
||||
# position :integer default("0")
|
||||
# total_score :float(24) default("100")
|
||||
# category_position :integer default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_homework_commons_on_course_id_and_id (course_id,id)
|
||||
# index_homework_commons_on_course_second_category_id (course_second_category_id)
|
||||
# index_homework_commons_on_homework_bank_id (homework_bank_id)
|
||||
#
|
||||
|
||||
class Trustie::HomeworkCommon < Trustie::Database
|
||||
belongs_to :course, class_name: "Trustie::Course"
|
||||
end
|
||||
end
|
||||
|
|
@ -39,14 +39,18 @@
|
|||
# business :boolean default("0")
|
||||
# profile_completed :boolean default("0")
|
||||
# laboratory_id :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# admin_visitable :boolean default("0")
|
||||
# collaborator :boolean default("0")
|
||||
# platform :string(255) default("0")
|
||||
# gitea_token :string(255)
|
||||
# gitea_uid :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# is_sync_pwd :boolean default("1")
|
||||
# watchers_count :integer default("0")
|
||||
# sponsor_certification :integer default("0")
|
||||
# sponsor_num :integer default("0")
|
||||
# sponsored_num :integer default("0")
|
||||
# description :text(65535)
|
||||
# devops_step :integer default("0")
|
||||
# gitea_token :string(255)
|
||||
# award_time :datetime
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
@ -54,9 +58,8 @@
|
|||
# index_users_on_homepage_engineer (homepage_engineer)
|
||||
# index_users_on_homepage_teacher (homepage_teacher)
|
||||
# index_users_on_laboratory_id (laboratory_id)
|
||||
# index_users_on_login (login) UNIQUE
|
||||
# index_users_on_mail (mail) UNIQUE
|
||||
# index_users_on_phone (phone) UNIQUE
|
||||
# index_users_on_login (login)
|
||||
# index_users_on_mail (mail)
|
||||
# index_users_on_type (type)
|
||||
#
|
||||
|
||||
|
|
@ -68,7 +71,6 @@ class User < Owner
|
|||
include Likeable
|
||||
include BaseModel
|
||||
include Droneable
|
||||
include User::Avatar
|
||||
# include Searchable::Dependents::User
|
||||
|
||||
# devops step
|
||||
|
|
@ -82,6 +84,7 @@ class User < Owner
|
|||
STATUS_ACTIVE = 1
|
||||
STATUS_REGISTERED = 2
|
||||
STATUS_LOCKED = 3
|
||||
STATUS_EDIT_INFO = 4
|
||||
|
||||
# tpi tpm权限控制
|
||||
EDU_ADMIN = 1 # 超级管理员
|
||||
|
|
@ -137,6 +140,10 @@ class User < Owner
|
|||
|
||||
has_many :attachments,foreign_key: :author_id, :dependent => :destroy
|
||||
|
||||
# 关注
|
||||
# has_many :be_watchers, foreign_key: :user_id, dependent: :destroy # 我的关注
|
||||
# has_many :be_watcher_users, through: :be_watchers, dependent: :destroy # 我关注的用户
|
||||
|
||||
has_one :ci_cloud_account, class_name: 'Ci::CloudAccount', dependent: :destroy
|
||||
|
||||
# 认证
|
||||
|
|
@ -156,11 +163,23 @@ class User < Owner
|
|||
has_many :project_trends, dependent: :destroy
|
||||
has_many :oauths , dependent: :destroy
|
||||
|
||||
# sponsor
|
||||
has_many :as_sponsors, class_name: 'Sponsorship', foreign_key: 'sponsor_id', dependent: :destroy
|
||||
has_many :as_sponsored, class_name: 'Sponsorship', foreign_key: 'developer_id', dependent: :destroy
|
||||
has_many :stopped_sponsors, class_name: 'StoppedSponsorship', foreign_key: 'sponsor_id', dependent: :destroy
|
||||
has_many :stopped_sponsored, class_name: 'StoppedSponsorship', foreign_key: 'developer_id', dependent: :destroy
|
||||
has_many :sponsor_tier, dependent: :destroy
|
||||
has_one :wallet, dependent: :destroy
|
||||
has_many :waitlist, class_name: 'Waitlist', foreign_key: 'reviewer_id'
|
||||
has_many :passed_waitlist, class_name: 'PassedWaitlist', foreign_key: 'reviewer_id' #as reviewer
|
||||
has_one :application, class_name: 'Waitlist', foreign_key: 'applicant_id'
|
||||
has_one :passed_application, class_name: 'PassedWaitlist', foreign_key: 'applicant_id'
|
||||
|
||||
has_many :organization_users, dependent: :destroy
|
||||
has_many :organizations, through: :organization_users
|
||||
|
||||
# Groups and active users
|
||||
scope :active, lambda { where(status: STATUS_ACTIVE) }
|
||||
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
|
||||
scope :like, lambda { |keywords|
|
||||
where("LOWER(concat(lastname, firstname, login, mail)) LIKE ?", "%#{keywords.split(" ").join('|')}%") unless keywords.blank?
|
||||
}
|
||||
|
|
@ -188,10 +207,6 @@ class User < Owner
|
|||
validate :validate_sensitive_string
|
||||
validate :validate_password_length
|
||||
|
||||
def name
|
||||
login
|
||||
end
|
||||
|
||||
# 删除自动登录的token,一旦退出下次会提示需要登录
|
||||
def delete_autologin_token(value)
|
||||
Token.where(:user_id => id, :action => 'autologin', :value => value).delete_all
|
||||
|
|
@ -206,7 +221,7 @@ class User < Owner
|
|||
end
|
||||
|
||||
def project_manager?(project)
|
||||
project.manager?(self) || self.admin?
|
||||
project.managers.exists?(user: self) || self.admin?
|
||||
end
|
||||
|
||||
# 学号
|
||||
|
|
@ -381,6 +396,10 @@ class User < Owner
|
|||
status == STATUS_LOCKED
|
||||
end
|
||||
|
||||
def need_edit_info?
|
||||
status == STATUS_EDIT_INFO
|
||||
end
|
||||
|
||||
def activate
|
||||
self.status = STATUS_ACTIVE
|
||||
end
|
||||
|
|
@ -393,6 +412,10 @@ class User < Owner
|
|||
self.status = STATUS_LOCKED
|
||||
end
|
||||
|
||||
def need_edit_info
|
||||
self.status = STATUS_EDIT_INFO
|
||||
end
|
||||
|
||||
def activate!
|
||||
update_attribute(:status, STATUS_ACTIVE)
|
||||
end
|
||||
|
|
@ -405,6 +428,10 @@ class User < Owner
|
|||
update_attribute(:status, STATUS_LOCKED)
|
||||
end
|
||||
|
||||
def need_edit_info!
|
||||
update_attribute(:status, STATUS_EDIT_INFO)
|
||||
end
|
||||
|
||||
# 课程用户身份
|
||||
def course_identity(course)
|
||||
if !logged?
|
||||
|
|
@ -582,6 +609,7 @@ class User < Owner
|
|||
# Returns the user who matches the given autologin +key+ or nil
|
||||
def self.try_to_autologin(key)
|
||||
user = Token.find_active_user('autologin', key)
|
||||
# user.daily_reward if user
|
||||
user.update(last_login_on: Time.now) if user
|
||||
user
|
||||
end
|
||||
|
|
@ -728,6 +756,50 @@ class User < Owner
|
|||
laboratory_id.present? && laboratory_id != 1
|
||||
end
|
||||
|
||||
def get_wallet
|
||||
if wallet.nil?
|
||||
create_wallet(balance: 100)
|
||||
reason = "系统初始赠送"
|
||||
CoinChange.create(amount: amount, reason: reason, to_wallet_id: wallet.id)
|
||||
end
|
||||
wallet
|
||||
end
|
||||
|
||||
def daily_reward
|
||||
t1 = Time.now
|
||||
t2 = Time.new(t1.year, t1.month, t1.day)
|
||||
|
||||
if(award_time.nil? or t2 > award_time)
|
||||
self.update_column(:award_time, Time.now)
|
||||
amount = 2
|
||||
user_wallet = get_wallet
|
||||
user_wallet.update(balance: user_wallet.balance += amount)
|
||||
reason = "每日登录奖励"
|
||||
CoinChange.create(amount: amount, reason: reason, to_wallet_id: user_wallet.id)
|
||||
end
|
||||
=begin
|
||||
award = false
|
||||
if(last_login_on.nil? or t2 > last_login_on)
|
||||
User.transaction(isolation: :serializable) do
|
||||
# User.transaction do
|
||||
if(self.last_login_on.nil? or t2 > self.last_login_on)
|
||||
self.update_column(:last_login_on, Time.now)
|
||||
award = true
|
||||
end
|
||||
end
|
||||
if(award)
|
||||
amount = 2
|
||||
user_wallet = get_wallet
|
||||
user_wallet.update(balance: user_wallet.balance += amount)
|
||||
reason = "每日登录奖励"
|
||||
CoinChange.create(amount: amount, reason: reason, to_wallet_id: user_wallet.id)
|
||||
end
|
||||
else
|
||||
# puts("#################################NOOO DAILY REWARD, #{last_login_on}, #{t2}")
|
||||
end
|
||||
=end
|
||||
end
|
||||
|
||||
protected
|
||||
def validate_password_length
|
||||
# 管理员的初始密码是5位
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
require 'letter_avatar/has_avatar'
|
||||
require 'chinese_pinyin'
|
||||
|
||||
class User
|
||||
module Avatar
|
||||
extend ActiveSupport::Concern
|
||||
include LetterAvatar::HasAvatar
|
||||
|
||||
def username
|
||||
self.lastname.blank? ? self.login : Pinyin.t(self.lastname)
|
||||
end
|
||||
|
||||
def get_letter_avatar_url(size = :lg)
|
||||
avatar_path(self.username, size).split('public/')&.last
|
||||
end
|
||||
|
||||
def self.get_letter_avatar_url(name)
|
||||
return "" if name.blank?
|
||||
avatar = LetterAvatar.generate Pinyin.t(name), 120
|
||||
avatar.split('public/')&.last
|
||||
end
|
||||
|
||||
def avatar_path(username, size)
|
||||
LetterAvatar.generate username, avatar_size(size)
|
||||
end
|
||||
|
||||
# 返回头像尺寸
|
||||
# xs: 22px
|
||||
# sm: 32px
|
||||
# md: 48px
|
||||
# lg: 120px
|
||||
def avatar_size(size)
|
||||
case size
|
||||
when :xs then 22
|
||||
when :sm then 32
|
||||
when :md then 48
|
||||
when :lg then 120
|
||||
else size
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
@ -12,9 +12,7 @@
|
|||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_user_actions_on_ip (ip)
|
||||
# index_user_actions_on_user_id (user_id)
|
||||
# index_user_actions_on_user_id_and_action_type (user_id,action_type)
|
||||
# index_user_actions_on_ip (ip)
|
||||
#
|
||||
|
||||
class UserAction < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -10,13 +10,10 @@
|
|||
# updated_at :datetime not null
|
||||
# register_status :integer default("0")
|
||||
# action_status :integer default("0")
|
||||
# is_delete :boolean default("0")
|
||||
# user_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_user_agents_on_ip (ip)
|
||||
# index_user_agents_on_user_id (user_id)
|
||||
# index_user_agents_on_ip (ip) UNIQUE
|
||||
#
|
||||
|
||||
class UserAgent < ApplicationRecord
|
||||
|
|
|
|||
|
|
@ -22,9 +22,6 @@
|
|||
# school_id :integer
|
||||
# description :string(255) default("")
|
||||
# department_id :integer
|
||||
# honor :text(65535)
|
||||
# edu_background :integer
|
||||
# edu_entry_year :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: waitlists
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# applicant_id :string(255)
|
||||
# integer :string(255)
|
||||
# reviewer_id :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class Waitlist < ApplicationRecord
|
||||
belongs_to :applicant, class_name: 'User'
|
||||
belongs_to :reviewer, class_name: 'User', optional: true
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: wallets
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# balance :integer
|
||||
# user_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
|
||||
class Wallet < ApplicationRecord
|
||||
belongs_to :user
|
||||
has_many :outcome, class_name: 'CoinChange', foreign_key: 'from_wallet_id', dependent: :destroy
|
||||
has_many :income, class_name: 'CoinChange', foreign_key: 'to_wallet_id', dependent: :destroy
|
||||
validates :balance, presence: true
|
||||
end
|
||||
|
|
@ -27,7 +27,7 @@ class Organizations::Teams::UpdateService < ApplicationService
|
|||
if team.authorize == "owner"
|
||||
update_params = params.slice(:description)
|
||||
else
|
||||
update_params = params.slice(:name, :nickname, :description, :authorize, :includes_all_project, :can_create_org_project)
|
||||
update_params = params.slice(:name, :description, :authorize, :includes_all_project, :can_create_org_project)
|
||||
end
|
||||
update_params
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
json.array! @file_list
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
json.id organization.id
|
||||
json.name organization.login
|
||||
json.nickname organization.nickname.blank? ? organization.name : organization.nickname
|
||||
json.nickname organization.nickname
|
||||
json.description organization.description
|
||||
json.website organization.website
|
||||
json.location organization.location
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
json.id team_project.id
|
||||
json.project do
|
||||
json.owner_login team_project&.project&.owner&.login
|
||||
json.owner_name team_project&.project&.owner&.real_name
|
||||
json.owner_name team_project&.project&.owner&.login
|
||||
json.owner_image_url url_to_avatar(team_project&.project&.owner)
|
||||
json.name team_project&.project&.name
|
||||
json.identifier team_project&.project&.identifier
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
json.id team.id
|
||||
json.name team.name
|
||||
json.nickname team.nickname.blank? ? team.name : team.nickname
|
||||
json.description team.description
|
||||
json.authorize team.authorize
|
||||
json.includes_all_project team.includes_all_project
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ json.author do
|
|||
json.name user.try(:show_real_name)
|
||||
json.type user&.type
|
||||
json.login user.login
|
||||
json.image_url url_to_avatar(user)
|
||||
json.image_url render_avatar_url(user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ json.projects @projects do |project|
|
|||
json.type user.type
|
||||
json.name user.try(:show_real_name)
|
||||
json.login user.login
|
||||
json.image_url url_to_avatar(user)
|
||||
json.image_url render_avatar_url(user)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,5 +5,4 @@ json.description @project.description
|
|||
json.project_category_id @project.project_category_id
|
||||
json.project_language_id @project.project_language_id
|
||||
json.is_public @project.is_public
|
||||
json.website @project.website
|
||||
json.lesson_url @project.lesson_url
|
||||
json.website @project.website
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
json.author do
|
||||
author = User.find_by(mail: commit['Author']['Email'])
|
||||
author = User.find_by(login: commit['Author']['Name'])
|
||||
json.partial! 'repositories/commit_author', locals: { user: author, name: commit['Committer']['Name'] }
|
||||
end
|
||||
|
||||
json.committer do
|
||||
author = User.find_by(mail: commit['Committer']['Email'])
|
||||
author = User.find_by(login: commit['Committer']['Name'])
|
||||
json.partial! 'repositories/commit_author', locals: { user: author, name: commit['Committer']['Name'] }
|
||||
end
|
||||
json.timestamp render_unix_time(commit['Committer']['When'])
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ else
|
|||
json.id nil
|
||||
json.login name
|
||||
json.name name
|
||||
json.image_url User::Avatar.get_letter_avatar_url(name)
|
||||
json.image_url File.join("avatars/User","b")
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,15 +5,12 @@ else
|
|||
json.total_count @hash_commit[:total_count]
|
||||
json.commits do
|
||||
json.array! @hash_commit[:body] do |commit|
|
||||
json.commit1 commit
|
||||
commiter = commit['committer']
|
||||
|
||||
forge_user =
|
||||
if commiter.present?
|
||||
User.simple_select.find_by(mail: commiter['email'])
|
||||
else
|
||||
User.simple_select.find_by(mail: commit['commit']['committer']['email'])
|
||||
end
|
||||
|
||||
if commiter.present?
|
||||
commit_user_id = commiter['id']
|
||||
forge_user = User.simple_select.find_by(gitea_uid: commit_user_id)
|
||||
end
|
||||
json.sha commit['sha']
|
||||
json.message commit['commit']['message']
|
||||
json.timestamp render_unix_time(commit['commit']['author']['date'])
|
||||
|
|
@ -26,7 +23,7 @@ else
|
|||
json.login commit['commit']['author']['name']
|
||||
json.type nil
|
||||
json.name commit['commit']['author']['name']
|
||||
json.image_url User::Avatar.get_letter_avatar_url(commit['commit']['author']['name'])
|
||||
json.image_url File.join("avatars/User","b")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
json.content @project.content
|
||||
json.website @project.website
|
||||
json.lesson_url @project.lesson_url
|
||||
if @result[:readme].blank?
|
||||
json.readme nil
|
||||
else
|
||||
|
|
|
|||
|
|
@ -6,5 +6,4 @@ json.project_category_id @project.project_category_id
|
|||
json.project_language_id @project.project_language_id
|
||||
json.private !@project.is_public
|
||||
json.website @project.website
|
||||
json.project_units @project.project_units.pluck(:unit_type)
|
||||
json.lesson_url @project.lesson_url
|
||||
json.project_units @project.project_units.pluck(:unit_type)
|
||||
|
|
@ -56,4 +56,5 @@ json.setting do
|
|||
end
|
||||
|
||||
json.common @common
|
||||
json.third_party @third_party
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
<%= simple_form_for(@sponsor_tier) do |f| %>
|
||||
<%= f.error_notification %>
|
||||
<%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>
|
||||
|
||||
<div class="form-inputs">
|
||||
<%= f.input :tier %>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<%= f.button :submit %>
|
||||
</div>
|
||||
<% end %>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue