diff --git a/app/controllers/admins/project_categories_controller.rb b/app/controllers/admins/project_categories_controller.rb index 3b5065a16..8b1dd1f77 100644 --- a/app/controllers/admins/project_categories_controller.rb +++ b/app/controllers/admins/project_categories_controller.rb @@ -5,7 +5,7 @@ class Admins::ProjectCategoriesController < Admins::BaseController def index sort_by = ProjectCategory.column_names.include?(params[:sort_by]) ? params[:sort_by] : 'created_at' sort_direction = %w(desc asc).include?(params[:sort_direction]) ? params[:sort_direction] : 'desc' - q = ProjectCategory.includes(:projects).ransack(name_cont: params[:name]) + q = ProjectCategory.ransack(name_cont: params[:name]) project_categories = q.result(distinct: true).order("#{sort_by} #{sort_direction}") @project_categories = paginate(project_categories) diff --git a/app/controllers/organizations/organizations_controller.rb b/app/controllers/organizations/organizations_controller.rb index 269ca66cc..b73d1efac 100644 --- a/app/controllers/organizations/organizations_controller.rb +++ b/app/controllers/organizations/organizations_controller.rb @@ -22,7 +22,7 @@ class Organizations::OrganizationsController < Organizations::BaseController @can_create_project = @organization.can_create_project?(current_user.id) @is_admin = can_edit_org? @is_member = @organization.is_member?(current_user.id) - Cache::V2::OwnerCommonService.new(@organization.login, @organization.mail).read + Cache::V2::OwnerCommonService.new(@organization.id).read end def create diff --git a/app/controllers/project_rank_controller.rb b/app/controllers/project_rank_controller.rb index d2477b331..7bd62987e 100644 --- a/app/controllers/project_rank_controller.rb +++ b/app/controllers/project_rank_controller.rb @@ -2,9 +2,11 @@ class ProjectRankController < ApplicationController # 根据时间获取热门项目 def index $redis_cache.zunionstore("recent-days-project-rank", get_timeable_key_names) + deleted_data = $redis_cache.smembers("v2-project-rank-deleted") + $redis_cache.zrem("recent-days-project-rank", deleted_data) unless deleted_data.blank? @project_rank = $redis_cache.zrevrange("recent-days-project-rank", 0, 4, withscores: true) rescue Exception => e - @project_rack = [] + @project_rank = [] end private diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 4c4aa3a00..1864c6964 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -191,7 +191,7 @@ class ProjectsController < ApplicationController def simple # 为了缓存活跃项目的基本信息,后续删除 - Cache::V2::ProjectCommonService.new(@project.id).reset + Cache::V2::ProjectCommonService.new(@project.id).read json_response(@project, current_user) end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 48f016b98..744468ed8 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -52,7 +52,7 @@ class UsersController < ApplicationController @projects_mirrior_count = user_projects.mirror.size @projects_sync_mirrior_count = user_projects.sync_mirror.size # 为了缓存活跃用户的基本信息,后续删除 - Cache::V2::OwnerCommonService.new(@user.login, @user.mail).read + Cache::V2::OwnerCommonService.new(@user.id).read end def watch_users diff --git a/app/docs/slate/source/images/logo.png b/app/docs/slate/source/images/logo.png index 30affed0b..2f34775dc 100644 Binary files a/app/docs/slate/source/images/logo.png and b/app/docs/slate/source/images/logo.png differ diff --git a/public/docs/images/logo-b38b63e6.png b/app/docs/slate/source/images/trustie_logo.png similarity index 100% rename from public/docs/images/logo-b38b63e6.png rename to app/docs/slate/source/images/trustie_logo.png diff --git a/app/forms/projects/update_form.rb b/app/forms/projects/update_form.rb index ae93abf30..3048bc079 100644 --- a/app/forms/projects/update_form.rb +++ b/app/forms/projects/update_form.rb @@ -3,11 +3,12 @@ class Projects::UpdateForm < BaseForm validates :name, presence: true validates :name, length: { maximum: 50 } validates :description, length: { maximum: 200 } + validates :identifier, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" } + validate do check_project_category(project_category_id) check_project_language(project_language_id) - Rails.logger.info project_identifier - Rails.logger.info identifier + check_repository_name(user_id, identifier) unless identifier.blank? || identifier == project_identifier end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9cad9f44b..f58436285 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -442,6 +442,14 @@ module ApplicationHelper User.find_by(gitea_uid: gitea_uid) end + def find_user_in_redis_cache(login, email) + $redis_cache.hgetall("v2-owner-common:#{login}-#{email}") + end + + def find_user_in_redis_cache_by_id(id) + $redis_cache.hgetall("v2-owner-common:#{id}") + end + def render_base64_decoded(str) return nil if str.blank? Base64.decode64 str diff --git a/app/helpers/repositories_helper.rb b/app/helpers/repositories_helper.rb index 1096d1d21..cc50c8d66 100644 --- a/app/helpers/repositories_helper.rb +++ b/app/helpers/repositories_helper.rb @@ -35,6 +35,16 @@ module RepositoriesHelper end end + def render_cache_commit_author(author_json) + Rails.logger.info author_json['Email'] + if author_json["name"].present? && author_json["email"].present? + return find_user_in_redis_cache(author_json['name'], author_json['email']) + end + if author_json["Name"].present? && author_json["Email"].present? + return find_user_in_redis_cache(author_json['Name'], author_json['Email']) + end + end + def readme_render_decode64_content(str, path) return nil if str.blank? begin diff --git a/app/jobs/cache_async_clear_job.rb b/app/jobs/cache_async_clear_job.rb new file mode 100644 index 000000000..651dfaf41 --- /dev/null +++ b/app/jobs/cache_async_clear_job.rb @@ -0,0 +1,12 @@ +class CacheAsyncClearJob < ApplicationJob + queue_as :cache + + def perform(type, id=nil) + case type + when "project_common_service" + Cache::V2::ProjectCommonService.new(id).clear + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id).clear + end + end +end \ No newline at end of file diff --git a/app/jobs/cache_async_reset_job.rb b/app/jobs/cache_async_reset_job.rb index da3f01168..0df0f0fd4 100644 --- a/app/jobs/cache_async_reset_job.rb +++ b/app/jobs/cache_async_reset_job.rb @@ -7,6 +7,8 @@ class CacheAsyncResetJob < ApplicationJob Cache::V2::PlatformStatisticService.new.reset when "project_common_service" Cache::V2::ProjectCommonService.new(id).reset + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id).reset when "user_statistic_service" Cache::V2::UserStatisticService.new(id).reset end diff --git a/app/jobs/cache_async_set_job.rb b/app/jobs/cache_async_set_job.rb index f617b1316..9c7015d42 100644 --- a/app/jobs/cache_async_set_job.rb +++ b/app/jobs/cache_async_set_job.rb @@ -7,6 +7,8 @@ class CacheAsyncSetJob < ApplicationJob Cache::V2::PlatformStatisticService.new(params).call when "project_common_service" Cache::V2::ProjectCommonService.new(id, params).call + when "owner_common_service" + Cache::V2::OwnnerCommonService.new(id, params).call when "user_statistic_service" Cache::V2::UserStatisticService.new(id, params).call end diff --git a/app/models/organization.rb b/app/models/organization.rb index a967e4782..40c676e05 100644 --- a/app/models/organization.rb +++ b/app/models/organization.rb @@ -84,7 +84,7 @@ class Organization < Owner after_save :reset_cache_data def reset_cache_data - Cache::V2::OwnerCommonService.new(self.login, self.mail).reset + Cache::V2::OwnerCommonService.new(self.id).reset end def self.build(name, nickname, gitea_token=nil) diff --git a/app/models/project.rb b/app/models/project.rb index e8760acf1..45b93cd00 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -128,7 +128,7 @@ class Project < ApplicationRecord has_many :pinned_projects, dependent: :destroy has_many :has_pinned_users, through: :pinned_projects, source: :user has_many :webhooks, class_name: "Gitea::Webhook", primary_key: :gpid, foreign_key: :repo_id - after_create :init_project_common, :incre_user_statistic, :incre_platform_statistic + after_create :incre_user_statistic, :incre_platform_statistic after_save :check_project_members, :reset_cache_data before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned before_destroy :decre_project_common @@ -169,12 +169,8 @@ class Project < ApplicationRecord end end - def init_project_common - CacheAsyncResetJob.perform_later("project_common_service", self.id) - end - def decre_project_common - $redis_cache.del("v2-project-common:#{self.id}") + CacheAsyncClearJob.perform_later('project_common_service', self.id) end def incre_user_statistic diff --git a/app/models/user.rb b/app/models/user.rb index dcefa8aaa..8613b68a5 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -208,7 +208,7 @@ class User < Owner validate :validate_password_length def reset_cache_data - Cache::V2::OwnerCommonService.new(self.login, self.mail).reset + Cache::V2::OwnerCommonService.new(self.id).reset end # 用户参与的所有项目 diff --git a/app/services/cache/v2/owner_common_service.rb b/app/services/cache/v2/owner_common_service.rb index d8b86d097..c97e34d48 100644 --- a/app/services/cache/v2/owner_common_service.rb +++ b/app/services/cache/v2/owner_common_service.rb @@ -1,12 +1,13 @@ class Cache::V2::OwnerCommonService < ApplicationService include AvatarHelper - attr_reader :owner_id, :login, :name, :avatar_url, :email - attr_accessor :owner + attr_reader :owner_id, :name + attr_accessor :owner, :login, :email - def initialize(login, email, params={}) - @login = login - @email = email + def initialize(owner_id, params={}) + @owner_id = owner_id + @email = params[:email] @name = params[:name] + @avatar_url = params[:avatar_url] end def read @@ -14,7 +15,6 @@ class Cache::V2::OwnerCommonService < ApplicationService end def call - load_owner set_owner_common end @@ -22,9 +22,15 @@ class Cache::V2::OwnerCommonService < ApplicationService reset_owner_common end + def clear + clear_owner_common + end + private def load_owner - @owner = Owner.find_by(login: @login) + @owner = Owner.find_by_id @owner_id + @login = @owner&.login + @email ||= @owner&.mail end def owner_common_key @@ -32,35 +38,47 @@ class Cache::V2::OwnerCommonService < ApplicationService end def owner_common_key_by_id - "v2-owner-common:#{@owner.id}" + "v2-owner-common:#{@owner&.id}" end def owner_common - $redis_cache.hgetall(owner_common_key).blank? ? reset_owner_common : $redis_cache.hgetall(owner_common_key) + result = $redis_cache.hgetall(owner_common_key_by_id) + result.blank? ? reset_owner_common : result end def set_owner_common - if $redis_cache.hgetall(owner_common_key).blank? + if $redis_cache.hgetall(owner_common_key_by_id).blank? reset_owner_common return - end - if @name.present? - if $redis_cache.hget(owner_common_key, "name").nil? - reset_owner_name - else - $redis_cache.hset(owner_common_key, "name", @name) - $redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner)) - - $redis_cache.hset(owner_common_key_by_id, "name", @name) - $redis_cache.hset(owner_common_key_by_id, "avatar_url", url_to_avatar(owner)) + else + load_owner + return if @owner.nil? + if @name.present? + if $redis_cache.hget(owner_common_key, "name").nil? + reset_owner_name + else + $redis_cache.hset(owner_common_key, "name", @name) + $redis_cache.hset(owner_common_key_by_id, "name", @name) + end end - end - if @email.present? - if $redis_cache.hget(owner_common_key, "email").nil? - reset_owner_email - else - $redis_cache.hset(owner_common_key, "email", @email) - $redis_cache.hset(owner_common_key_by_id, "email", @email) + if @email.present? + if $redis_cache.hget(owner_common_key, "email").nil? + reset_owner_email + else + # 更改邮箱这里把旧数据删除 + $redis_cache.del("v2-owner-common:#{@login}-*") + $redis_cache.hset(owner_common_key, "email", @email) + $redis_cache.hset(owner_common_key_by_id, "email", @email) + end + end + if @avatar_url.present? + if $redis_cache.hget(owner_common_key, "avatar_url").nil? + reset_owner_avatar_url + else + $redis_cache.hset(owner_common_key, "avatar_url", @avatar_url) + $redis_cache.hset(owner_common_key_by_id, "avatar_url", @avatar_url) + end + end end @@ -88,20 +106,30 @@ class Cache::V2::OwnerCommonService < ApplicationService def reset_owner_name $redis_cache.hset(owner_common_key, "name", owner&.real_name) - $redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner)) $redis_cache.hset(owner_common_key_by_id, "name", owner&.real_name) + end + + def reset_owner_avatar_url + $redis_cache.hset(owner_common_key, "avatar_url", url_to_avatar(owner)) $redis_cache.hset(owner_common_key_by_id, "avatar_url", url_to_avatar(owner)) end def reset_owner_common - load_owner - $redis_cache.del(owner_common_key) + clear_owner_common reset_owner_id reset_owner_type reset_owner_login reset_owner_email reset_owner_name + reset_owner_avatar_url $redis_cache.hgetall(owner_common_key) end + + def clear_owner_common + load_owner + return if @owner.nil? + $redis_cache.del(owner_common_key) + $redis_cache.del(owner_common_key_by_id) + end end \ No newline at end of file diff --git a/app/services/cache/v2/platform_statistic_service.rb b/app/services/cache/v2/platform_statistic_service.rb index bc6621a38..5bf4f4a74 100644 --- a/app/services/cache/v2/platform_statistic_service.rb +++ b/app/services/cache/v2/platform_statistic_service.rb @@ -64,7 +64,9 @@ class Cache::V2::PlatformStatisticService < ApplicationService end def platform_statistic - $redis_cache.hgetall(platform_statistic_key).blank? ? reset_platform_statistic : $redis_cache.hgetall(platform_statistic_key) + result = $redis_cache.hgetall(platform_statistic_key) + + result.blank? ? reset_platform_statistic : result end def set_platform_statistic diff --git a/app/services/cache/v2/project_common_service.rb b/app/services/cache/v2/project_common_service.rb index 77a7d27b7..760c6d05b 100644 --- a/app/services/cache/v2/project_common_service.rb +++ b/app/services/cache/v2/project_common_service.rb @@ -28,6 +28,10 @@ class Cache::V2::ProjectCommonService < ApplicationService reset_project_common end + def clear + clear_project_common + end + private def load_project @project = Project.find_by_id(project_id) @@ -78,109 +82,75 @@ class Cache::V2::ProjectCommonService < ApplicationService end def project_common - $redis_cache.hgetall(project_common_key).blank? ? reset_project_common : $redis_cache.hgetall(project_common_key) + result = $redis_cache.hgetall(project_common_key) + result.blank? ? reset_project_common : result end def set_project_common if $redis_cache.hgetall(project_common_key).blank? reset_project_common return - end - load_project - return unless @project.is_full_public - if @owner_id.present? - if $redis_cache.hget(project_common_key, owner_id_key).nil? - reset_project_owner_id - else - $redis_cache.hset(project_common_key, owner_id_key, @owner_id) + else + load_project + return unless @project.is_full_public + if @owner_id.present? + if $redis_cache.hget(project_common_key, owner_id_key).nil? + reset_project_owner_id + else + $redis_cache.hset(project_common_key, owner_id_key, @owner_id) + end end - end - if @name.present? - if $redis_cache.hget(project_common_key, name_key).nil? - reset_project_name - else - $redis_cache.hset(project_common_key, name_key, @name) + if @name.present? + if $redis_cache.hget(project_common_key, name_key).nil? + reset_project_name + else + $redis_cache.hset(project_common_key, name_key, @name) + end end - end - if @identifier.present? - if $redis_cache.hget(project_common_key, identifier_key).nil? - reset_project_identifier - else - $redis_cache.hset(project_common_key, identifier_key, @identifier) + if @identifier.present? + if $redis_cache.hget(project_common_key, identifier_key).nil? + reset_project_identifier + else + $redis_cache.hset(project_common_key, identifier_key, @identifier) + end end - end - if @description.present? - if $redis_cache.hget(project_common_key, description_key).nil? - reset_project_description - else - $redis_cache.hset(project_common_key, description_key, @description) + if @description.present? + if $redis_cache.hget(project_common_key, description_key).nil? + reset_project_description + else + $redis_cache.hset(project_common_key, description_key, @description) + end end - end - if @visits.present? - if $redis_cache.hget(project_common_key, visits_key).nil? - reset_project_visits - Cache::V2::ProjectRankService.call(@project_id, {visits: @visits}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {visits: @visits}) - else - puts project_common_key - puts visits_key - puts @visits + if @visits.present? $redis_cache.hincrby(project_common_key, visits_key, @visits.to_s) Cache::V2::ProjectRankService.call(@project_id, {visits: @visits}) Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {visits: @visits}) end - end - if @watchers.present? - if $redis_cache.hget(project_common_key, watchers_key).nil? - reset_project_watchers - else + if @watchers.present? $redis_cache.hincrby(project_common_key, watchers_key, @watchers) end - end - if @praises.present? - if $redis_cache.hget(project_common_key, praises_key).nil? - reset_project_praises - Cache::V2::ProjectRankService.call(@project_id, {praises: @praises}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {praises: @praises}) - else + if @praises.present? $redis_cache.hincrby(project_common_key, praises_key, @praises) - Cache::V2::ProjectRankService.call(@project_id, {praises: @praises}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {praises: @praises}) + Cache::V2::ProjectRankService.call(@project_id, {praises: @praises}) + Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {praises: @praises}) end - end - if @forks.present? - if $redis_cache.hget(project_common_key, forks_key).nil? - reset_project_forks - Cache::V2::ProjectRankService.call(@project_id, {forks: @forks}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {forks: @forks}) - else + if @forks.present? $redis_cache.hincrby(project_common_key, forks_key, @forks) Cache::V2::ProjectRankService.call(@project_id, {forks: @forks}) Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {forks: @forks}) end - end - if @issues.present? - if $redis_cache.hget(project_common_key, issues_key).nil? - reset_project_issues - Cache::V2::ProjectRankService.call(@project_id, {issues: @issues}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {issues: @issues}) - else + if @issues.present? $redis_cache.hincrby(project_common_key, issues_key, @issues) Cache::V2::ProjectRankService.call(@project_id, {issues: @issues}) Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {issues: @issues}) end - end - if @pullrequests.present? - if $redis_cache.hget(project_common_key, pullrequests_key).nil? - reset_project_pullrequests - Cache::V2::ProjectRankService.call(@project_id, {pullrequests: @pullrequests}) - Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {pullrequests: @pullrequests}) - else + if @pullrequests.present? $redis_cache.hincrby(project_common_key, pullrequests_key, @pullrequests) Cache::V2::ProjectRankService.call(@project_id, {pullrequests: @pullrequests}) Cache::V2::ProjectDateRankService.call(@project_id, Date.today, {pullrequests: @pullrequests}) end end + $redis_cache.hgetall(project_common_key) end @@ -241,4 +211,9 @@ class Cache::V2::ProjectCommonService < ApplicationService $redis_cache.hgetall(project_common_key) end + + def clear_project_common + $redis_cache.del(project_common_key) + Cache::V2::ProjectRankService.new(@project_id).clear + end end \ No newline at end of file diff --git a/app/services/cache/v2/project_rank_service.rb b/app/services/cache/v2/project_rank_service.rb index 45484dc08..7e5d323bf 100644 --- a/app/services/cache/v2/project_rank_service.rb +++ b/app/services/cache/v2/project_rank_service.rb @@ -23,6 +23,10 @@ class Cache::V2::ProjectRankService < ApplicationService reset_project_rank end + def clear + clear_project_rank + end + private def load_project_common @project_common = Cache::V2::ProjectCommonService.new(@project_id).read @@ -33,7 +37,8 @@ class Cache::V2::ProjectRankService < ApplicationService end def project_rank - $redis_cache.zscore(project_rank_key, @project_id).blank? ? reset_project_rank : $redis_cache.zscore(project_rank_key, @project_id) + result = $redis_cache.zscore(project_rank_key, @project_id) + result.blank? ? reset_project_rank : result end def set_project_rank @@ -41,23 +46,24 @@ class Cache::V2::ProjectRankService < ApplicationService if $redis_cache.zscore(project_rank_key, @project_id).blank? reset_project_rank return + else + if @visits.present? + $redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id) + end + if @praises.present? + $redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id) + end + if @forks.present? + $redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id) + end + if @issues.present? + $redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id) + end + if @pullrequests.present? + $redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id) + end + reset_user_project_rank end - if @visits.present? - $redis_cache.zincrby(project_rank_key, @visits.to_i * 1, @project_id) - end - if @praises.present? - $redis_cache.zincrby(project_rank_key, @praises.to_i * 5, @project_id) - end - if @forks.present? - $redis_cache.zincrby(project_rank_key, @forks.to_i * 5, @project_id) - end - if @issues.present? - $redis_cache.zincrby(project_rank_key, @issues.to_i * 10, @project_id) - end - if @pullrequests.present? - $redis_cache.zincrby(project_rank_key, @pullrequests.to_i * 10, @project_id) - end - reset_user_project_rank $redis_cache.zscore(project_rank_key, @project_id) end @@ -74,4 +80,8 @@ class Cache::V2::ProjectRankService < ApplicationService def reset_user_project_rank $redis_cache.zadd("v2-user-project-rank:#{@project_common["owner_id"]}", $redis_cache.zscore(project_rank_key, @project_id), @project_id) end + + def clear_project_rank + $redis_cache.sadd('v2-project-rank-deleted', @project_id) + end end \ No newline at end of file diff --git a/app/services/cache/v2/user_statistic_service.rb b/app/services/cache/v2/user_statistic_service.rb index 8caa66d88..b82797d84 100644 --- a/app/services/cache/v2/user_statistic_service.rb +++ b/app/services/cache/v2/user_statistic_service.rb @@ -12,6 +12,7 @@ class Cache::V2::UserStatisticService < ApplicationService @project_praise_count = params[:project_praise_count] @project_watcher_count = params[:project_watcher_count] @pullrequest_count = params[:pullrequest_count] + Cache::V2::OwnerCommonService.new(user_id).read end def read @@ -65,7 +66,8 @@ class Cache::V2::UserStatisticService < ApplicationService end def user_statistic - $redis_cache.hgetall(user_statistic_key).blank? ? reset_user_statistic : $redis_cache.hgetall(user_statistic_key) + result = $redis_cache.hgetall(user_statistic_key) + result.blank? ? reset_user_statistic : result end def set_user_statistic diff --git a/app/views/admins/project_categories/_list.html.erb b/app/views/admins/project_categories/_list.html.erb index 1a460a486..1a1626bc4 100644 --- a/app/views/admins/project_categories/_list.html.erb +++ b/app/views/admins/project_categories/_list.html.erb @@ -20,7 +20,7 @@
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队
- 扫一扫,关注trustie微信公众号,更方便获取平台动态,消息推送等提醒
- 想了解更多信息,请访问 www.trustie.net
-
如果您在使用中有任何的疑问和建议,欢迎您给我们反馈意见
QQ群:1071514693
Trustie团队
+GitLink团队