forked from Gitlink/forgeplus
Compare commits
178 Commits
master
...
standalone
Author | SHA1 | Date |
---|---|---|
![]() |
4e72e1e1bf | |
|
6bb3f92973 | |
|
d98b5b9f72 | |
|
6f7b40ec24 | |
|
d993df7df4 | |
|
701d5dea40 | |
|
6e16a9397c | |
|
e9a152032c | |
|
917bae4321 | |
|
ccc8f13959 | |
|
4b618d1a61 | |
|
9da61bd69e | |
|
db845e7df0 | |
|
d0209490c6 | |
|
9cd150be88 | |
|
de6ff8d863 | |
|
620ed26e45 | |
|
8a67c19c67 | |
|
5580a96fe7 | |
|
fd17fcab17 | |
|
2827e28b07 | |
|
b19560b174 | |
|
b5383bfa5a | |
|
5b056c04da | |
|
bc862f8d98 | |
|
b1c10d66f9 | |
|
5216e61479 | |
|
ce70378fc3 | |
|
cbb0a639b2 | |
|
a654a08e0c | |
|
b8724c02f7 | |
|
e59e4e4bd5 | |
|
ec44376e4d | |
|
a80b4d954e | |
|
2842df87c6 | |
|
6f9d902e70 | |
|
4091872091 | |
|
5a7aaff112 | |
|
558d720203 | |
|
46da5a0d84 | |
|
f59ab5bcf1 | |
|
f8350c4043 | |
|
ed7f5a08bb | |
|
acaa28cd02 | |
|
ddb5010e6d | |
|
f05cf0c000 | |
|
ff025e07dd | |
|
4c26085e58 | |
|
a30a3c56b6 | |
|
2e0b32f86b | |
|
dab636d122 | |
|
b616c971db | |
|
35bb8fbc11 | |
|
267279df2d | |
|
e53d6cd763 | |
|
3fd04109d6 | |
|
8487c67bab | |
|
dc01d7fc3e | |
|
7cb2321c02 | |
|
c589fcc6a4 | |
|
1fcdbe9dce | |
|
dc9ca7d0ca | |
|
edc00d28a7 | |
|
317ff3c76b | |
|
c781ca0da1 | |
|
a07da79e89 | |
|
54a85a60fa | |
|
895cd8f737 | |
![]() |
54b7f2c726 | |
![]() |
e440ee8483 | |
|
ed5d12654e | |
|
8239f13eaa | |
|
6c1f9cabda | |
|
5f3d51027e | |
|
84029bf49a | |
![]() |
ee77be7c8a | |
![]() |
05f103b0c4 | |
![]() |
ac8372d7e1 | |
![]() |
b9e2a3736c | |
|
311776a004 | |
|
12eaec0319 | |
|
47a5fe24c8 | |
|
4a3d1e5a69 | |
|
3a5d8e75df | |
|
23a65798df | |
|
cab5466ae4 | |
|
b18051ec31 | |
|
02526878fe | |
|
4657618753 | |
|
cb3bb23e79 | |
|
656d5b69b6 | |
|
121fa2bff4 | |
|
c63a86a797 | |
|
15d71bfd24 | |
|
df38df45d5 | |
|
b85913e485 | |
|
3427fa6768 | |
|
e92b288f41 | |
|
0725ef74de | |
|
00bb1e82af | |
|
f93e665239 | |
|
d578c5c8df | |
|
c872f50685 | |
|
368be1849c | |
|
7d3d95c406 | |
|
5c3c47d13b | |
|
676d2ddce1 | |
|
3d0fa0d50c | |
|
3c51d69555 | |
|
1d9df770b5 | |
|
c0fcf3445a | |
|
6fe16c7c82 | |
|
5e7fe0f28c | |
|
1cd43de75b | |
|
2a8e0d2be8 | |
|
c38a4e4e08 | |
|
202be8246b | |
|
774210206e | |
|
2899f3b18e | |
|
404a6a00e7 | |
|
f0c1e9e319 | |
|
7d17b654f6 | |
|
db2d398d94 | |
|
c0271707a1 | |
|
0af87a67ec | |
|
7bce320113 | |
|
4a8e3324af | |
|
3a14aa10ce | |
|
b799780637 | |
|
53c2ffffb3 | |
|
934b42f1a1 | |
|
c1d791741c | |
|
1aeed8236d | |
|
f0750333f9 | |
|
4085da7837 | |
|
ade03c5e2f | |
|
fe972f1141 | |
|
af67d984b4 | |
|
241bbc06ca | |
|
587facfb3d | |
|
8210404f4a | |
|
128c5c48e6 | |
|
99be556d5b | |
|
353449c53c | |
|
c983df57ee | |
|
39ae14bce7 | |
|
8c8925f3ae | |
|
6cfb5dfbe2 | |
|
0eb17aa90f | |
|
7c911f5b86 | |
|
0800f9e6e0 | |
|
726453ea99 | |
|
bef1350933 | |
|
2772b97e32 | |
|
f2a456c6ed | |
|
4bc945028b | |
|
8b90164247 | |
|
f2cdba29ea | |
|
3f78899c58 | |
|
5fc433d130 | |
|
bfe14352c0 | |
|
a746e791b0 | |
|
87412643cd | |
|
e4b5427725 | |
|
9fe3b5ae3e | |
|
a03d1efcb0 | |
|
2668630f2a | |
|
785ae13649 | |
|
c4b93f2bd3 | |
|
913eb62923 | |
|
112ee39efd | |
|
08d8abd163 | |
|
0229d99e74 | |
|
40873fe95d | |
|
dfe56d9f75 | |
|
5f46d205a9 | |
|
fdb713b76d | |
|
7c80f74e26 |
|
@ -73,7 +73,7 @@ vendor/bundle/
|
|||
/public/admin
|
||||
/mysql_data
|
||||
/public/repo/
|
||||
/coverage
|
||||
|
||||
|
||||
.generators
|
||||
.rakeTasks
|
||||
|
@ -81,6 +81,7 @@ db/bak/
|
|||
docker/
|
||||
educoder.sql
|
||||
redis_data/
|
||||
Dockerfile
|
||||
dump.rdb
|
||||
.tags*
|
||||
ceshi_user.xlsx
|
||||
|
|
33
Dockerfile
33
Dockerfile
|
@ -1,33 +0,0 @@
|
|||
FROM ubuntu:18.04
|
||||
|
||||
RUN apt update
|
||||
|
||||
RUN apt install -y openssl libssl-dev imagemagick git ruby-dev nodejs libmariadb-dev libmysqlclient-dev shared-mime-info libpq-dev libxml2-dev libxslt-dev
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt -y install tzdata
|
||||
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
|
||||
WORKDIR /home/app/gitlink
|
||||
|
||||
ADD ./ /home/app/gitlink
|
||||
|
||||
RUN gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
|
||||
|
||||
RUN gem update --system
|
||||
|
||||
RUN gem install bundler
|
||||
RUN gem install rake
|
||||
|
||||
RUN rm -rf Gemfile.lock
|
||||
|
||||
#RUN cp config/configuration.yml.example config/configuration.yml
|
||||
#RUN cp config/database.yml.example config/database.yml
|
||||
#RUN touch config/redis.yml
|
||||
#RUN touch config/elasticsearch.yml
|
||||
|
||||
RUN bundle install
|
||||
|
||||
EXPOSE 4000
|
||||
RUN rails s -p 4000 -b '0.0.0.0'
|
||||
|
||||
|
||||
|
15
Gemfile
15
Gemfile
|
@ -1,4 +1,4 @@
|
|||
# source 'https://gems.ruby-china.com'
|
||||
#source 'https://gems.ruby-china.com'
|
||||
source 'https://mirrors.cloud.tencent.com/rubygems/'
|
||||
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
||||
|
||||
|
@ -60,7 +60,6 @@ gem 'ransack'
|
|||
|
||||
group :development, :test do
|
||||
gem 'rspec-rails', '~> 3.8'
|
||||
gem 'rails-controller-testing'
|
||||
end
|
||||
|
||||
group :development do
|
||||
|
@ -79,7 +78,6 @@ group :test do
|
|||
gem 'capybara', '>= 2.15', '< 4.0'
|
||||
gem 'selenium-webdriver'
|
||||
gem 'chromedriver-helper'
|
||||
gem 'simplecov', '~>0.12.0', require: false
|
||||
end
|
||||
|
||||
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
||||
|
@ -101,11 +99,9 @@ gem 'font-awesome-sass', '4.7.0'
|
|||
gem 'rails-i18n', '~> 5.1'
|
||||
|
||||
# job
|
||||
gem 'sidekiq',"5.2.8"
|
||||
gem 'sidekiq'
|
||||
gem 'sinatra'
|
||||
gem "sidekiq-cron", "1.2.0"
|
||||
gem 'whenever'
|
||||
gem 'sidekiq_schedulable'
|
||||
gem "sidekiq-cron", "~> 1.1"
|
||||
|
||||
# batch insert
|
||||
gem 'bulk_insert'
|
||||
|
@ -136,9 +132,6 @@ gem 'harmonious_dictionary', '~> 0.0.1'
|
|||
|
||||
gem 'parallel', '~> 1.19', '>= 1.19.1'
|
||||
|
||||
# log
|
||||
gem 'multi_logger'
|
||||
|
||||
gem 'letter_avatar'
|
||||
|
||||
gem 'jwt'
|
||||
|
@ -147,4 +140,4 @@ gem 'doorkeeper'
|
|||
|
||||
gem 'doorkeeper-jwt'
|
||||
|
||||
gem 'gitea-client', '~> 0.11.1'
|
||||
gem 'gitea-client', '~> 0.11.6'
|
26
Gemfile.lock
26
Gemfile.lock
|
@ -106,8 +106,6 @@ GEM
|
|||
activerecord (>= 3.1.0, < 7)
|
||||
diff-lcs (1.3)
|
||||
diffy (3.3.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
doorkeeper (5.5.1)
|
||||
railties (>= 5)
|
||||
doorkeeper-jwt (0.4.1)
|
||||
|
@ -135,8 +133,6 @@ GEM
|
|||
fugit (1.4.1)
|
||||
et-orbi (~> 1.1, >= 1.1.8)
|
||||
raabro (~> 1.4)
|
||||
gitea-client (0.10.5)
|
||||
rest-client (~> 2.1.0)
|
||||
globalid (0.4.2)
|
||||
activesupport (>= 4.2.0)
|
||||
grape-entity (0.7.1)
|
||||
|
@ -147,9 +143,6 @@ GEM
|
|||
harmonious_dictionary (0.0.1)
|
||||
hashie (3.6.0)
|
||||
htmlentities (4.3.4)
|
||||
http-accept (1.7.0)
|
||||
http-cookie (1.0.5)
|
||||
domain_name (~> 0.5)
|
||||
i18n (1.8.2)
|
||||
concurrent-ruby (~> 1.0)
|
||||
io-like (0.3.1)
|
||||
|
@ -187,9 +180,6 @@ GEM
|
|||
mimemagic (~> 0.3.2)
|
||||
maruku (0.7.3)
|
||||
method_source (0.9.2)
|
||||
mime-types (3.4.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2022.0105)
|
||||
mimemagic (0.3.10)
|
||||
nokogiri (~> 1)
|
||||
rake
|
||||
|
@ -203,7 +193,6 @@ GEM
|
|||
mustermann (1.1.1)
|
||||
ruby2_keywords (~> 0.0.1)
|
||||
mysql2 (0.5.3)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.2)
|
||||
nokogiri (1.10.8)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
|
@ -303,11 +292,6 @@ GEM
|
|||
regexp_parser (1.7.0)
|
||||
request_store (1.5.0)
|
||||
rack (>= 1.4)
|
||||
rest-client (2.1.0)
|
||||
http-accept (>= 1.7.0, < 2.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
reverse_markdown (1.4.0)
|
||||
nokogiri
|
||||
roo (2.8.3)
|
||||
|
@ -434,9 +418,6 @@ GEM
|
|||
thread_safe (~> 0.1)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.8.2)
|
||||
unicode-display_width (1.6.1)
|
||||
web-console (3.7.0)
|
||||
actionview (>= 5.0)
|
||||
|
@ -478,7 +459,6 @@ DEPENDENCIES
|
|||
enumerize
|
||||
faraday (~> 0.15.4)
|
||||
font-awesome-sass (= 4.7.0)
|
||||
gitea-client (~> 0.10.2)
|
||||
grape-entity (~> 0.7.1)
|
||||
groupdate (~> 4.1.0)
|
||||
harmonious_dictionary (~> 0.0.1)
|
||||
|
@ -516,8 +496,8 @@ DEPENDENCIES
|
|||
sass-rails (~> 5.0)
|
||||
searchkick
|
||||
selenium-webdriver
|
||||
sidekiq (= 5.2.8)
|
||||
sidekiq-cron (= 1.2.0)
|
||||
sidekiq
|
||||
sidekiq-cron (~> 1.1)
|
||||
simple_form
|
||||
simple_xlsx_reader
|
||||
sinatra
|
||||
|
@ -532,4 +512,4 @@ DEPENDENCIES
|
|||
wkhtmltopdf-binary
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.3
|
||||
2.1.4
|
||||
|
|
2
LICENSE
2
LICENSE
|
@ -121,4 +121,4 @@ You may obtain a copy of Mulan PSL v2 at:
|
|||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
See the Mulan PSL v2 for more details.
|
||||
See the Mulan PSL v2 for more details.
|
204
README.md
204
README.md
|
@ -1,27 +1,17 @@
|
|||
# GitLink - CCF开源创新服务平台
|
||||
Trustie (确实)是一个以大众化协同开发、开放式资源共享、持续性可信评估为核心机理,面向高校创新实践的在线协作平台。
|
||||
|
||||
GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源创新服务平台,旨在以“为开源创新服务”为使命,以“成为开源创新的汇聚地”为愿景,秉承“创新、开放、协作、共享”的价值观,致力于为大规模开源开放协同创新助力赋能,打造创新成果孵化和新工科人才培养的开源创新生态!
|
||||
## 特性
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/gitlink.png?raw=true" width=80% /></center>
|
||||
|
||||
## 特色功能
|
||||
- 软件创作与生产深度融合的软件开发环境体系结构 软件自由创作和工程生产的高效衔接,适于软件开发中群体智慧的有效汇聚。
|
||||
|
||||
- **分布式协作开发**:基于Git打造分布式代码托管环境,提供免费公、私有代码仓库,支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻(Fork)、贡献合并请求(PR)、群智贡献审阅等功能,让您的项目在这里健康、快速的成长!
|
||||
- 构件化协同开发环境的可扩展运行框架多样化工具的集成和联动,形成了强动态扩展能力的平台框架。
|
||||
|
||||
- **一站式过程管理**:提供疑修(Issue)、里程碑、通知提醒、标签归档等多样化任务管理工具,支持各类开发任务的发布、指派与跟踪,同时提供在线Wiki文档、组织多粒度管理等功能,为您搭建一站式的项目过程管理环境,让您的团队协作更高效、过程更透明!
|
||||
- “互联网即资源库”的全新软件复用模式 成长式软件资源管理系统,实现了分散资源的知识融合、资源的可持续增长和有效复用。
|
||||
|
||||
- **高效流水线运维**:融合DevOps思想,提供轻量级的工作流引擎(Engine),打通编码、测试、构建、部署等开发运维环节;支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能,同时支持接入第三方运维工具,让您的代码更加快速、可靠地形成高质量的产品!
|
||||
|
||||
- **多层次代码分析**:提供软件软代码和芯片RTL代码的溯源分析、文件级和组件级许可证识别及风险分析、输入性开源漏洞检测和加固建议,支持分析结果的多层次可视化展示,帮助您实施有效开源治理,厘清代码引用链,发现并消除漏洞感染链,为安全合规的开源引用保驾护航!
|
||||
|
||||
- **多维度用户画像**:实时采集和分析平台中的各类开源资源数据,搭建多维度用户画像评估系统,提供开发活动统计、贡献度日历、用户能力建模、角色与专业定位分析等功能,让您在个人主页展示开发动态与创新能力!
|
||||
## 部署
|
||||
|
||||
|
||||
## 部署流程
|
||||
|
||||
|
||||
### 依赖库
|
||||
### Depends Versions
|
||||
|
||||
* Ruby 2.4.5
|
||||
|
||||
|
@ -33,53 +23,22 @@ GitLink(确实开源)是中国计算机学会(CCF)官方指定的开源
|
|||
|
||||
* imagemagick
|
||||
|
||||
### 步骤
|
||||
(1)安装 Rails 必要的一些三方库:
|
||||
- Mac OS X
|
||||
```bash
|
||||
brew install imagemagick ghostscript libxml2 libxslt libiconv
|
||||
### Steps
|
||||
|
||||
#### 1. 克隆稳定版本
|
||||
```
|
||||
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
|
||||
```
|
||||
|
||||
- Ubuntu
|
||||
#### 2. 安装依赖包
|
||||
|
||||
```bash
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y openssl libssl-dev imagemagick git ruby-dev nodejs libmariadb-dev libmysqlclient-dev shared-mime-info libpq-dev libxml2-dev libxslt-dev
|
||||
sudo DEBIAN_FRONTEND="noninteractive" apt-get install -y tzdata
|
||||
sudo ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
cd forgeplus && bundle install
|
||||
```
|
||||
|
||||
(2)安装 Ruby, Rails 运行环境:[如何快速正确的安装 Ruby, Rails 运行环境](https://ruby-china.org/wiki/install_ruby_guide)
|
||||
```bash
|
||||
#检验环境是否正确
|
||||
ruby -v
|
||||
#ruby 2.4.x ...
|
||||
#### 3. 配置初始化文件
|
||||
进入项目根目录执行一下命令:
|
||||
|
||||
gem -v
|
||||
#3.x.x
|
||||
|
||||
bundle -v
|
||||
#Bundler version 2.x.x
|
||||
|
||||
rails -v
|
||||
#Rails 5.2.x
|
||||
```
|
||||
|
||||
(3)克隆稳定版本
|
||||
```bash
|
||||
git clone -b master https://gitlink.org.cn/Gitlink/forgeplus.git
|
||||
```
|
||||
|
||||
(4)安装依赖包
|
||||
```bash
|
||||
#进入目录
|
||||
cd forgeplus
|
||||
#删除Gemfile.lock
|
||||
rm -rf Gemfile.lock
|
||||
#安装依赖包
|
||||
bundle install
|
||||
```
|
||||
|
||||
(5)配置初始化文件:进入项目根目录执行以下命令
|
||||
```bash
|
||||
cp config/configuration.yml.example config/configuration.yml
|
||||
cp config/database.yml.example config/database.yml
|
||||
|
@ -87,8 +46,12 @@ touch config/redis.yml
|
|||
touch config/elasticsearch.yml
|
||||
```
|
||||
|
||||
(6)配置数据库:数据库配置信息请查看/config/database.yml文件,项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
|
||||
```yaml
|
||||
#### 4. 配置数据库
|
||||
数据库配置信息请查看/config/database.yml文件,
|
||||
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
|
||||
默认配置如下:
|
||||
|
||||
```bash
|
||||
default: &default
|
||||
adapter: mysql2
|
||||
host: 127.0.0.1
|
||||
|
@ -97,15 +60,16 @@ default: &default
|
|||
password: 123456
|
||||
```
|
||||
|
||||
(7)配置gitea服务(可选):如需要部署自己的gitea平台,请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限,暂时推荐从forge平台获取[gitea部署文件](https://www.gitlink.org.cn/Gitlink/gitea-binary)进行部署
|
||||
#### 5. 配置gitea服务(可选)
|
||||
**如需要部署自己的gitea平台,请参考gitea官方平台:https://docs.gitea.io/zh-cn/install-from-binary/**
|
||||
|
||||
- 配置gitea服务步骤:
|
||||
|
||||
-- 部署gitea服务,并注册root账户
|
||||
|
||||
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||
**因目前gitea平台api受限,暂时推荐从forge平台获取gitea部署文件进行部署:https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
|
||||
|
||||
```yaml
|
||||
**配置gitea服务步骤**
|
||||
1. 部署gitea服务,并注册root账户
|
||||
2. 修改forge平台的 config/configuration.yml中的gitea服务指向地址,如:
|
||||
|
||||
```ruby
|
||||
gitea:
|
||||
access_key_id: 'root'
|
||||
access_key_secret: 'password'
|
||||
|
@ -113,100 +77,102 @@ gitea:
|
|||
base_url: '/api/v1'
|
||||
```
|
||||
|
||||
(8)配置/config/database.yml文件(安装redis环境:请自行搜索各平台如何安装部署redis环境)
|
||||
```yaml
|
||||
default: &default
|
||||
url: redis://localhost:6379
|
||||
db: 1
|
||||
#### 6. 安装redis环境
|
||||
**请自行搜索各平台如何安装部署redis环境**
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
url: redis://localhost:6379
|
||||
#### 7. 安装imagemagick插件
|
||||
- Mac OS X
|
||||
```bash
|
||||
brew install imagemagick ghostscript
|
||||
```
|
||||
|
||||
(9)创建数据库:开发环境为development, 生成环境为production
|
||||
- Linux
|
||||
```bash
|
||||
sudo apt-get install -y imagemagick
|
||||
```
|
||||
|
||||
#### 8. 创建数据库
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:create RAILS_ENV=development
|
||||
```
|
||||
|
||||
(10)导入数据表结构
|
||||
#### 9. 导入数据表结构
|
||||
|
||||
```bash
|
||||
bundle exec rake sync_table_structure:import_csv
|
||||
```
|
||||
|
||||
(11)执行migrate迁移文件:开发环境为development, 生成环境为production
|
||||
#### 10. 执行migrate迁移文件
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
rails db:migrate RAILS_ENV=development
|
||||
```
|
||||
|
||||
(12)clone前端代码:将前端代码克隆到public/react目录下,目录结构应该是: public/react/build
|
||||
#### 11. clone前端代码
|
||||
**将前端代码克隆到public/react目录下,目录结构应该是: public/react/build**
|
||||
```bash
|
||||
git clone -b master https://gitlink.org.cn/Gitlink/build.git
|
||||
git clone -b standalone https://git.trustie.net/jasder/build.git
|
||||
```
|
||||
|
||||
(13)启动redis(此处以macOS系统为例)
|
||||
#### 12. 启动redis(此处已mac系统为例)
|
||||
```bash
|
||||
redis-server&
|
||||
```
|
||||
|
||||
(14)启动sidekiq:开发环境为development, 生成环境为production
|
||||
#### 13. 启动sidekiq
|
||||
**开发环境为development, 生成环境为production**
|
||||
```bash
|
||||
bundle exec sidekiq -C config/sidekiq.yml -e production -d
|
||||
```
|
||||
|
||||
(15)启动rails服务
|
||||
#### 14. 启动rails服务
|
||||
```bash
|
||||
rails s
|
||||
```
|
||||
|
||||
(16)浏览器访问:在浏览器中输入如下地址访问
|
||||
#### 15. 浏览器访问
|
||||
在浏览器中输入如下地址访问:
|
||||
```bash
|
||||
http://localhost:3000/
|
||||
```
|
||||
|
||||
(17)其他说明:通过页面注册以第一个用户为平台管理员用户
|
||||
|
||||
#### 16. 其他说明
|
||||
通过页面注册都第一个用户为平台管理员用户
|
||||
|
||||
## 页面展示
|
||||
|
||||
- 项目列表
|
||||
- 代码库
|
||||
|
||||

|
||||
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/project_list.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 代码仓库
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/repo.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 任务管理
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/issues.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 合并请求
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/PR.png?raw=true" width=50% />
|
||||
</center>
|
||||
|
||||
- 引擎配置
|
||||
|
||||
<center>
|
||||
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/master/docs/figs/engine.png?raw=true" width=50% />
|
||||
</center>
|
||||

|
||||
|
||||
- 任务查看
|
||||
|
||||

|
||||
|
||||
- 任务指派
|
||||
|
||||

|
||||
|
||||
- 里程碑
|
||||
|
||||

|
||||
|
||||
### API
|
||||
- [API文档](https://forgeplus.trustie.net/docs/api)
|
||||
- [API](showdoc.com.cn)
|
||||
账号:forgeplus@admin.com 密码:forge123
|
||||
|
||||
## 贡献代码
|
||||
|
||||
我们期待您向GitLink提交贡献!在您贡献时,请遵循流程:[【Wiki文档-GitLink协作开发流程】](https://www.gitlink.org.cn/Gitlink/forgeplus/wiki "【Wiki文档-GitLink协作开发流程】")
|
||||
1. Fork 项目
|
||||
2. 创建本地分支(git checkout -b my-new-feature)
|
||||
3. 提交更改 (git commit -am 'Add some feature')
|
||||
4. 推送到分支 (git push origin my-new-feature)
|
||||
5. 向源项目的 **develop** 分支发起 Pull Request
|
||||
|
||||
#### 指导文档
|
||||
- [API文档](https://www.gitlink.org.cn/docs/api)
|
||||
- [Git常用命令](https://git-scm.com/)
|
||||
|
||||
## 许可证协议
|
||||
## License
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
|
@ -1,2 +0,0 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
|
@ -1,2 +0,0 @@
|
|||
// Place all the behaviors and hooks related to the matching controller here.
|
||||
// All this logic will automatically be available in application.js.
|
|
@ -1,3 +1,3 @@
|
|||
// Place all the styles related to the log controller here.
|
||||
// Place all the styles related to the admins/organizations controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -1,84 +0,0 @@
|
|||
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;
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
// 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/
|
|
@ -1,3 +0,0 @@
|
|||
// 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/
|
|
@ -1,3 +0,0 @@
|
|||
// 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/
|
|
@ -4,13 +4,13 @@ class AccountsController < ApplicationController
|
|||
|
||||
#skip_before_action :check_account, :only => [:logout]
|
||||
|
||||
def simple_update
|
||||
def simple_update
|
||||
simple_update_params.merge!(username: params[:username]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(email: params[:email]&.gsub(/\s+/, ""))
|
||||
simple_update_params.merge!(platform: (params[:platform] || 'forge')&.gsub(/\s+/, ""))
|
||||
Register::RemoteForm.new(simple_update_params).validate!
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
ActiveRecord::Base.transaction do
|
||||
result = auto_update(current_user, simple_update_params)
|
||||
if result[:message].blank?
|
||||
render_ok
|
||||
|
@ -270,7 +270,6 @@ 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}")
|
||||
|
@ -343,11 +342,11 @@ class AccountsController < ApplicationController
|
|||
render_ok
|
||||
end
|
||||
|
||||
def login_check
|
||||
def login_check
|
||||
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
|
||||
render_ok
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
# type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
|
||||
|
@ -390,7 +389,7 @@ class AccountsController < ApplicationController
|
|||
params.require(:user).permit(:login, :email, :phone)
|
||||
end
|
||||
|
||||
def login_params
|
||||
def login_params
|
||||
params.require(:account).permit(:login, :password)
|
||||
end
|
||||
|
||||
|
@ -405,7 +404,7 @@ class AccountsController < ApplicationController
|
|||
def reset_password_params
|
||||
params.permit(:login, :password, :password_confirmation, :code)
|
||||
end
|
||||
|
||||
|
||||
def find_user
|
||||
phone_or_mail = strip(reset_password_params[:login])
|
||||
User.where("phone = :search OR mail = :search", search: phone_or_mail).last
|
||||
|
@ -414,7 +413,7 @@ class AccountsController < ApplicationController
|
|||
def remote_register_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
||||
|
||||
def simple_update_params
|
||||
params.permit(:username, :email, :password, :platform)
|
||||
end
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
class Admins::OrganizationsController < Admins::BaseController
|
||||
before_action :finder_org, except: [:index]
|
||||
|
||||
def index
|
||||
params[:sort_by] = params[:sort_by].presence || 'created_on'
|
||||
params[:sort_direction] = params[:sort_direction].presence || 'desc'
|
||||
|
||||
orgs = Admins::OrganizationQuery.call(params)
|
||||
@orgs = paginate orgs
|
||||
end
|
||||
|
||||
def show
|
||||
end
|
||||
|
||||
def destroy
|
||||
@org.destroy!
|
||||
Admins::DeleteOrganizationService.call(@org.login)
|
||||
render_delete_success
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def finder_org
|
||||
@org = Organization.find(params[:id])
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,16 @@
|
|||
class Admins::ProjectsRankController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@rank_date = rank_date
|
||||
deleted_data = $redis_cache.smembers("v2-project-rank-deleted")
|
||||
$redis_cache.zrem("v2-project-rank-#{rank_date}", deleted_data) unless deleted_data.blank?
|
||||
@date_rank = $redis_cache.zrevrange("v2-project-rank-#{rank_date}", 0, -1, withscores: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rank_date
|
||||
params.fetch(:date, Date.today.to_s)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class Admins::UsersRankController < Admins::BaseController
|
||||
|
||||
def index
|
||||
@rank_date = rank_date
|
||||
@date_rank = $redis_cache.zrevrange("v2-user-rank-#{rank_date}", 0, -1, withscores: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def rank_date
|
||||
params.fetch(:date, Date.today.to_s)
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -20,10 +20,19 @@ class Api::V1::BaseController < ApplicationController
|
|||
# User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
|
||||
# end
|
||||
# end
|
||||
|
||||
def kaminary_select_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 200) ? 200 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
end
|
||||
|
||||
def limit
|
||||
params.fetch(:limit, 15)
|
||||
end
|
||||
|
||||
def page
|
||||
params.fetch(:page, 1)
|
||||
end
|
||||
|
@ -43,7 +52,6 @@ class Api::V1::BaseController < ApplicationController
|
|||
# 具有仓库的操作权限或者fork仓库的操作权限
|
||||
def require_operate_above_or_fork_project
|
||||
@project = load_project
|
||||
puts !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||
return render_forbidden if !current_user.admin? && !@project.operator?(current_user) && !(@project.fork_project.present? && @project.fork_project.operator?(current_user))
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
class Api::V1::Issues::AssignersController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 负责人列表
|
||||
def index
|
||||
@assigners = User.joins(assigned_issues: :project).where(projects: {id: @project&.id})
|
||||
@assigners = @assigners.order("users.id=#{current_user.id} desc").distinct
|
||||
@assigners = @assigners.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@assigners = kaminary_select_paginate(@assigners)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Api::V1::Issues::AuthorsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 发布人列表
|
||||
def index
|
||||
@authors = User.joins(issues: :project).where(projects: {id: @project&.id})
|
||||
@authors = @authors.order("users.id=#{current_user.id} desc").distinct
|
||||
@authors = @authors.ransack(login_or_nickname_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@authors = kaminary_select_paginate(@authors)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::Issues::IssuePrioritiesController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@priorities = IssuePriority.order(position: :asc)
|
||||
@priorities = @priorities.ransack(name_cont: params[:keyword]).result if params[:keyword]
|
||||
@priorities = kaminary_select_paginate(@priorities)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,65 @@
|
|||
class Api::V1::Issues::IssueTagsController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index]
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||
|
||||
def index
|
||||
@issue_tags = @project.issue_tags.reorder("#{sort_by} #{sort_direction}")
|
||||
@issue_tags = @issue_tags.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
||||
if params[:only_name]
|
||||
@issue_tags = kaminary_select_paginate(@issue_tags.select(:id, :name, :color))
|
||||
else
|
||||
@issue_tags = kaminari_paginate(@issue_tags.includes(:project, :user, :issue_issues, :pull_request_issues))
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@issue_tag = @project.issue_tags.new(issue_tag_params)
|
||||
if @issue_tag.save!
|
||||
render_ok
|
||||
else
|
||||
render_error("创建标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
before_action :load_issue_tag, only: [:update, :destroy]
|
||||
|
||||
def update
|
||||
@issue_tag.attributes = issue_tag_params
|
||||
if @issue_tag.save!
|
||||
render_ok
|
||||
else
|
||||
render_error("更新标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @issue_tag.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除标记失败!")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
def sort_by
|
||||
sort_by = params.fetch(:sort_by, "created_at")
|
||||
sort_by = IssueTag.column_names.include?(sort_by) ? sort_by : "created_at"
|
||||
sort_by
|
||||
end
|
||||
|
||||
def sort_direction
|
||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
||||
sort_direction
|
||||
end
|
||||
|
||||
def issue_tag_params
|
||||
params.permit(:name, :description, :color)
|
||||
end
|
||||
|
||||
def load_issue_tag
|
||||
@issue_tag = @project.issue_tags.find_by_id(params[:id])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
class Api::V1::Issues::JournalsController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :children_journals]
|
||||
before_action :require_public_and_member_above
|
||||
before_action :load_issue
|
||||
before_action :load_journal, only: [:children_journals, :update, :destroy]
|
||||
before_action :check_journal_operate_permission, only: [:update, :destroy]
|
||||
|
||||
def index
|
||||
@object_result = Api::V1::Issues::Journals::ListService.call(@issue, query_params, current_user)
|
||||
@total_journals_count = @object_result[:total_journals_count]
|
||||
@total_operate_journals_count = @object_result[:total_operate_journals_count]
|
||||
@total_comment_journals_count = @object_result[:total_comment_journals_count]
|
||||
@journals = kaminary_select_paginate(@object_result[:data])
|
||||
end
|
||||
|
||||
def create
|
||||
@object_result = Api::V1::Issues::Journals::CreateService.call(@issue, journal_params, current_user)
|
||||
end
|
||||
|
||||
def children_journals
|
||||
@object_results = Api::V1::Issues::Journals::ChildrenListService.call(@issue, @journal, query_params, current_user)
|
||||
@journals = kaminari_paginate(@object_results)
|
||||
end
|
||||
|
||||
def update
|
||||
@object_result = Api::V1::Issues::Journals::UpdateService.call(@issue, @journal, journal_params, current_user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @journal.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除评论失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def query_params
|
||||
params.permit(:category, :keyword, :sort_by, :sort_direction)
|
||||
end
|
||||
|
||||
def journal_params
|
||||
params.permit(:notes, :parent_id, :reply_id, :attachment_ids => [], :receivers_login => [])
|
||||
end
|
||||
|
||||
def load_issue
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
||||
if @issue.blank?
|
||||
render_not_found("疑修不存在!")
|
||||
end
|
||||
end
|
||||
|
||||
def load_journal
|
||||
@journal = Journal.find_by_id(params[:id])
|
||||
return render_not_found("评论不存在!") unless @journal.present?
|
||||
end
|
||||
|
||||
def check_journal_operate_permission
|
||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user || @journal.user == current_user || @journal.parent_journal&.user == current_user
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
class Api::V1::Issues::MilestonesController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :require_public_and_member_above, only: [:index, :show]
|
||||
before_action :require_operate_above, only: [:create, :update, :destroy]
|
||||
before_action :load_milestone, only: [:show, :update, :destroy]
|
||||
|
||||
# 里程碑列表
|
||||
def index
|
||||
@milestones = @project.versions
|
||||
@milestones = @milestones.ransack(id_eq: params[:keyword]).result.or(@milestones.ransack(name_or_description_cont: params[:keyword]).result) if params[:keyword].present?
|
||||
@closed_milestone_count = @milestones.closed.size
|
||||
@opening_milestone_count = @milestones.opening.size
|
||||
@milestones = params[:category] == "closed" ? @milestones.closed : @milestones.opening
|
||||
@milestones = @milestones.reorder("versions.#{sort_by} #{sort_direction}")
|
||||
if params[:only_name]
|
||||
@milestones = @milestones.select(:id, :name)
|
||||
@milestones = kaminary_select_paginate(@milestones)
|
||||
else
|
||||
@milestones = @milestones.includes(:issues, :closed_issues, :opened_issues)
|
||||
@milestones = kaminari_paginate(@milestones)
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@milestone = @project.versions.new(milestone_params)
|
||||
if @milestone.save!
|
||||
render_ok
|
||||
else
|
||||
render_error(@milestone.errors.full_messages.join(","))
|
||||
end
|
||||
end
|
||||
|
||||
# 里程碑详情
|
||||
def show
|
||||
@object_result = Api::V1::Issues::Milestones::DetailIssuesService.call(@project, @milestone, query_params, current_user)
|
||||
@total_issues_count = @object_result[:total_issues_count]
|
||||
@opened_issues_count = @object_result[:opened_issues_count]
|
||||
@closed_issues_count = @object_result[:closed_issues_count]
|
||||
|
||||
@issues = kaminari_paginate(@object_result[:data])
|
||||
end
|
||||
|
||||
def update
|
||||
@milestone.attributes = milestone_params
|
||||
if @milestone.save!
|
||||
render_ok
|
||||
else
|
||||
render_error(@milestone.errors.full_messages.join(","))
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
if @milestone.destroy!
|
||||
render_ok
|
||||
else
|
||||
render_error("删除里程碑失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def milestone_params
|
||||
params.permit(:name, :description, :effective_date)
|
||||
end
|
||||
|
||||
def query_params
|
||||
params.permit(:category, :author_id, :assigner_id, :sort_by, :sort_direction, :issue_tag_ids)
|
||||
end
|
||||
|
||||
def load_milestone
|
||||
@milestone = @project.versions.find_by_id(params[:id])
|
||||
return render_not_found('里程碑不存在!') unless @milestone.present?
|
||||
end
|
||||
|
||||
def sort_by
|
||||
sort_by = params.fetch(:sort_by, "created_on")
|
||||
sort_by = Version.column_names.include?(sort_by) ? sort_by : "created_on"
|
||||
|
||||
sort_by
|
||||
end
|
||||
|
||||
def sort_direction
|
||||
sort_direction = params.fetch(:sort_direction, "desc").downcase
|
||||
sort_direction = %w(desc asc).include?(sort_direction) ? sort_direction : "desc"
|
||||
sort_direction
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
class Api::V1::Issues::StatuesController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
# 状态列表
|
||||
def index
|
||||
@statues = IssueStatus.order("position asc")
|
||||
@statues = @statues.ransack(name_cont: params[:keyword]).result if params[:keyword].present?
|
||||
@statues = kaminary_select_paginate(@statues)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,115 @@
|
|||
class Api::V1::IssuesController < Api::V1::BaseController
|
||||
before_action :require_login, except: [:index, :show]
|
||||
before_action :require_public_and_member_above, only: [:index, :show, :create, :update, :destroy]
|
||||
before_action :require_operate_above, only: [:batch_update, :batch_destroy]
|
||||
|
||||
def index
|
||||
IssueTag.init_data(@project.id) unless $redis_cache.hget("project_init_issue_tags", @project.id)
|
||||
@object_result = Api::V1::Issues::ListService.call(@project, query_params, current_user)
|
||||
@total_issues_count = @object_result[:total_issues_count]
|
||||
@opened_issues_count = @object_result[:opened_issues_count]
|
||||
@closed_issues_count = @object_result[:closed_issues_count]
|
||||
if params[:only_name].present?
|
||||
@issues = kaminary_select_paginate(@object_result[:data].pluck(:id, :subject))
|
||||
else
|
||||
@issues = kaminari_paginate(@object_result[:data])
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@object_result = Api::V1::Issues::CreateService.call(@project, issue_params, current_user)
|
||||
end
|
||||
|
||||
before_action :load_issue, only: [:show, :update, :destroy]
|
||||
before_action :check_issue_operate_permission, only: [:update, :destroy]
|
||||
|
||||
def show
|
||||
@user_permission = current_user.present? && current_user.logged? && (@project.member?(current_user) || current_user.admin? || @issue.user == current_user)
|
||||
end
|
||||
|
||||
def update
|
||||
@object_result = Api::V1::Issues::UpdateService.call(@project, @issue, issue_params, current_user)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@object_result = Api::V1::Issues::DeleteService.call(@project, @issue, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("删除疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
before_action :load_issues, only: [:batch_update, :batch_destroy]
|
||||
|
||||
def batch_update
|
||||
@object_result = Api::V1::Issues::BatchUpdateService.call(@project, @issues, batch_issue_params, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("批量更新疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
def batch_destroy
|
||||
@object_result = Api::V1::Issues::BatchDeleteService.call(@project, @issues, current_user)
|
||||
if @object_result
|
||||
render_ok
|
||||
else
|
||||
render_error("批量删除疑修失败!")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_issue
|
||||
@issue = @project.issues.issue_issue.where(project_issues_index: params[:index]).where.not(id: params[:index]).take || Issue.find_by_id(params[:index])
|
||||
if @issue.blank?
|
||||
render_not_found("疑修不存在!")
|
||||
end
|
||||
end
|
||||
|
||||
def load_issues
|
||||
return render_error("请输入正确的ID数组!") unless params[:ids].is_a?(Array)
|
||||
params[:ids].each do |id|
|
||||
@issue = Issue.find_by_id(id)
|
||||
if @issue.blank?
|
||||
return render_not_found("ID为#{id}的疑修不存在!")
|
||||
end
|
||||
end
|
||||
@issues = Issue.where(id: params[:ids])
|
||||
end
|
||||
|
||||
def check_issue_operate_permission
|
||||
return render_forbidden("您没有操作权限!") unless @project.member?(current_user) || current_user.admin? || @issue.user == current_user
|
||||
end
|
||||
|
||||
def query_params
|
||||
params.permit(
|
||||
:category,
|
||||
:participant_category,
|
||||
:keyword, :author_id,
|
||||
:milestone_id, :assigner_id,
|
||||
:status_id,
|
||||
:sort_by, :sort_direction,
|
||||
:issue_tag_ids)
|
||||
end
|
||||
|
||||
def issue_params
|
||||
params.permit(
|
||||
:status_id, :priority_id, :milestone_id,
|
||||
:branch_name, :start_date, :due_date,
|
||||
:subject, :description,
|
||||
:issue_tag_ids => [],
|
||||
:assigner_ids => [],
|
||||
:attachment_ids => [],
|
||||
:receivers_login => [])
|
||||
end
|
||||
|
||||
def batch_issue_params
|
||||
params.permit(
|
||||
:status_id, :priority_id, :milestone_id,
|
||||
:issue_tag_ids => [],
|
||||
:assigner_ids => [])
|
||||
end
|
||||
end
|
|
@ -1,16 +1,40 @@
|
|||
class Api::V1::Projects::BranchesController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:all]
|
||||
before_action :require_public_and_member_above, only: [:index, :all]
|
||||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::Branches::ListService.call(@project, {name: params[:keyword], page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def all
|
||||
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:create]
|
||||
before_action :require_operate_above, only: [:create, :destroy]
|
||||
|
||||
def create
|
||||
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Branches::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除分支失败!')
|
||||
end
|
||||
end
|
||||
|
||||
before_action :require_manager_above, only: [:update_default_branch]
|
||||
|
||||
def update_default_branch
|
||||
@result_object = Api::V1::Projects::Branches::UpdateDefaultBranchService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('更新默认分支失败!')
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def branch_params
|
||||
params.require(:branch).permit(:new_branch_name, :old_branch_name)
|
||||
|
|
|
@ -3,6 +3,6 @@ class Api::V1::Projects::CodeStatsController < Api::V1::BaseController
|
|||
|
||||
def index
|
||||
@result_object = Api::V1::Projects::CodeStats::ListService.call(@project, {ref: params[:ref]}, current_user&.gitea_token)
|
||||
puts @result_object
|
||||
# puts @result_object
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
class Api::V1::Projects::CollaboratorsController < Api::V1::BaseController
|
||||
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@collaborators = @project.all_collaborators.like(params[:keyword])
|
||||
@collaborators = kaminary_select_paginate(@collaborators)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
class Api::V1::Projects::TagsController < Api::V1::BaseController
|
||||
before_action :require_public_and_member_above, only: [:index]
|
||||
|
||||
def index
|
||||
@release_tags = @repository.version_releases.pluck(:tag_name)
|
||||
@result_object = Api::V1::Projects::Tags::ListService.call(@project, {page: page, limit: limit}, current_user&.gitea_token)
|
||||
end
|
||||
|
||||
before_action :require_operate_above, only: [:destroy]
|
||||
|
||||
def destroy
|
||||
@result_object = Api::V1::Projects::Tags::DeleteService.call(@project, params[:name], current_user&.gitea_token)
|
||||
if @result_object
|
||||
return render_ok
|
||||
else
|
||||
return render_error('删除标签失败!')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,6 @@
|
|||
require 'oauth2'
|
||||
# require 'openssl'
|
||||
# require 'jwt'
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include CodeExample
|
||||
|
@ -10,14 +12,12 @@ 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
|
||||
|
@ -27,8 +27,6 @@ class ApplicationController < ActionController::Base
|
|||
# end
|
||||
end
|
||||
|
||||
before_action :update_last_login_on
|
||||
|
||||
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 = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8"
|
||||
|
||||
|
@ -86,7 +84,7 @@ class ApplicationController < ActionController::Base
|
|||
unless login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/ || login =~ /^1\d{10}$/
|
||||
tip_exception(-2, "请输入正确的手机号或邮箱")
|
||||
end
|
||||
|
||||
|
||||
user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login)
|
||||
if user_exist && type.to_i == 1
|
||||
tip_exception(-2, "该手机号码或邮箱已被注册")
|
||||
|
@ -299,14 +297,21 @@ class ApplicationController < ActionController::Base
|
|||
# Find the current user
|
||||
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}")
|
||||
if request.headers["Authorization"].present? && request.headers["Authorization"].start_with?('Bearer')
|
||||
tip_exception(401, "请登录后再操作!") unless valid_doorkeeper_token?
|
||||
if @doorkeeper_token.present?
|
||||
# client方法对接,需要一直带着用户标识uid
|
||||
if @doorkeeper_token.resource_owner_id.blank?
|
||||
tip_exception(-1, "缺少用户标识!") if params[:uid].nil?
|
||||
User.current = User.find(params[:uid])
|
||||
else
|
||||
User.current = User.find_by(id: @doorkeeper_token.resource_owner_id)
|
||||
if !valid_doorkeeper_token?
|
||||
header = request.authorization
|
||||
pattern = /^Bearer /i
|
||||
token = header.gsub(pattern, "")
|
||||
User.current, message = Bot.decode_jwt_token(token)
|
||||
tip_exception(401, message) if message.present?
|
||||
else
|
||||
if @doorkeeper_token.present?
|
||||
# client方法对接,需要一直带着用户标识uid
|
||||
if @doorkeeper_token.resource_owner_id.blank?
|
||||
tip_exception(-1, "缺少用户标识!") if params[:uid].nil?
|
||||
User.current = User.find(params[:uid])
|
||||
else
|
||||
User.current = User.find_by(id: @doorkeeper_token.resource_owner_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -367,20 +372,7 @@ class ApplicationController < ActionController::Base
|
|||
# RSS key authentication does not start a session
|
||||
User.find_by_rss_key(params[:key])
|
||||
end
|
||||
# User.current = User.find(2) # need to remove this statement before running in production
|
||||
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
|
||||
end
|
||||
|
||||
def try_to_autologin
|
||||
if cookies[autologin_cookie_name]
|
||||
|
@ -406,17 +398,12 @@ class ApplicationController < ActionController::Base
|
|||
respond_to do |format|
|
||||
format.json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
## 输出错误信息
|
||||
def error_status(message = nil)
|
||||
@status = -1
|
||||
@message = message
|
||||
end
|
||||
|
||||
# 实训等对应的仓库地址
|
||||
def repo_ip_url(repo_path)
|
||||
"#{edu_setting('git_address_ip')}/#{repo_path}"
|
||||
## 输出错误信息
|
||||
def error_status(message = nil)
|
||||
@status = -1
|
||||
@message = message
|
||||
end
|
||||
|
||||
def repo_url(repo_path)
|
||||
|
@ -655,23 +642,6 @@ class ApplicationController < ActionController::Base
|
|||
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
|
||||
|
@ -683,8 +653,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# 获取Oauth Client
|
||||
def get_client(site)
|
||||
client_id = Rails.configuration.educoder['client_id']
|
||||
client_secret = Rails.configuration.educoder['client_secret']
|
||||
client_id = Rails.configuration.Gitlink['client_id']
|
||||
client_secret = Rails.configuration.Gitlink['client_secret']
|
||||
|
||||
OAuth2::Client.new(client_id, client_secret, site: site)
|
||||
end
|
||||
|
@ -704,7 +674,7 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
def kaminari_paginate(relation)
|
||||
limit = params[:limit] || params[:per_page]
|
||||
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
|
||||
limit = (limit.to_i.zero? || limit.to_i > 50) ? 50 : limit.to_i
|
||||
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
|
||||
|
||||
relation.page(page).per(limit)
|
||||
|
@ -789,11 +759,11 @@ class ApplicationController < ActionController::Base
|
|||
# @project = nil if !@project.is_public?
|
||||
# render_forbidden and return
|
||||
else
|
||||
if @project.present?
|
||||
if @project.present?
|
||||
logger.info "###########: has project and but can't read project"
|
||||
@project = nil
|
||||
render_forbidden and return
|
||||
else
|
||||
else
|
||||
logger.info "###########:project not found"
|
||||
@project = nil
|
||||
render_not_found and return
|
||||
|
@ -838,54 +808,21 @@ class ApplicationController < ActionController::Base
|
|||
end
|
||||
|
||||
private
|
||||
def update_last_login_on
|
||||
if current_user.logged?
|
||||
current_user.update_column(:last_login_on, Time.now)
|
||||
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 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 render_parameter_missing
|
||||
render json: { status: -1, message: '参数缺失' }
|
||||
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)
|
||||
|
||||
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
|
||||
|
||||
# 记录热门搜索关键字
|
||||
def record_search_keyword
|
||||
keyword = params[:keyword].to_s.strip
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
class Blockchain::BaseController < ApplicationController
|
||||
|
||||
before_action :require_login
|
||||
before_action :connect_to_ci_database, if: -> { current_user && !current_user.is_a?(AnonymousUser) && !current_user.devops_uninit? }
|
||||
before_action :connect_to_ci_database, only: :load_repo
|
||||
|
||||
|
||||
def load_repo
|
||||
namespace = params[:owner]
|
||||
id = params[:repo] || params[:id]
|
||||
|
||||
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
|
||||
end
|
||||
|
||||
private
|
||||
def authorize_access_project!
|
||||
unless @project.manager?(current_user)
|
||||
return render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate_manager!
|
||||
unless @project.manager?(current_user)
|
||||
return render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def authenticate_admin!
|
||||
return render_forbidden unless current_user.admin?
|
||||
end
|
||||
|
||||
def authorize_owner!
|
||||
unless @project.owner?(current_user)
|
||||
return render_forbidden
|
||||
end
|
||||
end
|
||||
|
||||
def find_cloud_account
|
||||
@cloud_account ||= current_user.ci_cloud_account
|
||||
@cloud_account.blank? ? nil : @cloud_account
|
||||
end
|
||||
|
||||
def load_ci_user
|
||||
@ci_user ||= Ci::User.find_by(user_login: params[:owner])
|
||||
@ci_user.blank? ? raise("未找到相关的记录") : @ci_user
|
||||
end
|
||||
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
class BlockchainController < ApplicationController
|
||||
|
||||
def get_issue_token_num
|
||||
puts "pause"
|
||||
end
|
||||
|
||||
end
|
|
@ -6,10 +6,10 @@ class CompareController < ApplicationController
|
|||
end
|
||||
|
||||
def show
|
||||
if params[:type] == "sha"
|
||||
if params[:type] == "sha"
|
||||
load_compare_params
|
||||
@compare_result ||= gitea_compare(@base, @head)
|
||||
else
|
||||
else
|
||||
load_compare_params
|
||||
compare
|
||||
@merge_status, @merge_message = get_merge_message
|
||||
|
@ -63,7 +63,7 @@ class CompareController < ApplicationController
|
|||
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token)
|
||||
end
|
||||
|
||||
def page_size
|
||||
def page_size
|
||||
params.fetch(:page, 1).to_i
|
||||
end
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ module Api::ProjectHelper
|
|||
repo = params[:repo]
|
||||
|
||||
@project, @owner = Project.find_with_namespace(namespace, repo)
|
||||
|
||||
@repository = @project&.repository
|
||||
|
||||
if @project
|
||||
logger.info "###########:project founded"
|
||||
@project
|
||||
|
|
|
@ -44,7 +44,6 @@ 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)
|
||||
|
|
|
@ -3,12 +3,9 @@ class ForksController < ApplicationController
|
|||
before_action :require_profile_completed, only: [:create]
|
||||
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
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
class InstallationsController < ApplicationController
|
||||
include RegisterHelper
|
||||
before_action :require_login
|
||||
|
||||
def index
|
||||
@install_bots = BotInstall.where(:installer_id => current_user.id)
|
||||
end
|
||||
|
||||
def update_secret
|
||||
ActiveRecord::Base.transaction do
|
||||
bot = Bot.find params[:id]
|
||||
application = Doorkeeper::Application.find_by(uid: bot.client_id, secret: bot.client_secret)
|
||||
bot.client_secret = Doorkeeper::OAuth::Helpers::UniqueToken.generate
|
||||
bot.save!
|
||||
application.secret = bot.client_secret
|
||||
application.save!
|
||||
render_ok
|
||||
end
|
||||
end
|
||||
|
||||
def update_private_key
|
||||
bot = Bot.find params[:id]
|
||||
bot.private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
||||
bot.save!
|
||||
render_ok
|
||||
end
|
||||
|
||||
def auth_active
|
||||
begin
|
||||
@bot = Bot.find params[:id]
|
||||
tip_exception("该Bot已激活") if Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret).present?
|
||||
@bot.client_id = Doorkeeper::OAuth::Helpers::UniqueToken.generate if params[:client_id].blank?
|
||||
@bot.client_secret = Doorkeeper::OAuth::Helpers::UniqueToken.generate if params[:client_secret].blank?
|
||||
@bot.private_key = OpenSSL::PKey::RSA::generate(2048).to_s
|
||||
@bot.owner_id = current_user.id
|
||||
ActiveRecord::Base.transaction do
|
||||
# 注册bot对应oauth应用
|
||||
Doorkeeper::Application.create!(name: @bot.name, uid: @bot.client_id, secret: @bot.client_secret, redirect_uri: "https://gitlink.org.cn")
|
||||
# 注册bot对应用户
|
||||
result = autologin_register(User.generate_user_login('b'), nil, "#{SecureRandom.hex(6)}", 'bot', nil, nickname: @bot.name)
|
||||
tip_exception(-1, result[:message]) if result[:message].present?
|
||||
@bot.uid = result[:user][:id]
|
||||
@bot.save
|
||||
render_ok
|
||||
end
|
||||
rescue Exception => e
|
||||
tip_exception(-1, e.message)
|
||||
end
|
||||
end
|
||||
|
||||
def access_tokens
|
||||
@install_bot = BotInstall.find params[:id]
|
||||
@bot = @install_bot.bot
|
||||
@application = Doorkeeper::Application.find_by(uid: @bot.client_id, secret: @bot.client_secret)
|
||||
tip_exception("该Bot未激活") if @application.blank?
|
||||
# 给bot生成token,因为bot是机器人操作
|
||||
@access_token = Doorkeeper::AccessToken.create!({ :application_id => @application.id,
|
||||
:resource_owner_id => @bot.uid,
|
||||
:scopes => "public write",
|
||||
:expires_in => "604800",
|
||||
:use_refresh_token => true
|
||||
})
|
||||
render_ok(token: @access_token.token)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
@ -11,8 +11,6 @@ class IssuesController < ApplicationController
|
|||
before_action :set_issue, only: [:edit, :update, :destroy, :show, :copy, :close_issue, :lock_issue]
|
||||
before_action :check_token_enough, :find_atme_receivers, only: [:create, :update]
|
||||
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
include ApplicationHelper
|
||||
include TagChosenHelper
|
||||
|
||||
|
@ -113,7 +111,9 @@ class IssuesController < ApplicationController
|
|||
issue_params = issue_send_params(params)
|
||||
Issues::CreateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
@issue = Issue.new(issue_params)
|
||||
@issue.project_issues_index = @project.get_last_project_issues_index + 1
|
||||
if @issue.save!
|
||||
@project.del_project_issue_cache_delete_count
|
||||
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('ProjectIssue', current_user.id, @issue&.id) if Site.has_notice_menu?
|
||||
if params[:attachment_ids].present?
|
||||
|
@ -157,6 +157,8 @@ class IssuesController < ApplicationController
|
|||
|
||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
|
||||
# 新增时向grimoirelab推送事件
|
||||
IssueWebhookJob.set(wait: 5.seconds).perform_later(@issue.id)
|
||||
|
||||
# author: zxh
|
||||
# 扣除发起人的token
|
||||
|
@ -230,7 +232,6 @@ 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, "不允许修改为关闭状态")
|
||||
|
@ -238,9 +239,6 @@ class IssuesController < ApplicationController
|
|||
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id)
|
||||
Issues::UpdateForm.new({subject: issue_params[:subject], description: issue_params[:description].blank? ? issue_params[:description] : issue_params[:description].b}).validate!
|
||||
if @issue.update_attributes(issue_params)
|
||||
|
||||
user_trace_update_log(issue_hash)
|
||||
|
||||
if @issue&.pull_request.present?
|
||||
SendTemplateMessageJob.perform_later('PullRequestChanged', current_user.id, @issue&.pull_request&.id, @issue.previous_changes.slice(:assigned_to_id, :priority_id, :fixed_version_id, :issue_tags_value)) if Site.has_notice_menu?
|
||||
SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @issue&.pull_request&.id ) if @issue.previous_changes[:assigned_to_id].present? && Site.has_notice_menu?
|
||||
|
@ -318,6 +316,7 @@ class IssuesController < ApplicationController
|
|||
login = @issue.user.try(:login)
|
||||
SendTemplateMessageJob.perform_later('IssueDeleted', current_user.id, @issue&.subject, @issue.assigned_to_id, @issue.author_id) if Site.has_notice_menu?
|
||||
if @issue.destroy
|
||||
@project.incre_project_issue_cache_delete_count
|
||||
if issue_type == "2" && status_id != 5
|
||||
post_to_chain("add", token, login)
|
||||
end
|
||||
|
|
|
@ -4,7 +4,6 @@ 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
|
||||
|
@ -80,11 +79,9 @@ class JournalsController < ApplicationController
|
|||
|
||||
def update
|
||||
content = params[:content]
|
||||
if content.present?
|
||||
old_value = old_value_to_hash(@journal, params)
|
||||
if content.present?
|
||||
Journals::UpdateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
|
||||
if @journal.update_attribute(:notes, content)
|
||||
user_trace_update_log(old_value)
|
||||
normal_status(0, "更新成功")
|
||||
else
|
||||
normal_status(-1, "更新失败")
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
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
|
|
@ -6,7 +6,6 @@ class MembersController < ApplicationController
|
|||
before_action :operate!
|
||||
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)
|
||||
|
@ -43,9 +42,7 @@ 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)
|
||||
SendTemplateMessageJob.perform_later('ProjectRole', current_user.id, @user.id, @project.id, message_role_name) if Site.has_notice_menu?
|
||||
render_response(interactor)
|
||||
rescue Exception => e
|
||||
|
|
|
@ -8,14 +8,17 @@ class Organizations::ProjectsController < Organizations::BaseController
|
|||
.joins(team_projects: {team: :team_users})
|
||||
.where(team_users: {user_id: current_user.id}).to_sql
|
||||
@projects = Project.from("( #{ public_projects_sql} UNION #{ private_projects_sql } ) AS projects")
|
||||
|
||||
@projects = @projects.ransack(name_or_identifier_cont: params[:search]).result if params[:search].present?
|
||||
# 表情处理
|
||||
keywords = params[:search].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
|
||||
@projects = @projects.ransack(name_or_identifier_cont: keywords).result if params[:search].present?
|
||||
@projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}")
|
||||
@projects = paginate(@projects)
|
||||
end
|
||||
|
||||
def search
|
||||
tip_exception("请输入搜索关键词") if params[:search].nil?
|
||||
# 表情处理
|
||||
keywords = params[:search].to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
|
||||
public_projects_sql = @organization.projects.where(is_public: true).to_sql
|
||||
private_projects_sql = @organization.projects
|
||||
.where(is_public: false)
|
||||
|
@ -23,7 +26,7 @@ class Organizations::ProjectsController < Organizations::BaseController
|
|||
.where(team_users: {user_id: current_user.id}).to_sql
|
||||
@projects = Project.from("( #{ public_projects_sql} UNION #{ private_projects_sql } ) AS projects")
|
||||
|
||||
@projects = @projects.ransack(name_or_identifier_cont: params[:search]).result
|
||||
@projects = @projects.ransack(name_or_identifier_cont: keywords).result
|
||||
@projects = @projects.includes(:owner).order("projects.#{sort} #{sort_direction}")
|
||||
end
|
||||
|
||||
|
|
|
@ -39,13 +39,14 @@ class ProjectsController < ApplicationController
|
|||
|
||||
category_id = params[:category_id]
|
||||
@total_count =
|
||||
if category_id.blank?
|
||||
# ps = ProjectStatistic.first
|
||||
# ps.common_projects_count + ps.mirror_projects_count unless ps.blank?
|
||||
if category_id.blank? && params[:search].blank?
|
||||
# 默认查询时count性能问题处理
|
||||
ProjectCategory.sum("projects_count") - Project.visible.joins("left join organization_extensions on organization_extensions.organization_id = projects.user_id").where("organization_extensions.visibility =2").count
|
||||
elsif params[:search].present?
|
||||
@projects.total_count
|
||||
else
|
||||
cate = ProjectCategory.find_by(id: category_id)
|
||||
cate&.projects_count || 0
|
||||
cate = ProjectCategory.find_by(id: category_id)
|
||||
cate&.projects_count || 0
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,7 +54,7 @@ class ProjectsController < ApplicationController
|
|||
ActiveRecord::Base.transaction do
|
||||
Projects::CreateForm.new(project_params).validate!
|
||||
@project = Projects::CreateService.new(current_user, project_params).call
|
||||
OpenProjectDevOpsJob.perform_later(@project&.id, current_user.id)
|
||||
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(@project&.id, current_user.id)
|
||||
end
|
||||
rescue Exception => e
|
||||
uid_logger_error(e.message)
|
||||
|
|
|
@ -7,7 +7,6 @@ class PullRequestsController < ApplicationController
|
|||
before_action :load_pull_request, only: [:files, :commits]
|
||||
before_action :find_atme_receivers, only: [:create, :update]
|
||||
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
include TagChosenHelper
|
||||
include ApplicationHelper
|
||||
|
||||
|
@ -110,13 +109,8 @@ class PullRequestsController < ApplicationController
|
|||
reviewers = User.where(id: params[:reviewer_ids])
|
||||
@pull_request.reviewers = reviewers
|
||||
|
||||
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.gitea_number, @requests_params, current_user.gitea_token)
|
||||
|
||||
|
@ -241,10 +235,8 @@ class PullRequestsController < ApplicationController
|
|||
raise ActiveRecord::Rollback
|
||||
else
|
||||
author_id = pr.user_id
|
||||
author = User.find(author_id)
|
||||
if token_num > 0
|
||||
Blockchain::FixIssue.call({user_id: author_id.to_s, project_id: project.id.to_s, token_num: token_num})
|
||||
Blockchain::TransferService.call({payer_id: issue.author_id.to_s, transfer_login: author.login, transfer_amount: token_num, project_id: project.id})
|
||||
end
|
||||
# update issue to state 5
|
||||
issue.update(status_id: 5)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
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_navbar
|
||||
get_add_menu
|
||||
get_common_menu
|
||||
|
@ -13,14 +12,14 @@ class SettingsController < ApplicationController
|
|||
end
|
||||
|
||||
private
|
||||
def get_navbar
|
||||
def get_navbar
|
||||
@navbar = default_laboratory.navbar
|
||||
if User.current.logged?
|
||||
pernal_index = {"name"=>"个人主页", "link"=>get_site_url("url", "#{Rails.application.config_for(:configuration)['platform_url']}/current_user"), "hidden"=>false}
|
||||
@navbar << pernal_index
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_add_menu
|
||||
@add = []
|
||||
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
|
||||
|
@ -87,7 +86,7 @@ class SettingsController < ApplicationController
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def get_top_system_notification
|
||||
@top_system_notification = SystemNotification.is_top.first
|
||||
end
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
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
|
|
@ -1,212 +0,0 @@
|
|||
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
|
||||
else
|
||||
return render json: { status: -1, message: '赞助失败' }
|
||||
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
|
||||
|
||||
def community_data
|
||||
@sponsorships = Sponsorship.all
|
||||
t1 = Time.now
|
||||
t2 = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
@stopped_sponsorships = StoppedSponsorship.where('created_at >= ?', t2)
|
||||
@community_data_array = to_array(@sponsorships, @stopped_sponsorships)
|
||||
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
|
||||
|
||||
def to_array(sponsorships, stopped_sponsorships)
|
||||
t1 = Time.now
|
||||
start_time = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
|
||||
sponsor = Array.new(7)
|
||||
sponsored = Array.new(7)
|
||||
date = Array.new(7)
|
||||
# date[0] = Time.new(start_time.year, start_time.month, start_time.day)
|
||||
index = 0
|
||||
|
||||
(0..6).each do |i|
|
||||
# 更新日期,date[i]表示第i天0点
|
||||
date[i] = Time.new(start_time.year, start_time.month, start_time.day + i)
|
||||
end_time = Time.new(start_time.year, start_time.month, start_time.day + i+1)
|
||||
|
||||
sponsor_set = Set.new
|
||||
sponsored_set = Set.new
|
||||
|
||||
# 所有创建时间早于今天23:59的sponsorship
|
||||
today_sponsor = sponsorships.where('created_at < ?', end_time)
|
||||
# 所有结束时间晚于今天0:00的stopped_sponsorship
|
||||
today_stopped_sponsor = stopped_sponsorships.where('created_at <= ?', date[i])
|
||||
today_sponsor.each do |s|
|
||||
sponsor_set.add s.sponsor_id
|
||||
sponsored_set.add s.developer_id
|
||||
end
|
||||
|
||||
today_stopped_sponsor.each do |s|
|
||||
sponsor_set.add s.sponsor_id
|
||||
sponsored_set.add s.developer_id
|
||||
end
|
||||
|
||||
sponsor[i] = sponsor_set.size
|
||||
sponsored[i] = sponsored_set.size
|
||||
|
||||
end
|
||||
|
||||
Array[sponsor, sponsored, date]
|
||||
end
|
||||
end
|
|
@ -10,15 +10,15 @@ class Users::HeadmapsController < Users::BaseController
|
|||
private
|
||||
def start_stamp
|
||||
if params[:year].present?
|
||||
Date.new(params[:year], 1).to_time.to_i
|
||||
Date.new(params[:year].to_i, 1).to_time.to_i
|
||||
else
|
||||
Date.today.to_time.to_i - 365*24*60*60
|
||||
(Date.today - 1.years).to_time.to_i
|
||||
end
|
||||
end
|
||||
|
||||
def end_stamp
|
||||
if params[:year].present?
|
||||
Date.new(params[:year], 1).to_time.to_i + 365*24*60*60
|
||||
(Date.new(params[:year].to_i, 1) + 1.years).to_time.to_i
|
||||
else
|
||||
Date.today.to_time.to_i
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
class Users::MessagesController < Users::BaseController
|
||||
before_action :private_user_resources!
|
||||
before_action :find_receivers, only: [:create]
|
||||
before_action :check_auth
|
||||
|
||||
def index
|
||||
limit = params[:limit] || params[:per_page]
|
||||
|
@ -63,6 +64,10 @@ class Users::MessagesController < Users::BaseController
|
|||
end
|
||||
|
||||
private
|
||||
def check_auth
|
||||
return render_forbidden unless current_user.admin? || observed_logged_user?
|
||||
end
|
||||
|
||||
def message_type
|
||||
@message_type = begin
|
||||
case params[:type]
|
||||
|
|
|
@ -266,10 +266,6 @@ class UsersController < ApplicationController
|
|||
end
|
||||
# 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
|
||||
|
@ -502,136 +498,136 @@ class UsersController < ApplicationController
|
|||
# 替代解决方案
|
||||
# 读取所有交易信息
|
||||
end
|
||||
|
||||
def blockchain_create_trade
|
||||
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
is_current_admin_user = true
|
||||
if is_current_admin_user
|
||||
user_id = params['user_id'].to_i
|
||||
project_id = params['project_id'].to_i
|
||||
money = params['money'].to_f
|
||||
#description = params['description']
|
||||
token_num = params['token_num'].to_i
|
||||
# 锁仓
|
||||
result = Blockchain::CreateTrade.call({user_id: user_id, project_id: project_id, token_num: token_num})
|
||||
if result == false
|
||||
normal_status(-1, "创建交易失败")
|
||||
else
|
||||
bt = BlockchainTrade.new(user_id: user_id, project_id: project_id, token_num: token_num, money: money, state: 0) # state=0表示创建交易; state=1表示执行中; state=2表示执行完成
|
||||
bt.save()
|
||||
status = 2 # 交易创建成功
|
||||
render json: { status: status }
|
||||
end
|
||||
else
|
||||
normal_status(-1, "缺少权限")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def blockchain_get_trades
|
||||
trades = BlockchainTrade.where(state: 0).all()
|
||||
results = []
|
||||
trades.each do |t|
|
||||
project_id = t.project_id
|
||||
project = Project.find_by(id: project_id)
|
||||
if !project.nil?
|
||||
owner = User.find_by(id: project.user_id)
|
||||
else
|
||||
owner = nil
|
||||
end
|
||||
user_id = t.user_id
|
||||
creator = User.find_by(id: user_id)
|
||||
if project.nil? || owner.nil? || creator.nil?
|
||||
else
|
||||
results << [creator, owner, project, t]
|
||||
end
|
||||
end
|
||||
render json: { results: results }
|
||||
end
|
||||
|
||||
def blockchain_trade
|
||||
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
is_current_admin_user = true
|
||||
if is_current_admin_user
|
||||
user_id2 = params['user_id2'].to_i
|
||||
trade_id = params['trade_id'].to_i
|
||||
BlockchainTrade.find(trade_id).update(user_id2: user_id2, state: 1) # state=1表示锁定了,等待线下卖家发货
|
||||
render json: {status: 2} # window.location.reload()
|
||||
else
|
||||
normal_status(-1, "缺少权限")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def blockchain_verify_trade
|
||||
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
is_current_admin_user = true
|
||||
if is_current_admin_user
|
||||
trade_id = params['trade_id'].to_i
|
||||
BlockchainTrade.find(trade_id).update(state: 2) # state=2表示确认收货
|
||||
render json: {status: 2} # window.location.reload()
|
||||
else
|
||||
normal_status(-1, "缺少权限")
|
||||
end
|
||||
end
|
||||
|
||||
def blockchain_get_verify_trades
|
||||
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
is_current_admin_user = true
|
||||
if is_current_admin_user
|
||||
trades = BlockchainTrade.where(state: 1).all()
|
||||
results = []
|
||||
trades.each do |t|
|
||||
project_id = t.project_id
|
||||
project = Project.find_by(id: project_id)
|
||||
if !project.nil?
|
||||
owner = User.find_by(id: project.user_id)
|
||||
else
|
||||
owner = nil
|
||||
end
|
||||
user_id = t.user_id
|
||||
creator = User.find_by(id: user_id)
|
||||
user_id2 = t.user_id2
|
||||
buyer = User.find_by(id: user_id2)
|
||||
if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||
else
|
||||
results << [creator, owner, project, t, buyer]
|
||||
end
|
||||
end
|
||||
render json: { results: results }
|
||||
else
|
||||
normal_status(-1, "缺少权限")
|
||||
end
|
||||
end
|
||||
|
||||
def blockchain_get_history_trades
|
||||
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
is_current_admin_user = true
|
||||
if is_current_admin_user
|
||||
trades = BlockchainTrade.where(state: 2).all()
|
||||
results = []
|
||||
trades.each do |t|
|
||||
project_id = t.project_id
|
||||
project = Project.find_by(id: project_id)
|
||||
if !project.nil?
|
||||
owner = User.find_by(id: project.user_id)
|
||||
else
|
||||
owner = nil
|
||||
end
|
||||
user_id = t.user_id
|
||||
creator = User.find_by(id: user_id)
|
||||
user_id2 = t.user_id2
|
||||
buyer = User.find_by(id: user_id2)
|
||||
if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||
else
|
||||
results << [creator, owner, project, t, buyer]
|
||||
end
|
||||
end
|
||||
render json: { results: results }
|
||||
else
|
||||
normal_status(-1, "缺少权限")
|
||||
end
|
||||
end
|
||||
# #
|
||||
# # def blockchain_create_trade
|
||||
# # #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
# # is_current_admin_user = true
|
||||
# # if is_current_admin_user
|
||||
# # user_id = params['user_id'].to_i
|
||||
# # project_id = params['project_id'].to_i
|
||||
# # money = params['money'].to_f
|
||||
# # #description = params['description']
|
||||
# # token_num = params['token_num'].to_i
|
||||
# # # 锁仓
|
||||
# # result = Blockchain::CreateTrade.call({user_id: user_id, project_id: project_id, token_num: token_num})
|
||||
# # if result == false
|
||||
# # normal_status(-1, "创建交易失败")
|
||||
# # else
|
||||
# # bt = BlockchainTrade.new(user_id: user_id, project_id: project_id, token_num: token_num, money: money, state: 0) # state=0表示创建交易; state=1表示执行中; state=2表示执行完成
|
||||
# # bt.save()
|
||||
# # status = 2 # 交易创建成功
|
||||
# # render json: { status: status }
|
||||
# # end
|
||||
# # else
|
||||
# # normal_status(-1, "缺少权限")
|
||||
# # end
|
||||
# # end
|
||||
# #
|
||||
# #
|
||||
# # def blockchain_get_trades
|
||||
# # trades = BlockchainTrade.where(state: 0).all()
|
||||
# # results = []
|
||||
# # trades.each do |t|
|
||||
# # project_id = t.project_id
|
||||
# # project = Project.find_by(id: project_id)
|
||||
# # if !project.nil?
|
||||
# # owner = User.find_by(id: project.user_id)
|
||||
# # else
|
||||
# # owner = nil
|
||||
# # end
|
||||
# # user_id = t.user_id
|
||||
# # creator = User.find_by(id: user_id)
|
||||
# # if project.nil? || owner.nil? || creator.nil?
|
||||
# # else
|
||||
# # results << [creator, owner, project, t]
|
||||
# # end
|
||||
# # end
|
||||
# # render json: { results: results }
|
||||
# # end
|
||||
# #
|
||||
# # def blockchain_trade
|
||||
# # #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
# # is_current_admin_user = true
|
||||
# # if is_current_admin_user
|
||||
# # user_id2 = params['user_id2'].to_i
|
||||
# # trade_id = params['trade_id'].to_i
|
||||
# # BlockchainTrade.find(trade_id).update(user_id2: user_id2, state: 1) # state=1表示锁定了,等待线下卖家发货
|
||||
# # render json: {status: 2} # window.location.reload()
|
||||
# # else
|
||||
# # normal_status(-1, "缺少权限")
|
||||
# # end
|
||||
# # end
|
||||
#
|
||||
#
|
||||
# def blockchain_verify_trade
|
||||
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
# is_current_admin_user = true
|
||||
# if is_current_admin_user
|
||||
# trade_id = params['trade_id'].to_i
|
||||
# BlockchainTrade.find(trade_id).update(state: 2) # state=2表示确认收货
|
||||
# render json: {status: 2} # window.location.reload()
|
||||
# else
|
||||
# normal_status(-1, "缺少权限")
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def blockchain_get_verify_trades
|
||||
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
# is_current_admin_user = true
|
||||
# if is_current_admin_user
|
||||
# trades = BlockchainTrade.where(state: 1).all()
|
||||
# results = []
|
||||
# trades.each do |t|
|
||||
# project_id = t.project_id
|
||||
# project = Project.find_by(id: project_id)
|
||||
# if !project.nil?
|
||||
# owner = User.find_by(id: project.user_id)
|
||||
# else
|
||||
# owner = nil
|
||||
# end
|
||||
# user_id = t.user_id
|
||||
# creator = User.find_by(id: user_id)
|
||||
# user_id2 = t.user_id2
|
||||
# buyer = User.find_by(id: user_id2)
|
||||
# if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||
# else
|
||||
# results << [creator, owner, project, t, buyer]
|
||||
# end
|
||||
# end
|
||||
# render json: { results: results }
|
||||
# else
|
||||
# normal_status(-1, "缺少权限")
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# def blockchain_get_history_trades
|
||||
# #is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||
# is_current_admin_user = true
|
||||
# if is_current_admin_user
|
||||
# trades = BlockchainTrade.where(state: 2).all()
|
||||
# results = []
|
||||
# trades.each do |t|
|
||||
# project_id = t.project_id
|
||||
# project = Project.find_by(id: project_id)
|
||||
# if !project.nil?
|
||||
# owner = User.find_by(id: project.user_id)
|
||||
# else
|
||||
# owner = nil
|
||||
# end
|
||||
# user_id = t.user_id
|
||||
# creator = User.find_by(id: user_id)
|
||||
# user_id2 = t.user_id2
|
||||
# buyer = User.find_by(id: user_id2)
|
||||
# if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||
# else
|
||||
# results << [creator, owner, project, t, buyer]
|
||||
# end
|
||||
# end
|
||||
# render json: { results: results }
|
||||
# else
|
||||
# normal_status(-1, "缺少权限")
|
||||
# end
|
||||
# end
|
||||
|
||||
|
||||
def blockchain_get_issue_token_num
|
||||
|
@ -677,21 +673,6 @@ class UsersController < ApplicationController
|
|||
render_ok
|
||||
end
|
||||
|
||||
def update_sponsor_description
|
||||
@user = User.find params[:id]
|
||||
if @user.id == User.current.id
|
||||
# @user.update(description: params[:description])
|
||||
@user.sponsor_description = params[:sponsor_description]
|
||||
if @user.save!
|
||||
render_ok
|
||||
else
|
||||
render_error
|
||||
end
|
||||
else
|
||||
render_error
|
||||
end
|
||||
end
|
||||
|
||||
def sync_user_info
|
||||
user = User.find_by_login params[:login]
|
||||
return render_forbidden unless user === current_user
|
||||
|
@ -729,7 +710,7 @@ class UsersController < ApplicationController
|
|||
:occupation, :technical_title,
|
||||
:school_id, :department_id, :province, :city,
|
||||
:custom_department, :identity, :student_id, :description,
|
||||
:show_super_description, :super_description,:sponsor_description,
|
||||
:show_super_description, :super_description,
|
||||
:show_email, :show_location, :show_department]
|
||||
)
|
||||
end
|
||||
|
|
|
@ -4,7 +4,6 @@ class VersionReleasesController < ApplicationController
|
|||
before_action :require_login, except: [:index, :show]
|
||||
before_action :check_release_authorize, except: [:index, :show]
|
||||
before_action :find_version , only: [:show, :edit, :update, :destroy]
|
||||
skip_after_action :user_trace_log, only: [:update]
|
||||
|
||||
def index
|
||||
@version_releases = kaminari_paginate(@repository.version_releases.order(created_at: :desc))
|
||||
|
@ -23,7 +22,7 @@ class VersionReleasesController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
def show
|
||||
def show
|
||||
# @release = Gitea::Versions::GetService.call(current_user.gitea_token, @user&.login, @repository&.identifier, @version&.version_gid)
|
||||
end
|
||||
|
||||
|
@ -84,14 +83,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(current_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, "更新失败")
|
||||
|
|
|
@ -1,113 +0,0 @@
|
|||
class WalletsController < ApplicationController
|
||||
before_action :require_login, except: :community_data
|
||||
|
||||
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}") unless scope.nil?
|
||||
|
||||
@total = 0
|
||||
@total = scope.length unless scope.nil?
|
||||
@coin_changes = kaminari_paginate(scope) unless scope.nil?
|
||||
end
|
||||
|
||||
def balance_chart
|
||||
user = User.find_by_id(params[:id])
|
||||
@wallet = user.get_wallet
|
||||
scope = CoinChange.where('to_wallet_id = ? OR from_wallet_id = ?', @wallet.id, @wallet.id)
|
||||
t1 = Time.now
|
||||
t2 = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
@balance_chart_data = scope.where('created_at > ? AND created_at < ?', t2, t1)
|
||||
@balance_chart_array = to_array(@balance_chart_data, @wallet.id)
|
||||
end
|
||||
|
||||
def community_data
|
||||
t1 = Time.now
|
||||
t2 = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
coin_changes = CoinChange.where('created_at >= ?', t2)
|
||||
@community_data_array = community_data_to_array(coin_changes)
|
||||
end
|
||||
|
||||
private
|
||||
def to_array(data, id)
|
||||
t1 = Time.now
|
||||
start_time = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
end_time = Time.new(start_time.year, start_time.month, start_time.day + 1)
|
||||
|
||||
income = Array.new(7, 0) # 收入、支出
|
||||
outcome = Array.new(7, 0)
|
||||
date = Array.new(7)
|
||||
date[0] = Time.new(start_time.year, start_time.month, start_time.day)
|
||||
index = 0
|
||||
|
||||
data.each do |i|
|
||||
# 更新日期
|
||||
until (i.created_at >= start_time) && (i.created_at < end_time)
|
||||
index += 1
|
||||
start_time = end_time
|
||||
end_time = Time.new(start_time.year, start_time.month, start_time.day + 1)
|
||||
date[index] = Time.new(start_time.year, start_time.month, start_time.day)
|
||||
end
|
||||
|
||||
if i.from_wallet_id == id
|
||||
outcome[index] += i.amount
|
||||
else
|
||||
next if params[:sponsor] == true && i.from_wallet_id.nil?
|
||||
income[index] += i.amount
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
until end_time >= Time.now
|
||||
index += 1
|
||||
start_time = end_time
|
||||
end_time = Time.new(start_time.year, start_time.month, start_time.day + 1)
|
||||
date[index] = Time.new(start_time.year, start_time.month, start_time.day)
|
||||
end
|
||||
|
||||
Array[income, outcome, date]
|
||||
end
|
||||
|
||||
def community_data_to_array(coin_changes)
|
||||
t1 = Time.now
|
||||
start_time = Time.new(t1.year, t1.month, t1.day - 6)
|
||||
|
||||
nums = Array.new(7, 0)
|
||||
date = Array.new(7)
|
||||
end_time = Array.new(7)
|
||||
# date[0] = Time.new(start_time.year, start_time.month, start_time.day)
|
||||
index = 0
|
||||
|
||||
(0..6).each do |i|
|
||||
# 更新日期,date[i]表示第i天0点
|
||||
date[i] = Time.new(start_time.year, start_time.month, start_time.day + i)
|
||||
end_time[i] = Time.new(start_time.year, start_time.month, start_time.day + i+1)
|
||||
end
|
||||
|
||||
coin_changes.each do |cc|
|
||||
(0..6).each do |i|
|
||||
if !cc.from_wallet_id.nil? && cc.created_at>=date[i] && cc.created_at<end_time[i]
|
||||
nums[i] += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Array[nums, date]
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module Admins::OrganizationsHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module LogHelper
|
||||
end
|
|
@ -66,6 +66,7 @@ module ProjectsHelper
|
|||
jianmu_devops: jianmu_devops_code(project, user),
|
||||
jianmu_devops_url: jianmu_devops_url,
|
||||
cloud_ide_saas_url: cloud_ide_saas_url(user),
|
||||
open_blockchain: EduSetting.get("open_blockchain_projects").to_s.split(",").include?(project.id.to_s) || EduSetting.get("open_blockchain_projects").to_s.split(",").include?(project.identifier) || EduSetting.get("open_blockchain_users").to_s.split(",").include?(user.id) || EduSetting.get("open_blockchain_users").to_s.split(",").include?(user.login),
|
||||
ignore_id: project.ignore_id
|
||||
}).compact
|
||||
|
||||
|
@ -138,6 +139,62 @@ module ProjectsHelper
|
|||
"#{saas_url}/oauth/login?product_account_id=PA1001218&tenant_code=TI1001383&oauth_url=#{oauth_url}&token=#{token.value}"
|
||||
end
|
||||
|
||||
def ai_shang_v1_url(project)
|
||||
url = EduSetting.get("ai_shang_url") || "https://shang.gitlink.org.cn"
|
||||
case project.identifier.to_s.downcase
|
||||
when nil then ""
|
||||
when 'rails' then "#{url}/v1/rails/entropy"
|
||||
when 'jittor' then "#{url}/v1/jittor/entropy"
|
||||
when 'paddle' then "#{url}/v1/Paddle/entropy"
|
||||
when 'vue' then "#{url}/v1/vue/entropy"
|
||||
when 'bootstrap' then "#{url}/v1/bootstrap/entropy"
|
||||
when 'tensorflow' then "#{url}/v1/tensorflow/entropy"
|
||||
else ''
|
||||
end
|
||||
end
|
||||
|
||||
def ai_shang_v2_url(project)
|
||||
url = EduSetting.get("ai_shang_url") || "https://shang.gitlink.org.cn"
|
||||
case project.identifier.to_s.downcase
|
||||
when nil then ""
|
||||
when 'rails' then "#{url}/v2/getMediumData?repo_login=rails&repo_name=rails"
|
||||
when 'jittor' then "#{url}/v2/getMediumData?repo_login=Jittor&repo_name=jittor"
|
||||
when 'paddle' then "#{url}/v2/getMediumData?repo_login=PaddlePaddle&repo_name=Paddle"
|
||||
when 'vue' then "#{url}/v2/getMediumData?repo_login=vuejs&repo_name=vue"
|
||||
when 'bootstrap' then "#{url}/v2/getMediumData?repo_login=twbs&repo_name=bootstrap"
|
||||
when 'tensorflow' then "#{url}/v2/getMediumData?repo_login=tensorflow&repo_name=tensorflow"
|
||||
else ''
|
||||
end
|
||||
end
|
||||
|
||||
def ai_shang_v4_url(project)
|
||||
url = EduSetting.get("ai_shang_url") || "https://shang.gitlink.org.cn"
|
||||
case project.identifier.to_s.downcase
|
||||
when nil then ""
|
||||
when 'rails' then "#{url}/v2/getIndexData?repo_login=rails&repo_name=rails"
|
||||
when 'jittor' then "#{url}/v2/getIndexData?repo_login=Jittor&repo_name=jittor"
|
||||
when 'paddle' then "#{url}/v2/getIndexData?repo_login=PaddlePaddle&repo_name=Paddle"
|
||||
when 'vue' then "#{url}/v2/getIndexData?repo_login=vuejs&repo_name=vue"
|
||||
when 'bootstrap' then "#{url}/v2/getIndexData?repo_login=twbs&repo_name=bootstrap"
|
||||
when 'tensorflow' then "#{url}/v2/getIndexData?repo_login=tensorflow&repo_name=tensorflow"
|
||||
else ''
|
||||
end
|
||||
end
|
||||
|
||||
def ai_shang_v3_url(project)
|
||||
url = EduSetting.get("ai_shang_v3_url") || "https://entropy.ingress.isa.buaanlsde.cn"
|
||||
case project.identifier.to_s.downcase
|
||||
when nil then ""
|
||||
when 'rails' then "#{url}/rails/entropy"
|
||||
when 'jittor' then "#{url}/jittor/entropy"
|
||||
when 'paddle' then "#{url}/paddle/entropy"
|
||||
when 'vue' then "#{url}/vue/entropy"
|
||||
when 'bootstrap' then "#{url}/bootstrap/entropy"
|
||||
when 'tensorflow' then "#{url}/tensorflow/entropy"
|
||||
else ''
|
||||
end
|
||||
end
|
||||
|
||||
def aes_encrypt(key, des_text)
|
||||
# des_text='{"access_key_id":"STS.NTuC9RVmWfJqj3JkcMzPnDf7X","access_key_secret":"E8NxRZWGNxxMfwgt5nFLnBFgg6AzgXCZkSNCyqygLuHM","end_point":"oss-accelerate.aliyuncs.com","security_token":"CAIS8gF1q6Ft5B2yfSjIr5fACIPmu7J20YiaaBX7j2MYdt9Cq6Ocujz2IHhMenVhA+8Wv/02n2hR7PcYlq9IS55VWEqc/VXLaywQo22beIPkl5Gfz95t0e+IewW6Dxr8w7WhAYHQR8/cffGAck3NkjQJr5LxaTSlWS7OU/TL8+kFCO4aRQ6ldzFLKc5LLw950q8gOGDWKOymP2yB4AOSLjIx6lAt2T8vs/7hmZPFukSFtjCglL9J/baWC4O/csxhMK14V9qIx+FsfsLDqnUIs0YWpf0p3P0doGyf54vMWUM05A6dduPS7txkLAJwerjVl1/ADxc0/hqAASXhPeiktbmDjwvnSn4iKcSGQ+xoQB468eHXNdvf13dUlbbE1+JhRi0pZIB2UCtN9oTsLHcwIHt+EJaoMd3+hGwPVmvHSXzECDFHylZ8l/pzTwlE/aCtZyVmI5cZEvmWu2xBa3GRbULo7lLvyeX1cHTVmVWf4Nk6D09PzTU8qlAj","bucket":"edu-bigfiles1","region":"oss-cn-hangzhou","callback_url":"https://data.educoder.net/api/buckets/callback.json","bucket_host":"data.educoder.net"}'
|
||||
# des = OpenSSL::Cipher::Cipher.new('aes-256-ctr')
|
||||
|
|
|
@ -213,5 +213,12 @@ module RepositoriesHelper
|
|||
def tmp_dir
|
||||
"repo"
|
||||
end
|
||||
|
||||
|
||||
def repo_git_submodule_url(owner, repo, path)
|
||||
unless (path.starts_with?('http://') || path.starts_with?('https://'))
|
||||
path = File.expand_path(path, "/#{owner&.login}/#{repo&.identifier}")
|
||||
end
|
||||
|
||||
return path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
module SponsorTiersHelper
|
||||
end
|
|
@ -1,2 +0,0 @@
|
|||
module SponsorshipsHelper
|
||||
end
|
|
@ -1,6 +0,0 @@
|
|||
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
|
|
@ -1,2 +0,0 @@
|
|||
module WalletsHelper
|
||||
end
|
|
@ -0,0 +1,186 @@
|
|||
class IssueWebhookJob < ApplicationJob
|
||||
include ApplicationHelper
|
||||
queue_as :message
|
||||
|
||||
def perform(issue_id)
|
||||
issue = Issue.find_by(id: issue_id)
|
||||
return if issue.blank?
|
||||
project = issue.project
|
||||
user = issue.user
|
||||
domain = "#{Rails.application.config_for(:configuration)['platform_url']}"
|
||||
gitea_domain = GiteaService.gitea_config[:domain]
|
||||
ssh_url = "git@#{gitea_domain.gsub("https://", "")}:#{project.owner.login}/#{project.identifier}.git"
|
||||
event_json = {
|
||||
"action": "opened",
|
||||
"number": 1,
|
||||
"issue": {
|
||||
"id": issue.id,
|
||||
"url": "#{domain}/api/v1/#{project.owner.login}/#{project.identifier}/issues/#{issue.id}",
|
||||
"html_url": "#{domain}/#{project.owner.login}/#{project.identifier}/issues/#{issue.id}",
|
||||
"number": 1,
|
||||
"user": {
|
||||
"id": user.id,
|
||||
"login": "#{user.login}",
|
||||
"full_name": "",
|
||||
"email": "#{user.mail}",
|
||||
"avatar_url": "#{domain}/#{url_to_avatar(user)}",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "#{user.last_login_on}",
|
||||
"created": "#{user.created_on}",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "#{user.login}"
|
||||
},
|
||||
"original_author": "",
|
||||
"original_author_id": 0,
|
||||
"title": "#{issue.subject}",
|
||||
"body": "#{issue.description}",
|
||||
"ref": "",
|
||||
"labels": [],
|
||||
"milestone": nil,
|
||||
"assignee": nil,
|
||||
"assignees": nil,
|
||||
"state": "open",
|
||||
"is_locked": false,
|
||||
"comments": 0,
|
||||
"created_at": "#{issue.created_on}",
|
||||
"updated_at": "#{issue.updated_on}",
|
||||
"closed_at": nil,
|
||||
"due_date": nil,
|
||||
"pull_request": nil,
|
||||
"repository": {
|
||||
"id": 11307,
|
||||
"name": "#{project.identifier}",
|
||||
"owner": "#{project.owner.login}",
|
||||
"full_name": "#{project.owner.login}/#{project.identifier}"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"id": project.id,
|
||||
"owner": {
|
||||
"id": project.owner.id,
|
||||
"login": "#{project.owner.login}",
|
||||
"full_name": "",
|
||||
"email": "#{project.owner.mail}",
|
||||
"avatar_url": "#{domain}/#{url_to_avatar(project.owner)}",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "#{project.owner.last_login_on}",
|
||||
"created": "#{project.owner.created_on}",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "#{project.owner.login}"
|
||||
},
|
||||
"name": "#{project.identifier}",
|
||||
"full_name": "#{project.owner.login}/#{project.identifier}",
|
||||
"description": "",
|
||||
"empty": false,
|
||||
"private": false,
|
||||
"fork": false,
|
||||
"template": false,
|
||||
"parent": nil,
|
||||
"mirror": false,
|
||||
"size": 843,
|
||||
"html_url": "#{domain}/#{project.owner.login}/#{project.identifier}",
|
||||
"ssh_url": "#{ssh_url}",
|
||||
"clone_url": "#{domain}/#{project.owner.login}/#{project.identifier}.git",
|
||||
"original_url": "#{project.repository.mirror_url}",
|
||||
"website": "",
|
||||
"stars_count": 0,
|
||||
"forks_count": 0,
|
||||
"watchers_count": 1,
|
||||
"open_issues_count": 1,
|
||||
"open_pr_counter": 0,
|
||||
"release_counter": 0,
|
||||
"default_branch": "master",
|
||||
"archived": false,
|
||||
"created_at": "#{project.created_on}",
|
||||
"updated_at": "#{project.updated_on}",
|
||||
"permissions": {
|
||||
"admin": true,
|
||||
"push": true,
|
||||
"pull": true
|
||||
},
|
||||
"has_issues": true,
|
||||
"internal_tracker": {
|
||||
"enable_time_tracker": true,
|
||||
"allow_only_contributors_to_track_time": true,
|
||||
"enable_issue_dependencies": true
|
||||
},
|
||||
"has_wiki": true,
|
||||
"has_pull_requests": true,
|
||||
"has_projects": false,
|
||||
"ignore_whitespace_conflicts": false,
|
||||
"allow_merge_commits": true,
|
||||
"allow_rebase": true,
|
||||
"allow_rebase_explicit": true,
|
||||
"allow_squash_merge": true,
|
||||
"default_merge_style": "merge",
|
||||
"avatar_url": "",
|
||||
"internal": false,
|
||||
"mirror_interval": ""
|
||||
},
|
||||
"sender": {
|
||||
"id": user.id,
|
||||
"login": "#{user.login}",
|
||||
"full_name": "",
|
||||
"email": "#{user.mail}",
|
||||
"avatar_url": "#{domain}/#{url_to_avatar(user)}",
|
||||
"language": "",
|
||||
"is_admin": false,
|
||||
"last_login": "#{user.last_login_on}",
|
||||
"created": "#{user.created_on}",
|
||||
"restricted": false,
|
||||
"active": false,
|
||||
"prohibit_login": false,
|
||||
"location": "",
|
||||
"website": "",
|
||||
"description": "",
|
||||
"visibility": "public",
|
||||
"followers_count": 0,
|
||||
"following_count": 0,
|
||||
"starred_repos_count": 0,
|
||||
"username": "#{user.login}"
|
||||
}
|
||||
}
|
||||
# puts "event_json:#{event_json.to_json}"
|
||||
begin
|
||||
url = URI("http://117.50.185.50:80")
|
||||
http = Net::HTTP.new(url.host, url.port)
|
||||
request = Net::HTTP::Post.new(url)
|
||||
request["Content-Type"] = "application/json"
|
||||
uuid = SecureRandom.uuid
|
||||
request['X-GitHub-Delivery'] = uuid
|
||||
request['X-Gitea-Delivery'] = uuid
|
||||
request['X-Gogs-Delivery'] = uuid
|
||||
request['X-GitHub-Event'] = 'issues'
|
||||
request['X-Gitea-Event'] = 'issues'
|
||||
request['X-Gogs-Event'] = 'issues'
|
||||
request.body = JSON.dump(event_json)
|
||||
|
||||
response = http.request(request)
|
||||
Rails.logger.info "issue #{issue_id} webhook event======#{response.read_body}"
|
||||
rescue Exception => e
|
||||
Rails.logger.info "issue #{issue_id} webhook event error======#{e.message}"
|
||||
puts "issue: #{issue_id} webhook event error======#{e.message}"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -15,7 +15,7 @@ class MigrateRemoteRepositoryJob < ApplicationJob
|
|||
## open jianmu devops
|
||||
project_id = repo&.project&.id
|
||||
puts "############ mirror project_id,user_id: #{project_id},#{user_id} ############"
|
||||
OpenProjectDevOpsJob.perform_later(project_id, user_id) if project_id.present? && user_id.present?
|
||||
OpenProjectDevOpsJob.set(wait: 5.seconds).perform_later(project_id, user_id) if project_id.present? && user_id.present?
|
||||
puts "############ mirror status: #{repo.mirror.status} ############"
|
||||
else
|
||||
repo&.mirror&.failed!
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
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
|
|
@ -5,6 +5,7 @@ class OpenProjectDevOpsJob < ApplicationJob
|
|||
|
||||
def perform(project_id, user_id)
|
||||
project = Project.find_by(id: project_id)
|
||||
return if project.blank?
|
||||
user = User.find_by(id: user_id)
|
||||
code = jianmu_devops_code(project, user)
|
||||
uri = URI.parse("#{jianmu_devops_url}/activate?code=#{URI.encode_www_form_component(code)}")
|
||||
|
|
|
@ -34,8 +34,8 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
operator_id, issue_id = args[0], args[1]
|
||||
operator = User.find_by_id(operator_id)
|
||||
issue = Issue.find_by_id(issue_id)
|
||||
return unless operator.present? && issue.present?
|
||||
receivers = User.where(id: issue&.assigned_to_id).where.not(id: operator&.id)
|
||||
return unless operator.present? && issue.present?
|
||||
receivers = issue&.assigners.where.not(id: operator&.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueAssigned.get_message_content(receivers, operator, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id})
|
||||
receivers.find_each do |receiver|
|
||||
|
@ -56,7 +56,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
operator = User.find_by_id(operator_id)
|
||||
issue = Issue.find_by_id(issue_id)
|
||||
return unless operator.present? && issue.present?
|
||||
receivers = User.where(id: [issue&.assigned_to_id, issue&.author_id]).where.not(id: operator&.id)
|
||||
receivers = User.where(id: issue.assigners.pluck(:id).append(issue&.author_id)).where.not(id: operator&.id)
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueChanged.get_message_content(receivers, operator, issue, change_params.symbolize_keys)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_id: issue.id, change_params: change_params.symbolize_keys})
|
||||
receivers.find_each do |receiver|
|
||||
|
@ -67,7 +67,7 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
issue_id = args[0]
|
||||
issue = Issue.find_by_id(issue_id)
|
||||
return unless issue.present?
|
||||
receivers = User.where(id: [issue&.assigned_to_id, issue&.author_id])
|
||||
receivers = User.where(id: issue.assigners.pluck(:id).append(issue&.author_id))
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueExpire.get_message_content(receivers, issue)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {issue_id: issue.id})
|
||||
receivers.find_each do |receiver|
|
||||
|
@ -78,7 +78,11 @@ class SendTemplateMessageJob < ApplicationJob
|
|||
operator_id, issue_title, issue_assigned_to_id, issue_author_id = args[0], args[1], args[2], args[3]
|
||||
operator = User.find_by_id(operator_id)
|
||||
return unless operator.present?
|
||||
receivers = User.where(id: [issue_assigned_to_id, issue_author_id]).where.not(id: operator&.id)
|
||||
if issue_assigned_to_id.is_a?(Array)
|
||||
receivers = User.where(id: issue_assigned_to_id.append(issue_author_id)).where.not(id: operator&.id)
|
||||
else
|
||||
receivers = User.where(id: [issue_assigned_to_id, issue_author_id]).where.not(id: operator&.id)
|
||||
end
|
||||
receivers_string, content, notification_url = MessageTemplate::IssueDeleted.get_message_content(receivers, operator, issue_title)
|
||||
Notice::Write::CreateService.call(receivers_string, content, notification_url, source, {operator_id: operator.id, issue_title: issue_title})
|
||||
receivers.find_each do |receiver|
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
class Blockchain
|
||||
class << self
|
||||
def blockchain_config
|
||||
blockchain_config = {}
|
||||
|
||||
begin
|
||||
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||
blockchain_config = config[:blockchain].symbolize_keys!
|
||||
raise 'blockchain config missing' if blockchain_config.blank?
|
||||
rescue => ex
|
||||
raise ex if Rails.env.production?
|
||||
|
||||
puts %Q{\033[33m [warning] blockchain config or configuration.yml missing,
|
||||
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||
blockchain_config = {}
|
||||
end
|
||||
blockchain_config
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,7 +17,7 @@
|
|||
# disk_directory :string(255)
|
||||
# attachtype :integer default("1")
|
||||
# is_public :integer default("1")
|
||||
# copy_from :integer
|
||||
# copy_from :string(255)
|
||||
# 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)
|
||||
#
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: blockchain_trades
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# project_id :integer
|
||||
# description :text(65535)
|
||||
# money :float(24)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# user_id :integer
|
||||
# state :integer
|
||||
# user_id2 :integer
|
||||
# token_num :integer
|
||||
#
|
||||
|
||||
class BlockchainTrade < ApplicationRecord
|
||||
end
|
|
@ -0,0 +1,51 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: bot
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# bot_name :string(255)
|
||||
# bot_des :text(4294967295)
|
||||
# webhook :string(255)
|
||||
# is_public :integer
|
||||
# logo :string(255)
|
||||
# state :integer
|
||||
# client_id :string(255)
|
||||
# client_secret :string(255)
|
||||
# web_url :string(255)
|
||||
# category :string(255)
|
||||
# install_num :integer default("0")
|
||||
# update_time :datetime not null
|
||||
# create_time :datetime not null
|
||||
# private_key :text(65535)
|
||||
# uid :integer
|
||||
# owner_id :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# name (bot_name) UNIQUE
|
||||
#
|
||||
|
||||
class Bot < ApplicationRecord
|
||||
self.table_name = "bot"
|
||||
|
||||
has_many :install_bots
|
||||
|
||||
def name
|
||||
self.bot_name
|
||||
end
|
||||
|
||||
def self.decode_jwt_token(token)
|
||||
decoded_token = JWT.decode token, nil, false
|
||||
return [nil, "Token已过期"] if Time.now.to_i - 60 - decoded_token[0]["exp"].to_i > 0
|
||||
bot = Bot.find_by(id: decoded_token[0]["iss"])
|
||||
return [nil, "Token不存在"] if bot.blank?
|
||||
rsa_private = OpenSSL::PKey::RSA.new(bot.private_key)
|
||||
rsa_public = rsa_private.public_key
|
||||
JWT.decode token, rsa_public, true, { algorithm: 'RS256' }
|
||||
[User.find_by(id: bot.owner_id), ""]
|
||||
rescue JWT::DecodeError
|
||||
Rails.logger.error "jwt token decode error:#{token}"
|
||||
[nil, "无效Token"]
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,20 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: install_bot
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# bot_id :integer not null
|
||||
# installer_id :integer not null
|
||||
# store_id :integer not null
|
||||
# state :integer not null
|
||||
# create_time :datetime not null
|
||||
# update_time :datetime not null
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
|
||||
class BotInstall < ApplicationRecord
|
||||
self.table_name = "install_bot"
|
||||
belongs_to :bot
|
||||
|
||||
end
|
|
@ -39,18 +39,15 @@
|
|||
# business :boolean default("0")
|
||||
# profile_completed :boolean default("0")
|
||||
# laboratory_id :integer
|
||||
# platform :string(255) default("0")
|
||||
# gitea_token :string(255)
|
||||
# gitea_uid :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# admin_visitable :boolean default("0")
|
||||
# collaborator :boolean default("0")
|
||||
# gitea_uid :integer
|
||||
# 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")
|
||||
# sponsor_description :text(65535)
|
||||
# devops_step :integer default("0")
|
||||
# award_time :datetime
|
||||
# gitea_token :string(255)
|
||||
# platform :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
@ -58,8 +55,9 @@
|
|||
# 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)
|
||||
# index_users_on_mail (mail)
|
||||
# index_users_on_login (login) UNIQUE
|
||||
# index_users_on_mail (mail) UNIQUE
|
||||
# index_users_on_phone (phone) UNIQUE
|
||||
# index_users_on_type (type)
|
||||
#
|
||||
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
# == 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
|
|
@ -194,7 +194,7 @@ module ProjectOperable
|
|||
if owner.is_a?(User)
|
||||
managers.exists?(user_id: user.id)
|
||||
elsif owner.is_a?(Organization)
|
||||
managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || owner.is_only_admin?(user.id)
|
||||
managers.exists?(user_id: user.id) || owner.is_owner?(user.id) || (owner.is_only_admin?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0)
|
||||
else
|
||||
false
|
||||
end
|
||||
|
@ -205,7 +205,7 @@ module ProjectOperable
|
|||
if owner.is_a?(User)
|
||||
developers.exists?(user_id: user.id)
|
||||
elsif owner.is_a?(Organization)
|
||||
developers.exists?(user_id: user.id) || owner.is_only_write?(user.id)
|
||||
developers.exists?(user_id: user.id) || (owner.is_only_write?(user.id) && (teams.pluck(:id) & user.teams.pluck(:id)).size > 0)
|
||||
else
|
||||
false
|
||||
end
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: edu_settings
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# value :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# description :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_edu_settings_on_name (name) UNIQUE
|
||||
#
|
||||
|
||||
# == Schema Information
|
||||
#
|
||||
# Table name: edu_settings
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# name :string(255)
|
||||
# value :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# description :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_edu_settings_on_name (name) UNIQUE
|
||||
#
|
||||
|
||||
class EduSetting < ApplicationRecord
|
||||
after_commit :expire_value_cache
|
||||
|
|
|
@ -1,24 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: public_key
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# owner_id :integer not null
|
||||
# name :string(255) not null
|
||||
# fingerprint :string(255) not null
|
||||
# content :text(65535) not null
|
||||
# mode :integer default("2"), not null
|
||||
# type :integer default("1"), not null
|
||||
# login_source_id :integer default("0"), not null
|
||||
# created_unix :integer
|
||||
# updated_unix :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# IDX_public_key_fingerprint (fingerprint)
|
||||
# IDX_public_key_owner_id (owner_id)
|
||||
#
|
||||
|
||||
class Gitea::PublicKey < Gitea::Base
|
||||
self.inheritance_column = nil # FIX The single-table inheritance mechanism failed
|
||||
# establish_connection :gitea_db
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
# type :integer
|
||||
# status :integer
|
||||
# conflicted_files :text(65535)
|
||||
# commits_ahead :integer
|
||||
# commits_behind :integer
|
||||
# changed_protected_files :text(65535)
|
||||
# issue_id :integer
|
||||
# index :integer
|
||||
# head_repo_id :integer
|
||||
|
@ -17,11 +20,6 @@
|
|||
# merged_commit_id :string(40)
|
||||
# merger_id :integer
|
||||
# merged_unix :integer
|
||||
# commits_ahead :integer
|
||||
# commits_behind :integer
|
||||
# changed_protected_files :text(65535)
|
||||
# commit_num :integer
|
||||
# changed_files :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -1,37 +1,4 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: webhook
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# repo_id :integer
|
||||
# org_id :integer
|
||||
# url :text(65535)
|
||||
# http_method :string(255)
|
||||
# content_type :integer
|
||||
# secret :text(65535)
|
||||
# events :text(65535)
|
||||
# is_active :boolean
|
||||
# meta :text(65535)
|
||||
# last_status :integer
|
||||
# created_unix :integer
|
||||
# updated_unix :integer
|
||||
# is_system_webhook :boolean default("0"), not null
|
||||
# type :string(16)
|
||||
# branch_filter :text(65535)
|
||||
# signature :text(65535)
|
||||
# is_ssl :boolean
|
||||
# hook_task_type :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# IDX_webhook_created_unix (created_unix)
|
||||
# IDX_webhook_is_active (is_active)
|
||||
# IDX_webhook_org_id (org_id)
|
||||
# IDX_webhook_repo_id (repo_id)
|
||||
# IDX_webhook_updated_unix (updated_unix)
|
||||
#
|
||||
|
||||
class Gitea::Webhook < Gitea::Base
|
||||
class Gitea::Webhook < Gitea::Base
|
||||
serialize :events, JSON
|
||||
self.inheritance_column = nil
|
||||
|
||||
|
|
|
@ -1,34 +1,6 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: hook_task
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# repo_id :integer
|
||||
# hook_id :integer
|
||||
# uuid :string(255)
|
||||
# payload_content :text(65535)
|
||||
# event_type :string(255)
|
||||
# is_delivered :boolean
|
||||
# delivered :integer
|
||||
# is_succeed :boolean
|
||||
# request_content :text(65535)
|
||||
# response_content :text(65535)
|
||||
# type :string(255)
|
||||
# url :text(65535)
|
||||
# signature :text(65535)
|
||||
# http_method :string(255)
|
||||
# content_type :integer
|
||||
# is_ssl :boolean
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# IDX_hook_task_repo_id (repo_id)
|
||||
#
|
||||
|
||||
class Gitea::WebhookTask < Gitea::Base
|
||||
class Gitea::WebhookTask < Gitea::Base
|
||||
serialize :payload_content, JSON
|
||||
serialize :request_content, JSON
|
||||
serialize :response_content, JSON
|
||||
|
||||
self.inheritance_column = nil
|
||||
|
||||
|
@ -40,7 +12,7 @@ class Gitea::WebhookTask < Gitea::Base
|
|||
|
||||
def response_content_json
|
||||
JSON.parse(response_content)
|
||||
rescue
|
||||
rescue
|
||||
{}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -33,7 +33,6 @@
|
|||
# issue_classify :string(255)
|
||||
# ref_name :string(255)
|
||||
# branch_name :string(255)
|
||||
# blockchain_token_num :integer
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
@ -70,12 +69,24 @@ class Issue < ApplicationRecord
|
|||
has_many :issue_tags, through: :issue_tags_relates
|
||||
has_many :issue_times, dependent: :destroy
|
||||
has_many :issue_depends, dependent: :destroy
|
||||
has_many :issue_assigners, dependent: :destroy
|
||||
has_many :assigners, through: :issue_assigners
|
||||
has_many :issue_participants, dependent: :destroy
|
||||
has_many :participants, through: :issue_participants
|
||||
has_many :show_participants, -> {joins(:issue_participants).where.not(issue_participants: {participant_type: "atme"}).distinct}, through: :issue_participants, source: :participant
|
||||
has_many :show_assigners, -> {joins(:issue_assigners).distinct}, through: :issue_assigners, source: :assigner
|
||||
has_many :show_issue_tags, -> {joins(:issue_tags_relates).distinct}, through: :issue_tags_relates, source: :issue_tag
|
||||
|
||||
has_many :comment_journals, -> {where.not(notes: nil)}, class_name: "Journal", :as => :journalized
|
||||
has_many :operate_journals, -> {where(notes: nil)}, class_name: "Journal", :as => :journalized
|
||||
|
||||
scope :issue_includes, ->{includes(:user)}
|
||||
scope :issue_many_includes, ->{includes(journals: :user)}
|
||||
scope :issue_issue, ->{where(issue_classify: [nil,"issue"])}
|
||||
scope :issue_pull_request, ->{where(issue_classify: "pull_request")}
|
||||
scope :issue_index_includes, ->{includes(:tracker, :priority, :version, :issue_status, :journals,:issue_tags,user: :user_extension)}
|
||||
scope :closed, ->{where(status_id: 5)}
|
||||
scope :opened, ->{where.not(status_id: 5)}
|
||||
after_create :incre_project_common, :incre_user_statistic, :incre_platform_statistic
|
||||
after_save :change_versions_count, :send_update_message_to_notice_system
|
||||
after_destroy :update_closed_issues_count_in_project!, :decre_project_common, :decre_user_statistic, :decre_platform_statistic
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: issue_assigners
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# issue_id :integer
|
||||
# assigner_id :integer
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_issue_assigners_on_assigner_id (assigner_id)
|
||||
# index_issue_assigners_on_issue_id (issue_id)
|
||||
#
|
||||
|
||||
class IssueAssigner < ApplicationRecord
|
||||
belongs_to :issue
|
||||
belongs_to :assigner, class_name: "User"
|
||||
end
|
|
@ -0,0 +1,9 @@
|
|||
class IssueParticipant < ApplicationRecord
|
||||
|
||||
belongs_to :issue
|
||||
belongs_to :participant, class_name: "User"
|
||||
|
||||
enum participant_type: {"authored": 0, "assigned": 1, "commented": 2, "edited": 3, "atme": 4}
|
||||
|
||||
|
||||
end
|
|
@ -15,4 +15,21 @@
|
|||
|
||||
class IssuePriority < ApplicationRecord
|
||||
has_many :issues
|
||||
|
||||
def self.init_data
|
||||
map = {
|
||||
"1" => "低",
|
||||
"2" => "正常",
|
||||
"3" => "高",
|
||||
"4" => "紧急"
|
||||
}
|
||||
IssuePriority.order(id: :asc).each do |prty|
|
||||
if map["#{prty.id}"] == prty.name
|
||||
IssuePriority.find_or_create_by(id: prty.id, name: prty.name)
|
||||
else
|
||||
Issue.where(priority_id: prty.id).each{|i| i.update_column(:priority_id, 2)}
|
||||
prty.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,10 +20,28 @@ class IssueStatus < ApplicationRecord
|
|||
ADD = 1
|
||||
SOLVING = 2
|
||||
SOLVED = 3
|
||||
FEEDBACK = 4
|
||||
# FEEDBACK = 4
|
||||
CLOSED = 5
|
||||
REJECTED = 6
|
||||
|
||||
has_many :issues
|
||||
belongs_to :project, optional: true
|
||||
|
||||
def self.init_data
|
||||
map = {
|
||||
"1" => "新增",
|
||||
"2" => "正在解决",
|
||||
"3" => "已解决",
|
||||
"5" => "关闭",
|
||||
"6" => "拒绝"
|
||||
}
|
||||
IssueStatus.order(id: :asc).each do |stat|
|
||||
if map["#{stat.id}"] == stat.name
|
||||
IssueStatus.find_or_create_by(id: stat.id, name: stat.name)
|
||||
else
|
||||
Issue.where(status_id: stat.id).each{|i| i.update_column(:status_id, 1)}
|
||||
stat.destroy!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,6 +23,34 @@ class IssueTag < ApplicationRecord
|
|||
|
||||
has_many :issue_tags_relates, dependent: :destroy
|
||||
has_many :issues, through: :issue_tags_relates
|
||||
has_many :issue_issues, -> {where(issue_classify: [nil,"issue"])}, source: :issue, through: :issue_tags_relates
|
||||
has_many :pull_request_issues, -> {where(issue_classify: "pull_request")}, source: :issue, through: :issue_tags_relates
|
||||
belongs_to :project, optional: true, counter_cache: true
|
||||
belongs_to :user, optional: true
|
||||
|
||||
def self.init_data(project_id)
|
||||
data = [
|
||||
["缺陷", "表示项目存在问题", "#d92d4c"],
|
||||
["功能", "表示新功能申请", "#ee955a"],
|
||||
["疑问", "表示存在的问题", "#2d6ddc"],
|
||||
["支持", "表示特定功能或特定需求", "#019549"],
|
||||
["任务", "表示需要分配的任务", "#c1a30d"],
|
||||
["协助", "表示需要社区用户协助", "#2a0dc1"],
|
||||
["搁置", "表示此问题暂时不会继续处理", "#892794"],
|
||||
["文档", "表示文档材料补充", "#9ed600"],
|
||||
["测试", "表示需要测试的需求", "#2897b9"],
|
||||
["重复", "表示已存在类似的疑修", "#bb5332"]
|
||||
]
|
||||
data.each do |item|
|
||||
next if IssueTag.exists?(project_id: project_id, name: item[0])
|
||||
IssueTag.create!(project_id: project_id, name: item[0], description: item[1], color: item[2])
|
||||
end
|
||||
$redis_cache.hset("project_init_issue_tags", project_id, 1)
|
||||
end
|
||||
|
||||
def reset_counter_field
|
||||
self.update_column(:issues_count, issue_issues.size)
|
||||
self.update_column(:pull_requests_count, pull_request_issues.size)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -15,5 +15,29 @@
|
|||
|
||||
class IssueTagsRelate < ApplicationRecord
|
||||
belongs_to :issue
|
||||
belongs_to :issue_tag, counter_cache: :issues_count
|
||||
belongs_to :issue_tag
|
||||
|
||||
after_create :increment_issue_tags_counter_cache
|
||||
after_destroy :decrement_issue_tags_counter_cache
|
||||
|
||||
def increment_issue_tags_counter_cache
|
||||
Rails.logger.info "11111"
|
||||
Rails.logger.info self.issue.issue_classify
|
||||
|
||||
if self.issue.issue_classify == "issue"
|
||||
IssueTag.increment_counter :issues_count, issue_tag_id
|
||||
else
|
||||
IssueTag.increment_counter :pull_requests_count, issue_tag_id
|
||||
end
|
||||
end
|
||||
|
||||
def decrement_issue_tags_counter_cache
|
||||
Rails.logger.info "2222222"
|
||||
Rails.logger.info self.issue.issue_classify
|
||||
if self.issue.issue_classify == "issue"
|
||||
IssueTag.decrement_counter :issues_count, issue_tag_id
|
||||
else
|
||||
IssueTag.decrement_counter :pull_requests_count, issue_tag_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,9 +40,12 @@ class Journal < ApplicationRecord
|
|||
belongs_to :journalized, polymorphic: true
|
||||
belongs_to :review, optional: true
|
||||
belongs_to :resolveer, class_name: 'User', foreign_key: :resolveer_id, optional: true
|
||||
belongs_to :parent_journal, class_name: 'Journal', foreign_key: :parent_id, optional: true, counter_cache: :comments_count
|
||||
belongs_to :reply_journal, class_name: 'Journal', foreign_key: :reply_id, optional: true
|
||||
has_many :journal_details, :dependent => :delete_all
|
||||
has_many :attachments, as: :container, dependent: :destroy
|
||||
has_many :children_journals, class_name: 'Journal', foreign_key: :parent_id
|
||||
has_many :first_ten_children_journals, -> { order(created_on: :asc).limit(10)}, class_name: 'Journal', foreign_key: :parent_id
|
||||
has_many :children_journals, class_name: 'Journal', foreign_key: :parent_id, dependent: :destroy
|
||||
|
||||
scope :journal_includes, ->{includes(:user, :journal_details, :attachments)}
|
||||
scope :parent_journals, ->{where(parent_id: nil)}
|
||||
|
@ -54,6 +57,81 @@ class Journal < ApplicationRecord
|
|||
self.notes.blank? && self.journal_details.present?
|
||||
end
|
||||
|
||||
def operate_content
|
||||
content = ""
|
||||
detail = self.journal_details.take
|
||||
case detail.property
|
||||
when 'issue'
|
||||
return "创建了<b>疑修</b>"
|
||||
when 'attachment'
|
||||
old_value = Attachment.where(id: detail.old_value.split(",")).pluck(:filename).join("、")
|
||||
new_value = Attachment.where(id: detail.value.split(",")).pluck(:filename).join("、")
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "添加了<b>#{new_value}</b>附件"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "将附件由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
when 'issue_tag'
|
||||
old_value = IssueTag.where(id: detail.old_value.split(",")).pluck(:name).join("、")
|
||||
new_value = IssueTag.where(id: detail.value.split(",")).pluck(:name).join("、")
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "添加了<b>#{new_value}</b>标记"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "将标记由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
when 'assigner'
|
||||
old_value = User.where(id: detail.old_value.split(",")).pluck(:nickname).join("、")
|
||||
new_value = User.where(id: detail.value.split(",")).pluck(:nickname).join("、")
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "添加负责人<b>#{new_value}</b>"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "将负责人由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
when 'attr'
|
||||
content = "将"
|
||||
case detail.prop_key
|
||||
when 'subject'
|
||||
return "修改了<b>标题</b>"
|
||||
when 'description'
|
||||
return "修改了<b>描述</b>"
|
||||
when 'status_id'
|
||||
old_value = IssueStatus.find_by_id(detail.old_value)&.name
|
||||
new_value = IssueStatus.find_by_id(detail.value)&.name
|
||||
content += "状态"
|
||||
when 'priority_id'
|
||||
old_value = IssuePriority.find_by_id(detail.old_value)&.name
|
||||
new_value = IssuePriority.find_by_id(detail.value)&.name
|
||||
content += "优先级"
|
||||
when 'fixed_version_id'
|
||||
old_value = Version.find_by_id(detail.old_value)&.name
|
||||
new_value = Version.find_by_id(detail.value)&.name
|
||||
content += "里程碑"
|
||||
when 'branch_name'
|
||||
old_value = detail.old_value
|
||||
new_value = detail.value
|
||||
content += "关联分支"
|
||||
when 'start_date'
|
||||
old_value = detail.old_value
|
||||
new_value = detail.value
|
||||
content += "开始日期"
|
||||
when 'due_date'
|
||||
old_value = detail.old_value
|
||||
new_value = detail.value
|
||||
content += "结束日期"
|
||||
end
|
||||
if old_value.nil? || old_value.blank?
|
||||
content += "设置为<b>#{new_value}</b>"
|
||||
else
|
||||
new_value = "无" if new_value.blank?
|
||||
content += "由<b>#{old_value}</b>更改为<b>#{new_value}</b>"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def journal_content
|
||||
send_details = []
|
||||
if self.is_journal_detail?
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
# sync_course :boolean default("0")
|
||||
# sync_subject :boolean default("0")
|
||||
# sync_shixun :boolean default("0")
|
||||
# is_local :boolean default("0")
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -26,7 +26,7 @@ class MessageTemplate::IssueAssigned < MessageTemplate
|
|||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueAssigned.get_message_content [ERROR] #{e}")
|
||||
|
@ -52,7 +52,7 @@ class MessageTemplate::IssueAssigned < MessageTemplate
|
|||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{id}', issue&.project_issues_index.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
|
|
|
@ -20,7 +20,7 @@ class MessageTemplate::IssueAssignerExpire < MessageTemplate
|
|||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueAssignerExpire.get_message_content [ERROR] #{e}")
|
||||
|
|
|
@ -20,7 +20,7 @@ class MessageTemplate::IssueAtme < MessageTemplate
|
|||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{nickname}', operator&.real_name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
Rails.logger.info("MessageTemplate::IssueAtme.get_message_content [ERROR] #{e}")
|
||||
|
|
|
@ -27,20 +27,20 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = MessageTemplate::IssueChanged.sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
assigner1 = User.where(id: change_params[:assigned_to_id][0])
|
||||
assigner2 = User.where(id: change_params[:assigned_to_id][1])
|
||||
if change_count > 1
|
||||
content.sub!('{ifassigner}', '<br/>')
|
||||
else
|
||||
content.sub!('{ifassigner}', '')
|
||||
end
|
||||
content.sub!('{endassigner}', '')
|
||||
content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
|
||||
content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
|
||||
content.gsub!('{assigner1}', assigner1.present? ? assigner1.map{|a| a&.real_name}.join("、") : '未指派成员')
|
||||
content.gsub!('{assigner2}', assigner2.present? ? assigner2.map{|a| a&.real_name}.join("、") : '未指派成员')
|
||||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
|
@ -205,20 +205,20 @@ class MessageTemplate::IssueChanged < MessageTemplate
|
|||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{id}', issue&.project_issues_index.to_s)
|
||||
change_count = change_params.keys.size
|
||||
# 疑修负责人修改
|
||||
if change_params[:assigned_to_id].present?
|
||||
assigner1 = User.find_by_id(change_params[:assigned_to_id][0])
|
||||
assigner2 = User.find_by_id(change_params[:assigned_to_id][1])
|
||||
assigner1 = User.where(id: change_params[:assigned_to_id][0])
|
||||
assigner2 = User.where(id: change_params[:assigned_to_id][1])
|
||||
if change_count > 1
|
||||
content.sub!('{ifassigner}', '<br/>')
|
||||
else
|
||||
content.sub!('{ifassigner}', '')
|
||||
end
|
||||
content.sub!('{endassigner}', '')
|
||||
content.gsub!('{assigner1}', assigner1.present? ? assigner1&.real_name : '未指派成员')
|
||||
content.gsub!('{assigner2}', assigner2.present? ? assigner2&.real_name : '未指派成员')
|
||||
content.gsub!('{assigner1}', assigner1.present? ? assigner1.map{|a| a&.real_name}.join("、") : '未指派成员')
|
||||
content.gsub!('{assigner2}', assigner2.present? ? assigner2.map{|a| a&.real_name}.join("、") : '未指派成员')
|
||||
else
|
||||
content.gsub!(/({ifassigner})(.*)({endassigner})/, '')
|
||||
end
|
||||
|
|
|
@ -1,17 +1,3 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: message_templates
|
||||
#
|
||||
# id :integer not null, primary key
|
||||
# type :string(255)
|
||||
# sys_notice :text(65535)
|
||||
# email :text(65535)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
# notification_url :string(255)
|
||||
# email_title :string(255)
|
||||
#
|
||||
|
||||
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
||||
|
||||
end
|
||||
end
|
|
@ -28,7 +28,7 @@ class MessageTemplate::IssueExpire < MessageTemplate
|
|||
project = issue&.project
|
||||
owner = project&.owner
|
||||
content = sys_notice.gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
|
@ -53,7 +53,7 @@ class MessageTemplate::IssueExpire < MessageTemplate
|
|||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{baseurl}', base_url)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{id}', issue&.project_issues_index.to_s)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
return receiver&.mail, title, content
|
||||
|
|
|
@ -27,7 +27,7 @@ class MessageTemplate::ProjectIssue < MessageTemplate
|
|||
receivers = managers + followers
|
||||
return '', '', '' if receivers.blank?
|
||||
content = sys_notice.gsub('{nickname1}', operator&.real_name).gsub('{nickname2}', owner&.real_name).gsub('{repository}', project&.name).gsub('{title}', issue&.subject)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.id.to_s)
|
||||
url = notification_url.gsub('{owner}', owner&.login).gsub('{identifier}', project&.identifier).gsub('{id}', issue&.project_issues_index.to_s)
|
||||
|
||||
return receivers_string(receivers), content, url
|
||||
rescue => e
|
||||
|
@ -54,7 +54,7 @@ class MessageTemplate::ProjectIssue < MessageTemplate
|
|||
content.gsub!('{repository}', project&.name)
|
||||
content.gsub!('{login2}', owner&.login)
|
||||
content.gsub!('{identifier}', project&.identifier)
|
||||
content.gsub!('{id}', issue&.id.to_s)
|
||||
content.gsub!('{id}', issue&.project_issues_index.to_s)
|
||||
content.gsub!('{title}', issue&.subject)
|
||||
content.gsub!('{platform}', PLATFORM)
|
||||
|
||||
|
|
|
@ -39,18 +39,15 @@
|
|||
# business :boolean default("0")
|
||||
# profile_completed :boolean default("0")
|
||||
# laboratory_id :integer
|
||||
# platform :string(255) default("0")
|
||||
# gitea_token :string(255)
|
||||
# gitea_uid :integer
|
||||
# is_shixun_marker :boolean default("0")
|
||||
# admin_visitable :boolean default("0")
|
||||
# collaborator :boolean default("0")
|
||||
# gitea_uid :integer
|
||||
# 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")
|
||||
# sponsor_description :text(65535)
|
||||
# devops_step :integer default("0")
|
||||
# award_time :datetime
|
||||
# gitea_token :string(255)
|
||||
# platform :string(255)
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
@ -58,8 +55,9 @@
|
|||
# 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)
|
||||
# index_users_on_mail (mail)
|
||||
# index_users_on_login (login) UNIQUE
|
||||
# index_users_on_mail (mail) UNIQUE
|
||||
# index_users_on_phone (phone) UNIQUE
|
||||
# index_users_on_type (type)
|
||||
#
|
||||
|
||||
|
@ -146,6 +144,18 @@ class Organization < Owner
|
|||
end
|
||||
end
|
||||
|
||||
def projects_count
|
||||
Project.where( user_id: self.id).count
|
||||
end
|
||||
|
||||
def teams_count
|
||||
teams.count
|
||||
end
|
||||
|
||||
def organization_users_count
|
||||
organization_users.count
|
||||
end
|
||||
|
||||
def real_name
|
||||
name = lastname + firstname
|
||||
name = name.blank? ? (nickname.blank? ? login : nickname) : name
|
||||
|
|
|
@ -69,6 +69,8 @@ class Owner < ApplicationRecord
|
|||
has_many :applied_transfer_projects, dependent: :destroy
|
||||
|
||||
scope :like, lambda { |keywords|
|
||||
# 表情处理
|
||||
keywords = keywords.to_s.each_char.select { |c| c.bytes.first < 240 }.join('')
|
||||
sql = "CONCAT(lastname, firstname) LIKE :search OR nickname LIKE :search OR login LIKE :search "
|
||||
where(sql, :search => "%#{keywords.strip}%") unless keywords.blank?
|
||||
}
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
# == 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
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue