From cf6dc3a9b4f16bf877d37835b8c1e62ac0d66b1b Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 27 Jun 2025 14:39:28 +0800 Subject: [PATCH 01/21] =?UTF-8?q?fixed=20projects=20gpid=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=B4=A2=E5=BC=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- db/migrate/202506274325719_add_project_index_gpid.rb | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 db/migrate/202506274325719_add_project_index_gpid.rb diff --git a/db/migrate/202506274325719_add_project_index_gpid.rb b/db/migrate/202506274325719_add_project_index_gpid.rb new file mode 100644 index 000000000..1d680ce3c --- /dev/null +++ b/db/migrate/202506274325719_add_project_index_gpid.rb @@ -0,0 +1,5 @@ +class AddProjectIndexGpid < ActiveRecord::Migration[5.2] + def change + add_index :projects, :gpid + end +end From 3eebf61f031e4150c2e570238019a6000a9ed288 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 27 Jun 2025 14:40:37 +0800 Subject: [PATCH 02/21] =?UTF-8?q?fixed=20=E9=A1=B9=E7=9B=AE=E8=A1=A8?= =?UTF-8?q?=E5=A4=B4=E5=83=8F=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/projects/_project_detail.json.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/projects/_project_detail.json.jbuilder b/app/views/projects/_project_detail.json.jbuilder index 59160822f..3dc49f524 100644 --- a/app/views/projects/_project_detail.json.jbuilder +++ b/app/views/projects/_project_detail.json.jbuilder @@ -31,7 +31,7 @@ json.author do json.name user.try(:show_real_name) json.type user&.type json.login user.login - json.image_url url_to_avatar(user) + json.image_url url_to_avatar(user).present? ? url_to_avatar(user) : User::Avatar.get_letter_avatar_url(user.login) end end From a86372dc16ee29f4e1b89550bb00f32f14a752bf Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 27 Jun 2025 15:25:59 +0800 Subject: [PATCH 03/21] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E5=91=A8?= =?UTF-8?q?=E6=8A=A5=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/api/pm/weekly_issues/personal_issues.json.jbuilder | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/api/pm/weekly_issues/personal_issues.json.jbuilder b/app/views/api/pm/weekly_issues/personal_issues.json.jbuilder index 6c2f67909..d4f89b375 100644 --- a/app/views/api/pm/weekly_issues/personal_issues.json.jbuilder +++ b/app/views/api/pm/weekly_issues/personal_issues.json.jbuilder @@ -3,6 +3,6 @@ json.this_week_all_issues @this_week_all_issues.each do |issue| end json.this_week_total_count @this_week_all_issues.total_count json.next_week_all_issues @next_week_all_issues.each do |issue| - json.partial! "api/pm/weekly_issues/simple_detail", locals: {issue: issue, weekly_begin_date: @weekly_begin_date+1.week, weekly_end_date: @weekly_end_date+1.week} + json.partial! "api/pm/weekly_issues/simple_detail", locals: {issue: issue, weekly_begin_date: @weekly_begin_date.to_date+1.week, weekly_end_date: @weekly_end_date.to_date+1.week} end json.next_week_total_count @next_week_all_issues.total_count \ No newline at end of file From 8c9f6d61759d0a8039b114aeb975660470d8f1f3 Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 1 Jul 2025 16:19:15 +0800 Subject: [PATCH 04/21] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=90=8C?= =?UTF-8?q?=E6=AD=A5github=E7=BB=84=E7=BB=87=E4=B8=8B=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/v1/base_controller.rb | 5 +++ .../sync_repositories_controller.rb | 37 +++++++++++++++++++ config/routes/api.rb | 3 ++ 3 files changed, 45 insertions(+) create mode 100644 app/controllers/api/v1/organizations/sync_repositories_controller.rb diff --git a/app/controllers/api/v1/base_controller.rb b/app/controllers/api/v1/base_controller.rb index d9db4b99c..38e10d5f5 100644 --- a/app/controllers/api/v1/base_controller.rb +++ b/app/controllers/api/v1/base_controller.rb @@ -37,6 +37,11 @@ class Api::V1::BaseController < ApplicationController params.fetch(:page, 1) end + def load_organization + @organization = Organization.find_by(login: params[:owner]) || Organization.find_by(id: params[:owner]) + return render_not_found("组织不存在") if @organization.nil? + end + # 具有对仓库的管理权限 def require_manager_above @project = load_project diff --git a/app/controllers/api/v1/organizations/sync_repositories_controller.rb b/app/controllers/api/v1/organizations/sync_repositories_controller.rb new file mode 100644 index 000000000..9a4d7e077 --- /dev/null +++ b/app/controllers/api/v1/organizations/sync_repositories_controller.rb @@ -0,0 +1,37 @@ +class Api::V1::Organizations::SyncRepositoriesController < Api::V1::BaseController + before_action :load_organization, only: [:create] + + def create + return render_error("请输入正确的外部组织login") unless params[:external_login].present? + # 拉取外部组织仓库列表 + url = URI("https://api.github.com/orgs/#{params[:external_login]}/repos?page=#{params[:page]}&per_page=#{params[:limit]}") + https = Net::HTTP.new(url.host, url.port) + https.use_ssl = true + request = Net::HTTP::Get.new(url) + request["Authorization"] = "Bearer #{params[:external_token]}" + response = https.request(request) + if response.code == "200" + repos = JSON.parse(response.body) + repos.each do |repo| + # 检查是否已经存在该仓库 + @project = @organization.projects.find_by(identifier: repo["name"]) + if @project.present? + @project.update_column(:created_on, repo['created_at'].to_time) + @project.update_column(:updated_on, repo['updated_at'].to_time) + next + else + mirror_params = {name: repo["name"], user_id: @organization.id, description: repo["description"], repository_name: repo["name"], auth_token: params[:external_token], clone_addr: repo["clone_url"]} + @project = ::Projects::MigrateService.call(current_user, mirror_params) + @project.update_column(:created_on, repo['created_at'].to_time) + @project.update_column(:updated_on, repo['updated_at'].to_time) + end + end + end + end + + private + def sync_repository_params + params.permit(:external_token) + end + +end \ No newline at end of file diff --git a/config/routes/api.rb b/config/routes/api.rb index 3d8c8b536..d66bedc50 100644 --- a/config/routes/api.rb +++ b/config/routes/api.rb @@ -83,6 +83,9 @@ defaults format: :json do patch :update_phone end end + scope module: :organizations do + resources :sync_repositories, only: [:create] + end scope module: :users do resources :projects, only: [:index] resources :feedbacks, only: [:create] From cabc9775bc89473b59a4e5590cffa6515bc2c5bc Mon Sep 17 00:00:00 2001 From: yystopf Date: Wed, 2 Jul 2025 14:56:27 +0800 Subject: [PATCH 05/21] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=90=8C=E6=AD=A5=E9=A1=B9=E7=9B=AE=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/v1/organizations/sync_repositories_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/v1/organizations/sync_repositories_controller.rb b/app/controllers/api/v1/organizations/sync_repositories_controller.rb index 9a4d7e077..d02dcd40c 100644 --- a/app/controllers/api/v1/organizations/sync_repositories_controller.rb +++ b/app/controllers/api/v1/organizations/sync_repositories_controller.rb @@ -16,6 +16,11 @@ class Api::V1::Organizations::SyncRepositoriesController < Api::V1::BaseControll # 检查是否已经存在该仓库 @project = @organization.projects.find_by(identifier: repo["name"]) if @project.present? + if @project.repository.mirror.failed? + @project.destroy! + mirror_params = {name: repo["name"], user_id: @organization.id, description: repo["description"], repository_name: repo["name"], auth_token: params[:external_token], clone_addr: repo["clone_url"]} + @project = ::Projects::MigrateService.call(current_user, mirror_params) + end @project.update_column(:created_on, repo['created_at'].to_time) @project.update_column(:updated_on, repo['updated_at'].to_time) next From d286502224baa44bd118edbc5708e3c4d22fe2fe Mon Sep 17 00:00:00 2001 From: xxq250 Date: Wed, 2 Jul 2025 14:57:44 +0800 Subject: [PATCH 06/21] =?UTF-8?q?fixed=20=E7=94=A8=E6=88=B7=E6=90=9C?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E5=A2=9E=E5=8A=A0=E5=90=8D=E7=A7=B0=E6=A8=A1?= =?UTF-8?q?=E7=B3=8A=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/users/organizations_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/users/organizations_controller.rb b/app/controllers/users/organizations_controller.rb index 2d80adb9b..000d33f93 100644 --- a/app/controllers/users/organizations_controller.rb +++ b/app/controllers/users/organizations_controller.rb @@ -9,7 +9,7 @@ class Users::OrganizationsController < Users::BaseController @organizations = observed_user.organizations.with_visibility("common") end - @organizations = @organizations.ransack(login_cont: params[:search]).result if params[:search].present? + @organizations = @organizations.ransack(login_or_nickname_cont: params[:search]).result if params[:search].present? @home_top_ids = @organizations.joins(:home_top_settings).where(home_top_settings: {user_id: observed_user.id}).order("home_top_settings.created_at asc").pluck(:id) From 10c05896fc531f0a7834310815ffc8ae4580d19f Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 7 Jul 2025 15:05:47 +0800 Subject: [PATCH 07/21] =?UTF-8?q?fixed=20=E6=95=8F=E6=84=9F=E8=AF=8D?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/attachments_controller.rb | 1 + app/controllers/repositories_controller.rb | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index e4038fafa..3f94e00e7 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -33,6 +33,7 @@ class AttachmentsController < ApplicationController Rails.logger.info("request.host===#{request.host},request.referer===#{request.referer}") tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.","")) normal_status(-1, "参数缺失") if params[:download_url].blank? + render_error('不可访问') if params[:download_url].to_s.include?("chinese_dictionary.txt") url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s md5_file = Digest::MD5.hexdigest(params[:download_url]) FileUtils.mkdir_p("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") unless Dir.exists?("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index f5130e30c..a7f5558d8 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -84,7 +84,7 @@ class RepositoriesController < ApplicationController def sub_entries file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip)) - + render_error('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") if @project.educoder? if params[:type] === 'file' @sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri) @@ -307,6 +307,7 @@ class RepositoriesController < ApplicationController def raw domain = GiteaService.gitea_config[:domain] api_url = GiteaService.gitea_config[:base_url] + render_error('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" file_path = [domain, api_url, url].join From 4afce7809dfe875232abfbe8545dec8a8e5e77b8 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 7 Jul 2025 15:26:48 +0800 Subject: [PATCH 08/21] =?UTF-8?q?fixed=20=E6=95=8F=E6=84=9F=E8=AF=8D?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=EF=BC=8C=E6=96=B9=E6=B3=95=E6=94=B9?= =?UTF-8?q?=E4=B8=BAtip=5Fexception?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/attachments_controller.rb | 2 +- app/controllers/repositories_controller.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/attachments_controller.rb b/app/controllers/attachments_controller.rb index 3f94e00e7..200ad55e3 100644 --- a/app/controllers/attachments_controller.rb +++ b/app/controllers/attachments_controller.rb @@ -33,7 +33,7 @@ class AttachmentsController < ApplicationController Rails.logger.info("request.host===#{request.host},request.referer===#{request.referer}") tip_exception(403, "你没有权限访问") if request.host.present? && !request.referer.to_s.include?(request.host.to_s.gsub("www.","")) normal_status(-1, "参数缺失") if params[:download_url].blank? - render_error('不可访问') if params[:download_url].to_s.include?("chinese_dictionary.txt") + tip_exception('不可访问') if params[:download_url].to_s.include?("chinese_dictionary.txt") url = base_url.starts_with?("https:") ? params[:download_url].to_s.gsub("http:", "https:") : params[:download_url].to_s md5_file = Digest::MD5.hexdigest(params[:download_url]) FileUtils.mkdir_p("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") unless Dir.exists?("#{Rails.root}#{EduSetting.get("attachment_folder")}gitea/") diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index a7f5558d8..a5a740de7 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -84,7 +84,7 @@ class RepositoriesController < ApplicationController def sub_entries file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip)) - render_error('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") + tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") if @project.educoder? if params[:type] === 'file' @sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri) @@ -307,7 +307,7 @@ class RepositoriesController < ApplicationController def raw domain = GiteaService.gitea_config[:domain] api_url = GiteaService.gitea_config[:base_url] - render_error('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") + tip_exception('不可访问') if params[:filepath].to_s.include?("chinese_dictionary.txt") url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}" file_path = [domain, api_url, url].join From 44c8d0be7cec9f0a09871dc9ff50c88463efc611 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 7 Jul 2025 15:42:07 +0800 Subject: [PATCH 09/21] =?UTF-8?q?fixed=20=E5=A2=9E=E5=8A=A0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=96=87=E6=9C=AC=E5=86=85=E5=AE=B9=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=95=8F=E6=84=9F=E8=AF=8D=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/repositories_helper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 3ad563e0e..ebb3eb812 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -244,7 +244,9 @@ module RepositoriesHelper Rails.logger.info("entry===#{entry["type"]} #{entry["name"]}") content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] # readme_render_decode64_content(content, owner, repo, ref) - new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name']) + text = new_readme_render_decode64_content(content, owner, repo, ref, entry['path'], entry['name']) + text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text) + text end def decode64_content(entry, owner, repo, ref, path=nil) From b02cf8fe79645ef4b06d3478ace95239c7fad69c Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 7 Jul 2025 15:47:13 +0800 Subject: [PATCH 10/21] =?UTF-8?q?fixed=20=E5=A2=9E=E5=8A=A0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=96=87=E6=9C=AC=E5=86=85=E5=AE=B9=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=95=8F=E6=84=9F=E8=AF=8D=E6=A3=80=E6=B5=8B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/repositories_helper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index ebb3eb812..8101a7d81 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -266,7 +266,9 @@ module RepositoriesHelper if download_type(file_type) return entry['content'] end - render_decode64_content(entry['content']) + text = render_decode64_content(entry['content']) + text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text) + text end end From 981dde45efa948a6826075424401823b7d894621 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 7 Jul 2025 15:52:44 +0800 Subject: [PATCH 11/21] =?UTF-8?q?fixed=20=E5=A2=9E=E5=8A=A0=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=96=87=E6=9C=AC=E5=86=85=E5=AE=B9=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=95=8F=E6=84=9F=E8=AF=8D=E6=A3=80=E6=B5=8B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/helpers/repositories_helper.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 8101a7d81..f82e7abd1 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -255,9 +255,13 @@ module RepositoriesHelper content = entry['content'].present? ? entry['content'] : Gitea::Repository::Entries::GetService.call(owner, repo.identifier, URI.escape(entry['path']), ref: ref)['content'] # Rails.logger.info("content===#{content}") return Base64.decode64(content).force_encoding("GBK").encode("UTF-8") unless Base64.decode64(content).force_encoding('UTF-8').valid_encoding? - return Base64.decode64(content).force_encoding('UTF-8') + text = Base64.decode64(content).force_encoding('UTF-8') + text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text) + text elsif entry['is_text_file'] == true - return render_decode64_content(entry['content']) + text = render_decode64_content(entry['content']) + text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text) + text else file_type = File.extname(entry['name'].to_s)[1..-1] if image_type?(file_type) @@ -266,7 +270,7 @@ module RepositoriesHelper if download_type(file_type) return entry['content'] end - text = render_decode64_content(entry['content']) + text = render_decode64_content(entry['content']) text = "该内容不合规,请修改。" if text.present? && !HarmoniousDictionary.clean?(text) text end From 9d8600eb1c0ba7b636507d9fbd59e7808515fb59 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 11:52:24 +0800 Subject: [PATCH 12/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/accounts_controller.rb | 1 + app/controllers/application_controller.rb | 15 +--- app/controllers/concerns/login_helper.rb | 1 + app/libs/user_online.rb | 89 +++++++++++++++++++++++ 4 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 app/libs/user_online.rb diff --git a/app/controllers/accounts_controller.rb b/app/controllers/accounts_controller.rb index bbca99f1b..26c85f49c 100644 --- a/app/controllers/accounts_controller.rb +++ b/app/controllers/accounts_controller.rb @@ -292,6 +292,7 @@ class AccountsController < ApplicationController UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip) user.update_column(:last_login_on, Time.now) session[:"#{default_yun_session}"] = user.id + UserOnline.login(user.id) Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}") # 注册完成后有一天的试用申请(先去掉) # UserDayCertification.create(user_id: user.id, status: 1) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 074fd596e..a254e50eb 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -330,20 +330,6 @@ class ApplicationController < ActionController::Base User.current = find_current_user uid_logger("user_setup: " + (User.current.logged? ? "#{User.current.try(:login)} (id=#{User.current.try(:id)})" : "anonymous")) - # # 开放课程通过链接访问的用户 - # if !User.current.logged? && !params[:chinaoocTimestamp].blank? && !params[:websiteName].blank? && !params[:chinaoocKey].blank? - # content = "#{OPENKEY}#{params[:websiteName]}#{params[:chinaoocTimestamp]}" - # - # if Digest::MD5.hexdigest(content) == params[:chinaoocKey] - # user = open_class_user - # if user - # start_user_session(user) - # set_autologin_cookie(user) - # end - # User.current = user - # end - # end - if !User.current.logged? && Rails.env.development? user = User.find 1 User.current = user @@ -366,6 +352,7 @@ class ApplicationController < ActionController::Base end end end + UserOnline.login(User.current.id) # User.current = User.find 81403 end diff --git a/app/controllers/concerns/login_helper.rb b/app/controllers/concerns/login_helper.rb index c3b3ecc92..6a4dfa4b8 100644 --- a/app/controllers/concerns/login_helper.rb +++ b/app/controllers/concerns/login_helper.rb @@ -63,6 +63,7 @@ module LoginHelper user.delete_autologin_token(autologin) user.delete_session_token(session[:tk]) + UserOnline.logout(User.current.id) self.logged_user = nil end diff --git a/app/libs/user_online.rb b/app/libs/user_online.rb new file mode 100644 index 000000000..64de88093 --- /dev/null +++ b/app/libs/user_online.rb @@ -0,0 +1,89 @@ +module UserOnline + class << self + redis_config = YAML.load_file(Rails.root.join('config', 'redis.yml')) + if redis_config.present? + redis_url = redis_config[Rails.env]['url'] + $redis = Redis.new({:url=>redis_url}) + else + $redis = Rails.cache.data + end + def login(user_id) + set_bit(user_id, 1) + end + + def logout(user_id) + if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore) + now = Time.now() + keys = [] + (1..5).each do |i| + key = (now - i.minutes).strftime("%H-%M") + keys << "cache:online_user_#{key}" + set_bit_and_expire(cache_key, user_id, 0) unless $redis.ttl(cache_key) == -2 + end + end + set_bit(user_id, 0) + end + + def set_bit(user_id, flag) + if $redis.ttl(cache_key) == -2 + # 如果key不存在 + set_bit_and_expire(cache_key, user_id, flag) + else + if $redis.ttl(cache_key) ==-1 + # 可以存在,但过期时间没关联 + # 这种情况大概率是并发原因导致对相应key设置过期时跳过了。所以删除并重新设置过期时间 + $redis.del(cache_key) + set_bit_and_expire(cache_key, user_id, flag) + end + + # 统计当前时间下,前5分钟的活跃人数 + $redis.setbit(cache_key, user_id, flag) + end + end + + def set_bit_and_expire(cache_key, user_id, flag) + $redis.setbit(cache_key, user_id, flag) + # $redis.setbit(last_cache_key, user_id, flag) + # 现在统计5分钟在线人数,这里设置6分钟过期,目的是统计当前时刻的前5分钟 + $redis.expire(cache_key, 6 * 60) + end + + def count + if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore) + now = Time.now() + keys = [] + (0..4).each do |i| + key = (now - i.minutes).strftime("%H-%M") + keys << "cache:online_user_#{key}" + end + # 防止每个分钟数据有重复,所以去重去除 + $redis.bitop("OR", "daiao", keys) + $redis.bitcount("daiao") + else + 0 + end + end + + def cache_key + if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore) + "cache:online_user_#{Time.now().strftime("%H-%M")}" + else + raise '请配置config.cache_store = redis_store' + end + end + + def last_cache_key + if Rails.cache.is_a?(ActiveSupport::Cache::RedisStore) + # 如设置5分钟内即300秒有请求的用户视为在线, 则最大会统计到10分钟内有活动用户 + # TODO 更精确时长 + begin_hour = Time.now.beginning_of_hour + minutes_piece = (Time.now - begin_hour) / (60 * 5) + time = begin_hour.since((minutes_piece.to_i - 1) * (60 * 5)).strftime("%H-%M") + "cache:online_user_#{time}" + else + raise '请配置config.cache_store = redis_store' + end + end + + end +end From 7f386622a3a35621fab6c9788399cc0c1bba63aa Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 11:54:52 +0800 Subject: [PATCH 13/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95,=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admins/dashboards_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/admins/dashboards_controller.rb b/app/controllers/admins/dashboards_controller.rb index 47f7d56a2..e9ec59dcf 100644 --- a/app/controllers/admins/dashboards_controller.rb +++ b/app/controllers/admins/dashboards_controller.rb @@ -67,9 +67,9 @@ class Admins::DashboardsController < Admins::BaseController CommitLog.count end - @subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数"] + @subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数", "在线用户数"] @subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload"] - @subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count] + @subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count, UserOnline.count] if EduSetting.get("open_baidu_tongji").to_s == "true" tongji_service = Baidu::TongjiService.new From bff04758b89828fc490044e9372967016c63a4ac Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 11:55:25 +0800 Subject: [PATCH 14/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95,=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/admins/dashboards_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admins/dashboards_controller.rb b/app/controllers/admins/dashboards_controller.rb index e9ec59dcf..ab2b057dd 100644 --- a/app/controllers/admins/dashboards_controller.rb +++ b/app/controllers/admins/dashboards_controller.rb @@ -68,7 +68,7 @@ class Admins::DashboardsController < Admins::BaseController end @subject_name = ["用户数", "项目数", "组织数", "Issue数", "Issue评论数", "PR数", "Commit数", "在线用户数"] - @subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload"] + @subject_icon = ["fa-user","fa-git", "fa-sitemap", "fa-warning", "fa-comments", "fa-share-alt", "fa-upload", "fa-user"] @subject_data = [@user_count, @project_count, @organization_count, @issue_count, @comment_count, @pr_count, @commit_count, UserOnline.count] if EduSetting.get("open_baidu_tongji").to_s == "true" From 4151b3564ff53705b67f68fef84dcd5bcede7313 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 14:15:16 +0800 Subject: [PATCH 15/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95,=E7=BB=9F=E8=AE=A1=E5=BC=80?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/admins/dashboards/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admins/dashboards/index.html.erb b/app/views/admins/dashboards/index.html.erb index a55ef55e4..677b3416f 100644 --- a/app/views/admins/dashboards/index.html.erb +++ b/app/views/admins/dashboards/index.html.erb @@ -2,7 +2,7 @@ <% add_admin_breadcrumb('概览', admins_path) %> <% end %> -<% cache "/admin/dashboards/#{Time.now.strftime('%Y-%m-%d')}", :expires_in => 1.days do %> +<% cache_if EduSetting.get("open_baidu_tongji").to_s == "true", "/admin/dashboards/#{Time.now.strftime('%Y-%m-%d')}", :expires_in => 1.days do %>
From a90bed0b8f1b795a3e43c5cbfccb05bd96d603b2 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 14:20:29 +0800 Subject: [PATCH 16/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95,=E7=BB=9F=E8=AE=A1=E7=BC=93?= =?UTF-8?q?=E5=AD=98=E5=8F=96=E6=B6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/admins/dashboards/index.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admins/dashboards/index.html.erb b/app/views/admins/dashboards/index.html.erb index 677b3416f..656d00ceb 100644 --- a/app/views/admins/dashboards/index.html.erb +++ b/app/views/admins/dashboards/index.html.erb @@ -2,7 +2,7 @@ <% add_admin_breadcrumb('概览', admins_path) %> <% end %> -<% cache_if EduSetting.get("open_baidu_tongji").to_s == "true", "/admin/dashboards/#{Time.now.strftime('%Y-%m-%d')}", :expires_in => 1.days do %> +<%# cache_if EduSetting.get("open_baidu_tongji").to_s == "true", "/admin/dashboards/#{Time.now.strftime('%Y-%m-%d')}", :expires_in => 1.days do %>
@@ -32,7 +32,7 @@
-<%end %> +<%#end %>
From 9d968ac5db123eb1682845b0a1bd9663b439bd39 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Fri, 18 Jul 2025 14:59:27 +0800 Subject: [PATCH 17/21] =?UTF-8?q?add=20=E5=9C=A8=E7=BA=BF=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=AE=B0=E5=BD=95=E6=95=B0=E5=8D=95=E7=8B=AC=E6=98=BE?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/main_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/main_controller.rb b/app/controllers/main_controller.rb index da8ad26cb..592d10089 100644 --- a/app/controllers/main_controller.rb +++ b/app/controllers/main_controller.rb @@ -5,7 +5,7 @@ class MainController < ApplicationController skip_before_action :setup_laboratory def first_stamp - render :json => { status: 0, message: Time.now.to_i } + render :json => { status: 0, message: Time.now.to_i, online: UserOnline.count } end def test_404 From 85b55619c684f41918a6be45c3206dd2d1b549dc Mon Sep 17 00:00:00 2001 From: yystopf Date: Fri, 18 Jul 2025 21:08:28 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=E6=9C=80?= =?UTF-8?q?=E8=BF=91=E6=8F=90=E4=BA=A4=E6=96=87=E4=BB=B6=E6=95=B0=E8=BF=87?= =?UTF-8?q?=E5=A4=9A=E6=97=A0=E6=B3=95=E5=8A=A0=E8=BD=BD=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/api/v1/projects/commits/recent_service.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/services/api/v1/projects/commits/recent_service.rb b/app/services/api/v1/projects/commits/recent_service.rb index 9a226d9f2..09a1ee94e 100644 --- a/app/services/api/v1/projects/commits/recent_service.rb +++ b/app/services/api/v1/projects/commits/recent_service.rb @@ -25,7 +25,9 @@ class Api::V1::Projects::Commits::RecentService < ApplicationService param = { access_token: token, page: page, - limit: limit + limit: limit, + stats: false, + files: false } param.merge!(keyword: keyword) if keyword.present? From bd3dd5df4ad36debc012311b6a2877e77613bf41 Mon Sep 17 00:00:00 2001 From: xxq250 Date: Mon, 21 Jul 2025 15:16:13 +0800 Subject: [PATCH 19/21] =?UTF-8?q?add=20=E6=95=8F=E6=84=9F=E8=AF=8D?= =?UTF-8?q?=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chinese_dictionary.txt | 2 -- config/harmonious_dictionary/harmonious.hash | Bin 48912 -> 48906 bytes 2 files changed, 2 deletions(-) diff --git a/config/harmonious_dictionary/chinese_dictionary.txt b/config/harmonious_dictionary/chinese_dictionary.txt index 386534f3f..fe884de46 100644 --- a/config/harmonious_dictionary/chinese_dictionary.txt +++ b/config/harmonious_dictionary/chinese_dictionary.txt @@ -638,7 +638,6 @@ a级情片 法仑 法伦 法轮 -法论 反封锁技术 反腐败论坛 反共 @@ -1252,7 +1251,6 @@ fa轮 指点江山论坛 中俄边界 中功 -中共 中国威胁论 中国问题论坛 中国之春 diff --git a/config/harmonious_dictionary/harmonious.hash b/config/harmonious_dictionary/harmonious.hash index afab436f7c7bc9e95b3e2f3934f50b1ee10342ab..019e0105198c45acd22efe7c565f1ef823f26d54 100644 GIT binary patch delta 34 qcmbR6kE!b)(*_;A$t8WllV{E0+3cscP?Ax2^9T2-jGH?=J4yiu*bblo delta 51 zcmV-30L=f2{sNHx0lORFjMoAG264lo}}p67v86 From b3e5af3f2b84f502ec5492caa70ce66d2b59fadb Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 22 Jul 2025 09:41:18 +0800 Subject: [PATCH 20/21] =?UTF-8?q?=E6=9B=B4=E6=94=B9=EF=BC=9A=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E6=A8=A1=E6=9D=BF=E7=94=A8=E6=88=B7=E6=A0=87=E8=AF=86?= =?UTF-8?q?=E6=96=B0=E5=A2=9E*?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/competition_infos_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/competition_infos_controller.rb b/app/controllers/competition_infos_controller.rb index 93e8e74e7..4cbacdc99 100644 --- a/app/controllers/competition_infos_controller.rb +++ b/app/controllers/competition_infos_controller.rb @@ -163,7 +163,7 @@ class CompetitionInfosController < ApplicationController member_array << member end send_data["members"] = member_array - login_index = column_names.index("用户标识") + login_index = column_names.index("用户标识*") user = User.find_by(login:row[login_index]) || User.find_by(phone: send_data['phone']) if user.present? begin @@ -191,7 +191,7 @@ class CompetitionInfosController < ApplicationController format.xlsx { set_export_cookies enroll_fields = @competition_info.enroll_fields.except("ID") - @table_columns = ["用户标识"] | enroll_fields.keys + @table_columns = ["用户标识*"] | enroll_fields.keys if EduSetting.get("is_local") == "true" @table_columns = @table_columns + ["成员姓名", "成员单位", "成员手机号"] else From 31e4d73e2a0ea19d84788bcfe749907e7321061e Mon Sep 17 00:00:00 2001 From: yystopf Date: Tue, 22 Jul 2025 10:20:30 +0800 Subject: [PATCH 21/21] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=E5=91=A8?= =?UTF-8?q?=E6=8A=A5=E6=97=B6=E9=97=B4=E7=AD=9B=E9=80=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/api/pm/weekly_issues_controller.rb | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/controllers/api/pm/weekly_issues_controller.rb b/app/controllers/api/pm/weekly_issues_controller.rb index 4510e5ff7..88bd06d75 100644 --- a/app/controllers/api/pm/weekly_issues_controller.rb +++ b/app/controllers/api/pm/weekly_issues_controller.rb @@ -5,9 +5,11 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController return render_error('请输入正确的用户ID.') if params[:user_id].blank? @all_issues = Issue.joins(:issue_participants).where(issue_participants: {participant_id: params[:user_id], participant_type: ['assigned']}) @all_issues = @all_issues.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3]) - @this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s).distinct + @weekly_begin_date = params[:weekly_begin_date].to_time || Date.today.beginning_of_week rescue Date.today.beginning_of_week + @weekly_end_date = params[:weekly_end_date].to_time || Date.today.end_of_week rescue Date.today.end_of_week + @this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date.to_s, @weekly_end_date.to_s).distinct @this_week_all_issues = @this_week_all_issues.order('created_on desc').pm_includes - @next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (Date.today.beginning_of_week+1.week).to_s, (Date.today.end_of_week+1.week).to_s).distinct + @next_week_all_issues = @all_issues.where("due_date >= ? and start_date <=?", (@weekly_begin_date+1.week).to_s, (@weekly_end_date+1.week).to_s).distinct @next_week_all_issues = @next_week_all_issues.order('created_on desc').pm_includes @this_week_requirement_issues = @this_week_all_issues.where(pm_issue_type: 1) @this_week_task_issues = @this_week_all_issues.where(pm_issue_type: 2) @@ -27,7 +29,9 @@ class Api::Pm::WeeklyIssuesController < Api::Pm::BaseController @enterprise_identifier = params[:enterprise_identifier] || '' @all_issues = Issue.where(enterprise_identifier: @enterprise_identifier, pm_issue_type: [1,2,3]) @all_issues = @all_issues.where(pm_project_id: params[:pm_project_ids].split(",")) if params[:pm_project_ids].present? - @this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", Date.today.beginning_of_week.to_s, Date.today.end_of_week.to_s) + @weekly_begin_date = params[:weekly_begin_date] || Date.today.beginning_of_week.to_s + @weekly_end_date = params[:weekly_end_date] || Date.today.end_of_week.to_s + @this_week_all_issues = @all_issues.where("due_date >= ? and start_date <= ?", @weekly_begin_date, @weekly_end_date) @this_week_all_issues_group_count = @this_week_all_issues.group(:pm_project_id).count data = {} @this_week_all_issues_group_count.keys.each do |pm_project_id|