Compare commits

..

9 Commits

Author SHA1 Message Date
anph d76d85b8fb change 2023-10-07 15:09:30 +08:00
anph 82907e001f update 2023-09-22 21:10:33 +08:00
anph b8f9deb1ed GLCC 2023-08-15 00:15:10 +08:00
jasder 4fa10a3683 Merge pull request 'fix mege develop' (#248) from develop into master 2021-11-14 20:39:31 +08:00
jasder cb11a5c8e9 发布v3.1.1版本
* FIX 修复pulls、issues 搜索数量统计问题
* FIX 解决在线创建文件错误提示信息不准确的问题
* FIX table name bug
* FIX 解决applied_projects相关表操作的问题
* FIX 解决排序参数的判断预防SQL注入
* FIX 项目导航栏数量改为开启中的数量
* FIX 解决项目邀请码的索引查询问题
* FIX FIX get readme file bug
* FIX sql attack
* FIX projects load by invite code slowly
2021-06-18 17:09:57 +08:00
jasder c5d73b7cf8 v3.1.0
* 改版升级个人主页
* 修复bug
* 更改license
2021-06-09 09:52:57 +08:00
jasder 8a10a183e0 Merge branch 'develop' 2021-05-24 10:18:03 +08:00
jasder 6d1bcabd51 Merge branch 'master' of https://git.trustie.net/jasder/forgeplus 2021-05-24 10:10:24 +08:00
jasder 86f03ffafc Merge OK 2021-05-08 17:46:22 +08:00
576 changed files with 7035 additions and 23692 deletions

View File

@ -23,7 +23,7 @@
* Fix 版本库中附件下载400(#51625) * Fix 版本库中附件下载400(#51625)
* Fix loading页面优化(#51588) * Fix loading页面优化(#51588)
* Fix 提交详情页面优化(#51577) * Fix 提交详情页面优化(#51577)
* Fix 修复修复制功能(#51569) * Fix 修复修复制功能(#51569)
* Fix 修复新建发行版用户信息显示错误的问题(#51665) * Fix 修复新建发行版用户信息显示错误的问题(#51665)
* Fix 修复查看文件详细信息报错的问题(#51561) * Fix 修复查看文件详细信息报错的问题(#51561)
* Fix 修复提交记录中时间显示格式问题(#51526) * Fix 修复提交记录中时间显示格式问题(#51526)
@ -62,7 +62,7 @@
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08 ## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
* BUGFIXES * BUGFIXES
* Fix 解决修标题过长导致的排版问题(45469) * Fix 解决修标题过长导致的排版问题(45469)
* Fix 解决合并请求详情页面排版错误的问题(45457) * Fix 解决合并请求详情页面排版错误的问题(45457)
* FIX 解决转移仓库界面专有名词描述错误的问题(45455) * FIX 解决转移仓库界面专有名词描述错误的问题(45455)
* Fix 解决markdown格式文件自动生成数字排序的问题(45454) * Fix 解决markdown格式文件自动生成数字排序的问题(45454)

16
Gemfile
View File

@ -1,5 +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" } git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '~> 5.2.0' gem 'rails', '~> 5.2.0'
@ -102,7 +101,6 @@ gem 'rails-i18n', '~> 5.1'
gem 'sidekiq' gem 'sidekiq'
gem 'sinatra' gem 'sinatra'
gem "sidekiq-cron", "~> 1.1" gem "sidekiq-cron", "~> 1.1"
gem 'sidekiq-failures'
# batch insert # batch insert
gem 'bulk_insert' gem 'bulk_insert'
@ -120,10 +118,6 @@ gem 'deep_cloneable', '~> 3.0.0'
# oauth2 # oauth2
gem 'omniauth', '~> 1.9.0' gem 'omniauth', '~> 1.9.0'
gem 'omniauth-oauth2', '~> 1.6.0' gem 'omniauth-oauth2', '~> 1.6.0'
gem "omniauth-github"
gem "omniauth-rails_csrf_protection"
gem 'omniauth-gitee', '~> 1.0.0'
gem "omniauth-wechat-oauth2"
# global var # global var
gem 'request_store' gem 'request_store'
@ -134,11 +128,3 @@ gem 'harmonious_dictionary', '~> 0.0.1'
gem 'parallel', '~> 1.19', '>= 1.19.1' gem 'parallel', '~> 1.19', '>= 1.19.1'
gem 'letter_avatar' gem 'letter_avatar'
gem 'jwt'
gem 'doorkeeper'
gem 'doorkeeper-jwt'
gem 'gitea-client', '~> 0.10.6'

View File

@ -106,10 +106,6 @@ GEM
activerecord (>= 3.1.0, < 7) activerecord (>= 3.1.0, < 7)
diff-lcs (1.3) diff-lcs (1.3)
diffy (3.3.0) diffy (3.3.0)
doorkeeper (5.5.1)
railties (>= 5)
doorkeeper-jwt (0.4.1)
jwt (>= 2.1)
e2mmap (0.1.0) e2mmap (0.1.0)
elasticsearch (7.5.0) elasticsearch (7.5.0)
elasticsearch-api (= 7.5.0) elasticsearch-api (= 7.5.0)
@ -454,8 +450,6 @@ DEPENDENCIES
chromedriver-helper chromedriver-helper
deep_cloneable (~> 3.0.0) deep_cloneable (~> 3.0.0)
diffy diffy
doorkeeper
doorkeeper-jwt
enumerize enumerize
faraday (~> 0.15.4) faraday (~> 0.15.4)
font-awesome-sass (= 4.7.0) font-awesome-sass (= 4.7.0)
@ -464,7 +458,6 @@ DEPENDENCIES
harmonious_dictionary (~> 0.0.1) harmonious_dictionary (~> 0.0.1)
jbuilder (~> 2.5) jbuilder (~> 2.5)
jquery-rails jquery-rails
jwt
kaminari (~> 1.1, >= 1.1.1) kaminari (~> 1.1, >= 1.1.1)
letter_avatar letter_avatar
listen (>= 3.0.5, < 3.2) listen (>= 3.0.5, < 3.2)

View File

@ -14,7 +14,6 @@
//= require bootstrap-datepicker //= require bootstrap-datepicker
//= require bootstrap-datetimepicker //= require bootstrap-datetimepicker
//= require bootstrap.viewer //= require bootstrap.viewer
//= require bootstrap/bootstrap-toggle
//= require jquery.mloading //= require jquery.mloading
//= require jquery-confirm.min //= require jquery-confirm.min
//= require common //= require common

View File

@ -1,180 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function ($) {
'use strict';
// TOGGLE PUBLIC CLASS DEFINITION
// ==============================
var Toggle = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, this.defaults(), options)
this.render()
}
Toggle.VERSION = '2.2.0'
Toggle.DEFAULTS = {
on: 'On',
off: 'Off',
onstyle: 'primary',
offstyle: 'default',
size: 'normal',
style: '',
width: null,
height: null
}
Toggle.prototype.defaults = function() {
return {
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
}
}
Toggle.prototype.render = function () {
this._onstyle = 'btn-' + this.options.onstyle
this._offstyle = 'btn-' + this.options.offstyle
var size = this.options.size === 'large' ? 'btn-lg'
: this.options.size === 'small' ? 'btn-sm'
: this.options.size === 'mini' ? 'btn-xs'
: ''
var $toggleOn = $('<label class="btn">').html(this.options.on)
.addClass(this._onstyle + ' ' + size)
var $toggleOff = $('<label class="btn">').html(this.options.off)
.addClass(this._offstyle + ' ' + size + ' active')
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
.addClass(size)
var $toggleGroup = $('<div class="toggle-group">')
.append($toggleOn, $toggleOff, $toggleHandle)
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
.addClass(size).addClass(this.options.style)
this.$element.wrap($toggle)
$.extend(this, {
$toggle: this.$element.parent(),
$toggleOn: $toggleOn,
$toggleOff: $toggleOff,
$toggleGroup: $toggleGroup
})
this.$toggle.append($toggleGroup)
var width = this.options.width || Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth())+($toggleHandle.outerWidth()/2)
var height = this.options.height || Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())
$toggleOn.addClass('toggle-on')
$toggleOff.addClass('toggle-off')
this.$toggle.css({ width: width, height: height })
if (this.options.height) {
$toggleOn.css('line-height', $toggleOn.height() + 'px')
$toggleOff.css('line-height', $toggleOff.height() + 'px')
}
this.update(true)
this.trigger(true)
}
Toggle.prototype.toggle = function () {
if (this.$element.prop('checked')) this.off()
else this.on()
}
Toggle.prototype.on = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
this.$element.prop('checked', true)
if (!silent) this.trigger()
}
Toggle.prototype.off = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
this.$element.prop('checked', false)
if (!silent) this.trigger()
}
Toggle.prototype.enable = function () {
this.$toggle.removeAttr('disabled')
this.$element.prop('disabled', false)
}
Toggle.prototype.disable = function () {
this.$toggle.attr('disabled', 'disabled')
this.$element.prop('disabled', true)
}
Toggle.prototype.update = function (silent) {
if (this.$element.prop('disabled')) this.disable()
else this.enable()
if (this.$element.prop('checked')) this.on(silent)
else this.off(silent)
}
Toggle.prototype.trigger = function (silent) {
this.$element.off('change.bs.toggle')
if (!silent) this.$element.change()
this.$element.on('change.bs.toggle', $.proxy(function() {
this.update()
}, this))
}
Toggle.prototype.destroy = function() {
this.$element.off('change.bs.toggle')
this.$toggleGroup.remove()
this.$element.removeData('bs.toggle')
this.$element.unwrap()
}
// TOGGLE PLUGIN DEFINITION
// ========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.toggle')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
if (typeof option == 'string' && data[option]) data[option]()
})
}
var old = $.fn.bootstrapToggle
$.fn.bootstrapToggle = Plugin
$.fn.bootstrapToggle.Constructor = Toggle
// TOGGLE NO CONFLICT
// ==================
$.fn.toggle.noConflict = function () {
$.fn.bootstrapToggle = old
return this
}
// TOGGLE DATA-API
// ===============
$(function() {
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
})
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
var $checkbox = $(this).find('input[type=checkbox]')
$checkbox.bootstrapToggle('toggle')
e.preventDefault()
})
}(jQuery);

View File

@ -1,9 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-lg":"small"===this.options.size?"btn-sm":"mini"===this.options.size?"btn-xs":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.outerWidth(),d.outerWidth())+e.outerWidth()/2,i=this.options.height||Math.max(c.outerHeight(),d.outerHeight());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
//# sourceMappingURL=bootstrap-toggle.min.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"bootstrap-toggle.min.js","sources":["bootstrap-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","outerHeight","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,SAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,SACV,SAAtBjB,KAAKI,QAAQa,KAAkB,SAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUa,aAAcV,EAAWU,cAAeT,EAAcS,aAAa,EACpHlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUc,cAAeX,EAAWW,cACjFd,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQQ,KAAMrB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUe,IAAI,cAAef,EAAUL,SAAW,MAClDQ,EAAWY,IAAI,cAAeZ,EAAWR,SAAW,OAErDpB,KAAKyC,QAAO,GACZzC,KAAK0C,SAAQ,IAGdrC,EAAOgB,UAAUsB,OAAS,WACrB3C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU+B,GAC/B,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUP,IAAM,SAAU8B,GAChC,MAAI5C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQa,YAAY7C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBW,GAAQ5C,KAAK0C,aAGnBrC,EAAOgB,UAAUyB,OAAS,WACzB9C,KAAKgC,QAAQe,WAAW,YACxB/C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU2B,QAAU,WAC1BhD,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUoB,OAAS,SAAUG,GAC/B5C,KAAKO,SAAS0B,KAAK,YAAajC,KAAKgD,UACpChD,KAAK8C,SACN9C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG+B,GACtC5C,KAAKc,IAAI8B,IAGfvC,EAAOgB,UAAUqB,QAAU,SAAUE,GACpC5C,KAAKO,SAASO,IAAI,oBACb8B,GAAQ5C,KAAKO,SAAS0C,SAC3BjD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEqD,MAAM,WAC5ClD,KAAKyC,UACHzC,QAGJK,EAAOgB,UAAU8B,QAAU,WAC1BnD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAasB,SAClBpD,KAAKO,SAAS8C,WAAW,aACzBrD,KAAKO,SAAS+C,SAiBf,IAAIC,GAAM1D,EAAE2D,GAAGC,eAEf5D,GAAE2D,GAAGC,gBAA8B3D,EACnCD,EAAE2D,GAAGC,gBAAgBC,YAAcrD,EAKnCR,EAAE2D,GAAGb,OAAOgB,WAAa,WAExB,MADA9D,GAAE2D,GAAGC,gBAAkBF,EAChBvD,MAMRH,EAAE,WACDA,EAAE,6CAA6C4D,oBAGhD5D,EAAE+D,UAAU/C,GAAG,kBAAmB,2BAA4B,SAASgD,GACtE,GAAIC,GAAYjE,EAAEG,MAAM+D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}

View File

@ -1,180 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function ($) {
'use strict';
// TOGGLE PUBLIC CLASS DEFINITION
// ==============================
var Toggle = function (element, options) {
this.$element = $(element)
this.options = $.extend({}, this.defaults(), options)
this.render()
}
Toggle.VERSION = '2.2.0'
Toggle.DEFAULTS = {
on: 'On',
off: 'Off',
onstyle: 'primary',
offstyle: 'default',
size: 'normal',
style: '',
width: null,
height: null
}
Toggle.prototype.defaults = function() {
return {
on: this.$element.attr('data-on') || Toggle.DEFAULTS.on,
off: this.$element.attr('data-off') || Toggle.DEFAULTS.off,
onstyle: this.$element.attr('data-onstyle') || Toggle.DEFAULTS.onstyle,
offstyle: this.$element.attr('data-offstyle') || Toggle.DEFAULTS.offstyle,
size: this.$element.attr('data-size') || Toggle.DEFAULTS.size,
style: this.$element.attr('data-style') || Toggle.DEFAULTS.style,
width: this.$element.attr('data-width') || Toggle.DEFAULTS.width,
height: this.$element.attr('data-height') || Toggle.DEFAULTS.height
}
}
Toggle.prototype.render = function () {
this._onstyle = 'btn-' + this.options.onstyle
this._offstyle = 'btn-' + this.options.offstyle
var size = this.options.size === 'large' ? 'btn-large'
: this.options.size === 'small' ? 'btn-small'
: this.options.size === 'mini' ? 'btn-mini'
: ''
var $toggleOn = $('<label class="btn">').html(this.options.on)
.addClass(this._onstyle + ' ' + size)
var $toggleOff = $('<label class="btn">').html(this.options.off)
.addClass(this._offstyle + ' ' + size + ' active')
var $toggleHandle = $('<span class="toggle-handle btn btn-default">')
.addClass(size)
var $toggleGroup = $('<div class="toggle-group">')
.append($toggleOn, $toggleOff, $toggleHandle)
var $toggle = $('<div class="toggle btn" data-toggle="toggle">')
.addClass( this.$element.prop('checked') ? this._onstyle : this._offstyle+' off' )
.addClass(size).addClass(this.options.style)
this.$element.wrap($toggle)
$.extend(this, {
$toggle: this.$element.parent(),
$toggleOn: $toggleOn,
$toggleOff: $toggleOff,
$toggleGroup: $toggleGroup
})
this.$toggle.append($toggleGroup)
var width = this.options.width || Math.max($toggleOn.width(), $toggleOff.width())+($toggleHandle.outerWidth()/2)
var height = this.options.height || Math.max($toggleOn.height(), $toggleOff.height())
$toggleOn.addClass('toggle-on')
$toggleOff.addClass('toggle-off')
this.$toggle.css({ width: width, height: height })
if (this.options.height) {
$toggleOn.css('line-height', $toggleOn.height() + 'px')
$toggleOff.css('line-height', $toggleOff.height() + 'px')
}
this.update(true)
this.trigger(true)
}
Toggle.prototype.toggle = function () {
if (this.$element.prop('checked')) this.off()
else this.on()
}
Toggle.prototype.on = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._offstyle + ' off').addClass(this._onstyle)
this.$element.prop('checked', true)
if (!silent) this.trigger()
}
Toggle.prototype.off = function (silent) {
if (this.$element.prop('disabled')) return false
this.$toggle.removeClass(this._onstyle).addClass(this._offstyle + ' off')
this.$element.prop('checked', false)
if (!silent) this.trigger()
}
Toggle.prototype.enable = function () {
this.$toggle.removeAttr('disabled')
this.$element.prop('disabled', false)
}
Toggle.prototype.disable = function () {
this.$toggle.attr('disabled', 'disabled')
this.$element.prop('disabled', true)
}
Toggle.prototype.update = function (silent) {
if (this.$element.prop('disabled')) this.disable()
else this.enable()
if (this.$element.prop('checked')) this.on(silent)
else this.off(silent)
}
Toggle.prototype.trigger = function (silent) {
this.$element.off('change.bs.toggle')
if (!silent) this.$element.change()
this.$element.on('change.bs.toggle', $.proxy(function() {
this.update()
}, this))
}
Toggle.prototype.destroy = function() {
this.$element.off('change.bs.toggle')
this.$toggleGroup.remove()
this.$element.removeData('bs.toggle')
this.$element.unwrap()
}
// TOGGLE PLUGIN DEFINITION
// ========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.toggle')
var options = typeof option == 'object' && option
if (!data) $this.data('bs.toggle', (data = new Toggle(this, options)))
if (typeof option == 'string' && data[option]) data[option]()
})
}
var old = $.fn.bootstrapToggle
$.fn.bootstrapToggle = Plugin
$.fn.bootstrapToggle.Constructor = Toggle
// TOGGLE NO CONFLICT
// ==================
$.fn.toggle.noConflict = function () {
$.fn.bootstrapToggle = old
return this
}
// TOGGLE DATA-API
// ===============
$(function() {
$('input[type=checkbox][data-toggle^=toggle]').bootstrapToggle()
})
$(document).on('click.bs.toggle', 'div[data-toggle^=toggle]', function(e) {
var $checkbox = $(this).find('input[type=checkbox]')
$checkbox.bootstrapToggle('toggle')
e.preventDefault()
})
}(jQuery);

View File

@ -1,9 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.js v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.toggle"),f="object"==typeof b&&b;e||d.data("bs.toggle",e=new c(this,f)),"string"==typeof b&&e[b]&&e[b]()})}var c=function(b,c){this.$element=a(b),this.options=a.extend({},this.defaults(),c),this.render()};c.VERSION="2.2.0",c.DEFAULTS={on:"On",off:"Off",onstyle:"primary",offstyle:"default",size:"normal",style:"",width:null,height:null},c.prototype.defaults=function(){return{on:this.$element.attr("data-on")||c.DEFAULTS.on,off:this.$element.attr("data-off")||c.DEFAULTS.off,onstyle:this.$element.attr("data-onstyle")||c.DEFAULTS.onstyle,offstyle:this.$element.attr("data-offstyle")||c.DEFAULTS.offstyle,size:this.$element.attr("data-size")||c.DEFAULTS.size,style:this.$element.attr("data-style")||c.DEFAULTS.style,width:this.$element.attr("data-width")||c.DEFAULTS.width,height:this.$element.attr("data-height")||c.DEFAULTS.height}},c.prototype.render=function(){this._onstyle="btn-"+this.options.onstyle,this._offstyle="btn-"+this.options.offstyle;var b="large"===this.options.size?"btn-large":"small"===this.options.size?"btn-small":"mini"===this.options.size?"btn-mini":"",c=a('<label class="btn">').html(this.options.on).addClass(this._onstyle+" "+b),d=a('<label class="btn">').html(this.options.off).addClass(this._offstyle+" "+b+" active"),e=a('<span class="toggle-handle btn btn-default">').addClass(b),f=a('<div class="toggle-group">').append(c,d,e),g=a('<div class="toggle btn" data-toggle="toggle">').addClass(this.$element.prop("checked")?this._onstyle:this._offstyle+" off").addClass(b).addClass(this.options.style);this.$element.wrap(g),a.extend(this,{$toggle:this.$element.parent(),$toggleOn:c,$toggleOff:d,$toggleGroup:f}),this.$toggle.append(f);var h=this.options.width||Math.max(c.width(),d.width())+e.outerWidth()/2,i=this.options.height||Math.max(c.height(),d.height());c.addClass("toggle-on"),d.addClass("toggle-off"),this.$toggle.css({width:h,height:i}),this.options.height&&(c.css("line-height",c.height()+"px"),d.css("line-height",d.height()+"px")),this.update(!0),this.trigger(!0)},c.prototype.toggle=function(){this.$element.prop("checked")?this.off():this.on()},c.prototype.on=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._offstyle+" off").addClass(this._onstyle),this.$element.prop("checked",!0),void(a||this.trigger()))},c.prototype.off=function(a){return this.$element.prop("disabled")?!1:(this.$toggle.removeClass(this._onstyle).addClass(this._offstyle+" off"),this.$element.prop("checked",!1),void(a||this.trigger()))},c.prototype.enable=function(){this.$toggle.removeAttr("disabled"),this.$element.prop("disabled",!1)},c.prototype.disable=function(){this.$toggle.attr("disabled","disabled"),this.$element.prop("disabled",!0)},c.prototype.update=function(a){this.$element.prop("disabled")?this.disable():this.enable(),this.$element.prop("checked")?this.on(a):this.off(a)},c.prototype.trigger=function(b){this.$element.off("change.bs.toggle"),b||this.$element.change(),this.$element.on("change.bs.toggle",a.proxy(function(){this.update()},this))},c.prototype.destroy=function(){this.$element.off("change.bs.toggle"),this.$toggleGroup.remove(),this.$element.removeData("bs.toggle"),this.$element.unwrap()};var d=a.fn.bootstrapToggle;a.fn.bootstrapToggle=b,a.fn.bootstrapToggle.Constructor=c,a.fn.toggle.noConflict=function(){return a.fn.bootstrapToggle=d,this},a(function(){a("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle()}),a(document).on("click.bs.toggle","div[data-toggle^=toggle]",function(b){var c=a(this).find("input[type=checkbox]");c.bootstrapToggle("toggle"),b.preventDefault()})}(jQuery);
//# sourceMappingURL=bootstrap2-toggle.min.js.map

View File

@ -1 +0,0 @@
{"version":3,"file":"bootstrap2-toggle.min.js","sources":["bootstrap2-toggle.js"],"names":["$","Plugin","option","this","each","$this","data","options","Toggle","element","$element","extend","defaults","render","VERSION","DEFAULTS","on","off","onstyle","offstyle","size","style","width","height","prototype","attr","_onstyle","_offstyle","$toggleOn","html","addClass","$toggleOff","$toggleHandle","$toggleGroup","append","$toggle","prop","wrap","parent","Math","max","outerWidth","css","update","trigger","toggle","silent","removeClass","enable","removeAttr","disable","change","proxy","destroy","remove","removeData","unwrap","old","fn","bootstrapToggle","Constructor","noConflict","document","e","$checkbox","find","preventDefault","jQuery"],"mappings":";;;;;;;CASE,SAAUA,GACV,YAoID,SAASC,GAAOC,GACf,MAAOC,MAAKC,KAAK,WAChB,GAAIC,GAAUL,EAAEG,MACZG,EAAUD,EAAMC,KAAK,aACrBC,EAA2B,gBAAVL,IAAsBA,CAEtCI,IAAMD,EAAMC,KAAK,YAAcA,EAAO,GAAIE,GAAOL,KAAMI,IACvC,gBAAVL,IAAsBI,EAAKJ,IAASI,EAAKJ,OAtItD,GAAIM,GAAS,SAAUC,EAASF,GAC/BJ,KAAKO,SAAYV,EAAES,GACnBN,KAAKI,QAAYP,EAAEW,UAAWR,KAAKS,WAAYL,GAC/CJ,KAAKU,SAGNL,GAAOM,QAAW,QAElBN,EAAOO,UACNC,GAAI,KACJC,IAAK,MACLC,QAAS,UACTC,SAAU,UACVC,KAAM,SACNC,MAAO,GACPC,MAAO,KACPC,OAAQ,MAGTf,EAAOgB,UAAUZ,SAAW,WAC3B,OACCI,GAAIb,KAAKO,SAASe,KAAK,YAAcjB,EAAOO,SAASC,GACrDC,IAAKd,KAAKO,SAASe,KAAK,aAAejB,EAAOO,SAASE,IACvDC,QAASf,KAAKO,SAASe,KAAK,iBAAmBjB,EAAOO,SAASG,QAC/DC,SAAUhB,KAAKO,SAASe,KAAK,kBAAoBjB,EAAOO,SAASI,SACjEC,KAAMjB,KAAKO,SAASe,KAAK,cAAgBjB,EAAOO,SAASK,KACzDC,MAAOlB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASM,MAC3DC,MAAOnB,KAAKO,SAASe,KAAK,eAAiBjB,EAAOO,SAASO,MAC3DC,OAAQpB,KAAKO,SAASe,KAAK,gBAAkBjB,EAAOO,SAASQ,SAI/Df,EAAOgB,UAAUX,OAAS,WACzBV,KAAKuB,SAAW,OAASvB,KAAKI,QAAQW,QACtCf,KAAKwB,UAAY,OAASxB,KAAKI,QAAQY,QACvC,IAAIC,GAA6B,UAAtBjB,KAAKI,QAAQa,KAAmB,YAClB,UAAtBjB,KAAKI,QAAQa,KAAmB,YACV,SAAtBjB,KAAKI,QAAQa,KAAkB,WAC/B,GACCQ,EAAY5B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQS,IACzDc,SAAS3B,KAAKuB,SAAW,IAAMN,GAC7BW,EAAa/B,EAAE,uBAAuB6B,KAAK1B,KAAKI,QAAQU,KAC1Da,SAAS3B,KAAKwB,UAAY,IAAMP,EAAO,WACrCY,EAAgBhC,EAAE,gDACpB8B,SAASV,GACPa,EAAejC,EAAE,8BACnBkC,OAAON,EAAWG,EAAYC,GAC5BG,EAAUnC,EAAE,iDACd8B,SAAU3B,KAAKO,SAAS0B,KAAK,WAAajC,KAAKuB,SAAWvB,KAAKwB,UAAU,QACzEG,SAASV,GAAMU,SAAS3B,KAAKI,QAAQc,MAEvClB,MAAKO,SAAS2B,KAAKF,GACnBnC,EAAEW,OAAOR,MACRgC,QAAShC,KAAKO,SAAS4B,SACvBV,UAAWA,EACXG,WAAYA,EACZE,aAAcA,IAEf9B,KAAKgC,QAAQD,OAAOD,EAEpB,IAAIX,GAAQnB,KAAKI,QAAQe,OAASiB,KAAKC,IAAIZ,EAAUN,QAASS,EAAWT,SAAUU,EAAcS,aAAa,EAC1GlB,EAASpB,KAAKI,QAAQgB,QAAUgB,KAAKC,IAAIZ,EAAUL,SAAUQ,EAAWR,SAC5EK,GAAUE,SAAS,aACnBC,EAAWD,SAAS,cACpB3B,KAAKgC,QAAQO,KAAMpB,MAAOA,EAAOC,OAAQA,IACrCpB,KAAKI,QAAQgB,SAChBK,EAAUc,IAAI,cAAed,EAAUL,SAAW,MAClDQ,EAAWW,IAAI,cAAeX,EAAWR,SAAW,OAErDpB,KAAKwC,QAAO,GACZxC,KAAKyC,SAAQ,IAGdpC,EAAOgB,UAAUqB,OAAS,WACrB1C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKc,MACnCd,KAAKa,MAGXR,EAAOgB,UAAUR,GAAK,SAAU8B,GAC/B,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKwB,UAAY,QAAQG,SAAS3B,KAAKuB,UAChEvB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUP,IAAM,SAAU6B,GAChC,MAAI3C,MAAKO,SAAS0B,KAAK,aAAoB,GAC3CjC,KAAKgC,QAAQY,YAAY5C,KAAKuB,UAAUI,SAAS3B,KAAKwB,UAAY,QAClExB,KAAKO,SAAS0B,KAAK,WAAW,QACzBU,GAAQ3C,KAAKyC,aAGnBpC,EAAOgB,UAAUwB,OAAS,WACzB7C,KAAKgC,QAAQc,WAAW,YACxB9C,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAU0B,QAAU,WAC1B/C,KAAKgC,QAAQV,KAAK,WAAY,YAC9BtB,KAAKO,SAAS0B,KAAK,YAAY,IAGhC5B,EAAOgB,UAAUmB,OAAS,SAAUG,GAC/B3C,KAAKO,SAAS0B,KAAK,YAAajC,KAAK+C,UACpC/C,KAAK6C,SACN7C,KAAKO,SAAS0B,KAAK,WAAYjC,KAAKa,GAAG8B,GACtC3C,KAAKc,IAAI6B,IAGftC,EAAOgB,UAAUoB,QAAU,SAAUE,GACpC3C,KAAKO,SAASO,IAAI,oBACb6B,GAAQ3C,KAAKO,SAASyC,SAC3BhD,KAAKO,SAASM,GAAG,mBAAoBhB,EAAEoD,MAAM,WAC5CjD,KAAKwC,UACHxC,QAGJK,EAAOgB,UAAU6B,QAAU,WAC1BlD,KAAKO,SAASO,IAAI,oBAClBd,KAAK8B,aAAaqB,SAClBnD,KAAKO,SAAS6C,WAAW,aACzBpD,KAAKO,SAAS8C,SAiBf,IAAIC,GAAMzD,EAAE0D,GAAGC,eAEf3D,GAAE0D,GAAGC,gBAA8B1D,EACnCD,EAAE0D,GAAGC,gBAAgBC,YAAcpD,EAKnCR,EAAE0D,GAAGb,OAAOgB,WAAa,WAExB,MADA7D,GAAE0D,GAAGC,gBAAkBF,EAChBtD,MAMRH,EAAE,WACDA,EAAE,6CAA6C2D,oBAGhD3D,EAAE8D,UAAU9C,GAAG,kBAAmB,2BAA4B,SAAS+C,GACtE,GAAIC,GAAYhE,EAAEG,MAAM8D,KAAK,uBAC7BD,GAAUL,gBAAgB,UAC1BI,EAAEG,oBAGFC"}

View File

@ -8,7 +8,6 @@
@import "jquery.mloading"; @import "jquery.mloading";
@import "jquery-confirm.min"; @import "jquery-confirm.min";
@import "bootstrap-datetimepicker.min"; @import "bootstrap-datetimepicker.min";
@import "bootstrap/bootstrap-toggle.min";
@import "codemirror/lib/codemirror"; @import "codemirror/lib/codemirror";
@import "editormd/css/editormd.min"; @import "editormd/css/editormd.min";
@ -205,13 +204,3 @@ input.form-control {
font-size: 1rem; font-size: 1rem;
} }
} }
.table th, .table td {
padding: 0.75rem 0.1rem;
vertical-align: top;
border-top: 1px solid #dee2e6;
}
.table .thead-light th{
white-space: nowrap;
}

View File

@ -1,83 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
.checkbox label .toggle,
.checkbox-inline .toggle {
margin-left: -20px;
margin-right: 5px;
}
.toggle {
position: relative;
overflow: hidden;
}
.toggle input[type="checkbox"] {
display: none;
}
.toggle-group {
position: absolute;
width: 200%;
top: 0;
bottom: 0;
left: 0;
transition: left 0.35s;
-webkit-transition: left 0.35s;
-moz-user-select: none;
-webkit-user-select: none;
}
.toggle.off .toggle-group {
left: -100%;
}
.toggle-on {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 50%;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-off {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
right: 0;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-handle {
position: relative;
margin: 0 auto;
padding-top: 0px;
padding-bottom: 0px;
height: 100%;
width: 0px;
border-width: 0 1px;
}
.toggle.btn { min-width: 59px; min-height: 34px; }
.toggle-on.btn { padding-right: 24px; }
.toggle-off.btn { padding-left: 24px; }
.toggle.btn-lg { min-width: 79px; min-height: 45px; }
.toggle-on.btn-lg { padding-right: 31px; }
.toggle-off.btn-lg { padding-left: 31px; }
.toggle-handle.btn-lg { width: 40px; }
.toggle.btn-sm { min-width: 50px; min-height: 30px;}
.toggle-on.btn-sm { padding-right: 20px; }
.toggle-off.btn-sm { padding-left: 20px; }
.toggle.btn-xs { min-width: 35px; min-height: 22px;}
.toggle-on.btn-xs { padding-right: 12px; }
.toggle-off.btn-xs { padding-left: 12px; }

View File

@ -1,28 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
.checkbox label .toggle,.checkbox-inline .toggle{margin-left:-20px;margin-right:5px}
.toggle{position:relative;overflow:hidden}
.toggle input[type=checkbox]{display:none}
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
.toggle.off .toggle-group{left:-100%}
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
.toggle.btn{min-width:59px;min-height:34px}
.toggle-on.btn{padding-right:24px}
.toggle-off.btn{padding-left:24px}
.toggle.btn-lg{min-width:79px;min-height:45px}
.toggle-on.btn-lg{padding-right:31px}
.toggle-off.btn-lg{padding-left:31px}
.toggle-handle.btn-lg{width:40px}
.toggle.btn-sm{min-width:50px;min-height:30px}
.toggle-on.btn-sm{padding-right:20px}
.toggle-off.btn-sm{padding-left:20px}
.toggle.btn-xs{min-width:35px;min-height:22px}
.toggle-on.btn-xs{padding-right:12px}
.toggle-off.btn-xs{padding-left:12px}

View File

@ -1,85 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
label.checkbox .toggle,
label.checkbox.inline .toggle {
margin-left: -20px;
margin-right: 5px;
}
.toggle {
min-width: 40px;
height: 20px;
position: relative;
overflow: hidden;
}
.toggle input[type="checkbox"] {
display: none;
}
.toggle-group {
position: absolute;
width: 200%;
top: 0;
bottom: 0;
left: 0;
transition: left 0.35s;
-webkit-transition: left 0.35s;
-moz-user-select: none;
-webkit-user-select: none;
}
.toggle.off .toggle-group {
left: -100%;
}
.toggle-on {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 50%;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-off {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
right: 0;
margin: 0;
border: 0;
border-radius: 0;
}
.toggle-handle {
position: relative;
margin: 0 auto;
padding-top: 0px;
padding-bottom: 0px;
height: 100%;
width: 0px;
border-width: 0 1px;
}
.toggle-handle.btn-mini {
top: -1px;
}
.toggle.btn { min-width: 30px; }
.toggle-on.btn { padding-right: 24px; }
.toggle-off.btn { padding-left: 24px; }
.toggle.btn-large { min-width: 40px; }
.toggle-on.btn-large { padding-right: 35px; }
.toggle-off.btn-large { padding-left: 35px; }
.toggle.btn-small { min-width: 25px; }
.toggle-on.btn-small { padding-right: 20px; }
.toggle-off.btn-small { padding-left: 20px; }
.toggle.btn-mini { min-width: 20px; }
.toggle-on.btn-mini { padding-right: 12px; }
.toggle-off.btn-mini { padding-left: 12px; }

View File

@ -1,28 +0,0 @@
/*! ========================================================================
* Bootstrap Toggle: bootstrap2-toggle.css v2.2.0
* http://www.bootstraptoggle.com
* ========================================================================
* Copyright 2014 Min Hur, The New York Times Company
* Licensed under MIT
* ======================================================================== */
label.checkbox .toggle,label.checkbox.inline .toggle{margin-left:-20px;margin-right:5px}
.toggle{min-width:40px;height:20px;position:relative;overflow:hidden}
.toggle input[type=checkbox]{display:none}
.toggle-group{position:absolute;width:200%;top:0;bottom:0;left:0;transition:left .35s;-webkit-transition:left .35s;-moz-user-select:none;-webkit-user-select:none}
.toggle.off .toggle-group{left:-100%}
.toggle-on{position:absolute;top:0;bottom:0;left:0;right:50%;margin:0;border:0;border-radius:0}
.toggle-off{position:absolute;top:0;bottom:0;left:50%;right:0;margin:0;border:0;border-radius:0}
.toggle-handle{position:relative;margin:0 auto;padding-top:0;padding-bottom:0;height:100%;width:0;border-width:0 1px}
.toggle-handle.btn-mini{top:-1px}
.toggle.btn{min-width:30px}
.toggle-on.btn{padding-right:24px}
.toggle-off.btn{padding-left:24px}
.toggle.btn-large{min-width:40px}
.toggle-on.btn-large{padding-right:35px}
.toggle-off.btn-large{padding-left:35px}
.toggle.btn-small{min-width:25px}
.toggle-on.btn-small{padding-right:20px}
.toggle-off.btn-small{padding-left:20px}
.toggle.btn-mini{min-width:20px}
.toggle-on.btn-mini{padding-right:12px}
.toggle-off.btn-mini{padding-left:12px}

View File

@ -1,45 +1,14 @@
class AccountsController < ApplicationController class AccountsController < ApplicationController
before_action :require_login, only: [:login_check, :simple_update]
include ApplicationHelper include ApplicationHelper
#skip_before_action :check_account, :only => [:logout] #skip_before_action :check_account, :only => [:logout]
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
result = auto_update(current_user, simple_update_params)
if result[:message].blank?
render_ok
else
render_error(result[:message])
end
end
end
def index def index
render json: session render json: session
end end
# 为了同步平台上未注册gitea的用户
def gitea_register
user = User.find_by(login: sync_gitea_params[:login])
Users::SyncGiteaForm.new(sync_gitea_params.merge(user: user)).validate!
return render_error("该用户已同步协作平台") if user.gitea_token.present? && user.gitea_uid.present?
result = create_gitea_user!(user, sync_gitea_params[:login], sync_gitea_params[:email], sync_gitea_params[:password])
result[:user] ? render_ok : render_error(result[:message])
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台同步注册的用户 # 其他平台同步注册的用户
def remote_register def remote_register
Register::RemoteForm.new(remote_register_params).validate!
username = params[:username]&.gsub(/\s+/, "") username = params[:username]&.gsub(/\s+/, "")
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
email = params[:email]&.gsub(/\s+/, "") email = params[:email]&.gsub(/\s+/, "")
@ -124,9 +93,7 @@ class AccountsController < ApplicationController
sync_params = { sync_params = {
password: params[:password].to_s, password: params[:password].to_s,
email: @user.mail, email: @user.mail
login_name: @user.login,
source_id: 0
} }
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
@ -157,6 +124,7 @@ class AccountsController < ApplicationController
password = register_params[:password].strip password = register_params[:password].strip
# gitea用户注册, email, username, password # gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
if interactor.success? if interactor.success?
gitea_user = interactor.result gitea_user = interactor.result
@ -171,6 +139,7 @@ class AccountsController < ApplicationController
else else
tip_exception(-1, interactor.error) tip_exception(-1, interactor.error)
end end
rescue Register::BaseForm::EmailError => e rescue Register::BaseForm::EmailError => e
render_error(-2, e.message) render_error(-2, e.message)
rescue Register::BaseForm::LoginError => e rescue Register::BaseForm::LoginError => e
@ -224,9 +193,7 @@ class AccountsController < ApplicationController
sync_params = { sync_params = {
password: params[:password].to_s, password: params[:password].to_s,
email: @user.mail, email: @user.mail
login_name: @user.login,
source_id: 0
} }
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params) interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
@ -349,11 +316,6 @@ class AccountsController < ApplicationController
render_ok render_ok
end end
def login_check
Register::LoginCheckColumnsForm.new(check_params.merge(user: current_user)).validate!
render_ok
end
private private
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 # type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
@ -392,10 +354,6 @@ class AccountsController < ApplicationController
{ login: pre + code, email: email, phone: phone } { login: pre + code, email: email, phone: phone }
end end
def sync_gitea_params
params.permit(:login, :email, :password)
end
def user_params def user_params
params.require(:user).permit(:login, :email, :phone) params.require(:user).permit(:login, :email, :phone)
end end
@ -412,11 +370,4 @@ class AccountsController < ApplicationController
params.permit(:login, :namespace, :password, :code) params.permit(:login, :namespace, :password, :code)
end end
def remote_register_params
params.permit(:username, :email, :password, :platform)
end
def simple_update_params
params.permit(:username, :email, :password, :platform)
end
end end

View File

@ -1,33 +1,10 @@
class Admins::DashboardsController < Admins::BaseController class Admins::DashboardsController < Admins::BaseController
def index def index
# 用户活跃数 @active_user_count = User.where(last_login_on: today).count
day_user_ids = CommitLog.where(created_at: today).pluck(:user_id).uniq @weekly_active_user_count = User.where(last_login_on: current_week).count
weekly_user_ids = CommitLog.where(created_at: current_week).pluck(:user_id).uniq @month_active_user_count = User.where(last_login_on: current_month).count
month_user_ids = CommitLog.where(created_at: current_month).pluck(:user_id).uniq
@active_user_count = User.where(last_login_on: today).or(User.where(id: day_user_ids)).count
@weekly_active_user_count = User.where(last_login_on: current_week).or(User.where(id: weekly_user_ids)).count
@month_active_user_count = User.where(last_login_on: current_month).or(User.where(id: month_user_ids)).count
user_ids = User.where(created_on: pre_week).pluck(:id).uniq
weekly_keep_user_count = User.where(id: user_ids).where(last_login_on: current_week).count
@weekly_keep_rate = format("%.2f", user_ids.size > 0 ? weekly_keep_user_count.to_f / user_ids.size : 0)
# 新用户注册数 @new_user_count = User.where(created_on: current_month).count
@day_new_user_count = User.where(created_on: today).count
@weekly_new_user_count = User.where(created_on: current_week).count
@month_new_user_count = User.where(created_on: current_month).count
# 活跃项目数
day_project_ids = (CommitLog.where(created_at: today).pluck(:project_id).uniq + Issue.where(created_on: today).pluck(:project_id).uniq).uniq
weekly_project_ids = (CommitLog.where(created_at: current_week).pluck(:project_id).uniq + Issue.where(created_on: current_week).pluck(:project_id).uniq).uniq
month_project_ids = (CommitLog.where(created_at: current_month).pluck(:project_id).uniq + Issue.where(created_on: current_month).pluck(:project_id).uniq).uniq
@day_active_project_count = Project.where(updated_on: today).or(Project.where(id: day_project_ids)).count
@weekly_active_project_count = Project.where(updated_on: current_week).or(Project.where(id: weekly_project_ids)).count
@month_active_project_count = Project.where(updated_on: current_month).or(Project.where(id: month_project_ids)).count
# 新增项目数
@day_new_project_count = Project.where(created_on: today).count
@weekly_new_project_count = Project.where(created_on: current_week).count
@month_new_project_count = Project.where(created_on: current_month).count
end end
def month_active_user def month_active_user
@ -65,14 +42,10 @@ class Admins::DashboardsController < Admins::BaseController
end end
def current_week def current_week
7.days.ago.end_of_day..Time.now.end_of_day 7.days.ago.beginning_of_day..Time.now.end_of_day
end end
def current_month def current_month
30.days.ago.end_of_day..Time.now.end_of_day 30.days.ago.beginning_of_day..Time.now.end_of_day
end
def pre_week
14.days.ago.end_of_day..7.days.ago.end_of_day
end end
end end

View File

@ -1,49 +0,0 @@
class Admins::FeedbacksController < Admins::BaseController
before_action :get_feedback, only: [:new_history, :create_history, :destroy]
def index
sort_by = Feedback.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
feedbacks = Feedback.order("#{sort_by} #{sort_direction}")
@feedbacks = paginate(feedbacks)
end
def destroy
if @feedback.destroy
redirect_to admins_feedbacks_path
flash[:success] = "反馈意见删除成功"
else
redirect_to admins_feedbacks_path
flash[:danger] = "反馈意见删除失败"
end
end
def new_history
@feedback_message_history = FeedbackMessageHistory.new
end
def create_history
@feedback_message_history = @feedback.feedback_message_histories.new(feedback_message_history_params)
@feedback_message_history.user = current_user
if @feedback_message_history.save
redirect_to admins_feedbacks_path
flash[:success] = "发送通知成功"
else
redirect_to admins_feedbacks_path
flash[:danger] = @feedback_message_history.errors.full_messages.join(", ")
end
end
private
def feedback_params
params.require(:feedback).permit!
end
def feedback_message_history_params
params.require(:feedback_message_history).permit(:title, :content)
end
def get_feedback
@feedback = Feedback.find_by_id(params[:id])
end
end

View File

@ -2,7 +2,7 @@ class Admins::ImportUsersController < Admins::BaseController
def create def create
return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile)
result = Admins::ImportUserFromExcelService.call(params[:file].to_io) result = Admins::ImportUserService.call(params[:file].to_io)
render_ok(result) render_ok(result)
rescue Admins::ImportUserService::Error => ex rescue Admins::ImportUserService::Error => ex
render_error(ex) render_error(ex)

View File

@ -2,24 +2,8 @@ class Admins::MessageTemplatesController < Admins::BaseController
before_action :get_template, only: [:edit, :update, :destroy] before_action :get_template, only: [:edit, :update, :destroy]
def index def index
message_templates = MessageTemplate.ransack(sys_notice_or_email_or_email_title_cont: params[:search]).result message_templates = MessageTemplate.group(:type).count.keys
@message_templates = kaminari_paginate(message_templates) @message_templates = kaminari_array_paginate(message_templates)
end
def new
@message_template = MessageTemplate.new
end
def create
@message_template = MessageTemplate::CustomTip.new(message_template_params)
@message_template.type = "MessageTemplate::CustomTip"
if @message_template.save!
redirect_to admins_message_templates_path
flash[:success] = "创建消息模板成功"
else
render :new
flash[:danger] = "创建消息模板失败"
end
end end
def edit def edit
@ -47,9 +31,7 @@ class Admins::MessageTemplatesController < Admins::BaseController
private private
def message_template_params def message_template_params
# type = @message_template.present? ? @message_template.type : "MessageTemplate::CustomTip" params.require(@message_template.type.split("::").join("_").underscore.to_sym).permit!
# params.require(type.split("::").join("_").underscore.to_sym).permit!
params.require(:message_template).permit!
end end
def get_template def get_template

View File

@ -1,26 +0,0 @@
class Admins::NpsController < Admins::BaseController
def index
@on_off_switch = EduSetting.get("nps-on-off-switch").to_s == 'true'
@user_nps = UserNp.joins(:user).order(created_at: :desc)
keyword = params[:keyword].to_s.strip.presence
if keyword
sql = 'CONCAT(users.lastname, users.firstname) LIKE :keyword OR users.nickname LIKE :keyword OR users.login LIKE :keyword OR users.mail LIKE :keyword OR users.phone LIKE :keyword'
@user_nps = @user_nps.where(sql, keyword: "%#{keyword}%")
end
@user_nps = @user_nps.where("action_type != 'close'") if params[:done_score].present?
@min_score = @user_nps.where("action_type != 'close'").minimum("score")
@max_score = @user_nps.where("action_type != 'close'").maximum("score")
@score_total_count = UserNp.where("action_type !='close'").count
@user_nps = paginate @user_nps.includes(:user)
end
def switch_change
edu_setting = EduSetting.find_by(name: "nps-on-off-switch")
if edu_setting.blank?
edu_setting = EduSetting.new(name: "nps-on-off-switch")
end
edu_setting.value = params[:switch].to_s
edu_setting.save
render_ok
end
end

View File

@ -1,6 +1,6 @@
class Admins::ProjectIgnoresController < Admins::BaseController class Admins::ProjectIgnoresController < Admins::BaseController
before_action :set_ignore, only: [:edit,:update, :destroy,:show] before_action :set_ignore, only: [:edit,:update, :destroy,:show]
# before_action :validate_params, only: [:create, :update] before_action :validate_params, only: [:create, :update]
def index def index
sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at' sort_by = Ignore.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
@ -31,12 +31,12 @@ class Admins::ProjectIgnoresController < Admins::BaseController
# } # }
@project_ignore = Ignore.new(ignore_params) @project_ignore = Ignore.new(ignore_params)
if @project_ignore.save if @project_ignore.save!
redirect_to admins_project_ignores_path redirect_to admins_project_ignores_path
flash[:success] = "创建成功" flash[:success] = "创建成功"
else else
redirect_to admins_project_ignores_path render :new
flash[:danger] = @project_ignore.errors.full_messages.join(",") flash[:danger] = "创建失败"
end end
end end
@ -58,8 +58,8 @@ class Admins::ProjectIgnoresController < Admins::BaseController
redirect_to admins_project_ignores_path redirect_to admins_project_ignores_path
flash[:success] = "更新成功" flash[:success] = "更新成功"
else else
redirect_to admins_project_ignores_path render :edit
flash[:danger] = @project_ignore.errors.full_messages.join(",") flash[:danger] = "更新失败"
end end
end end
@ -98,23 +98,23 @@ class Admins::ProjectIgnoresController < Admins::BaseController
params.require(:ignore).permit(:name,:content) params.require(:ignore).permit(:name,:content)
end end
# def validate_params def validate_params
# name = params[:ignore][:name] name = params[:ignore][:name]
# if name.blank? if name.blank?
# flash[:danger] = "名称不允许为空" flash[:danger] = "名称不允许为空"
# redirect_to admins_project_ignores_path redirect_to admins_project_ignores_path
# elsif check_ignore_present?(name) && @project_ignore.blank? elsif check_ignore_present?(name) && @project_ignore.blank?
# flash[:danger] = "创建失败:名称已存在" flash[:danger] = "创建失败:名称已存在"
# redirect_to admins_project_ignores_path redirect_to admins_project_ignores_path
# end end
# end end
# def check_ignore_present?(name) def check_ignore_present?(name)
# return true if name.blank? return true if name.blank?
# name_downcase = name.downcase name_downcase = name.downcase
# name_upcase = name.upcase name_upcase = name.upcase
# name_first_big = name.capitalize name_first_big = name.capitalize
# Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big) Ignore.exists?(name: name_downcase) || Ignore.exists?(name: name_upcase) || Ignore.exists?(name: name_first_big)
# end end
end end

View File

@ -27,18 +27,17 @@ class Admins::ProjectLanguagesController < Admins::BaseController
flash[:success] = '创建成功' flash[:success] = '创建成功'
else else
redirect_to admins_project_languages_path redirect_to admins_project_languages_path
flash[:danger] = @project_language.errors.full_messages.join(",") flash[:danger] = '创建失败'
end end
end end
def update def update
@project_language.attributes = {name: @name} if @project_language.update_attribute(:name, @name)
if @project_language.save
redirect_to admins_project_languages_path redirect_to admins_project_languages_path
flash[:success] = '更新成功' flash[:success] = '更新成功'
else else
redirect_to admins_project_languages_path redirect_to admins_project_languages_path
flash[:danger] = @project_language.errors.full_messages.join(",") flash[:success] = '更新失败'
end end
end end

View File

@ -1,6 +1,6 @@
class Admins::ProjectLicensesController < Admins::BaseController class Admins::ProjectLicensesController < Admins::BaseController
before_action :set_license, only: [:edit,:update, :destroy,:show] before_action :set_license, only: [:edit,:update, :destroy,:show]
# before_action :validate_params, only: [:create, :update] before_action :validate_params, only: [:create, :update]
def index def index
sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at' sort_by = License.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at'
@ -30,12 +30,13 @@ class Admins::ProjectLicensesController < Admins::BaseController
# position: max_position # position: max_position
# } # }
@project_license = License.new(license_params) @project_license = License.new(license_params)
if @project_license.save
if @project_license.save!
redirect_to admins_project_licenses_path redirect_to admins_project_licenses_path
flash[:success] = "创建成功" flash[:success] = "创建成功"
else else
redirect_to admins_project_licenses_path render :new
flash[:danger] = @project_license.errors.full_messages.join(",") flash[:danger] = "创建失败"
end end
end end
@ -53,13 +54,12 @@ class Admins::ProjectLicensesController < Admins::BaseController
# permissions: permissions.to_s, # permissions: permissions.to_s,
# limitations: limitations.to_s # limitations: limitations.to_s
# } # }
@project_license.attributes = license_params if @project_license.update_attributes(license_params)
if @project_license.save
redirect_to admins_project_licenses_path redirect_to admins_project_licenses_path
flash[:success] = "更新成功" flash[:success] = "更新成功"
else else
render admins_project_licenses_path render :edit
flash[:danger] = @project_license.errors.full_messages.join(",") flash[:danger] = "更新失败"
end end
end end
@ -98,23 +98,23 @@ class Admins::ProjectLicensesController < Admins::BaseController
params.require(:license).permit(:name,:content) params.require(:license).permit(:name,:content)
end end
# def validate_params def validate_params
# name = params[:license][:name] name = params[:license][:name]
# if name.blank? if name.blank?
# flash[:danger] = "名称不允许为空" flash[:danger] = "名称不允许为空"
# redirect_to admins_project_licenses_path redirect_to admins_project_licenses_path
# elsif check_license_present?(name) && @project_license.blank? elsif check_license_present?(name) && @project_license.blank?
# flash[:danger] = "创建失败:名称已存在" flash[:danger] = "创建失败:名称已存在"
# redirect_to admins_project_licenses_path redirect_to admins_project_licenses_path
# end end
# end end
# def check_license_present?(name) def check_license_present?(name)
# return true if name.blank? return true if name.blank?
# name_downcase = name.downcase name_downcase = name.downcase
# name_upcase = name.upcase name_upcase = name.upcase
# name_first_big = name.capitalize name_first_big = name.capitalize
# License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big) License.exists?(name: name_downcase) || License.exists?(name: name_upcase) || License.exists?(name: name_first_big)
# end end
end end

View File

@ -1,55 +0,0 @@
class Api::V1::BaseController < ApplicationController
include Api::ProjectHelper
include Api::UserHelper
include Api::PullHelper
# before_action :doorkeeper_authorize!
# skip_before_action :user_setup
protected
# def current_user
# #client方法对接需要一直带着用户标识uid
# Rails.logger.info doorkeeper_token
# if doorkeeper_token && doorkeeper_token.resource_owner_id.blank?
# # return User.anonymous if params[:uid].nil?
# # tip_exception("2222")
# # return render_error('缺少用户标识!') if params[:uid].nil?
# User.current = User.find(params[:uid])
# else
# User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token
# end
# end
def limit
params.fetch(:limit, 15)
end
def page
params.fetch(:page, 1)
end
# 具有对仓库的管理权限
def require_manager_above
@project = load_project
return render_forbidden if !current_user.admin? && !@project.manager?(current_user)
end
# 具有对仓库的操作权限
def require_operate_above
@project = load_project
return render_forbidden if !current_user.admin? && !@project.operator?(current_user)
end
# 具有仓库的操作权限或者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
# 具有对仓库的访问权限
def require_public_and_member_above
@project = load_project
return render_forbidden if !@project.is_public && !current_user.admin? && !@project.member?(current_user)
end
end

View File

@ -1,18 +0,0 @@
class Api::V1::Projects::BranchesController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:all]
def all
@result_object = Api::V1::Projects::Branches::AllListService.call(@project, current_user&.gitea_token)
end
before_action :require_operate_above, only: [:create]
def create
@result_object = Api::V1::Projects::Branches::CreateService.call(@project, branch_params, current_user&.gitea_token)
end
private
def branch_params
params.require(:branch).permit(:new_branch_name, :old_branch_name)
end
end

View File

@ -1,8 +0,0 @@
class Api::V1::Projects::CodeStatsController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:index]
def index
@result_object = Api::V1::Projects::CodeStats::ListService.call(@project, {ref: params[:ref]}, @project.owner&.gitea_token)
# puts @result_object
end
end

View File

@ -1,12 +0,0 @@
class Api::V1::Projects::CommitsController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:index, :diff]
def index
@result_object = Api::V1::Projects::Commits::ListService.call(@project, {page: page, limit: limit, sha: params[:sha]}, current_user&.gitea_token)
puts @result_object
end
def diff
@result_object = Api::V1::Projects::Commits::DiffService.call(@project, params[:sha], current_user&.gitea_token)
end
end

View File

@ -1,17 +0,0 @@
class Api::V1::Projects::ContentsController < Api::V1::BaseController
before_action :require_operate_above_or_fork_project, only: [:batch]
def batch
@batch_content_params = batch_content_params
# 处理下author和committer信息如果没传则默认为当前用户信息
@batch_content_params.merge!(author_email: current_user.mail, author_name: current_user.login) if batch_content_params[:author_email].blank? && batch_content_params[:author_name].blank?
@batch_content_params.merge!(committer_email: current_user.mail, committer_name: current_user.login) if batch_content_params[:committer_email].blank? && batch_content_params[:committer_name].blank?
@result_object = Api::V1::Projects::Contents::BatchCreateService.call(@project, @batch_content_params, @project.owner.gitea_token)
end
private
def batch_content_params
params.require(:content).permit(:author_email, :author_name, :author_timeunix, :branch, :committer_email, :committer_name, :committer_timeunix, :message, :new_branch, files: [ :action_type, :content, :encoding, :file_path])
end
end

View File

@ -1,12 +0,0 @@
class Api::V1::Projects::GitController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:trees, :blobs]
def trees
@result_object = Api::V1::Projects::Git::TreesService.call(@project, params[:sha], {recursive: params[:recursive], page: page, limit: limit}, current_user&.gitea_token)
end
def blobs
@result_object = Api::V1::Projects::Git::BlobsService.call(@project, params[:sha], current_user&.gitea_token)
end
end

View File

@ -1,5 +0,0 @@
class Api::V1::Projects::Pulls::BaseController < Api::V1::BaseController
before_action :require_public_and_member_above
before_action :load_pull_request
end

View File

@ -1,40 +0,0 @@
class Api::V1::Projects::Pulls::JournalsController < Api::V1::Projects::Pulls::BaseController
def index
@journals = Api::V1::Projects::Pulls::Journals::ListService.call(@project, @pull_request, params, current_user)
@journals = @journals.limit(200)
end
def create
@journal = Api::V1::Projects::Pulls::Journals::CreateService.call(@project, @pull_request, create_params, current_user)
end
before_action :find_journal, only: [:update, :destroy]
def update
@journal = Api::V1::Projects::Pulls::Journals::UpdateService.call(@project, @pull_request, @journal, update_params, current_user)
end
def destroy
if @journal.destroy
render_ok
else
render_error("删除评论失败!")
end
end
private
def create_params
params.permit(:parent_id, :line_code, :note, :commit_id, :path, :type, :review_id, :diff => {})
end
def update_params
params.permit(:note, :commit_id, :state)
end
def find_journal
@journal = @pull_request.journals.find_by_id(params[:id])
return render_not_found unless @journal.present?
end
end

View File

@ -1,20 +0,0 @@
class Api::V1::Projects::Pulls::PullsController < Api::V1::BaseController
before_action :require_public_and_member_above
def index
@pulls = Api::V1::Projects::Pulls::ListService.call(@project, query_params)
@pulls = kaminari_paginate(@pulls)
end
before_action :load_pull_request, only: [:show]
def show
@result_object = Api::V1::Projects::Pulls::GetService.call(@project, @pull_request, current_user&.gitea_token)
@last_review = @pull_request.reviews.order(created_at: :desc).take
end
private
def query_params
params.permit(:status, :keyword, :priority_id, :issue_tag_id, :version_id, :reviewer_id, :sort_by, :sort_direction)
end
end

View File

@ -1,23 +0,0 @@
class Api::V1::Projects::Pulls::ReviewsController < Api::V1::Projects::Pulls::BaseController
def index
@reviews = @pull_request.reviews
@reviews = @reviews.where(status: params[:status]) if params[:status].present?
# @reviews = kaminari_paginate(@reviews)
end
before_action :require_reviewer, only: [:create]
def create
@review = Api::V1::Projects::Pulls::Reviews::CreateService.call(@project, @pull_request, review_params, current_user)
end
private
def require_reviewer
return render_forbidden('您没有审查权限,请联系项目管理员') if !current_user.admin? && !@pull_request.reviewers.exists?(current_user.id) && !@project.manager?(current_user)
end
def review_params
params.require(:review).permit(:content, :commit_id, :status)
end
end

View File

@ -1,10 +0,0 @@
class Api::V1::Projects::Pulls::VersionsController < Api::V1::Projects::Pulls::BaseController
def index
@result_object = Api::V1::Projects::Pulls::Versions::ListService.call(@project, @pull_request, {page: page, limit: limit}, current_user&.gitea_token)
end
def diff
@result_object = Api::V1::Projects::Pulls::Versions::GetDiffService.call(@project, @pull_request, params[:id], {filepath: params[:filepath]}, current_user&.gitea_token)
end
end

View File

@ -1,61 +0,0 @@
class Api::V1::Projects::WebhooksController < Api::V1::BaseController
before_action :require_manager_above
before_action :find_webhook, only: [:show, :update, :destroy, :tests, :hooktasks]
def index
# @result_object = Api::V1::Projects::Webhooks::ListService.call(@project, current_user&.gitea_token)
@webhooks = @project.webhooks
@webhooks = @webhooks.where(type: params[:type]) if params[:type].present?
@webhooks = kaminari_paginate(@webhooks)
end
def create
return render_error("webhooks数量已到上限请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 49
@result_object = Api::V1::Projects::Webhooks::CreateService.call(@project, create_webhook_params, current_user&.gitea_token)
end
def show
@result_object = Api::V1::Projects::Webhooks::GetService.call(@project, params[:id], current_user&.gitea_token)
end
def update
@result_object = Api::V1::Projects::Webhooks::UpdateService.call(@project, params[:id], webhook_params, current_user&.gitea_token)
end
def destroy
@result_object = Api::V1::Projects::Webhooks::DeleteService.call(@project, params[:id], current_user&.gitea_token)
if @result_object
return render_ok
else
return render_error('删除失败!')
end
end
def tests
@result_object = Api::V1::Projects::Webhooks::TestsService.call(@project, params[:id], current_user&.gitea_token)
if @result_object
return render_ok
else
return render_error('推送失败!')
end
end
def hooktasks
@hooktasks = @webhook.tasks.where(is_delivered: true).order("delivered desc")
@hooktasks = kaminari_paginate(@hooktasks)
end
private
def create_webhook_params
params.require(:webhook).permit(:active, :branch_filter, :http_method, :url, :content_type, :secret, :type, events: [])
end
def webhook_params
params.require(:webhook).permit(:active, :branch_filter, :http_method, :url, :content_type, :secret, events: [])
end
def find_webhook
@webhook = Gitea::Webhook.find_by_id(params[:id])
return render_not_found unless @webhook.present?
end
end

View File

@ -1,19 +0,0 @@
class Api::V1::ProjectsController < Api::V1::BaseController
before_action :require_public_and_member_above, only: [:show, :compare, :blame]
def index
render_ok
end
def show
@result_object = Api::V1::Projects::GetService.call(@project, current_user.gitea_token)
end
def compare
@result_object = Api::V1::Projects::CompareService.call(@project, params[:from], params[:to], current_user&.gitea_token)
end
def blame
@result_object = Api::V1::Projects::BlameService.call(@project, params[:sha], params[:filepath], current_user&.gitea_token)
end
end

View File

@ -1,16 +0,0 @@
class Api::V1::Users::FeedbacksController < Api::V1::BaseController
before_action :load_observe_user
before_action :check_auth_for_observe_user
def create
@result = Api::V1::Users::Feedbacks::CreateService.call(@observe_user, feedback_params)
return render_error("反馈意见创建失败.") if @result.nil?
return render_ok
end
private
def feedback_params
params.permit(:content)
end
end

View File

@ -1,13 +0,0 @@
class Api::V1::Users::ProjectsController < Api::V1::BaseController
before_action :load_observe_user
def index
@object_results = Api::V1::Users::Projects::ListService.call(@observe_user, query_params, current_user)
@projects = kaminari_paginate(@object_results)
end
private
def query_params
params.permit(:category, :is_public, :project_type, :sort_by, :sort_direction, :search)
end
end

View File

@ -1,81 +0,0 @@
class Api::V1::UsersController < Api::V1::BaseController
before_action :load_observe_user
before_action :check_auth_for_observe_user
def send_email_vefify_code
code = %W(0 1 2 3 4 5 6 7 8 9)
verification_code = code.sample(6).join
mail = params[:email]
code_type = params[:code_type]
sign = Digest::MD5.hexdigest("#{OPENKEY}#{mail}")
Rails.logger.info sign
tip_exception(501, "请求不合理") if sign != params[:smscode]
# 60s内不能重复发送
send_email_limit_cache_key = "send_email_60_second_limit:#{mail}"
tip_exception(-2, '请勿频繁操作') if Rails.cache.exist?(send_email_limit_cache_key)
send_email_control = LimitForbidControl::SendEmailCode.new(mail)
tip_exception(-2, '邮件发送太频繁,请稍后再试') if send_email_control.forbid?
begin
UserMailer.update_email(mail, verification_code).deliver_now
Rails.cache.write(send_email_limit_cache_key, 1, expires_in: 1.minute)
send_email_control.increment!
rescue Exception => e
logger_error(e)
tip_exception(-2,"邮件发送失败,请稍后重试")
end
ver_params = {code_type: code_type, code: verification_code, email: mail}
last_code = VerificationCode.where(code_type: code_type, email: mail).last
last_code.update_attributes!({created_at: Time.current - 10.minute}) if last_code.present?
data = VerificationCode.new(ver_params)
if data.save!
render_ok
else
tip_exception(-1, "创建数据失败")
end
end
def check_password
password = params[:password]
return tip_exception(-5, "8~16位密码支持字母数字和符号") unless password =~ CustomRegexp::PASSWORD
return tip_exception(-5, "密码错误") unless @observe_user.check_password?(password)
render_ok
end
def check_email
mail = strip(params[:email])
return tip_exception(-2, "邮件格式有误") unless mail =~ CustomRegexp::EMAIL
exist_owner = Owner.find_by(mail: mail)
return tip_exception(-2, '邮箱已被使用') if exist_owner
render_ok
end
def check_email_verify_code
code = strip(params[:code])
mail = strip(params[:email])
code_type = params[:code_type]
return tip_exception(-2, "邮件格式有误") unless mail =~ CustomRegexp::EMAIL
verifi_code = VerificationCode.where(email: mail, code: code, code_type: code_type).last
return render_ok if code == "123123" && EduSetting.get("code_debug") # 万能验证码,用于测试 # TODO 万能验证码,用于测试
return tip_exception(-6, "验证码不正确") if verifi_code&.code != code
return tip_exception(-6, "验证码已失效") if !verifi_code&.effective?
render_ok
end
def update_email
@result_object = Api::V1::Users::UpdateEmailService.call(@observe_user, params, current_user.gitea_token)
if @result_object
return render_ok
else
return render_error('更改邮箱失败!')
end
end
end

View File

@ -174,11 +174,11 @@ class ApplicationController < ActionController::Base
end end
def require_profile_completed def require_profile_completed
# tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed? tip_exception(411, "请完善资料后再操作") unless User.current.profile_is_completed?
end end
def require_user_profile_completed(user) def require_user_profile_completed(user)
# tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed? tip_exception(412, "请用户完善资料后再操作") unless user.profile_is_completed?
end end
# 异常提醒 # 异常提醒
@ -248,18 +248,6 @@ class ApplicationController < ActionController::Base
#return if params[:controller] == "main" #return if params[:controller] == "main"
# Find the current user # Find the current user
#Rails.logger.info("current_laboratory is #{current_laboratory} domain is #{request.subdomain}") #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)
end
end
else
User.current = find_current_user User.current = find_current_user
uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous")) uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous"))
@ -278,14 +266,12 @@ class ApplicationController < ActionController::Base
end end
if !User.current.logged? && Rails.env.development? if !User.current.logged? && Rails.env.development?
user = User.find 1 User.current = User.find 104
User.current = user
start_user_session(user)
end end
# 测试版前端需求 # 测试版前端需求
# logger.info("subdomain:#{request.subdomain}") logger.info("subdomain:#{request.subdomain}")
# if request.subdomain != "www" # if request.subdomain != "www"
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除 # if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
# User.current = User.find 81403 # User.current = User.find 81403
@ -298,7 +284,6 @@ class ApplicationController < ActionController::Base
# cookies.signed[:user_id] = user.id # cookies.signed[:user_id] = user.id
# end # end
# end # end
end
# User.current = User.find 81403 # User.current = User.find 81403
end end
@ -701,24 +686,18 @@ class ApplicationController < ActionController::Base
@project, @owner = Project.find_with_namespace(namespace, id) @project, @owner = Project.find_with_namespace(namespace, id)
if @project and (current_user.can_read_project?(@project) || controller_path == "projects/project_invite_links") if @project and current_user.can_read_project?(@project)
logger.info "########### has project and can read project" logger.info "########### has project and can read project"
@project @project
# elsif @project && current_user.is_a?(AnonymousUser) # elsif @project && current_user.is_a?(AnonymousUser)
# logger.info "###########This is AnonymousUser" # logger.info "###########This is AnonymousUser"
# @project = nil if !@project.is_public? # @project = nil if !@project.is_public?
# render_forbidden and return # render_forbidden and return
else
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" logger.info "###########project not found"
@project = nil @project = nil
render_not_found and return render_not_found and return
end end
end
@project @project
end end
@ -730,20 +709,14 @@ class ApplicationController < ActionController::Base
Rails.application.config_for(:configuration)['platform_url'] || request.base_url Rails.application.config_for(:configuration)['platform_url'] || request.base_url
end end
def image_type?(str)
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
default_type.include?(str&.downcase)
end
def convert_image! def convert_image!
@image = params[:image] @image = params[:image]
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image @image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
return unless @image.present? return unless @image.present?
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
if @image.class == ActionDispatch::Http::UploadedFile if @image.class == ActionDispatch::Http::UploadedFile
return render_error('请上传文件') if @image.size.zero? render_error('请上传文件') if @image.size.zero?
return render_error('文件大小超过限制') if @image.size > max_size.to_i render_error('文件大小超过限制') if @image.size > max_size.to_i
return render_error('头像格式不正确!') unless image_type?(File.extname(@image.original_filename.to_s)[1..-1])
else else
image = @image.to_s.strip image = @image.to_s.strip
return render_error('请上传正确的图片') if image.blank? return render_error('请上传正确的图片') if image.blank?

View File

@ -31,11 +31,11 @@ class AttachmentsController < ApplicationController
def get_file def get_file
normal_status(-1, "参数缺失") if params[:download_url].blank? normal_status(-1, "参数缺失") if params[:download_url].blank?
url = base_url.starts_with?("https:") ? URI.encode(params[:download_url].to_s.gsub("http:", "https:")) : URI.encode(params[:download_url].to_s) url = URI.encode(params[:download_url].to_s.gsub("http:", "https:"))
if url.starts_with?(base_url) && !url.starts_with?("#{base_url}/repo") if url.starts_with?(base_url)
domain = GiteaService.gitea_config[:domain] domain = Gitea.gitea_config[:domain]
api_url = GiteaService.gitea_config[:base_url] api_url = Gitea.gitea_config[:base_url]
url = ("/repos"+url.split(base_url + "/api")[1]).gsub('?filepath=', '/').gsub('&', '?') url = url.split(base_url)[1].gsub("api", "repos").gsub('?filepath=', '/').gsub('&', '?')
request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join request_url = [domain, api_url, url, "?ref=#{params[:ref]}&access_token=#{current_user&.gitea_token}"].join
response = Faraday.get(request_url) response = Faraday.get(request_url)
filename = url.to_s.split("/").pop() filename = url.to_s.split("/").pop()
@ -213,17 +213,20 @@ class AttachmentsController < ApplicationController
def attachment_candown def attachment_candown
unless current_user.admin? || current_user.business? unless current_user.admin? || current_user.business?
candown = true candown = true
if @file.container unless params[:type] == 'history'
if @file.container && current_user.logged?
if @file.container.is_a?(Issue) if @file.container.is_a?(Issue)
project = @file.container.project course = @file.container.project
candown = project.is_public || (current_user.logged? && project.member?(current_user)) candown = course.member?(current_user)
elsif @file.container.is_a?(Journal) elsif @file.container.is_a?(Journal)
project = @file.container.issue.project course = @file.container.issue.project
candown = project.is_public || (current_user.logged? && project.member?(current_user)) candown = course.member?(current_user)
else else
project = nil course = nil
end
tip_exception(403, "您没有权限进入") if course.present? && !candown
tip_exception(403, "您没有权限进入") if @file.container.is_a?(ApplyUserAuthentication)
end end
tip_exception(403, "您没有权限进入") if project.present? && !candown
end end
end end
end end

View File

@ -8,7 +8,7 @@ class Ci::BaseController < ApplicationController
namespace = params[:owner] namespace = params[:owner]
id = params[:repo] || params[:id] id = params[:repo] || params[:id]
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id, current_user.login) @ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
end end
def load_all_repo def load_all_repo

View File

@ -14,12 +14,12 @@ class Ci::CloudAccountsController < Ci::BaseController
def create def create
flag, msg = check_bind_cloud_account! flag, msg = check_bind_cloud_account!
return tip_exception(msg) if flag === true return render_error(msg) if flag === true
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@cloud_account = bind_account! @cloud_account = bind_account!
if @cloud_account.blank? if @cloud_account.blank?
tip_exception('激活失败, 请检查你的云服务器信息是否正确.') render_error('激活失败, 请检查你的云服务器信息是否正确.')
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
else else
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED) current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
@ -27,17 +27,17 @@ class Ci::CloudAccountsController < Ci::BaseController
end end
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def activate def activate
return tip_exception('请先认证') unless current_user.ci_certification? return render_error('请先认证') unless current_user.ci_certification?
begin begin
@cloud_account = Ci::CloudAccount.find params[:id] @cloud_account = Ci::CloudAccount.find params[:id]
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
if @repo if @repo
return tip_exception('该项目已经激活') if @repo.repo_active? return render_error('该项目已经激活') if @repo.repo_active?
@repo.activate!(@project) @repo.activate!(@project)
else else
@repo = Ci::Repo.auto_create!(@ci_user, @project) @repo = Ci::Repo.auto_create!(@ci_user, @project)
@ -50,7 +50,7 @@ class Ci::CloudAccountsController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
end end
@ -59,39 +59,39 @@ class Ci::CloudAccountsController < Ci::BaseController
def bind def bind
flag, msg = check_bind_cloud_account! flag, msg = check_bind_cloud_account!
return tip_exception(msg) if flag === true return render_error(msg) if flag === true
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@cloud_account = bind_account! @cloud_account = bind_account!
if @cloud_account.blank? if @cloud_account.blank?
tip_exception('激活失败, 请检查你的云服务器信息是否正确.') render_error('激活失败, 请检查你的云服务器信息是否正确.')
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
else else
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED) current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
end end
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def trustie_bind def trustie_bind
account = params[:account].to_s account = params[:account].to_s
return tip_exception("account不能为空.") if account.blank? return render_error("account不能为空.") if account.blank?
flag, msg = check_trustie_bind_cloud_account! flag, msg = check_trustie_bind_cloud_account!
return tip_exception(msg) if flag === true return render_error(msg) if flag === true
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@cloud_account = trustie_bind_account! @cloud_account = trustie_bind_account!
if @cloud_account.blank? if @cloud_account.blank?
tip_exception('激活失败, 请检查你的云服务器信息是否正确.') render_error('激活失败, 请检查你的云服务器信息是否正确.')
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
else else
current_user.set_drone_step!(User::DEVOPS_UNVERIFIED) current_user.set_drone_step!(User::DEVOPS_UNVERIFIED)
end end
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def unbind def unbind
@ -107,18 +107,18 @@ class Ci::CloudAccountsController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def oauth_grant def oauth_grant
password = params[:password].to_s password = params[:password].to_s
return tip_exception('你输入的密码不正确.') unless current_user.check_password?(password) return render_error('你输入的密码不正确.') unless current_user.check_password?(password)
oauth = current_user.oauths.last oauth = current_user.oauths.last
return tip_exception("服务器出小差了.") if oauth.blank? return render_error("服务器出小差了.") if oauth.blank?
result = gitea_oauth_grant!(password, oauth) result = gitea_oauth_grant!(password, oauth)
return tip_exception('授权失败.') unless result === true return render_error('授权失败.') unless result === true
current_user.set_drone_step!(User::DEVOPS_CERTIFICATION) current_user.set_drone_step!(User::DEVOPS_CERTIFICATION)
end end

View File

@ -30,7 +30,7 @@ class Ci::PipelinesController < Ci::BaseController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
size = Ci::Pipeline.where('branch=? and identifier=? and owner=?', params[:branch], params[:repo], params[:owner]).size size = Ci::Pipeline.where('branch=? and identifier=? and owner=?', params[:branch], params[:repo], params[:owner]).size
if size > 0 if size > 0
tip_exception("#{params[:branch]}分支已经存在流水线!") render_error("#{params[:branch]}分支已经存在流水线!")
return return
end end
pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name],owner: params[:owner], pipeline = Ci::Pipeline.new(pipeline_name: params[:pipeline_name], file_name: params[:file_name],owner: params[:owner],
@ -53,7 +53,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok({id: pipeline.id}) render_ok({id: pipeline.id})
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
# 在代码库创建文件 # 在代码库创建文件
@ -81,7 +81,6 @@ class Ci::PipelinesController < Ci::BaseController
repo_branch: pipeline.branch, repo_branch: pipeline.branch,
repo_config: pipeline.file_name repo_config: pipeline.file_name
} }
Rails.logger.info("########create_params===#{create_params.to_json}")
repo = Ci::Repo.create_repo(create_params) repo = Ci::Repo.create_repo(create_params)
repo repo
end end
@ -119,7 +118,7 @@ class Ci::PipelinesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def destroy def destroy
@ -133,7 +132,7 @@ class Ci::PipelinesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def content def content
@ -183,7 +182,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def update_stage def update_stage
@ -193,7 +192,7 @@ class Ci::PipelinesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def delete_stage def delete_stage
@ -206,7 +205,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def update_stage_index(pipeline_id, show_index, diff) def update_stage_index(pipeline_id, show_index, diff)
@ -230,7 +229,7 @@ class Ci::PipelinesController < Ci::BaseController
unless steps.empty? unless steps.empty?
steps.each do |step| steps.each do |step|
unless step[:template_id] unless step[:template_id]
tip_exception('请选择模板!') render_error('请选择模板!')
return return
end end
if !step[:id] if !step[:id]
@ -247,7 +246,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def create_stage_step def create_stage_step
@ -263,7 +262,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def update_stage_step def update_stage_step
@ -280,7 +279,7 @@ class Ci::PipelinesController < Ci::BaseController
render_ok render_ok
end end
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def delete_stage_step def delete_stage_step
@ -290,6 +289,6 @@ class Ci::PipelinesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
end end

View File

@ -30,19 +30,19 @@ class Ci::ProjectsController < Ci::BaseController
@file = interactor.result @file = interactor.result
render_result(1, "更新成功") render_result(1, "更新成功")
else else
tip_exception(interactor.error) render_error(interactor.error)
end end
end end
def activate def activate
return tip_exception('你还未认证') unless current_user.ci_certification? return render_error('你还未认证') unless current_user.ci_certification?
begin begin
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
if @repo if @repo
@repo.destroy! if @repo&.repo_user_id == 0 return render_error('该项目已经激活') if @repo.repo_active?
return tip_exception('该项目已经激活') if @repo.repo_active?
@repo.activate!(@project) @repo.activate!(@project)
return render_ok
else else
@repo = Ci::Repo.auto_create!(@ci_user, @project) @repo = Ci::Repo.auto_create!(@ci_user, @project)
@ci_user.update_column(:user_syncing, false) @ci_user.update_column(:user_syncing, false)
@ -55,12 +55,12 @@ class Ci::ProjectsController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
end end
def deactivate def deactivate
return tip_exception('该项目已经取消激活') if !@repo.repo_active? return render_error('该项目已经取消激活') if !@repo.repo_active?
@project.update_column(:open_devops, false) @project.update_column(:open_devops, false)
@repo.deactivate_repos! @repo.deactivate_repos!

View File

@ -20,14 +20,14 @@ class Ci::SecretsController < Ci::BaseController
if result["id"] if result["id"]
render_ok render_ok
else else
tip_exception(result["message"]) render_error(result["message"])
end end
else else
result = Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], options).create_secret result = Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], options).create_secret
if result["id"] if result["id"]
render_ok render_ok
else else
tip_exception(result["message"]) render_error(result["message"])
end end
end end
end end
@ -39,14 +39,14 @@ class Ci::SecretsController < Ci::BaseController
Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], {name: name}).delete_secret Ci::Drone::API.new(@ci_user.user_hash, ci_drone_url, params[:owner], params[:repo], {name: name}).delete_secret
render_ok render_ok
else else
tip_exception("参数名不能为空") render_error("参数名不能为空")
end end
rescue Exception => ex rescue Exception => ex
render_ok render_ok
end end
def ci_drone_url def ci_drone_url
user = User.find_by(login: params[:owner]) || User.find_by(login: current_user.login) user = User.find_by(login: params[:owner])
user&.ci_cloud_account.drone_url user&.ci_cloud_account.drone_url
end end

View File

@ -50,7 +50,7 @@ class Ci::TemplatesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def update def update
@ -63,7 +63,7 @@ class Ci::TemplatesController < Ci::BaseController
) )
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
def destroy def destroy
@ -73,7 +73,7 @@ class Ci::TemplatesController < Ci::BaseController
end end
render_ok render_ok
rescue Exception => ex rescue Exception => ex
tip_exception(ex.message) render_error(ex.message)
end end
#======流水线模板查询=====# #======流水线模板查询=====#

View File

@ -1,30 +0,0 @@
class CommitLogsController < ApplicationController
def create
tip_exception "未认证" unless params[:token].to_s == "7917908927b6f1b792f2027a08a8b24a2de42c1692c2fd45da0dee5cf90a5af5"
ref = params[:ref]
user_name = params[:pusher][:login]
user_mail = params[:pusher][:email]
user = User.find_by(mail: user_mail)
user = User.find_by(login: user_name) if user.blank?
repository_id = params[:repository][:id]
repository_name = params[:repository][:name]
repository_full_name = params[:repository][:full_name]
owner_name = repository_full_name.split("/")[0]
owner = User.find_by(login: owner_name)
project = Project.where(identifier: repository_name).where(user_id: owner&.id)&.first
project = Project.where(identifier: repository_name).where(gpid: repository_id)&.first if project.blank?
project.update_column(:updated_on, Time.now) if project.present?
params[:commits].each do |commit|
commit_id = commit[:id]
message = commit[:message]
CommitLog.create(user: user, project: project, repository_id: repository_id,
name: repository_name, full_name: repository_full_name,
ref: ref, commit_id: commit_id, message: message)
# 统计数据新增
CacheAsyncSetJob.perform_later("project_common_service", {commits: 1}, project.id)
end
end
end

View File

@ -6,33 +6,22 @@ class CompareController < ApplicationController
end end
def show def show
if params[:type] == "sha"
load_compare_params
@compare_result ||= gitea_compare(@base, @head)
else
load_compare_params load_compare_params
compare compare
@merge_status, @merge_message = get_merge_message @merge_status, @merge_message = get_merge_message
end end
@page_size = page_size <= 0 ? 1 : page_size
@page_limit = page_limit <=0 ? 15 : page_limit
@page_offset = (@page_size -1) * @page_limit
Rails.logger.info("+========#{@page_size}-#{@page_limit}-#{@page_offset}")
end
private private
def get_merge_message def get_merge_message
if @base.blank? || @head.blank? if @base.blank? || @head.blank?
return -2, "请选择分支" return -2, "请选择分支"
else else
return -2, "目标仓库未开启合并请求PR功能" unless @project.has_menu_permission("pulls")
if @head.include?(":") if @head.include?(":")
fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take fork_project = @project.forked_projects.joins(:owner).where(users: {login: @head.to_s.split("/")[0]}).take
return -2, "请选择正确的仓库" unless fork_project.present? return -2, "请选择正确的仓库" unless fork_project.present?
@exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take @exist_pullrequest = @project.pull_requests.where(is_original: true, head: @head.to_s.split(":")[1], base: @base, status: 0, fork_project_id: fork_project.id).take
else else
@exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).last @exist_pullrequest = @project.pull_requests.where(is_original: false, head: @base, base: @head, status: 0).take
end end
if @exist_pullrequest.present? if @exist_pullrequest.present?
return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>" return -2, "在这些分支之间的合并请求已存在:<a href='/#{@owner.login}/#{@project.identifier}/pulls/#{@exist_pullrequest.id}'>#{@exist_pullrequest.try(:title)}</a>"
@ -53,22 +42,12 @@ class CompareController < ApplicationController
end end
def load_compare_params def load_compare_params
# @base = Addressable::URI.unescape(params[:base]) @base = Addressable::URI.unescape(params[:base])
@base = params[:base].include?(":") ? Addressable::URI.unescape(params[:base].split(":")[0]) + ':' + Base64.decode64(params[:base].split(":")[1]) : Base64.decode64(params[:base]) @head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head]
@head = params[:head].include?('.json') ? params[:head][0..-6] : params[:head]
# @head = Addressable::URI.unescape(@head)
@head = @head.include?(":") ? Addressable::URI.unescape(@head.split(":")[0]) + ':' + Base64.decode64(@head.split(":")[1]) : Base64.decode64(@head)
end end
def gitea_compare(base, head) def gitea_compare(base, head)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, Addressable::URI.escape(base), Addressable::URI.escape(head), current_user.gitea_token) Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
end
def page_size
params.fetch(:page, 1).to_i
end
def page_limit
params.fetch(:limit, 15).to_i
end end
end end

View File

@ -18,15 +18,15 @@ module Acceleratorable
end end
def accelerator_domain def accelerator_domain
GiteaService.gitea_config[:accelerator]["domain"] Gitea.gitea_config[:accelerator]["domain"]
end end
def accelerator_username def accelerator_username
GiteaService.gitea_config[:accelerator]["access_key_id"] Gitea.gitea_config[:accelerator]["access_key_id"]
end end
def config_accelerator? def config_accelerator?
GiteaService.gitea_config[:accelerator].present? Gitea.gitea_config[:accelerator].present?
end end
def is_foreign_url?(clone_addr) def is_foreign_url?(clone_addr)

View File

@ -1,20 +0,0 @@
module Api::ProjectHelper
extend ActiveSupport::Concern
def load_project
namespace = params[:owner]
repo = params[:repo]
@project, @owner = Project.find_with_namespace(namespace, repo)
if @project
logger.info "###########project founded"
@project
else
logger.info "###########project not found"
@project = nil
render_not_found and return
end
@project
end
end

View File

@ -1,19 +0,0 @@
module Api::PullHelper
extend ActiveSupport::Concern
def load_pull_request
pull_request_id = params[:pull_id] || params[:id]
@pull_request = @project.pull_requests.where(gitea_number: pull_request_id).where.not(id: pull_request_id).take || PullRequest.find_by_id(pull_request_id)
@issue = @pull_request&.issue
if @pull_request
logger.info "###########pull_request founded"
@pull_request
else
logger.info "###########pull_request not found"
@pull_request = nil
render_not_found and return
end
@pull_request
end
end

View File

@ -1,28 +0,0 @@
module Api::UserHelper
extend ActiveSupport::Concern
def load_observe_user
username = params[:owner]
@observe_user = User.find_by(login: username)
if @observe_user
logger.info "###########observe_user not founded"
@observe_user
else
logger.info "###########observe_user not found"
@observe_user = nil
render_not_found and return
end
@observe_user
end
# 是否具有查看用户或编辑用户的权限
def check_auth_for_observe_user
return render_forbidden unless current_user.admin? || @observe_user.id == current_user.id
end
def strip(str)
str.to_s.strip.presence
end
end

View File

@ -160,9 +160,9 @@ module Ci::CloudAccountManageable
state = SecureRandom.hex(8) state = SecureRandom.hex(8)
# redirect_uri eg: # redirect_uri eg:
# https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805 # https://localhost:3000/login/oauth/authorize?client_id=94976481-ad0e-4ed4-9247-7eef106007a2&redirect_uri=http%3A%2F%2F121.69.81.11%3A80%2Flogin&response_type=code&state=9cab990b9cfb1805
# redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login") redirect_uri = CGI.escape("#{@cloud_account.drone_url}/login")
# clientId = client_id(oauth) clientId = client_id(oauth)
grant_url = "#{@cloud_account.drone_url}/login" grant_url = "#{Gitea.gitea_config[:domain]}/login/oauth/authorize?client_id=#{clientId}&redirect_uri=#{redirect_uri}&response_type=code&state=#{state}"
logger.info "[gitea] grant_url: #{grant_url}" logger.info "[gitea] grant_url: #{grant_url}"
conn = Faraday.new(url: grant_url) do |req| conn = Faraday.new(url: grant_url) do |req|
@ -188,7 +188,6 @@ module Ci::CloudAccountManageable
response = conn.get response = conn.get
logger.info "[drone] response headers: #{response.headers}" logger.info "[drone] response headers: #{response.headers}"
# true
response.headers['location'].include?('error') ? false : true response.headers['location'].include?('error') ? false : true
end end

View File

@ -35,15 +35,15 @@ module LaboratoryHelper
# my_projects: "/users/#{current_user.try(:login)}/projects", # my_projects: "/users/#{current_user.try(:login)}/projects",
# my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist", # my_projects: "https://www.trustie.net/users/#{current_user.try(:login)}/user_projectlist",
{ {
new_syllabuses: "https://forge.educoder.net/syllabuses/new", new_syllabuses: "https://www.trustie.net/syllabuses/new",
new_course: "https://forge.educoder.net/courses/new", new_course: "https://www.trustie.net/courses/new",
edit_account: "https://forge.educoder.net/my/account", edit_account: "https://www.trustie.net/my/account",
my_courses: "https://forge.educoder.net/users/#{current_user.try(:login)}/user_courselist", my_courses: "https://www.trustie.net/users/#{current_user.try(:login)}/user_courselist",
my_projects: "/users/#{current_user.try(:login)}/projects", my_projects: "/users/#{current_user.try(:login)}/projects",
my_organ: "https://forge.educoder.net/users/#{current_user.try(:login)}/user_organizations", my_organ: "https://www.trustie.net/users/#{current_user.try(:login)}/user_organizations",
default_url: "https://www.educoder.net/", default_url: Rails.application.config_for(:configuration)['platform_url'],
tiding_url: "https://www.educoder.net/users/#{current_user.try(:login)}/user_tidings", tiding_url: "https://www.trustie.net/users/#{current_user.try(:login)}/user_messages",
register_url: "https://www.educoder.net/user/register" register_url: "https://www.trustie.net/login?login=false"
} }
end end
end end

View File

@ -11,7 +11,7 @@ module LoginHelper
def set_autologin_cookie(user) def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin") token = Token.get_or_create_permanent_login_token(user, "autologin")
# sync_user_token_to_trustie(user.login, token.value) sync_user_token_to_trustie(user.login, token.value)
Rails.logger.info "###### def set_autologin_cookie and get_or_create_permanent_login_token result: #{token&.value}" Rails.logger.info "###### def set_autologin_cookie and get_or_create_permanent_login_token result: #{token&.value}"
cookie_options = { cookie_options = {
@ -108,15 +108,10 @@ module LoginHelper
def sync_pwd_to_gitea!(user, hash={}) def sync_pwd_to_gitea!(user, hash={})
return true if user.is_sync_pwd? return true if user.is_sync_pwd?
sync_params = { sync_params = { email: user.mail }
login_name: user.name,
source_id: 0,
email: user.mail
}
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash)) interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params.merge(hash))
if interactor.success? if interactor.success?
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########" Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea success _########"
user.update_column(:is_sync_pwd, true)
true true
else else
Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}" Rails.logger.info "########_ login is #{user.login} sync_pwd_to_gitea fail!: #{interactor.error}"

View File

@ -1,82 +1,30 @@
module RegisterHelper module RegisterHelper
extend ActiveSupport::Concern extend ActiveSupport::Concern
def autologin_register(username, email, password, platform = 'forge', phone = nil, nickname =nil, need_edit_info = false) def autologin_register(username, email, password, platform= 'forge')
result = {message: nil, user: nil} result = {message: nil, user: nil}
email = email.blank? ? "#{username}@example.org" : email
user = User.new(admin: false, login: username, mail: email, type: "User") user = User.new(admin: false, login: username, mail: email, type: "User")
user.password = password user.password = password
user.platform = platform user.platform = platform
user.phone = phone if phone.present?
user.nickname = nickname if nickname.present?
if need_edit_info
user.need_edit_info
else
user.activate user.activate
end
return unless user.valid? return unless user.valid?
create_gitea_user!(user, username, email, password)
end
def create_gitea_user!(forge_user, username, email, password=random_password)
interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password}) interactor = Gitea::RegisterInteractor.call({username: username, email: email, password: password})
result = {} if interactor.success?
if interactor.success? || interactor.result[:message].to_s.include?("已被注册") gitea_user = interactor.result
gitea_user = interactor.result[:message].to_s.include?("已被注册") ? Gitea::User::GetService.call(username, password) : interactor.result
Rails.logger.info "##### [gitea] create_gitea_user result: #{gitea_user}"
if gitea_user[:body].present?
result = Gitea::User::GenerateTokenService.call(username, password) result = Gitea::User::GenerateTokenService.call(username, password)
forge_user.gitea_token = result['sha1'] user.gitea_token = result['sha1']
forge_user.gitea_uid = gitea_user[:body]['id'] if gitea_user[:body].present? && gitea_user[:body]['id'] !=0 user.gitea_uid = gitea_user[:body]['id']
forge_user.mail = email if user.save!
if forge_user.save UserExtension.create!(user_id: user.id)
UserExtension.create!(user_id: forge_user.id) if forge_user.user_extension.blank? result[:user] = {id: user.id, token: user.gitea_token}
result[:user] = {id: forge_user.id, token: forge_user.gitea_token}
end end
else else
result[:message] = interactor.result[:message] result[:message] = interactor.error
end
else
Rails.logger.info "##### [gitea] create_gitea_user result: #{interactor.result[:message]}"
result[:message] = interactor.result[:message]
end end
result result
end end
def random_password
"#{Random.rand(11111111)}"
end
def auto_update(user, params={})
return if params.blank?
result = {message: nil, user: nil}
before_login = user.login
user.login = params[:username]
user.password = params[:password]
user.mail = params[:email]
if user.save!
sync_params = {
password: params[:password].to_s,
email: params[:email],
login_name: params[:username],
new_name: params[:username],
source_id: 0
}
interactor = Gitea::User::UpdateInteractor.call(before_login, sync_params)
if interactor.success?
result[:user] = user
else
result[:message] = '用户同步Gitea失败!'
end
else
result[:message] = user.errors.full_messages.join(",")
return
end
end
end end

View File

@ -3,7 +3,7 @@ module RenderHelper
render json: { status: 0, message: 'success' }.merge(data) render json: { status: 0, message: 'success' }.merge(data)
end end
def render_error(message = '', status=-1) def render_error(status = -1, message = '')
render json: { status: status, message: message } render json: { status: status, message: message }
end end

View File

@ -5,26 +5,7 @@ module Repository::LanguagesPercentagable
result = Gitea::Repository::Languages::ListService.call(@owner.login, result = Gitea::Repository::Languages::ListService.call(@owner.login,
@repository.identifier, current_user&.gitea_token) @repository.identifier, current_user&.gitea_token)
@transform_language = @transform_language = result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil result[:status] === :success ? hash_transform_precentagable(result[:body]) : nil
update_project_language(@transform_language) unless @transform_language.nil?
@transform_language
end
def update_project_language(language)
return if @project.project_language.present?
db_language = ProjectLanguage.find_or_create_by!(name: language.keys.first.downcase.upcase_first)
@project.update_column(:project_language_id, db_language.id)
rescue
return
update_project_language(@transform_language) unless @transform_language.nil?
@transform_language
end
def update_project_language(language)
db_language = ProjectLanguage.find_or_create_by!(name: language.keys.first.downcase.upcase_first)
@project.update_column(:project_language_id, db_language.id) if @project.project_language_id.nil?
rescue
return
end end
# hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781} # hash eq:{"JavaScript": 301681522,"Ruby": 1444004,"Roff": 578781}

View File

@ -6,23 +6,14 @@ class ForksController < ApplicationController
def create def create
@new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call @new_project = Projects::ForkService.new(current_user, @project, params[:organization]).call
# TODO: fix Educoder shixun
if @new_project.persisted?
ProjectScore.create(:project_id => @new_project.id, :score => 0) if @new_project.project_score.nil?
project_info = ProjectInfo.new(:user_id => current_user.id, :project_id => @new_project.id)
@project.project_infos << project_info
end
end end
private private
def authenticate_project! def authenticate_project!
Rails.logger.info "authenticate_project1=======================#{current_user&.id},#{@project.user_id}"
Rails.logger.info "authenticate_project2=======================#{current_user&.id == @project.user_id}"
if current_user&.id == @project.user_id if current_user&.id == @project.user_id
render_result(-1, "自己不能fork自己的项目") render_result(-1, "自己不能fork自己的项目")
elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier) elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier)
render_result(0, "fork失败你已拥有了这个项目") render_result(-1, "fork失败你已拥有了这个项目")
end end
# return if current_user != @project.owner # return if current_user != @project.owner
# render_result(-1, "自己不能fork自己的项目") # render_result(-1, "自己不能fork自己的项目")

View File

@ -2,12 +2,12 @@ class IssueTagsController < ApplicationController
before_action :require_login, except: [:index] before_action :require_login, except: [:index]
before_action :load_repository before_action :load_repository
before_action :set_user before_action :set_user
before_action :check_issue_tags_permission before_action :check_issue_permission, except: :index
before_action :set_issue_tag, only: [:edit, :update, :destroy] before_action :set_issue_tag, only: [:edit, :update, :destroy]
def index def index
issue_tags = @project.issue_tags.includes(:issues).reorder("issue_tags.#{order_name} #{order_type}") issue_tags = @project.issue_tags.reorder("#{order_name} #{order_type}")
@user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user)) @user_admin_or_member = current_user.present? && (current_user.admin || @project.member?(current_user))
@page = params[:page] || 1 @page = params[:page] || 1
@limit = params[:limit] || 15 @limit = params[:limit] || 15
@ -17,7 +17,7 @@ class IssueTagsController < ApplicationController
def create def create
title = params[:name].to_s.strip.first(15) title = params[:name].to_s.strip.first(10)
desc = params[:description].to_s.first(30) desc = params[:description].to_s.first(30)
color = params[:color] || "#ccc" color = params[:color] || "#ccc"
@ -29,7 +29,7 @@ class IssueTagsController < ApplicationController
if title.present? if title.present?
if IssueTag.exists?(name: title, project_id: @project.id) if IssueTag.exists?(name: title, project_id: @project.id)
normal_status(-1, "项目标记已存在") normal_status(-1, "标签已存在")
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
@ -37,12 +37,12 @@ class IssueTagsController < ApplicationController
if issue_tag.save if issue_tag.save
# gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call # gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
# if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"]) # if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
normal_status(0, "项目标记创建成功!") # normal_status(0, "标签创建成功")
# else # else
# normal_status(-1, "项目标记创建失败") # normal_status(-1, "标签创建失败")
# end # end
else else
normal_status(-1, "项目标记创建失败") normal_status(-1, "标签创建失败")
end end
rescue => e rescue => e
puts "create version release error: #{e.message}" puts "create version release error: #{e.message}"
@ -51,7 +51,7 @@ class IssueTagsController < ApplicationController
end end
end end
else else
normal_status(-1, "项目标记名称不能为空") normal_status(-1, "标签名称不能为空")
end end
end end
@ -60,8 +60,8 @@ class IssueTagsController < ApplicationController
end end
def update def update
title = params[:name].to_s.strip.first(15) title = params[:name]
desc = params[:description].to_s.first(30) desc = params[:description]
color = params[:color] || "#ccc" color = params[:color] || "#ccc"
tag_params = { tag_params = {
@ -71,19 +71,19 @@ class IssueTagsController < ApplicationController
} }
if title.present? if title.present?
if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title) if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title)
normal_status(-1, "项目标记已存在") normal_status(-1, "标签已存在")
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
if @issue_tag.update_attributes(tag_params) if @issue_tag.update_attributes(tag_params)
# gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call # gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
# if gitea_tag # if gitea_tag
# normal_status(0, "项目标记更新成功") # normal_status(0, "标签更新成功")
# else # else
# normal_status(-1, "项目标记更新失败") # normal_status(-1, "标签更新失败")
# end # end
else else
normal_status(-1, "项目标记更新失败") normal_status(-1, "标签更新失败")
end end
rescue => e rescue => e
puts "create version release error: #{e.message}" puts "create version release error: #{e.message}"
@ -92,7 +92,7 @@ class IssueTagsController < ApplicationController
end end
end end
else else
normal_status(-1, "项目标记名称不能为空") normal_status(-1, "标签名称不能为空")
end end
end end
@ -102,12 +102,12 @@ class IssueTagsController < ApplicationController
if @issue_tag.destroy if @issue_tag.destroy
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call # issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
# if issue_tag # if issue_tag
# normal_status(0, "项目标记删除成功") # normal_status(0, "标签删除成功")
# else # else
# normal_status(-1, "项目标记删除失败") # normal_status(-1, "标签删除失败")
# end # end
else else
normal_status(-1, "项目标记删除失败") normal_status(-1, "标签删除失败")
end end
rescue => e rescue => e
puts "create version release error: #{e.message}" puts "create version release error: #{e.message}"
@ -122,16 +122,16 @@ class IssueTagsController < ApplicationController
@user = @project.owner @user = @project.owner
end end
def check_issue_tags_permission def check_issue_permission
unless @project.manager?(current_user) || current_user.admin? unless @project.member?(current_user) || current_user.admin?
return render_forbidden('你不是管理员,没有权限操作') normal_status(-1, "您没有权限")
end end
end end
def set_issue_tag def set_issue_tag
@issue_tag = IssueTag.find_by_id(params[:id]) @issue_tag = IssueTag.find_by_id(params[:id])
unless @issue_tag.present? unless @issue_tag.present?
normal_status(-1, "项目标记不存在") normal_status(-1, "标签不存在")
end end
end end

View File

@ -15,7 +15,6 @@ class IssuesController < ApplicationController
include TagChosenHelper include TagChosenHelper
def index def index
@user_operate_issue = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user))
@user_admin_or_member = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user) || @project.is_public?) @user_admin_or_member = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user) || @project.is_public?)
issues = @project.issues.issue_issue.issue_index_includes issues = @project.issues.issue_issue.issue_index_includes
issues = issues.where(is_private: false) unless @user_admin_or_member issues = issues.where(is_private: false) unless @user_admin_or_member
@ -24,13 +23,13 @@ class IssuesController < ApplicationController
@filter_issues = @all_issues @filter_issues = @all_issues
@filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD @filter_issues = @filter_issues.where.not(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::ADD
@filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING @filter_issues = @filter_issues.where(status_id: IssueStatus::CLOSED) if params[:status_type].to_i == IssueStatus::SOLVING
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present? @filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED) @open_issues = @all_issues.where.not(status_id: IssueStatus::CLOSED)
@close_issues = @all_issues.where(status_id: IssueStatus::CLOSED) @close_issues = @all_issues.where(status_id: IssueStatus::CLOSED)
@assign_to_me = @filter_issues.where(assigned_to_id: current_user&.id)
@my_published = @filter_issues.where(author_id: current_user&.id)
scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue") scopes = Issues::ListQueryService.call(issues,params.delete_if{|k,v| v.blank?}, "Issue")
@issues_size = scopes.size @issues_size = scopes.size
@assign_to_me = scopes.where(assigned_to_id: current_user&.id)
@my_published = scopes.where(author_id: current_user&.id)
@issues = paginate(scopes) @issues = paginate(scopes)
respond_to do |format| respond_to do |format|
@ -109,7 +108,7 @@ class IssuesController < ApplicationController
def create def create
issue_params = issue_send_params(params) 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! Issues::CreateForm.new({subject:issue_params[:subject]}).validate!
@issue = Issue.new(issue_params) @issue = Issue.new(issue_params)
if @issue.save! if @issue.save!
SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('IssueAssigned', current_user.id, @issue&.id) if Site.has_notice_menu?
@ -126,15 +125,9 @@ class IssuesController < ApplicationController
end end
end end
if params[:issue_tag_ids].present? if params[:issue_tag_ids].present?
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
params[:issue_tag_ids].each do |tag| params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag) IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end end
else
return normal_status(-1, "请输入正确的标记。")
end
end end
if params[:assigned_to_id].present? if params[:assigned_to_id].present?
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id, Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
@ -149,13 +142,11 @@ class IssuesController < ApplicationController
end end
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" 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 AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
render json: {status: 0, message: "创建成", id: @issue.id} render json: {status: 0, message: "创建成", id: @issue.id}
else else
normal_status(-1, "创建失败") normal_status(-1, "创建失败")
end end
@ -174,17 +165,10 @@ class IssuesController < ApplicationController
last_token = @issue.token last_token = @issue.token
last_status_id = @issue.status_id last_status_id = @issue.status_id
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank? @issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
if params[:issue_tag_ids].present? if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all @issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag| params[:issue_tag_ids].each do |tag|
next if tag == [""] IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end end
end end
@ -223,7 +207,7 @@ class IssuesController < ApplicationController
normal_status(-1, "不允许修改为关闭状态") normal_status(-1, "不允许修改为关闭状态")
else else
issue_params = issue_send_params(params).except(:issue_classify, :author_id, :project_id) 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! Issues::UpdateForm.new({subject:issue_params[:subject]}).validate!
if @issue.update_attributes(issue_params) if @issue.update_attributes(issue_params)
if @issue&.pull_request.present? 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('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?
@ -247,7 +231,7 @@ class IssuesController < ApplicationController
end end
if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时 if params[:status_id].to_i == 5 #任务由非关闭状态到关闭状态时
@issue.issue_times.update_all(end_time: Time.now) @issue.issue_times.update_all(end_time: Time.now)
# @issue.update_closed_issues_count_in_project! @issue.update_closed_issues_count_in_project!
if @issue.issue_type.to_s == "2" && last_status_id != 5 if @issue.issue_type.to_s == "2" && last_status_id != 5
if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时才给token if @issue.assigned_to_id.present? && last_status_id == 3 #只有当用户完成100%时才给token
post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login)) post_to_chain("add", @issue.token, @issue.get_assign_user.try(:login))
@ -489,8 +473,7 @@ class IssuesController < ApplicationController
end end
def operate_issue_permission def operate_issue_permission
@issue = Issue.find_by_id(params[:id]) unless @issue.present? return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || @project.is_public?)
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || (@project.is_public && @issue.nil?) || (@project.is_public && @issue.present? && @issue.author_id == current_user.id))
end end
def export_issues(issues) def export_issues(issues)

View File

@ -23,7 +23,6 @@ class JournalsController < ApplicationController
normal_status(-1, "评论内容不能为空") normal_status(-1, "评论内容不能为空")
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Journals::CreateForm.new({notes: notes.to_s.strip.blank? ? notes.to_s.strip : notes.to_s.strip.b}).validate!
journal_params = { journal_params = {
journalized_id: @issue.id , journalized_id: @issue.id ,
journalized_type: "Issue", journalized_type: "Issue",
@ -54,9 +53,6 @@ class JournalsController < ApplicationController
end end
end end
end end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end end
def destroy def destroy
@ -75,7 +71,6 @@ class JournalsController < ApplicationController
def update def update
content = params[:content] content = params[:content]
if content.present? 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) if @journal.update_attribute(:notes, content)
normal_status(0, "更新成功") normal_status(0, "更新成功")
else else
@ -84,9 +79,7 @@ class JournalsController < ApplicationController
else else
normal_status(-1, "评论的内容不能为空") normal_status(-1, "评论的内容不能为空")
end end
rescue Exception => exception
puts exception.message
normal_status(-1, exception.message)
end end
def get_children_journals def get_children_journals

View File

@ -21,14 +21,6 @@ class MainController < ApplicationController
uid_logger("main start is #{cookies[:_educoder_session]}") uid_logger("main start is #{cookies[:_educoder_session]}")
end end
if params[:path] && params[:path].start_with?('projects/')
project_id = params[:path].split("/")[1]
project = Project.find_by_id(project_id)
if project.present?
return redirect_to("/projects/#{project.owner.login}/#{project.identifier}", status: 301)
end
end
# TODO: 这块之后需要整合者架构重新变化统一跳转到index后再路由分发 # TODO: 这块之后需要整合者架构重新变化统一跳转到index后再路由分发
if params[:path] && params[:path]&.include?("h5educoderbuild") && params[:path].split("/").first == "h5educoderbuild" if params[:path] && params[:path]&.include?("h5educoderbuild") && params[:path].split("/").first == "h5educoderbuild"
render file: 'public/h5educoderbuild/index.html', :layout => false, :content_type=> 'text/html' render file: 'public/h5educoderbuild/index.html', :layout => false, :content_type=> 'text/html'

View File

@ -1,56 +0,0 @@
class MarkFilesController < ApplicationController
before_action :require_login
before_action :load_project
before_action :load_pull_request
def index
@files_result = Gitea::PullRequest::FilesService.call(@owner.login, @project.identifier, @pull_request.gitea_number, current_user&.gitea_token, { "only-file-name": true })
@mark_files = MarkFile.where(pull_request_id: @pull_request.id)
end
def create
# unless @pull_request.mark_files.present?
# MarkFile.bulk_insert(*%i[pull_request_id, file_path_sha file_path created_at updated_at]) do |worker|
# @files_result['Files'].each do |file|
# worker.add(pull_request_id: @pull_request.id, file_path_sha: SecureRandom.uuid.gsub("-", ""), file_path: file['Name'])
# end
# end
# end
end
def mark_file_as_unread
tip_exception "参数错误" if params[:file_path_sha].blank?
file_path = Base64.strict_decode64(params[:file_path_sha].to_s)
mark_file = @pull_request.mark_files.find_or_initialize_by(file_path_sha: params[:file_path_sha])
mark_file.file_path = file_path
mark_file.user_id = current_user.id
mark_file.mark_as_read = false
mark_file.save
render_ok
rescue Exception => e
tip_exception "参数解析错误"
end
def mark_file_as_read
tip_exception "参数错误" if params[:file_path_sha].blank?
file_path = Base64.strict_decode64(params[:file_path_sha].to_s)
mark_file = @pull_request.mark_files.find_or_initialize_by(file_path_sha: params[:file_path_sha])
mark_file.file_path = file_path
mark_file.user_id = current_user.id
mark_file.mark_as_read = true
mark_file.save
render_ok
rescue Exception => e
tip_exception "参数解析错误"
end
private
def review_params
params.require(:review).permit(:content, :commit_id, :status)
end
def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
end

View File

@ -3,19 +3,11 @@ class MembersController < ApplicationController
before_action :load_project before_action :load_project
before_action :find_user_with_id, only: %i[create remove change_role] before_action :find_user_with_id, only: %i[create remove change_role]
before_action :check_user_profile_completed, only: [:create] before_action :check_user_profile_completed, only: [:create]
before_action :operate! before_action :operate!, except: %i[index]
before_action :check_member_exists!, only: %i[create] before_action :check_member_exists!, only: %i[create]
before_action :check_member_not_exists!, only: %i[remove change_role] before_action :check_member_not_exists!, only: %i[remove change_role]
def create def create
if @user.gitea_token.blank?
result = Gitea::User::GetService.call(@user.login)
if result[:status] == :error
# gitea不存在用户@user,直接注册
user_result = create_gitea_user!(@user, @user.login, @user.mail)
return render_error(user_result[:message]) if user_result[:message]
end
end
interactor = Projects::AddMemberInteractor.call(@project.owner, @project, @user) interactor = Projects::AddMemberInteractor.call(@project.owner, @project, @user)
SendTemplateMessageJob.perform_later('ProjectJoined', current_user.id, @user.id, @project.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectJoined', current_user.id, @user.id, @project.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('ProjectMemberJoined', current_user.id, @user.id, @project.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectMemberJoined', current_user.id, @user.id, @project.id) if Site.has_notice_menu?
@ -34,9 +26,6 @@ class MembersController < ApplicationController
@total_count = scope.size @total_count = scope.size
@members = paginate(scope) @members = paginate(scope)
if @project.owner.is_a?(Organization) && (params[:page].to_i == 1 || params[:page].blank?) && !@project.members.exists?(user_id: current_user.id)
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take
end
end end
def remove def remove
@ -72,14 +61,11 @@ class MembersController < ApplicationController
end end
def check_member_exists! def check_member_exists!
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take return render_error("user_id为#{params[:user_id]}的用户已经是项目成员") if member_exists?
return render_error("#{@user&.nickname}已经是项目成员") if member_exists? || (params[:user_id].to_i == current_user.id && @current_user_header_team.present?)
end end
def check_member_not_exists! def check_member_not_exists!
@current_user_header_team = Team.joins(:team_users, :team_projects).where(team_projects: {project_id: @project.id}, team_users: {user_id: current_user.id}).order(authorize: :desc).take return render_error("user_id为#{params[:user_id]}的用户还不是项目成员") unless member_exists?
return render_error("用户为组织成员,请到组织下操作!") if (params[:user_id].to_i == current_user.id && @current_user_header_team.present?) && !member_exists?
return render_error("#{@user&.nickname}还不是项目成员") unless member_exists?
end end
def check_user_profile_completed def check_user_profile_completed

View File

@ -1,33 +0,0 @@
class NoticesController < ApplicationController
def create
return tip_exception("参数有误") if params["source"].blank?
user_id = params[:user_id]
if params["source"] == "CompetitionBegin"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionBegin', user_id, competition_id)
elsif params["source"] == "CompetitionResult"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionResult', user_id, competition_id)
elsif params["source"] == "CompetitionReview"
competition_id = params[:competition_id]
SendTemplateMessageJob.perform_later('CompetitionReview', user_id, competition_id)
elsif params["source"] == "CustomTip"
users_id = params[:users_id]
props = params[:props].to_unsafe_hash
return tip_exception("参数有误") unless props.is_a?(Hash) && users_id.is_a?(Array)
template_id = params[:template_id]
SendTemplateMessageJob.perform_later('CustomTip', users_id, template_id, props)
else
tip_exception("#{params["source"]}未配置")
end
render_ok
end
private
def params_props
params.require(:notice).permit(:props)
end
end

View File

@ -1,17 +0,0 @@
class NpsController < ApplicationController
before_action :require_login
# close,关闭
# createIssue,创建issue
# createPullRequest,创建PR
# auditPullRequest,审核PR
# indexProject,项目主页
# createProject,创建项目
# createOrganization,创建组织
def create
tip_exception "缺少参数" if params[:action_id].blank? || params[:action_type].blank?
UserNp.create(:action_id => params[:action_id].to_i, :action_type => params[:action_type], :user_id => User.current.id, :score => params[:score].to_f, memo: params[:memo])
render_ok
end
end

View File

@ -2,7 +2,6 @@ class Oauth::BaseController < ActionController::Base
include RenderHelper include RenderHelper
include LoginHelper include LoginHelper
include ControllerRescueHandler include ControllerRescueHandler
include RegisterHelper
# include LaboratoryHelper # include LaboratoryHelper
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
@ -23,7 +22,7 @@ class Oauth::BaseController < ActionController::Base
end end
def auth_hash def auth_hash
# Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}") Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}")
request.env['omniauth.auth'] request.env['omniauth.auth']
end end

View File

@ -1,68 +0,0 @@
class Oauth::CallbacksController < Oauth::BaseController
def create
process_callback
rescue Exception => e
Rails.logger.info "授权失败:#{e}"
tip_exception("授权失败")
end
private
def config_providers
config = Rails.application.config_for(:configuration)
config.dig("oauth").keys
end
# QQ: {"ret":0,"msg":"","is_lost":0,"nickname":"颜值不算太高","gender":"男","gender_type":1,"province":"","city":"","year":"2013","constellation":"","figureurl":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/30","figureurl_1":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/50","figureurl_2":"http://qzapp.qlogo.cn/qzapp/101508858/0F860F4B329768F47B22341C5FD9089C/100","figureurl_qq_1":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=40\u0026t=1568887757","figureurl_qq_2":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=100\u0026t=1568887757","figureurl_qq":"http://thirdqq.qlogo.cn/g?b=oidb\u0026k=My3segFVHFqVmauibJQUltw\u0026s=140\u0026t=1568887757","figureurl_type":"1","is_yellow_vip":"0","vip":"0","yellow_vip_level":"0","level":"0","is_yellow_year_vip":"0"}
def process_callback
Rails.logger.info("[OAuth2] omniauth.auth -> #{request.env['omniauth.auth'].inspect}")
if auth_hash.blank?
redirect_to("/login") && return
end
new_user = false
platform = auth_hash[:provider]
uid = auth_hash[:uid]
mail = auth_hash.info.email || nil
nickname = ["gitee", "github"].include?(platform) ? auth_hash.info.name : auth_hash.info.nickname
open_user = "OpenUsers::#{platform.to_s.capitalize}".constantize.find_by(uid: uid)
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
has_user = User.find_by(mail: mail)
if has_user.present?
"OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user_id: has_user.id, uid: uid, extra: auth_hash.extra)
successful_authentication(has_user)
else
new_user = true
login = build_login_name(platform, auth_hash.info.nickname)
mail = "#{login}@example.org" if mail.blank?
code = %W(0 1 2 3 4 5 6 7 8 9)
rand_password = code.sample(10).join
reg_result = autologin_register(login, mail, rand_password, platform, nil, nickname)
Rails.logger.info("[OAuth2] omniauth.auth [reg_result] #{reg_result} ")
if reg_result[:message].blank?
open_user = "OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user_id: reg_result[:user][:id], uid: uid, extra: auth_hash.extra)
successful_authentication(open_user.user)
else
tip_exception(reg_result.present? ? reg_result[:message] : "授权失败")
end
end
else
"OpenUsers::#{platform.to_s.capitalize}".constantize.create!(user: current_user, uid: login, extra: auth_hash.extra)
end
end
redirect_to root_path(new_user: new_user)
end
# gitee,github nickname=login,如果系统未占用保留原用户名
def build_login_name(provider, nickname)
if ["gitee", "github"].include?(provider) && User.find_by(login: nickname).blank?
nickname
else
User.generate_user_login('p')
end
end
end

View File

@ -1,130 +0,0 @@
class ObRepositorySyncsController < ApplicationController
before_action :require_login
before_action :load_project
before_action :load_ob_repository_sync, except: [:create]
before_action :authenticate_user!
def index
render_ok(data: @ob_repository_sync)
end
def create
tip_exception "参数错误" if params[:github_address].blank? && params[:gitee_address].blank?
project_name ="#{@project.owner.name}:#{@project.identifier}"
service = ObRepositorySync::ApiService.new(project_name)
domain = GiteaService.gitea_config[:domain]
project_params = params.merge({ "gitlink_address": "#{domain}/#{@project.owner&.login}/#{@project.identifier}.git" })
res = service.create_projects(project_params)
tip_exception "保存失败: #{res["msg"]}" if res["code"].to_s != "200"
sync_id = res["data"]["id"]
ob_repository_sync = ObRepositorySync.find_or_initialize_by(project_id: @project.id)
ob_repository_sync.project_id = @project.id
ob_repository_sync.user_id = current_user.id
ob_repository_sync.name = project_name
ob_repository_sync.github_address = "#{params[:github_address]}"
ob_repository_sync.gitee_address = "#{params[:gitee_address]}"
ob_repository_sync.github_token = "#{params[:github_token]}"
ob_repository_sync.gitee_token = "#{params[:gitee_token]}"
ob_repository_sync.sync_id = sync_id
ob_repository_sync.save!
render_ok
end
def delete
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.delete_project @ob_repository_sync.sync_id
tip_exception "删除失败: #{res["msg"]}" if res["code"].to_s != "200"
if res["code"].to_s == "200"
@ob_repository_sync.destroy!
end
render_ok
end
def jobs
tip_exception "该项目未创建同步任务" if @ob_repository_sync.blank?
page = params[:page] || 1
limit = params[:limit] || 10
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
source = ""
if params[:type] && params[:type].to_s.downcase == "github"
source = "github_branch"
elsif params[:type] && params[:type].to_s.downcase == "gitee"
source = "gitee_branch"
end
res = service.get_projects_jobs(source, page, limit)
data = res["data"]["list"]
render_ok(count: res["data"]["total"], data: data)
end
def create_jobs
tip_exception "必须配置一个分支" if params[:github_branch].blank? && params[:gitee_branch].blank? && params[:gitlink_branch].blank?
ob_jobs = ObRepositorySyncJob.where(ob_repository_sync_id: @ob_repository_sync.id)
ob_jobs = ob_jobs.where(job_type: params[:job_type]) if params[:job_type].present?
ob_jobs = ob_jobs.where(github_branch: params[:github_branch]) if params[:github_branch].present?
ob_jobs = ob_jobs.where(gitee_branch: params[:gitee_branch]) if params[:gitee_branch].present?
ob_jobs = ob_jobs.where(gitlink_branch: params[:gitlink_branch]) if params[:gitlink_branch].present?
tip_exception "该分支组合已配置,不能重复!" if ob_jobs.count > 0
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.create_projects_jobs(params)
tip_exception "保存失败: #{res["msg"]}" if res["code"].to_s != "200"
job_id = res["data"]["id"]
job = ObRepositorySyncJob.new
job.ob_repository_sync_id = @ob_repository_sync.id
job.github_branch = "#{params[:github_branch]}"
job.gitee_branch = "#{params[:gitee_branch]}"
job.gitlink_branch = "#{params[:gitlink_branch]}"
job.job_type = "#{params[:job_type]}"
job.base = "#{params[:base]}"
job.job_id = job_id
job.save
render_ok
end
def delete_job
tip_exception "缺少参数job_id" if params[:job_id].blank?
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.delete_job params[:job_id]
tip_exception "删除失败: #{res["msg"]}" if res["code"].to_s != "200"
job = ObRepositorySyncJob.find_by(ob_repository_sync_id: @ob_repository_sync.id, job_id: params[:job_id])
job.destroy! if job.present?
render_ok
end
def start_job
tip_exception "缺少参数job_id" if params[:job_id].blank?
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.start_job params[:job_id]
tip_exception "启动错误: #{res["msg"]}" if res["code"].to_s != "200"
render_ok
end
def stop_job
tip_exception "缺少参数job_id" if params[:job_id].blank?
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.stop_job params[:job_id]
tip_exception "停止错误: #{res["msg"]}" if res["code"].to_s != "200"
render_ok
end
def job_logs
tip_exception "该项目未创建同步任务" if @ob_repository_sync.blank?
tip_exception "缺少参数job_id" if params[:job_id].blank?
service = ObRepositorySync::ApiService.new(@ob_repository_sync.name)
res = service.job_logs params[:job_id]
tip_exception "请求错误: #{res["msg"]}" if res["code"].to_s != "200"
render_ok(count: res["data"]["total"], data: res["data"]["list"])
end
private
def load_ob_repository_sync
@ob_repository_sync = ObRepositorySync.find_by(project_id: @project.id)
end
def authenticate_user!
return if @project.member?(current_user) || current_user.admin?
render_forbidden('你没有权限操作')
end
end

View File

@ -4,14 +4,8 @@ class Organizations::OrganizationUsersController < Organizations::BaseController
def index def index
@organization_users = @organization.organization_users.includes(:user) @organization_users = @organization.organization_users.includes(:user)
if params[:search].present?
search = params[:search].to_s.downcase search = params[:search].to_s.downcase
user_condition_users = User.like(search).to_sql @organization_users = @organization_users.joins(:user).merge(User.like(search))
team_condition_teams = User.joins(:teams).merge(@organization.teams.like(search)).to_sql
users = User.from("( #{user_condition_users} UNION #{team_condition_teams }) AS users")
@organization_users = @organization_users.where(user_id: users).distinct
end
@organization_users = kaminari_paginate(@organization_users) @organization_users = kaminari_paginate(@organization_users)
end end

View File

@ -28,10 +28,9 @@ class Organizations::OrganizationsController < Organizations::BaseController
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name]) tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
Organizations::CreateForm.new(organization_params.merge(original_name: "")).validate! Organizations::CreateForm.new(organization_params).validate!
@organization = Organizations::CreateService.call(current_user, organization_params) @organization = Organizations::CreateService.call(current_user, organization_params)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present? Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
Cache::V2::OwnerCommonService.new(@organization.id).reset
end end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
@ -40,16 +39,15 @@ class Organizations::OrganizationsController < Organizations::BaseController
def update def update
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Organizations::CreateForm.new(organization_params.merge(original_name: @organization.login)).validate! Organizations::CreateForm.new(organization_params).validate!
login = @organization.login login = @organization.login
@organization.login = organization_params[:name] if organization_params[:name].present? @organization.login = organization_params[:name] if organization_params[:name].present?
@organization.nickname = organization_params[:nickname] if organization_params[:nickname].present? @organization.nickname = organization_params[:nickname] if organization_params[:nickname].present?
@organization.save! @organization.save!
sync_organization_extension! sync_organization_extension!
Gitea::Organization::UpdateService.call(current_user.gitea_token, login, @organization.reload) Gitea::Organization::UpdateService.call(@organization.gitea_token, login, @organization.reload)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present? Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
Cache::V2::OwnerCommonService.new(@organization.id).reset
end end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
@ -59,16 +57,10 @@ class Organizations::OrganizationsController < Organizations::BaseController
def destroy def destroy
tip_exception("密码不正确") unless current_user.check_password?(password) tip_exception("密码不正确") unless current_user.check_password?(password)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
gitea_destroy = Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login) Gitea::Organization::DeleteService.call(@organization.gitea_token, @organization.login)
if gitea_destroy[:status] == 204
@organization.destroy! @organization.destroy!
end
render_ok render_ok
elsif gitea_destroy[:status] == 500
tip_exception("当组织内含有仓库时,无法删除此组织")
else
tip_exception("")
end
end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
tip_exception(e.message) tip_exception(e.message)

View File

@ -14,6 +14,22 @@ class Organizations::ProjectsController < Organizations::BaseController
@projects = paginate(@projects) @projects = paginate(@projects)
end end
#######################change#################################
def organizationBadge
watchers_count = @organization.watchers_count
@watchered = judge_level(watchers_count, 10, 20, 100)
@badge = organizationBadge.find_or_create_by(organization_id: @organization.id)
if @watchered != @badge.watched
@badge.watched = @watchered
@badge.save
end
render :json => {list: [{watchered: @watchered}], count: 1}
end
#######################change#################################
def search def search
tip_exception("请输入搜索关键词") if params[:search].nil? tip_exception("请输入搜索关键词") if params[:search].nil?
public_projects_sql = @organization.projects.where(is_public: true).to_sql public_projects_sql = @organization.projects.where(is_public: true).to_sql
@ -42,4 +58,17 @@ class Organizations::ProjectsController < Organizations::BaseController
def sort_direction def sort_direction
%w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc' %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc'
end end
def judge_level(judged, low, mid, high)
if judged < low
return 0
elsif judged < mid
return 1
elsif judged < high
return 2
else
return 3
end
end
end end

View File

@ -6,7 +6,6 @@ class Organizations::TeamProjectsController < Organizations::BaseController
def index def index
@team_projects = @team.team_projects @team_projects = @team.team_projects
@team_projects = paginate(@team_projects) @team_projects = paginate(@team_projects)
end end
@ -21,17 +20,6 @@ class Organizations::TeamProjectsController < Organizations::BaseController
tip_exception(e.message) tip_exception(e.message)
end end
def create_all
tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project
ActiveRecord::Base.transaction do
@organization.projects.each do |project|
TeamProject.build(@organization.id, @team.id, project.id)
end
Gitea::Organization::TeamProject::CreateAllService.call(@organization.gitea_token, @team.gtid, @organization.login)
render_ok
end
end
def destroy def destroy
tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@ -44,17 +32,6 @@ class Organizations::TeamProjectsController < Organizations::BaseController
tip_exception(e.message) tip_exception(e.message)
end end
def destroy_all
tip_exception("该组织团队项目包括组织所有项目,不允许更改") if @team.includes_all_project
ActiveRecord::Base.transaction do
@team.team_projects.each do |project|
project.destroy!
end
Gitea::Organization::TeamProject::DeleteAllService.call(@organization.gitea_token, @team.gtid, @organization.login)
render_ok
end
end
private private
def load_organization def load_organization
@organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id]) @organization = Organization.find_by(login: params[:organization_id]) || Organization.find_by(id: params[:organization_id])
@ -69,7 +46,7 @@ class Organizations::TeamProjectsController < Organizations::BaseController
end end
def load_operate_project def load_operate_project
@operate_project = @organization.projects.where(id: project_mark).take || @organization.projects.where(identifier: project_mark).take @operate_project = Project.find_by(id: project_mark) || Project.find_by(identifier: project_mark)
tip_exception("项目不存在") if @operate_project.nil? tip_exception("项目不存在") if @operate_project.nil?
end end

View File

@ -18,7 +18,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id) @team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id)
@organization_user = OrganizationUser.build(@organization.id, @operate_user.id) @organization_user = OrganizationUser.build(@organization.id, @operate_user.id)
SendTemplateMessageJob.perform_later('TeamJoined', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('OrganizationRole', @operate_user.id, @organization.id, @team.authorize_name) if Site.has_notice_menu?
Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login) Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
end end
rescue Exception => e rescue Exception => e
@ -31,7 +31,6 @@ class Organizations::TeamUsersController < Organizations::BaseController
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
@team_user.destroy! @team_user.destroy!
Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login) Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
SendTemplateMessageJob.perform_later('TeamLeft', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
org_team_users = @organization.team_users.where(user_id: @operate_user.id) org_team_users = @organization.team_users.where(user_id: @operate_user.id)
unless org_team_users.present? unless org_team_users.present?
@organization.organization_users.find_by(user_id: @operate_user.id).destroy! @organization.organization_users.find_by(user_id: @operate_user.id).destroy!

View File

@ -4,14 +4,6 @@ class Organizations::TeamsController < Organizations::BaseController
before_action :check_user_can_edit_org, only: [:create, :update, :destroy] before_action :check_user_can_edit_org, only: [:create, :update, :destroy]
def index def index
if params[:is_full].present?
if can_edit_org?
@teams = @organization.teams
else
@teams = []
end
else
#if @organization.is_owner?(current_user) || current_user.admin? #if @organization.is_owner?(current_user) || current_user.admin?
@teams = @organization.teams @teams = @organization.teams
#else #else
@ -22,7 +14,6 @@ class Organizations::TeamsController < Organizations::BaseController
@teams = kaminari_paginate(@teams) @teams = kaminari_paginate(@teams)
end end
end
def search def search
tip_exception("请输入搜索关键词") if params[:search].nil? tip_exception("请输入搜索关键词") if params[:search].nil?
@ -43,13 +34,9 @@ class Organizations::TeamsController < Organizations::BaseController
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
if @organization.teams.count >= 50
return tip_exception("组织的团队数量已超过限制!")
else
Organizations::CreateTeamForm.new(team_params).validate! Organizations::CreateTeamForm.new(team_params).validate!
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params) @team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
end end
end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
tip_exception(e.message) tip_exception(e.message)

View File

@ -20,7 +20,7 @@ class OwnersController < ApplicationController
@is_admin = current_user.admin? || @owner.is_owner?(current_user.id) @is_admin = current_user.admin? || @owner.is_owner?(current_user.id)
@is_member = @owner.is_member?(current_user.id) @is_member = @owner.is_member?(current_user.id)
# 用户 # 用户
elsif @owner.is_a?(User) else
#待办事项,现在未做 #待办事项,现在未做
if User.current.admin? || User.current.login == @owner.login if User.current.admin? || User.current.login == @owner.login
@waiting_applied_messages = @owner.applied_messages.waiting @waiting_applied_messages = @owner.applied_messages.waiting
@ -45,6 +45,7 @@ class OwnersController < ApplicationController
@projects_common_count = user_projects.common.size @projects_common_count = user_projects.common.size
@projects_mirrior_count = user_projects.mirror.size @projects_mirrior_count = user_projects.mirror.size
@projects_sync_mirrior_count = user_projects.sync_mirror.size @projects_sync_mirrior_count = user_projects.sync_mirror.size
puts @owner.as_json
end end
end end

View File

@ -12,7 +12,6 @@ class PraiseTreadController < ApplicationController
begin begin
return normal_status(2, "你已点过赞了") if current_user.liked?(@project) return normal_status(2, "你已点过赞了") if current_user.liked?(@project)
current_user.like!(@project) current_user.like!(@project)
SendTemplateMessageJob.perform_later('ProjectPraised', current_user.id, @project.id) if Site.has_notice_menu?
render_ok({praises_count: @project.praises_count, praised: current_user.liked?(@project)}) render_ok({praises_count: @project.praises_count, praised: current_user.liked?(@project)})
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)

View File

@ -10,7 +10,7 @@ class ProjectCategoriesController < ApplicationController
end end
def group_list def group_list
@project_categories = ProjectCategory.select("id, name, projects_count, private_projects_count, (projects_count - private_projects_count) as public_projects_count").having('public_projects_count > 0').order(public_projects_count: :desc) @project_categories = ProjectCategory.where('projects_count > 0').order(projects_count: :desc)
# projects = Project.no_anomory_projects.visible # projects = Project.no_anomory_projects.visible
# @category_group_list = projects.joins(:project_category).group("project_categories.id", "project_categories.name").size # @category_group_list = projects.joins(:project_category).group("project_categories.id", "project_categories.name").size
end end

View File

@ -3,7 +3,7 @@ class ProjectTrendsController < ApplicationController
before_action :check_project_public before_action :check_project_public
def index def index
project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner) project_trends = @project.project_trends.preload(:user, trend: :user)
check_time = params[:time] #时间的筛选 check_time = params[:time] #时间的筛选
check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version

View File

@ -1,42 +0,0 @@
class Projects::ProjectInviteLinksController < Projects::BaseController
before_action :require_manager!, except: [:show_link, :redirect_link]
before_action :require_login
def current_link
role = params[:role]
is_apply = params[:is_apply]
return render_error('请输入正确的参数!') unless role.present? && is_apply.present?
@project_invite_link = ProjectInviteLink.find_by(user_id: current_user.id, project_id: @project.id, role: role, is_apply: is_apply)
@project_invite_link = ProjectInviteLink.build!(@project, current_user, role, is_apply) unless @project_invite_link.present?
end
def generate_link
ActiveRecord::Base.transaction do
params_data = link_params.merge({user_id: current_user.id, project_id: @project.id})
Projects::ProjectInviteLinks::CreateForm.new(params_data).validate!
@project_invite_link = ProjectInviteLink.build!(project, user, params_data[:role], params_data[:is_apply])
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def show_link
@project_invite_link = ProjectInviteLink.find_by(sign: params[:invite_sign])
return render_not_found unless @project_invite_link.present?
end
def redirect_link
Projects::LinkJoinService.call(current_user, @project, params[:invite_sign])
render_ok
rescue Exception => e
uid_logger_error(e.message)
normal_status(-1, e.message)
end
private
def link_params
params.require(:project_invite_link).permit(:role, :is_apply)
end
end

View File

@ -9,7 +9,7 @@ class Projects::WebhooksController < Projects::BaseController
def create def create
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
return render_error("webhooks数量已到上限请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 49 return render_error("webhooks数量已到上限请删除暂不使用的webhooks以进行添加操作") if @project.webhooks.size > 19
return render_error("参数错误.") unless webhook_params.present? return render_error("参数错误.") unless webhook_params.present?
form = Projects::Webhooks::CreateForm.new(webhook_params) form = Projects::Webhooks::CreateForm.new(webhook_params)
return render json: {status: -1, message: form.errors} unless form.validate! return render json: {status: -1, message: form.errors} unless form.validate!

View File

@ -13,20 +13,16 @@ class ProjectsController < ApplicationController
def menu_list def menu_list
menu = [] menu = []
user_is_admin = current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("home")) menu.append(menu_hash_by_name("home"))
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code") menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues") menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge? menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls")
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge? menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki")
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops")
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions") menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge? menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources")
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
menu.append(menu_hash_by_name("activity")) menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("sonar")) menu.append(menu_hash_by_name("settings")) if current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("settings")) if user_is_admin && @project.forge?
menu.append(menu_hash_by_name("quit")) if !user_is_admin && @project.member(current_user.id) && @project.forge?
render json: menu render json: menu
end end
@ -40,9 +36,8 @@ class ProjectsController < ApplicationController
category_id = params[:category_id] category_id = params[:category_id]
@total_count = @total_count =
if category_id.blank? if category_id.blank?
# ps = ProjectStatistic.first ps = ProjectStatistic.first
# ps.common_projects_count + ps.mirror_projects_count unless ps.blank? ps.common_projects_count + ps.mirror_projects_count unless ps.blank?
@projects.total_count
else else
cate = ProjectCategory.find_by(id: category_id) cate = ProjectCategory.find_by(id: category_id)
cate&.projects_count || 0 cate&.projects_count || 0
@ -54,13 +49,6 @@ class ProjectsController < ApplicationController
Projects::CreateForm.new(project_params).validate! Projects::CreateForm.new(project_params).validate!
@project = Projects::CreateService.new(current_user, project_params).call @project = Projects::CreateService.new(current_user, project_params).call
# TODO: fix Educoder shixun
if @project.persisted?
ProjectScore.create(:project_id => @project.id, :score => 0) if @project.project_score.nil?
project_info = ProjectInfo.new(:user_id => current_user.id, :project_id => @project.id)
@project.project_infos << project_info
end
end end
rescue Exception => e rescue Exception => e
uid_logger_error(e.message) uid_logger_error(e.message)
@ -71,7 +59,7 @@ class ProjectsController < ApplicationController
Projects::MigrateForm.new(mirror_params).validate! Projects::MigrateForm.new(mirror_params).validate!
@project = @project =
if EduSetting.get("mirror_address").to_s.include?("github") && enable_accelerator?(mirror_params[:clone_addr]) if enable_accelerator?(mirror_params[:clone_addr])
source_clone_url = mirror_params[:clone_addr] source_clone_url = mirror_params[:clone_addr]
uid_logger("########## 已动加速器 ##########") uid_logger("########## 已动加速器 ##########")
result = Gitea::Accelerator::MigrateService.call(mirror_params) result = Gitea::Accelerator::MigrateService.call(mirror_params)
@ -83,11 +71,6 @@ class ProjectsController < ApplicationController
else else
Projects::MigrateService.call(current_user, mirror_params) Projects::MigrateService.call(current_user, mirror_params)
end end
elsif EduSetting.get("mirror_address").to_s.include?("cnpmjs") && mirror_params[:clone_addr].include?("github.com")
source_clone_url = mirror_params[:clone_addr]
clone_url = source_clone_url.gsub('github.com', 'github.com.cnpmjs.org')
uid_logger("########## 更改clone_addr ##########")
Projects::MigrateService.call(current_user, mirror_params.merge(source_clone_url: source_clone_url, clone_addr: clone_url))
else else
Projects::MigrateService.call(current_user, mirror_params) Projects::MigrateService.call(current_user, mirror_params)
end end
@ -99,9 +82,8 @@ class ProjectsController < ApplicationController
def branches def branches
return @branches = [] unless @project.forge? return @branches = [] unless @project.forge?
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier) result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier, params[:name]) @branches = result.is_a?(Hash) && result.key?(:status) ? [] : result
@branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result
end end
def branches_slice def branches_slice
@ -112,18 +94,18 @@ class ProjectsController < ApplicationController
end end
def group_type_list def group_type_list
# project_statics = ProjectStatistic.first project_statics = ProjectStatistic.first
@project_statics_list = [ @project_statics_list = [
{ {
project_type: 'common', project_type: 'common',
name: '开源托管项目', name: '开源托管项目',
projects_count: Project.common.size || 0 projects_count: project_statics&.common_projects_count || 0
}, },
{ {
project_type: 'mirror', project_type: 'mirror',
name: '开源镜像项目', name: '开源镜像项目',
projects_count: Project.sync_mirror.size + Project.mirror.size || 0 projects_count: project_statics&.mirror_projects_count || 0
} }
] ]
@ -147,7 +129,7 @@ class ProjectsController < ApplicationController
validate_params = project_params.slice(:name, :description, validate_params = project_params.slice(:name, :description,
:project_category_id, :project_language_id, :private, :identifier) :project_category_id, :project_language_id, :private, :identifier)
Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier, project_name: @project.name)).validate! Projects::UpdateForm.new(validate_params.merge(user_id: @project.user_id, project_identifier: @project.identifier)).validate!
private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false private = @project.forked_from_project.present? ? !@project.forked_from_project.is_public : params[:private] || false
@ -162,15 +144,6 @@ class ProjectsController < ApplicationController
} }
gitea_repo = Gitea::Repository::UpdateService.call(@owner, @project&.repository&.identifier, gitea_params) gitea_repo = Gitea::Repository::UpdateService.call(@owner, @project&.repository&.identifier, gitea_params)
@project.repository.update_attributes({hidden: gitea_repo["private"], identifier: gitea_repo["name"]}) @project.repository.update_attributes({hidden: gitea_repo["private"], identifier: gitea_repo["name"]})
# 更新对应所属分类下的项目数量(私有)
before_is_public = @project.previous_changes[:is_public].present? ? @project.previous_changes[:is_public][0] : @project.is_public
after_is_public = @project.previous_changes[:is_public].present? ? @project.previous_changes[:is_public][1] : @project.is_public
before_pc_id = @project.previous_changes[:project_category_id].present? ? @project.previous_changes[:project_category_id][0] : @project.project_category_id
after_pc_id = @project.previous_changes[:project_category_id].present? ? @project.previous_changes[:project_category_id][1] : @project.project_category_id
before_pc = ProjectCategory.find_by_id(before_pc_id)
after_pc = ProjectCategory.find_by_id(after_pc_id)
before_pc.decrement!(:private_projects_count, 1) if before_pc.present? && !before_is_public
after_pc.increment!(:private_projects_count, 1) if after_pc.present? && !after_is_public
end end
SendTemplateMessageJob.perform_later('ProjectSettingChanged', current_user.id, @project&.id, @project.previous_changes.slice(:name, :description, :project_category_id, :project_language_id, :is_public, :identifier)) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectSettingChanged', current_user.id, @project&.id, @project.previous_changes.slice(:name, :description, :project_category_id, :project_language_id, :is_public, :identifier)) if Site.has_notice_menu?
end end
@ -188,8 +161,6 @@ class ProjectsController < ApplicationController
Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call Gitea::Repository::DeleteService.new(@project.owner, @project.identifier).call
@project.destroy! @project.destroy!
@project.forked_projects.update_all(forked_from_project_id: nil) @project.forked_projects.update_all(forked_from_project_id: nil)
# 如果该项目有所属的项目分类以及为私有项目,需要更新对应数量
@project.project_category.decrement!(:private_projects_count, 1) if @project.project_category.present? && !@project.is_public
render_ok render_ok
end end
else else
@ -200,22 +171,6 @@ class ProjectsController < ApplicationController
tip_exception(e.message) tip_exception(e.message)
end end
def quit
user_is_admin = current_user.admin? || @project.manager?(current_user)
if !user_is_admin && @project.member(current_user.id) && @project.forge?
ActiveRecord::Base.transaction do
Projects::DeleteMemberInteractor.call(@project.owner, @project, current_user)
SendTemplateMessageJob.perform_later('ProjectMemberLeft', current_user.id, current_user.id, @project.id) if Site.has_notice_menu?
render_ok
end
else
render_forbidden('你不能退出该仓库')
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
def watch_users def watch_users
watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct watchers = @project.watchers.includes(:user).order("watchers.created_at desc").distinct
@watchers_count = watchers.size @watchers_count = watchers.size
@ -229,7 +184,7 @@ class ProjectsController < ApplicationController
end end
def fork_users def fork_users
fork_users = @project.fork_users.includes(:owner, :project, :fork_project).order("fork_users.created_at desc").distinct fork_users = @project.fork_users.includes(:user, :project, :fork_project).order("fork_users.created_at desc").distinct
@forks_count = fork_users.size @forks_count = fork_users.size
@fork_users = paginate(fork_users) @fork_users = paginate(fork_users)
end end

View File

@ -2,7 +2,7 @@ class PullRequestsController < ApplicationController
before_action :require_login, except: [:index, :show, :files, :commits] before_action :require_login, except: [:index, :show, :files, :commits]
before_action :require_profile_completed, only: [:create] before_action :require_profile_completed, only: [:create]
before_action :load_repository before_action :load_repository
before_action :check_menu_authorize, only: [:index, :show, :create, :update, :refuse_merge, :pr_merge] before_action :check_menu_authorize
before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits] before_action :find_pull_request, except: [:index, :new, :create, :check_can_merge,:get_branches,:create_merge_infos, :files, :commits]
before_action :load_pull_request, only: [:files, :commits] before_action :load_pull_request, only: [:files, :commits]
before_action :find_atme_receivers, only: [:create, :update] before_action :find_atme_receivers, only: [:create, :update]
@ -16,7 +16,7 @@ class PullRequestsController < ApplicationController
issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user)) issues = issues.where(is_private: false) unless current_user.present? && (current_user.admin? || @project.member?(current_user))
@all_issues = issues.distinct @all_issues = issues.distinct
@filter_issues = @all_issues @filter_issues = @all_issues
@filter_issues = @filter_issues.where("issues.subject LIKE ? OR issues.description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present? @filter_issues = @filter_issues.where("subject LIKE ? OR description LIKE ? ", "%#{params[:search]}%", "%#{params[:search]}%") if params[:search].present?
@open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN}) @open_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::OPEN})
@close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED}) @close_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::CLOSED})
@merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED}) @merged_issues = @filter_issues.joins(:pull_request).where(pull_requests: {status: PullRequest::MERGED})
@ -29,7 +29,7 @@ class PullRequestsController < ApplicationController
end end
def new def new
@all_branches = Branches::ListService.call(@owner, @project, params[:branch_name]) @all_branches = Branches::ListService.call(@owner, @project)
@is_fork = @project.forked_from_project_id.present? @is_fork = @project.forked_from_project_id.present?
@projects_names = [{ @projects_names = [{
project_user_login: @owner.try(:login), project_user_login: @owner.try(:login),
@ -50,20 +50,16 @@ class PullRequestsController < ApplicationController
end end
def get_branches def get_branches
branch_result = Branches::ListService.call(@owner, @project, params[:name]) branch_result = Branches::ListService.call(@owner, @project)
render json: branch_result render json: branch_result
# return json: branch_result # return json: branch_result
end end
def create def create
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
Issues::CreateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params) @pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
if @gitea_pull_request[:status] == :success if @gitea_pull_request[:status] == :success
@pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"]) @pull_request.bind_gitea_pull_request!(@gitea_pull_request[:body]["number"], @gitea_pull_request[:body]["id"])
reviewers = User.where(id: params[:reviewer_ids])
@pull_request.reviewers = reviewers
SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('PullRequestAssigned', current_user.id, @pull_request&.id) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}" Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
@ -73,8 +69,6 @@ class PullRequestsController < ApplicationController
raise ActiveRecord::Rollback raise ActiveRecord::Rollback
end end
end end
rescue => e
normal_status(-1, e.message)
end end
def edit def edit
@ -84,7 +78,6 @@ class PullRequestsController < ApplicationController
end end
def update def update
return render_forbidden("你没有权限操作.") unless @project.operator?(current_user)
if params[:title].nil? if params[:title].nil?
normal_status(-1, "名称不能为空") normal_status(-1, "名称不能为空")
elsif params[:issue_tag_ids].nil? elsif params[:issue_tag_ids].nil?
@ -92,11 +85,15 @@ class PullRequestsController < ApplicationController
else else
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
begin begin
Issues::UpdateForm.new({subject: params[:title], description: params[:body].blank? ? params[:body] : params[:body].b}).validate!
merge_params merge_params
reviewers = User.where(id: params[:reviewer_ids]) @issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
@pull_request.reviewers = reviewers if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
end
end
if @issue.update_attributes(@issue_params) if @issue.update_attributes(@issue_params)
if @pull_request.update_attributes(@local_params.compact) if @pull_request.update_attributes(@local_params.compact)
@ -105,15 +102,8 @@ class PullRequestsController < ApplicationController
if gitea_pull[:status] === :success if gitea_pull[:status] === :success
if params[:issue_tag_ids].present? if params[:issue_tag_ids].present?
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag| params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag) IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end end
end end
if params[:status_id].to_i == 5 if params[:status_id].to_i == 5
@ -146,8 +136,6 @@ class PullRequestsController < ApplicationController
colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user) colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user)
if colsed === true if colsed === true
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE) @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE)
# 合并请求下issue处理为关闭
@issue&.update_attributes!({status_id:5})
SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('PullRequestClosed', current_user.id, @pull_request.id) if Site.has_notice_menu?
normal_status(1, "已拒绝") normal_status(1, "已拒绝")
else else
@ -169,7 +157,6 @@ class PullRequestsController < ApplicationController
@issue_assign_to = @issue.get_assign_user @issue_assign_to = @issue.get_assign_user
@gitea_pull = Gitea::PullRequest::GetService.call(@owner.login, @gitea_pull = Gitea::PullRequest::GetService.call(@owner.login,
@repository.identifier, @pull_request.gitea_number, current_user&.gitea_token) @repository.identifier, @pull_request.gitea_number, current_user&.gitea_token)
# @last_review = @pull_request.reviews.take
end end
def pr_merge def pr_merge
@ -193,8 +180,6 @@ class PullRequestsController < ApplicationController
# @pull_request.project_trend_status! # @pull_request.project_trend_status!
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE) @pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE)
@issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id) @issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
# 合并请求下issue处理为关闭
@issue&.update_attributes!({status_id:5})
SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu? SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu?
normal_status(1, "合并成功") normal_status(1, "合并成功")
else else
@ -212,7 +197,7 @@ class PullRequestsController < ApplicationController
def check_can_merge def check_can_merge
target_head = params[:head] #源分支 target_head = params[:head] #源分支
target_base = params[:base] #目标分支 target_base = params[:base] #目标分支
is_original = params[:is_original] || false is_original = params[:is_original]
if target_head.blank? || target_base.blank? if target_head.blank? || target_base.blank?
normal_status(-2, "请选择分支") normal_status(-2, "请选择分支")
elsif target_head === target_base && !is_original elsif target_head === target_base && !is_original
@ -243,11 +228,11 @@ class PullRequestsController < ApplicationController
private private
def load_pull_request def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) @pull_request = PullRequest.find params[:id]
end end
def find_pull_request def find_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id]) @pull_request = PullRequest.find_by_id(params[:id])
@issue = @pull_request&.issue @issue = @pull_request&.issue
if @pull_request.blank? if @pull_request.blank?
normal_status(-1, "合并请求不存在") normal_status(-1, "合并请求不存在")
@ -258,7 +243,7 @@ class PullRequestsController < ApplicationController
def get_relatived def get_relatived
@project_tags = @project.issue_tags&.select(:id,:name, :color).as_json @project_tags = @project.issue_tags&.select(:id,:name, :color).as_json
@project_versions = @project.versions.opening&.select(:id,:name, :status).as_json @project_versions = @project.versions&.select(:id,:name, :status).as_json
@project_members = @project.all_developers @project_members = @project.all_developers
@project_priories = IssuePriority&.select(:id,:name, :position).as_json @project_priories = IssuePriority&.select(:id,:name, :position).as_json
end end
@ -271,12 +256,12 @@ class PullRequestsController < ApplicationController
base: params[:base], #目标分支 base: params[:base], #目标分支
milestone: 0, #里程碑,未与本地的里程碑关联 milestone: 0, #里程碑,未与本地的里程碑关联
} }
assignee_login = User.find_by_id(params[:assigned_to_id])&.login
@requests_params = @local_params.merge({ @requests_params = @local_params.merge({
assignee: current_user.try(:login),
# assignees: ["#{params[:assigned_login].to_s}"], # assignees: ["#{params[:assigned_login].to_s}"],
assignees: ["#{assignee_login.to_s}"], assignees: ["#{current_user.try(:login).to_s}"],
labels: params[:issue_tag_ids] labels: params[:issue_tag_ids],
# due_date: Time.now due_date: Time.now
}) })
@issue_params = { @issue_params = {
author_id: current_user.id, author_id: current_user.id,
@ -286,7 +271,7 @@ class PullRequestsController < ApplicationController
assigned_to_id: params[:assigned_to_id], assigned_to_id: params[:assigned_to_id],
fixed_version_id: params[:fixed_version_id], fixed_version_id: params[:fixed_version_id],
issue_tags_value: params[:issue_tag_ids].present? ? params[:issue_tag_ids].join(",") : "", issue_tags_value: params[:issue_tag_ids].present? ? params[:issue_tag_ids].join(",") : "",
priority_id: params[:priority_id], priority_id: params[:priority_id] || "2",
issue_classify: "pull_request", issue_classify: "pull_request",
issue_type: params[:issue_type] || "1", issue_type: params[:issue_type] || "1",
tracker_id: 2, tracker_id: 2,

View File

@ -9,15 +9,61 @@ class RepositoriesController < ApplicationController
before_action :load_repository before_action :load_repository
before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive] before_action :authorizate!, except: [:sync_mirror, :tags, :commit, :archive]
before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror] before_action :authorizate_user_can_edit_repo!, only: %i[sync_mirror]
before_action :get_ref, only: %i[entries sub_entries top_counts files archive] before_action :get_ref, only: %i[entries sub_entries top_counts file archive]
before_action :get_latest_commit, only: %i[entries sub_entries top_counts] before_action :get_latest_commit, only: %i[entries sub_entries top_counts]
before_action :get_statistics, only: %i[top_counts] before_action :get_statistics, only: %i[top_counts]
before_action :preload_badge, only: [:badges]
def files def files
result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token) result = @project.educoder? ? nil : Gitea::Repository::Files::GetService.call(@owner, @project.identifier, @ref, params[:search], @owner.gitea_token)
render json: result render json: result
end end
def preload_badge
@praised_cache = "praised"
@forked_cache = "forked"
@watchered_cache = "watchered"
@badge = RepositoryBadge.find_or_create_by(user_id: observed_user.id)
$redis_cache.hset(project_statistic_key, @many_projects_cache, @badge.many_projects)
$redis_cache.hset(project_statistic_key, @manyParisesProject_cache, @badge.manyParisesProject)
$redis_cache.hset(project_statistic_key, @parises_project_cache, @badge.parises_project)
end
####################change for repository############################
def badges
preload_badge
@badges_dic = Hash.new(0)
praises_count = @project.praises_count.to_i
forked_count = @project.forked_count.to_i
watchers_count = @project.watchers_count.to_i
@praised = judge_level(praises_count, 10, 20,100)
redis_judge_reload @praised_cache, @praised
@badges_dic["praised_cache"] = $redis_cache.hget(project_statistic_key, @praised_cache).to_i
@forked = judge_level(forked_count, 5, 10,100)
redis_judge_reload @forked_cache, @forked
@badges_dic["forked_cache"] = $redis_cache.hget(project_statistic_key, @forked_cache).to_i
@watchered = judge_level(watchers_count, 10, 20,100)
redis_judge_reload @watchered_cache, @watchered
@badges_dic["forked_cache"] = $redis_cache.hget(project_statistic_key, @forked_cache).to_i
badges_visable = Array.new
@badges_dic.each do |key,value|
if value > 0
badges_visable.append({"#{key}":value})
end
end
render :json => {list: badges_visable, count: badges_visable.size}
end
##########################################################
# 新版项目详情 # 新版项目详情
def detail def detail
@user = current_user @user = current_user
@ -47,19 +93,14 @@ class RepositoriesController < ApplicationController
end end
def entries def entries
@week_project_visit_record, @month_project_visit_record = TimeableVisitRecord.build(@project.id)
if @week_project_visit_record.visits < 300 && @month_project_visit_record.visits < 1000
@week_project_visit_record.increment!(:visits)
@month_project_visit_record.increment!(:visits)
@project.increment!(:visits) @project.increment!(:visits)
CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id) CacheAsyncSetJob.perform_later("project_common_service", {visits: 1}, @project.id)
end
if @project.educoder? if @project.educoder?
@entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name) @entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder.repo_name)
else else
@entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call @entries = Gitea::Repository::Entries::ListService.new(@owner, @project.identifier, ref: @ref).call
@entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : [] @entries = @entries.present? ? @entries.sort_by{ |hash| hash['type'] } : []
@path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/" @path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
end end
end end
@ -68,7 +109,8 @@ class RepositoriesController < ApplicationController
end end
def sub_entries def sub_entries
file_path_uri = URI.escape(URI.encode(params[:filepath].to_s.strip)) file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
if @project.educoder? if @project.educoder?
if params[:type] === 'file' if params[:type] === 'file'
@ -76,35 +118,18 @@ class RepositoriesController < ApplicationController
logger.info "######### sub_entries: #{@sub_entries}" logger.info "######### sub_entries: #{@sub_entries}"
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1 return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = { tmp_entries = [{
"content" => @sub_entries['data']['content'], "content" => @sub_entries['data']['content'],
"type" => "blob" "type" => "blob"
} }]
@sub_entries = { @sub_entries = {
"trees"=>tmp_entries, "trees"=>tmp_entries,
"commits" => [{}] "commits" => [{}]
} }
else else
begin
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri}) @sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
end
rescue
return render_error('该文件暂未开放,敬请期待.')
end
end end
else else
@path = GiteaService.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref) interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
if interactor.success? if interactor.success?
result = interactor.result result = interactor.result
@ -116,17 +141,13 @@ class RepositoriesController < ApplicationController
end end
def commits def commits
if @project.educoder?
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
else
if params[:filepath].present? if params[:filepath].present?
file_path_uri = URI.escape(URI.encode(params[:filepath].to_s.strip)) file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri, @hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
sha: params[:sha], page: params[:page], limit: params[:limit], token: @owner&.gitea_token).call sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
else else
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier, @hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: @owner&.gitea_token).call sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
end
end end
end end
@ -137,40 +158,22 @@ class RepositoriesController < ApplicationController
def commit def commit
@sha = params[:sha] @sha = params[:sha]
if @project.educoder? @commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
return render_error('暂未开放,敬请期待.') @commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
else
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, @owner&.gitea_token)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, @owner&.gitea_token, {diff: true})
render_error(@commit[:message], @commit[:status]) if @commit.has_key?(:status) || @commit_diff.has_key?(:status)
end
end end
def tags def tags
if params[:only_name].present? result = Gitea::Repository::Tags::ListService.call(current_user&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
result = Gitea::Repository::Tags::ListNameService.call(@owner, @project.identifier, params[:name])
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result @tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
else
name_result = Gitea::Repository::Tags::ListNameService.call(@owner, @project.identifier, params[:name])
@tag_names = result.is_a?(Hash) && result.key?(:status) ? [] : name_result
result = Gitea::Repository::Tags::ListService.call(@owner&.gitea_token, @owner.login, @project.identifier, {page: params[:page], limit: params[:limit]})
@tags = result.is_a?(Hash) && result.key?(:status) ? [] : result
end
end end
def contributors def contributors
if params[:filepath].present? || @project.educoder? if params[:filepath].present?
@contributors = [] @contributors = []
else else
result = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier) @contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
@contributors = result.is_a?(Hash) && result.key?(:status) ? [] : result
end end
rescue
@contributors = []
end end
def edit def edit
@ -234,34 +237,28 @@ class RepositoriesController < ApplicationController
def readme def readme
if params[:filepath].present? if params[:filepath].present?
result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], @owner&.gitea_token) result = Gitea::Repository::Readme::DirService.call(@owner.login, @repository.identifier, params[:filepath], params[:ref], current_user&.gitea_token)
else else
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], @owner&.gitea_token) result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
end end
@path = GiteaService.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
@readme = result[:status] === :success ? result[:body] : nil @readme = result[:status] === :success ? result[:body] : nil
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path) @readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref])
@readme['replace_content'] = readme_decode64_content(@readme, @owner, @repository, params[:ref], @path) render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha", "replace_content")
rescue rescue
render json: nil render json: nil
end end
def languages def languages
if @project.educoder?
render json: {}
else
render json: languages_precentagable render json: languages_precentagable
end end
end
def archive def archive
domain = GiteaService.gitea_config[:domain] domain = Gitea.gitea_config[:domain]
api_url = GiteaService.gitea_config[:base_url] api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{Addressable::URI.escape(params[:archive])}" archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
file_path = [domain, api_url, archive_url].join file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("?") file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
return render_not_found if !request.format.zip? && !request.format.gzip? return render_not_found if !request.format.zip? && !request.format.gzip?
@ -269,14 +266,14 @@ class RepositoriesController < ApplicationController
end end
def raw def raw
domain = GiteaService.gitea_config[:domain] domain = Gitea.gitea_config[:domain]
api_url = GiteaService.gitea_config[:base_url] api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{params[:filepath]}?ref=#{params[:ref]}"
file_path = [domain, api_url, url].join file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{@owner&.gitea_token}"].join("&") file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&") if @repository.hidden?
redirect_to file_path redirect_to URI.escape(file_path)
end end
private private
@ -300,18 +297,18 @@ class RepositoriesController < ApplicationController
# TODO 获取最新commit信息 # TODO 获取最新commit信息
def project_commits def project_commits
if params[:filepath].present? if params[:filepath].present?
file_path_uri = URI.escape(URI.encode(params[:filepath].to_s.strip)) file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri, Gitea::Repository::Commits::FileListService.new(@project.owner.login, @project.identifier, file_path_uri,
sha: get_ref, page: 1, limit: 1, token: @project&.owner&.gitea_token).call sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
else else
Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier, Gitea::Repository::Commits::ListService.new(@project.owner.login, @project.identifier,
sha: get_ref, page: 1, limit: 1, token: @project&.owner&.gitea_token).call sha: get_ref, page: 1, limit: 1, token: current_user&.gitea_token).call
end end
end end
def get_statistics def get_statistics
@branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size @branches_count = @project.educoder? ? 0 : Gitea::Repository::Branches::ListService.new(@project.owner, @project.identifier).call&.size
@tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(@project&.owner&.gitea_token, @project.owner.login, @project.identifier).call&.size @tags_count = @project.educoder? ? 0 : Gitea::Repository::Tags::ListService.new(current_user&.gitea_token, @project.owner.login, @project.identifier).call&.size
end end
def get_ref def get_ref
@ -396,7 +393,7 @@ class RepositoriesController < ApplicationController
local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id)) local_requests = PullRequest.new(local_params.merge(user_id: current_user.try(:id), project_id: @project.id, issue_id: @pull_issue.id))
if local_requests.save if local_requests.save
gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call gitea_request = Gitea::PullRequest::CreateService.new(current_user.try(:gitea_token), @owner.login, @project.try(:identifier), requests_params).call
if gitea_request[:status] == :success && local_requests.update_attributes(gitea_number: gitea_request["body"]["number"]) if gitea_request[:status] == :success && local_requests.update_attributes(gpid: gitea_request["body"]["number"])
local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create") local_requests.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
end end
end end
@ -404,4 +401,37 @@ class RepositoriesController < ApplicationController
end end
end end
def judge_level(judged, low, mid, high)
if judged < low
return 0
elsif judged < mid
return 1
elsif judged < high
return 2
else
return 3
end
end
def redis_judge_reload(judge_cache, new_value)
if $redis_cache.hget(project_statistic_key, judge_cache).to_i != new_value
$redis_cache.del(project_statistic_key)
updateService judge_cache, new_value
load_redis
end
end
def project_statistic_key
"project:#{@project.id}"
end
def updateService(update_name, update_value)
@badge = RepositoryBadge.find_or_create_by(user_id: observed_user.id)
@badge.update_attribute(update_name,update_value)
@badge.save
end
end end

View File

@ -1,20 +0,0 @@
class ReviewsController < ApplicationController
before_action :require_login
before_action :load_project
before_action :load_pull_request
def create
return render_forbidden('您不是审查人员,无法进行审查!') if current_user&.id != @pull_request.issue.assigned_to_id
@review = Api::V1::Projects::Pulls::Reviews::CreateService.call(@project, @pull_request, review_params, current_user)
end
private
def review_params
params.require(:review).permit(:content, :commit_id, :status)
end
def load_pull_request
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
end

View File

@ -1,23 +1,13 @@
class SettingsController < ApplicationController class SettingsController < ApplicationController
def show def show
@old_projects_url = nil @old_projects_url = nil
get_navbar
get_add_menu get_add_menu
get_common_menu get_common_menu
get_personal_menu get_personal_menu
get_top_system_notification get_top_system_notification
get_banner
end end
private private
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 def get_add_menu
@add = [] @add = []
Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site| Site.add.select(:id, :name, :url, :key).to_a.map(&:serializable_hash).each do |site|
@ -68,14 +58,4 @@ class SettingsController < ApplicationController
def append_http(url) def append_http(url)
url.to_s.start_with?("http") ? url : [request.protocol, request.host_with_port, url].join('') url.to_s.start_with?("http") ? url : [request.protocol, request.host_with_port, url].join('')
end end
def get_banner
@banner = {
title: EduSetting.get("banner_title") || '大学开源',
sub_title: EduSetting.get("banner_sub_title") || '让大学绽放开源之花',
content: EduSetting.get("banner_content") || "Powered by Trustie and GitLink"
}
@banner
end
end end

View File

@ -1,41 +0,0 @@
class SonarTasksController < ApplicationController
before_action :require_login
before_action :load_project
before_action :authenticate_user!
def index
@sonar_task = SonarTask.find_by(project_id: @project.id)
tip_exception(-1, "代码未检测,请点击开始检测按钮检测!") if @sonar_task.blank?
if @sonar_task.complete_status == 0
service = Sonar::ApiService.new(@project.id)
service.task_result(@sonar_task.task_id)
end
end
def create
Sonar::ApiService.call(@project.id)
render_ok
end
def type_detail
service = Sonar::ApiService.new(@project.id)
@data = service.type_detail(params[:task_id], params[:type])
end
def code_source
service = Sonar::ApiService.new(@project.id)
@data = service.source_code(params[:task_id], params[:component])
Rails.logger.info "data=======#{@data}"
end
private
def authenticate_user!
return if @project.member?(current_user) || current_user.admin? || current_user.business? || educoder_auth_teacher?(current_user)
render_forbidden('你没有权限操作')
end
def educoder_auth_teacher?(user)
user.user_extension&.identity == 'teacher' && user.professional_certification?
end
end

View File

@ -2,24 +2,24 @@ class StatisticController < ApplicationController
# 平台概况 # 平台概况
def platform_profile def platform_profile
@platform_user_query = Statistic::PlatformUserQuery.new(params).call rescue [0, 0, 0] @platform_user_query = Statistic::PlatformUserQuery.new(params).call
@platform_project_query = Statistic::PlatformProjectQuery.new(params).call rescue [0, 0, 0] @platform_project_query = Statistic::PlatformProjectQuery.new(params).call
@platform_course_query = Statistic::PlatformCourseQuery.new(params).call rescue [0, 0, 0] @platform_course_query = Statistic::PlatformCourseQuery.new(params).call
end end
# 平台代码提交数据 # 平台代码提交数据
def platform_code def platform_code
@platform_pull_request_query = Statistic::PlatformPullRequestQuery.new(params).call rescue [0, 0] @platform_pull_request_query = Statistic::PlatformPullRequestQuery.new(params).call
@platform_commit_query = Statistic::PlatformCommitQuery.new(params,current_user).call rescue [0, 0] @platform_commit_query = Statistic::PlatformCommitQuery.new(params,current_user).call
end end
# 项目案例活跃度排行榜 # 项目案例活跃度排行榜
def active_project_rank def active_project_rank
@active_project_rank_query = Statistic::ActiveProjectRankQuery.new(params, current_user).call rescue [] @active_project_rank_query = Statistic::ActiveProjectRankQuery.new(params, current_user).call
end end
# 开发者活跃度排行榜 # 开发者活跃度排行榜
def active_developer_rank def active_developer_rank
@active_developer_rank_query = Statistic::ActiveDeveloperRankQuery.new(params, current_user).call rescue [] @active_developer_rank_query = Statistic::ActiveDeveloperRankQuery.new(params, current_user).call
end end
end end

View File

@ -1,26 +0,0 @@
class Traces::BaseController < ApplicationController
helper_method :observed_logged_user?, :observed_user
before_action :check_trace_system
def observed_user
@_observed_user ||= (User.find_by_login(params[:user_id]) || User.find_by_id(params[:user_id]))
end
def observed_logged_user?
observed_user.id == User.current&.id
end
protected
def check_auth
return render_forbidden unless current_user.admin? || observed_logged_user?
end
def check_trace_system
code, data, error = Trace::SystemInfoService.call(current_user.trace_token)
return render_ok({code: 501, data: {operate_time: data['operate_time']}, message: '系统维护中'}) if data['status'] === 0
rescue
# 这里根据需求跳转到404
return render_not_found
end
end

View File

@ -1,10 +1,7 @@
class Users::IsPinnedProjectsController < Users::BaseController class Users::IsPinnedProjectsController < Users::BaseController
before_action :private_user_resources!, only: [:pin] before_action :private_user_resources!, only: [:pin]
def index def index
@is_pinned_projects = observed_user.pinned_projects.left_joins(:project) @is_pinned_projects = observed_user.pinned_projects.order(position: :desc, created_at: :asc).includes(project: [:project_category, :project_language, :repository]).order(position: :desc)
.where("projects.is_public = TRUE")
.order(position: :desc, created_at: :asc)
.includes(project: [:project_category, :project_language, :repository]).order(position: :desc)
@is_pinned_projects = kaminari_paginate(@is_pinned_projects) @is_pinned_projects = kaminari_paginate(@is_pinned_projects)
end end

View File

@ -1,5 +1,6 @@
class Users::StatisticsController < Users::BaseController class Users::StatisticsController < Users::BaseController
before_action :preload_develop_data, only: [:develop] before_action :preload_develop_data, only: [:develop]
before_action :preload_badge_data, only: [:badges]
# 近期活动统计 # 近期活动统计
def activity def activity
@ -12,7 +13,7 @@ class Users::StatisticsController < Users::BaseController
@commit_data = [] @commit_data = []
date_range.each do |date| date_range.each do |date|
@date_data << date.strftime("%Y.%m.%d") @date_data << date.strftime("%Y.%m.%d")
@issue_data << observed_user.issues.issue_issue.where("DATE(created_on) = ?", date).size @issue_data << observed_user.issues.where("DATE(created_on) = ?", date).size
@pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size @pull_request_data << observed_user.pull_requests.where("DATE(created_at) = ?", date).size
date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i} date_commit_data = commit_data.blank? ? nil : commit_data.select{|item| item["timestamp"] == date.to_time.to_i}
@commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i) @commit_data << (date_commit_data.blank? ? 0 : date_commit_data[0]["contributions"].to_i)
@ -20,6 +21,35 @@ class Users::StatisticsController < Users::BaseController
render :json => {dates: @date_data, issues_count: @issue_data, pull_requests_count: @pull_request_data, commits_count: @commit_data} render :json => {dates: @date_data, issues_count: @issue_data, pull_requests_count: @pull_request_data, commits_count: @commit_data}
end end
###############change###############
# 用户badges 接口 url 路径为/api/users/:user_id/statistic/badges
# 三类
# 第一类 贡献类
# 1. 用户累积获得高星
# 2. 用户关注数超过10人
# 3. 用户的累积获赞人数
# 4. 用户连续一周有commit
# 5. 用户累积pr数
# 第二类 活动类
# 第三类 特殊类
def badges
badges_visable = Array.new
@badges_dic.each do |key,value|
if value > 0
#与describe同理此处应该再增加一个 url字典
describe = @badges_describe_dic[key]
badges_visable.append({"#{key}":value, "describe":describe})
end
end
render :json => {list: badges_visable, count: badges_visable.size}
end
###############change###############
# 开发能力 # 开发能力
def develop def develop
if params[:start_time].present? && params[:end_time].present? if params[:start_time].present? && params[:end_time].present?
@ -217,3 +247,206 @@ class Users::StatisticsController < Users::BaseController
end end
end end
end end
def count_filter(collection, count_field, countf)
return collection.where("#{count_field} >= ?", countf)
end
# 判断是否拥有
def judge_have(judged, count)
return judged >= count ? 1 : 0
end
# 判断等级
def judge_level(judged, low, mid, high)
if judged < low
return 0
elsif judged < mid
return 1
elsif judged < high
return 2
else
return 3
end
end
###############change###############
# 用户badges 接口 url 路径为/api/users/:user_id/statistic/badges
# 三类
# 第一类 贡献类
# 2.用户有项目获得高星
# 3.用户有数个高星项目
# 4.用户拥有一个点赞数很高的项目
# 5.用户拥有数个点赞数很高的项目
# 6. 用户关注数超过10人
# 7. 用户的累积获赞人数
# 8. 用户累积pr数
# 第二类 活动类
# 第三类 活跃类
# 1. 用户拥有10个项目以上
# 2. 用户连续一周/月有commit
# 3. 用户涨粉迅速
def preload_badge_data
badge_describe
cache_describe
#加载缓存资源
load_redis
#存放用户获得的徽章字典
@badges_dic = Hash.new(0)
# 有些数据可以考虑直接从缓存中读取,由于题目要求不能破坏原本的函数,暂时缓存写了直接查询,
# 例如 Watcher.where(watchable: observed_user).count 可以用@user_result["follow-count"]来替代
#
@user_result = Cache::V2::UserStatisticService.new(observed_user.id).read
# 用户项目获得的徽章
#用户语言数量 y
# 用户项目数量 y
project_count = @user_result["project-count"].to_i
if project_count > 10
@badges_dic["project_count"] = project_count
end
# 用户点赞数量 y
# 用户项目被follow数量
praises_project_count = count_filter(Project.where(user_id:observed_user.id), 'praises_count' , 10).count
praises_project = Project.where(user_id:observed_user.id).maximum('praises_count')
watchers_project_count = count_filter(Project.where(user_id:observed_user.id), 'watchers_count' , 10).count
watchers_project = Project.where(user_id:observed_user.id).maximum('watchers_count')
# 项目数
@many_projects = judge_have(project_count, 5)
redis_judge_reload @many_projects_cache, @many_projects
@badges_dic["many_projects"] = $redis_cache.hget(user_statistic_key, @many_projects_cache).to_i
# 用户有超过五个以上的高点赞项目
@manyParisesProject = judge_have(praises_project_count, 5)
redis_judge_reload @manyParisesProject_cache, @manyParisesProject
@badges_dic["manyParisesProject"] = $redis_cache.hget(user_statistic_key, @manyParisesProject_cache).to_i
#用户有一个点赞数很高的项目 金/银/铜
@parises_project = judge_level(praises_project, 3, 5, 10)
redis_judge_reload @many_projects_cache, @parises_project
@badges_dic["parises_project"] = $redis_cache.hget(user_statistic_key, @parises_project_cache).to_i
# 用户有超过五个以上的高关注项目
@manyWatchersProject = judge_have(watchers_project_count, 5)
redis_judge_reload @manyWatchersProject_cache, @manyWatchersProject
@badges_dic["manyWatchersProject"] = $redis_cache.hget(user_statistic_key, @manyWatchersProject_cache).to_i
#用户有一个关注数很高的项目 金/银/铜
@watchers_project = judge_level(watchers_project, 3, 5, 10)
redis_judge_reload @watchers_project_cache, @watchers_project
@badges_dic["watchers_project"] = $redis_cache.hget(user_statistic_key, @watchers_project_cache).to_i
# 用户被follow数量 y
fans = Watcher.where(watchable: observed_user).count
# 用户pr数量 y
pr = PullRequest.where(user_id: observed_user.id).count
# 用户issue数量 y
issue = Issue.where(author_id: observed_user.id).count
#用户有关注数很多 金/银/铜
@many_fans = judge_level(fans, 5, 50, 100)
redis_judge_reload @many_fans_cache, @many_fans
@badges_dic["many_fans"] = $redis_cache.hget(user_statistic_key, @many_fans_cache).to_i
#用户pr很多 金/银/铜
@many_pr = judge_level(pr, 5, 50, 100)
redis_judge_reload @many_pr_cache, @many_pr
@badges_dic["many_pr"] = $redis_cache.hget(user_statistic_key, @many_pr_cache).to_i
#用户issue很多 金/银/铜
@many_issue = judge_level(issue, 5, 50, 100)
redis_judge_reload @many_issue_cache, @many_issue
@badges_dic["many_issue"] = $redis_cache.hget(user_statistic_key, @many_issue_cache).to_i
#一周内活跃
commit_request = Gitea::User::HeadmapService.call(observed_user.login, 1.week.ago.to_date.to_time.to_i, Date.today.to_time.to_i)
commit_data = commit_request[2]
active_commit = commit_data.select{|item| item["contributions"] >= 1}.size
@active_in_week = active_commit == 7 ? 1 : 0
@badges_dic["active_in_week"] = $redis_cache.hget(user_statistic_key, @active_in_week_cache).to_i
#TODO fans_raise_quickly
end
def user_statistic_key
"user:#{@user_id}"
end
def redis_judge_reload(judge_cache, new_value)
if $redis_cache.hget(user_statistic_key, judge_cache).to_i != new_value
$redis_cache.del(user_statistic_key)
updateService judge_cache, new_value
load_redis
end
end
def cache_describe
@many_projects_cache = "many_projects"
@manyParisesProject_cache = "manyParisesProject"
@parises_project_cache = "parises_project"
@manyWatchersProject_cache = "manyWatchersProject"
@watchers_project_cache = "watchers_project"
@many_fans_cache = "many_fans"
@many_pr_cache = "many_pr"
@many_issue_cache = "many_issue"
@active_in_week_cache = "active_in_week"
end
def badge_describe
@badges_describe_dic = Hash.new(0)
@badges_describe_dic["many_projects"] = "参与了多个project"
@badges_describe_dic["manyParisesProject"] = "有多个点赞数高的project"
@badges_describe_dic["parises_project"] = "有一个项目获得了很高的点赞数!"
@badges_describe_dic["manyWatchersProject"] = "有多个关注三诉讼诉讼诉讼诉讼诉讼诉讼数高的project"
@badges_describe_dic["watchers_project"] = "有一个项目获得了很高的关注数!"
@badges_describe_dic["watchers_project"] = "有一个项目获得了很高的关注数!"
@badges_describe_dic["many_fans"] = "粉丝数很多!"
@badges_describe_dic["many_fans"] = "贡献了很多pr"
@badges_describe_dic["many_pr"] = "贡献了很多issue"
@badges_describe_dic["many_issue"] = "粉丝数很多!"
@badges_describe_dic["active_in_week"] = "一周活跃打卡成就!"
end
def load_redis
@badge = Badge.find_or_create_by(user_id: observed_user.id)
$redis_cache.hset(user_statistic_key, @many_projects_cache, @badge.many_projects)
$redis_cache.hset(user_statistic_key, @manyParisesProject_cache, @badge.manyParisesProject)
$redis_cache.hset(user_statistic_key, @parises_project_cache, @badge.parises_project)
$redis_cache.hset(user_statistic_key, @manyWatchersProject_cache, @badge.manyWatchersProject)
$redis_cache.hset(user_statistic_key, @watchers_project_cache, @badge.watchers_project)
$redis_cache.hset(user_statistic_key, @many_fans_cache, @badge.many_fans)
$redis_cache.hset(user_statistic_key, @many_pr_cache, @badge.many_pr)
$redis_cache.hset(user_statistic_key, @many_issue_cache, @badge.many_issue)
$redis_cache.hset(user_statistic_key, @active_in_week_cache, @badge.active_in_week)
end
def updateService(update_name, update_value)
#添加事务,如果更新失败则回滚
ActiveRecord::Base.transaction do
@badge = Badge.find_or_create_by!(user_id: observed_user.id)
@badge.update_attributes!(update_name => update_value)
@badge.save!
end
end

View File

@ -23,8 +23,6 @@ class Users::TemplateMessageSettingsController < Users::BaseController
def get_current_setting def get_current_setting
@current_setting = @_observed_user.user_template_message_setting @current_setting = @_observed_user.user_template_message_setting
@current_setting = UserTemplateMessageSetting.build(@_observed_user.id) if @current_setting.nil? @current_setting = UserTemplateMessageSetting.build(@_observed_user.id) if @current_setting.nil?
@current_setting.notification_body.merge!(UserTemplateMessageSetting.init_notification_body.except(*@current_setting.notification_body.keys))
@current_setting.email_body.merge!(UserTemplateMessageSetting.init_email_body.except(*@current_setting.email_body.keys))
end end
def setting_params def setting_params

View File

@ -4,7 +4,7 @@ class UsersController < ApplicationController
before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard] before_action :load_user, only: [:show, :homepage_info, :sync_token, :sync_gitea_pwd, :projects, :watch_users, :fan_users, :hovercard]
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard] before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
before_action :require_login, only: %i[me list] before_action :require_login, only: %i[me list sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info] before_action :connect_to_ci_db, only: [:get_user_info]
before_action :convert_image!, only: [:update] before_action :convert_image!, only: [:update]
skip_before_action :check_sign, only: [:attachment_show] skip_before_action :check_sign, only: [:attachment_show]
@ -51,6 +51,8 @@ class UsersController < ApplicationController
@projects_common_count = user_projects.common.size @projects_common_count = user_projects.common.size
@projects_mirrior_count = user_projects.mirror.size @projects_mirrior_count = user_projects.mirror.size
@projects_sync_mirrior_count = user_projects.sync_mirror.size @projects_sync_mirrior_count = user_projects.sync_mirror.size
# 为了缓存活跃用户的基本信息,后续删除
Cache::V2::OwnerCommonService.new(@user.id).read
end end
def watch_users def watch_users
@ -83,24 +85,6 @@ class UsersController < ApplicationController
end end
end end
def update_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
Util.write_file(@image, avatar_path(@user))
return render_ok({message: '头像修改成功'})
rescue Exception => e
uid_logger_error(e.message)
render_error(-1, '头像修改失败!')
end
def get_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
redirect_to Rails.application.config_for(:configuration)['platform_url'] + "/" + url_to_avatar(@user).to_s
end
def me def me
@user = current_user @user = current_user
end end
@ -209,7 +193,7 @@ class UsersController < ApplicationController
def trustie_related_projects def trustie_related_projects
projects = Project.includes(:owner, :members, :project_score).where(id: params[:ids]).order("updated_on desc") projects = Project.includes(:owner, :members, :project_score).where(id: params[:ids]).order("updated_on desc")
projects_json = [] projects_json = []
domain_url = EduSetting.get('host_name') + '/projects' domain_url = EduSetting.get('host_name')
if projects.present? if projects.present?
projects.each do |p| projects.each do |p|
project_url = "/#{p.owner.login}/#{p.identifier}" project_url = "/#{p.owner.login}/#{p.identifier}"
@ -278,69 +262,25 @@ class UsersController < ApplicationController
render_ok render_ok
end end
# TODO: For Educoder def sync_user_info
def change_password
user = User.find_by_login params[:login] user = User.find_by_login params[:login]
return render_error("用户 #{params[:login]} 不存在.") if user.nil? return render_forbidden unless user === current_user
form_params= {
login: params[:login],
email: user&.mail,
password: params[:password],
user: user
}
Gitea::User::ChangePasswordForm.new(form_params).validate!
sync_params = { sync_params = {
password: params[:password].to_s, email: params[:email],
email: user.mail, password: params[:password]
login_name: user.login,
source_id: 0
} }
if sync_params.present? Users::UpdateInfoForm.new(sync_params.merge(login: params[:login])).validate!
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params) interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success? if interactor.success?
user.update!(password: params[:password], is_sync_pwd: true) user.update!(password: params[:password], mail: params[:email], status: User::STATUS_EDIT_INFO)
render_ok render_ok
else else
render_error(interactor.error) render_error(interactor.error)
end end
end end
end
# TODO: For Educoder
def change_email
user = User.find_by_login params[:login]
return render_error("用户 #{rq_params[:login]} 不存在.") if user.nil?
form_params= {
login: params[:login],
email: user&.mail,
user: user
}
Gitea::User::ChangeEmailForm.new(form_params).validate!
sync_params = {
email: params[:email]
}
if sync_params.present?
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(mail: params[:email])
render_ok
else
render_error(interactor.error)
end
end
end
def email_search
return render_error('请输入email') if params[:email].blank?
@user = User.find_by(mail: params[:email])
end
private private
def load_user def load_user
@ -354,7 +294,6 @@ class UsersController < ApplicationController
:occupation, :technical_title, :occupation, :technical_title,
:school_id, :department_id, :province, :city, :school_id, :department_id, :province, :city,
:custom_department, :identity, :student_id, :description, :custom_department, :identity, :student_id, :description,
:show_super_description, :super_description,
:show_email, :show_location, :show_department] :show_email, :show_location, :show_department]
) )
end end

View File

@ -14,7 +14,7 @@ class VersionReleasesController < ApplicationController
def new def new
#获取所有的分支 #获取所有的分支
@all_branches = [] @all_branches = []
get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier), params[:branch_name]).call get_all_branches = Gitea::Repository::Branches::ListService.new(@user, @repository.try(:identifier)).call
if get_all_branches && get_all_branches.size > 0 if get_all_branches && get_all_branches.size > 0
get_all_branches.each do |b| get_all_branches.each do |b|
@all_branches.push(b["name"]) @all_branches.push(b["name"])

View File

@ -1,13 +1,13 @@
--- ---
title: GitLink API Reference title: Trustie API Reference
language_tabs: # must be one of https://git.io/vQNgJ language_tabs: # must be one of https://git.io/vQNgJ
- shell: Shell - shell: Shell
- javascript: JavaScript - javascript: JavaScript
toc_footers: toc_footers:
- <a href='https://www.gitlink.org.cn/login'>Sign In for a User</a> - <a href='https://www.trustie.net/login?login=false'>Sign Up for a User</a>
- <a href='https://www.gitlink.org.cn'>Powered by GitLink</a> - <a href='https://www.trustie.net'>Powered by Trustie</a>
includes: includes:
- licenses - licenses
@ -30,8 +30,8 @@ code_clipboard: true
# Introduction # Introduction
Welcome to the GitLink API! You can use our API to access GitLink API endpoints, which can get information on projects, repository, and users in our platform. Welcome to the Trustie API! You can use our API to access Trustie API endpoints, which can get information on projects, repository, and users in our platform.
We have language bindings in Shell,avaScript! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right. We have language bindings in Shell,avaScript! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
This example API documentation page was created with [GitLink](https://www.gitlink.org.cn). Feel free to edit it and use it as a base for your own API's documentation. This example API documentation page was created with [Trustie](https://www.trustie.net). Feel free to edit it and use it as a base for your own API's documentation.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Some files were not shown because too many files have changed in this diff Show More