| @@ -51,6 +51,51 @@ http://localhost:3000/api/accounts/remote_register | jq | |||
| |-- token |string|用户token| | |||
| 返回值 | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success", | |||
| "user": { | |||
| "id": 36400, | |||
| "token": "8c87a80d9cfacc92fcb2451845104f35119eda96" | |||
| } | |||
| } | |||
| ``` | |||
| --- | |||
| #### 独立注册接口 | |||
| ``` | |||
| POST accounts/register | |||
| ``` | |||
| *示例* | |||
| ```bash | |||
| curl -X POST \ | |||
| -d "login=2456233122@qq.com" \ | |||
| -d "password=djs_D_00001" \ | |||
| -d "namespace=16895620" \ | |||
| -d "code=forge" \ | |||
| http://localhost:3000/api/accounts/remote_register | jq | |||
| ``` | |||
| *请求参数说明:* | |||
| |参数名|必选|类型|说明| | |||
| |-|-|-|-| | |||
| |login |是|string |邮箱或者手机号 | | |||
| |namespace |是|string |登录名 | | |||
| |password |是|string |密码 | | |||
| |code |是|string |验证码 | | |||
| *返回参数说明:* | |||
| |参数名|类型|说明| | |||
| |-|-|-| | |||
| |user|json object |返回数据| | |||
| |-- id |int |用户id | | |||
| |-- token |string|用户token| | |||
| 返回值 | |||
| ```json | |||
| { | |||
| @@ -1,4 +1,5 @@ | |||
| class AccountsController < ApplicationController | |||
| include ApplicationHelper | |||
| #skip_before_action :check_account, :only => [:logout] | |||
| @@ -9,7 +10,7 @@ class AccountsController < ApplicationController | |||
| # 其他平台同步注册的用户 | |||
| def remote_register | |||
| username = params[:username]&.gsub(/\s+/, "") | |||
| tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.is_reversed(username).present? | |||
| tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username) | |||
| email = params[:email]&.gsub(/\s+/, "") | |||
| password = params[:password] | |||
| platform = (params[:platform] || 'forge')&.gsub(/\s+/, "") | |||
| @@ -109,60 +110,46 @@ class AccountsController < ApplicationController | |||
| # 用户注册 | |||
| # 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用 | |||
| # params[:login] 邮箱或者手机号 | |||
| # params[:namespace] 登录名 | |||
| # params[:code] 验证码 | |||
| # code_type 1:注册手机验证码 8:邮箱注册验证码 | |||
| # 本地forge注册入口 | |||
| # 本地forge注册入口需要重新更改逻辑 | |||
| def register | |||
| # type只可能是1或者8 | |||
| user = nil | |||
| begin | |||
| # 查询验证码是否正确;type只可能是1或者8 | |||
| type = phone_mail_type(params[:login].strip) | |||
| # code = params[:code].strip | |||
| if type == 1 | |||
| uid_logger("start register by phone: type is #{type}") | |||
| pre = 'p' | |||
| email = nil | |||
| phone = params[:login] | |||
| # verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 1).last | |||
| # TODO: 暂时限定邮箱注册 | |||
| return normal_status(-1, '只支持邮箱注册') | |||
| else | |||
| uid_logger("start register by email: type is #{type}") | |||
| pre = 'm' | |||
| email = params[:login] | |||
| phone = nil | |||
| return normal_status(-1, "该邮箱已注册") if User.exists?(mail: params[:login]) | |||
| return normal_status(-1, "邮箱格式错误") unless params[:login] =~ CustomRegexp::EMAIL | |||
| # verifi_code = VerificationCode.where(email: email, code: code, code_type: 8).last | |||
| end | |||
| # uid_logger("start register: verifi_code is #{verifi_code}, code is #{code}, time is #{Time.now.to_i - verifi_code.try(:created_at).to_i}") | |||
| # check_code = (verifi_code.try(:code) == code.strip && (Time.now.to_i - verifi_code.created_at.to_i) <= 10*60) | |||
| # todo 上线前请删除万能验证码"513231" | |||
| return normal_status(-1, "8~16位密码,支持字母数字和符号") unless params[:password] =~ CustomRegexp::PASSWORD | |||
| code = generate_identifier User, 8, pre | |||
| login = pre + code | |||
| @user = User.new(admin: false, login: login, mail: email, phone: phone, type: "User") | |||
| @user.password = params[:password] | |||
| # 现在因为是验证码,所以在注册的时候就可以激活 | |||
| @user.activate | |||
| # 必须要用save操作,密码的保存是在users中 | |||
| interactor = Gitea::RegisterInteractor.call({username: login, email: email, password: params[:password]}) | |||
| Register::Form.new(register_params).validate! | |||
| user = Users::RegisterService.call(register_params) | |||
| password = register_params[:password].strip | |||
| # gitea用户注册, email, username, password | |||
| interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password}) | |||
| if interactor.success? | |||
| gitea_user = interactor.result | |||
| result = Gitea::User::GenerateTokenService.new(login, params[:password]).call | |||
| @user.gitea_token = result['sha1'] | |||
| @user.gitea_uid = gitea_user[:body]['id'] | |||
| if @user.save! | |||
| UserExtension.create!(user_id: @user.id) | |||
| successful_authentication(@user) | |||
| normal_status("注册成功") | |||
| result = Gitea::User::GenerateTokenService.call(user.login, password) | |||
| user.gitea_token = result['sha1'] | |||
| user.gitea_uid = gitea_user[:body]['id'] | |||
| if user.save! | |||
| UserExtension.create!(user_id: user.id) | |||
| successful_authentication(user) | |||
| render_ok | |||
| end | |||
| else | |||
| tip_exception(-1, interactor.error) | |||
| end | |||
| rescue Register::BaseForm::EmailError => e | |||
| render_error(-2, e.message) | |||
| rescue Register::BaseForm::LoginError => e | |||
| render_error(-3, e.message) | |||
| rescue Register::BaseForm::PhoneError => e | |||
| render_error(-4, e.message) | |||
| rescue Register::BaseForm::PasswordFormatError => e | |||
| render_error(-5, e.message) | |||
| rescue Register::BaseForm::VerifiCodeError => e | |||
| render_error(-6, e.message) | |||
| rescue Exception => e | |||
| Gitea::User::DeleteService.call(user.login) unless user.nil? | |||
| uid_logger_error(e.message) | |||
| tip_exception(-1, e.message) | |||
| end | |||
| @@ -297,7 +284,7 @@ class AccountsController < ApplicationController | |||
| # 发送验证码 | |||
| # params[:login] 手机号或者邮箱号 | |||
| # params[:type]为事件通知类型 1:用户注册注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 | |||
| # params[:type]为事件通知类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加 | |||
| # 发送验证码:send_type 1:注册手机验证码 2:找回密码手机验证码 3:找回密码邮箱验证码 4:绑定手机 5:绑定邮箱 | |||
| # 6:手机验证码登录 7:邮箱验证码登录 8:邮箱注册验证码 9: 验收手机号有效 | |||
| def get_verification_code | |||
| @@ -311,19 +298,22 @@ class AccountsController < ApplicationController | |||
| sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}") | |||
| tip_exception(501, "请求不合理") if sign != params[:smscode] | |||
| logger.info "########### 验证码:#{verification_code}" | |||
| logger.info("########get_verification_code: login_type: #{login_type}, send_type:#{send_type}, ") | |||
| # 记录验证码 | |||
| check_verification_code(verification_code, send_type, value) | |||
| sucess_status | |||
| render_ok | |||
| end | |||
| # 1 手机类型;0 邮箱类型 | |||
| # 注意新版的login是自动名生成的 | |||
| def phone_mail_type value | |||
| value =~ /^1\d{10}$/ ? 1 : 0 | |||
| # check user's login or email or phone is used | |||
| # params[:value] 手机号或者邮箱号或者登录名 | |||
| # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) | |||
| def check | |||
| Register::CheckColumnsForm.new(check_params).validate! | |||
| render_ok | |||
| end | |||
| private | |||
| # type 事件类型 1:用户注册 2:忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加 | |||
| @@ -369,4 +359,13 @@ class AccountsController < ApplicationController | |||
| def account_params | |||
| params.require(:account).permit(:login, :password) | |||
| end | |||
| def check_params | |||
| params.permit(:type, :value) | |||
| end | |||
| def register_params | |||
| params.permit(:login, :namespace, :password, :code) | |||
| end | |||
| end | |||
| @@ -10,6 +10,10 @@ class Admins::SystemNotificationsController < Admins::BaseController | |||
| @notifications = paginate(notifications) | |||
| end | |||
| def history | |||
| @users = @notification.users | |||
| end | |||
| def new | |||
| @notification = SystemNotification.new | |||
| end | |||
| @@ -70,49 +70,11 @@ class ApplicationController < ActionController::Base | |||
| (current_user.professional_certification && (ue.teacher? || ue.professional?)) | |||
| end | |||
| def shixun_marker | |||
| unless current_user.is_shixun_marker? || current_user.admin_or_business? | |||
| tip_exception(403, "..") | |||
| end | |||
| end | |||
| # 实训的访问权限 | |||
| def shixun_access_allowed | |||
| if !current_user.shixun_permission(@shixun) | |||
| tip_exception(403, "..") | |||
| end | |||
| end | |||
| def admin_or_business? | |||
| User.current.admin? || User.current.business? | |||
| end | |||
| # 访问课堂时没权限直接弹加入课堂的弹框 :409 | |||
| def user_course_identity | |||
| @user_course_identity = current_user.course_identity(@course) | |||
| if @user_course_identity > Course::STUDENT && @course.is_public == 0 | |||
| tip_exception(401, "..") unless User.current.logged? | |||
| check_account | |||
| tip_exception(@course.excellent ? 410 : 409, "您没有权限进入") | |||
| end | |||
| if @user_course_identity > Course::CREATOR && @user_course_identity <= Course::STUDENT && @course.tea_id != current_user.id | |||
| # 实名认证和职业认证的身份判断 | |||
| tip_exception(411, "你的实名认证和职业认证审核未通过") if @course.authentication && | |||
| @course.professional_certification && (!current_user.authentication && !current_user.professional_certification) | |||
| tip_exception(411, "你的实名认证审核未通过") if @course.authentication && !current_user.authentication | |||
| tip_exception(411, "你的职业认证审核未通过") if @course.professional_certification && !current_user.professional_certification | |||
| end | |||
| uid_logger("###############user_course_identity:#{@user_course_identity}") | |||
| end | |||
| # 题库的访问权限 | |||
| def bank_visit_auth | |||
| tip_exception(-2,"未通过职业认证") if current_user.is_teacher? && !current_user.certification_teacher? && !current_user.admin_or_business? && @bank.user_id != current_user.id && @bank.is_public | |||
| tip_exception(403, "无权限") unless @bank.user_id == current_user.id || current_user.admin_or_business? || | |||
| (current_user.certification_teacher? && @bank.is_public) | |||
| end | |||
| # 判断用户的邮箱或者手机是否可用 | |||
| # params[:type] 1: 注册;2:忘记密码;3:绑定 | |||
| def check_mail_and_phone_valid login, type | |||
| @@ -120,16 +82,16 @@ class ApplicationController < ActionController::Base | |||
| login =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])$/ | |||
| tip_exception(-2, "请输入正确的手机号或邮箱") | |||
| end | |||
| # 考虑到安全参数问题,多一次查询,去掉Union | |||
| user = User.where(phone: login).first || User.where(mail: login).first | |||
| if type.to_i == 1 && !user.nil? | |||
| user_exist = Owner.exists?(phone: login) || Owner.exists?(mail: login) | |||
| if user_exist && type.to_i == 1 | |||
| tip_exception(-2, "该手机号码或邮箱已被注册") | |||
| elsif type.to_i == 2 && user.nil? | |||
| elsif type.to_i == 2 && !user_exist | |||
| tip_exception(-2, "该手机号码或邮箱未注册") | |||
| elsif type.to_i == 3 && user.present? | |||
| elsif type.to_i == 3 && user_exist | |||
| tip_exception(-2, "该手机号码或邮箱已绑定") | |||
| end | |||
| sucess_status | |||
| render_ok | |||
| end | |||
| # 发送及记录激活码 | |||
| @@ -186,26 +148,6 @@ class ApplicationController < ActionController::Base | |||
| end | |||
| end | |||
| def find_course | |||
| return normal_status(2, '缺少course_id参数!') if params[:course_id].blank? | |||
| @course = Course.find(params[:course_id]) | |||
| tip_exception(404, "") if @course.is_delete == 1 && !current_user.admin_or_business? | |||
| rescue Exception => e | |||
| tip_exception(e.message) | |||
| end | |||
| def course_manager | |||
| return normal_status(403, '只有课堂管理员才有权限') if @user_course_identity > Course::CREATOR | |||
| end | |||
| def find_board | |||
| return normal_status(2, "缺少board_id参数") if params[:board_id].blank? | |||
| @board = Board.find(params[:board_id]) | |||
| rescue Exception => e | |||
| uid_logger_error(e.message) | |||
| tip_exception(e.message) | |||
| end | |||
| def validate_type(object_type) | |||
| normal_status(2, "参数") if params.has_key?(:sort_type) && !SORT_TYPE.include?(params[:sort_type].strip) | |||
| end | |||
| @@ -215,21 +157,6 @@ class ApplicationController < ActionController::Base | |||
| @page_size = params[:page_size] || 15 | |||
| end | |||
| # 课堂教师权限 | |||
| def teacher_allowed | |||
| logger.info("#####identity: #{current_user.course_identity(@course)}") | |||
| unless current_user.course_identity(@course) < Course::STUDENT | |||
| normal_status(403, "") | |||
| end | |||
| end | |||
| # 课堂教师、课堂管理员、超级管理员的权限(不包含助教) | |||
| def teacher_or_admin_allowed | |||
| unless current_user.course_identity(@course) < Course::ASSISTANT_PROFESSOR | |||
| normal_status(403, "") | |||
| end | |||
| end | |||
| def require_admin | |||
| normal_status(403, "") unless User.current.admin? | |||
| end | |||
| @@ -3,8 +3,8 @@ module RenderHelper | |||
| render json: { status: 0, message: 'success' }.merge(data) | |||
| end | |||
| def render_error(message = '') | |||
| render json: { status: -1, message: message } | |||
| def render_error(status = -1, message = '') | |||
| render json: { status: status, message: message } | |||
| end | |||
| def render_not_acceptable(message = '请求已拒绝') | |||
| @@ -27,7 +27,7 @@ class Organizations::OrganizationsController < Organizations::BaseController | |||
| def create | |||
| ActiveRecord::Base.transaction do | |||
| tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.is_reversed(organization_params[:name]).present? | |||
| tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name]) | |||
| Organizations::CreateForm.new(organization_params).validate! | |||
| @organization = Organizations::CreateService.call(current_user, organization_params) | |||
| Util.write_file(@image, avatar_path(@organization)) if params[:image].present? | |||
| @@ -0,0 +1,15 @@ | |||
| class Users::SystemNotificationHistoriesController < Users::BaseController | |||
| before_action :private_user_resources!, only: [:create] | |||
| def create | |||
| @history = observed_user.system_notification_histories.new(system_notification_id: params[:system_notification_id]) | |||
| if @history.save | |||
| render_ok | |||
| else | |||
| Rails.logger.info @history.errors.as_json | |||
| render_error(@history.errors.full_messages.join(",")) | |||
| end | |||
| rescue Exception => e | |||
| uid_logger_error(e.message) | |||
| tip_exception(e.message) | |||
| end | |||
| end | |||
| @@ -199,6 +199,36 @@ await octokit.request('GET /api/users/:login/messages.json') | |||
| Success Data. | |||
| </aside> | |||
| ## 用户阅读系统通知 | |||
| 用户阅读系统通知 | |||
| > 示例: | |||
| ```shell | |||
| curl -X POST http://localhost:3000/api/users/yystopf/system_notification_histories.json | |||
| ``` | |||
| ```javascript | |||
| await octokit.request('GET /api/users/:login/system_notification_histories.json') | |||
| ``` | |||
| ### HTTP 请求 | |||
| `POST /api/users/:login/system_notification_histories.json` | |||
| ### 请求字段说明: | |||
| 参数 | 类型 | 字段说明 | |||
| --------- | ----------- | ----------- | |||
| |system_notification_id |integer |阅读的系统通知id | | |||
| > 返回的JSON示例: | |||
| ```json | |||
| { | |||
| "status": 0, | |||
| "message": "success" | |||
| } | |||
| ``` | |||
| ## 发送消息 | |||
| 发送消息, 目前只支持atme | |||
| @@ -23,7 +23,11 @@ class BaseForm | |||
| end | |||
| def check_reversed_keyword(repository_name) | |||
| raise "项目标识已被占用." if ReversedKeyword.is_reversed(repository_name).exists? | |||
| raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name) | |||
| end | |||
| private | |||
| def strip(str) | |||
| str.to_s.strip.presence | |||
| end | |||
| end | |||
| @@ -0,0 +1,51 @@ | |||
| module Register | |||
| class BaseForm < ::BaseForm | |||
| include ActiveModel::Model | |||
| Error = Class.new(StandardError) | |||
| EmailError = Class.new(Error) | |||
| LoginError = Class.new(Error) | |||
| PhoneError = Class.new(Error) | |||
| PasswordFormatError = Class.new(Error) | |||
| VerifiCodeError = Class.new(Error) | |||
| private | |||
| def check_login(login) | |||
| login = strip(login) | |||
| raise LoginError, "登录名格式有误" unless login =~ CustomRegexp::LOGIN | |||
| login_exist = Owner.exists?(login: login) || ReversedKeyword.check_exists?(login) | |||
| raise LoginError, '登录名已被使用' if login_exist | |||
| end | |||
| def check_mail(mail) | |||
| mail = strip(mail) | |||
| raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL | |||
| mail_exist = Owner.exists?(mail: mail) | |||
| raise EmailError, '邮箱已被使用' if mail_exist | |||
| end | |||
| def check_phone(phone) | |||
| phone = strip(phone) | |||
| raise PhoneError, "手机号格式有误" unless phone =~ CustomRegexp::PHONE | |||
| phone_exist = Owner.exists?(phone: phone) | |||
| raise PhoneError, '手机号已被使用' if phone_exist | |||
| end | |||
| def check_password(password) | |||
| password = strip(password) | |||
| raise PasswordFormatError, "8~16位密码,支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD | |||
| end | |||
| def check_verifi_code(verifi_code, code) | |||
| code = strip(code) | |||
| # return if code == "123123" # TODO 万能验证码,用于测试 | |||
| raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code | |||
| raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective? | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,19 @@ | |||
| module Register | |||
| class CheckColumnsForm < Register::BaseForm | |||
| attr_accessor :type, :value | |||
| validates :type, presence: true, numericality: true | |||
| validates :value, presence: true | |||
| validate :check! | |||
| def check! | |||
| # params[:type] 为事件类型 1:登录名(login) 2:email(邮箱) 3:phone(手机号) | |||
| case strip(type).to_i | |||
| when 1 then check_login(strip(value)) | |||
| when 2 then check_mail(strip(value)) | |||
| when 3 then check_phone(strip(value)) | |||
| else raise("type值无效") | |||
| end | |||
| end | |||
| end | |||
| end | |||
| @@ -0,0 +1,27 @@ | |||
| module Register | |||
| class Form < Register::BaseForm | |||
| # login 登陆方式,支持邮箱、登陆、手机号等 | |||
| # namespace 用户空间地址 | |||
| # type: 1:手机号注册;2:邮箱注册 | |||
| attr_accessor :login, :namespace, :password, :code, :type | |||
| validates :login, :code, :password, :namespace, presence: true | |||
| validate :check! | |||
| def check! | |||
| Rails.logger.info "Register::Form params: code: #{code}; login: #{login}; namespace: #{namespace}; password: #{password}; type: #{type}" | |||
| db_verifi_code = | |||
| if type == 1 | |||
| check_phone(login) | |||
| VerificationCode.where(phone: login, code: code, code_type: 1).last | |||
| elsif type == 0 | |||
| check_mail(login) | |||
| VerificationCode.where(email: login, code: code, code_type: 8).last | |||
| end | |||
| check_login(namespace) | |||
| check_verifi_code(db_verifi_code, code) | |||
| check_password(password) | |||
| end | |||
| end | |||
| end | |||
| @@ -455,5 +455,11 @@ module ApplicationHelper | |||
| sidebar_item(url, "数据统计", icon: 'bar-chart', controller: 'root') | |||
| end | |||
| end | |||
| # 1 手机类型;0 邮箱类型 | |||
| # 注意新版的login是自动名生成的 | |||
| def phone_mail_type value | |||
| value =~ /^1\d{10}$/ ? 1 : 0 | |||
| end | |||
| end | |||
| @@ -1,6 +1,7 @@ | |||
| module CustomRegexp | |||
| PHONE = /1\d{10}/ | |||
| EMAIL = /\A[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+\z/ | |||
| LOGIN = /^(?!_)(?!.*?_$)[a-zA-Z0-9_-]+$/ #只含有数字、字母、下划线不能以下划线开头和结尾 | |||
| LASTNAME = /\A[a-zA-Z0-9\u4e00-\u9fa5]+\z/ | |||
| NICKNAME = /\A[\u4e00-\u9fa5_a-zA-Z0-9]+\z/ | |||
| PASSWORD = /\A[a-z_A-Z0-9\-\.!@#\$%\\\^&\*\)\(\+=\{\}\[\]\/",'_<>~\·`\?:;|]{8,16}\z/ | |||
| @@ -1,17 +1,11 @@ | |||
| class UserMailer < ApplicationMailer | |||
| # 注意:这个地方一定要和你的邮箱服务域名一致 | |||
| default from: 'educoder@trustie.org' | |||
| default from: 'notification@trustie.org' | |||
| # 用户注册验证码 | |||
| def register_email(mail, code) | |||
| @code = code | |||
| mail(to: mail, subject: '验证你的电子邮件') | |||
| mail(to: mail, subject: 'Gitink | 注册验证码') | |||
| end | |||
| # 课堂讨论区的邮件通知 | |||
| def course_message_email(mail, message_id) | |||
| @message = Message.find_by(id: message_id) | |||
| @course = @message&.board&.course | |||
| mail(to: mail, subject: '课堂发布了新的帖子') if @message.present? && @course.present? | |||
| end | |||
| end | |||
| @@ -18,6 +18,10 @@ class ReversedKeyword < ApplicationRecord | |||
| before_validation :set_identifier | |||
| def self.check_exists?(identifier) | |||
| self.is_reversed(identifier).exists? | |||
| end | |||
| private | |||
| def set_identifier | |||
| @@ -15,6 +15,13 @@ class SystemNotification < ApplicationRecord | |||
| default_scope { order(created_at: :desc)} | |||
| has_many :system_notification_histories | |||
| has_many :users, through: :system_notification_histories | |||
| scope :is_top, lambda { where(is_top: true) } | |||
| def read_member?(user_id) | |||
| self.system_notification_histories.where(user_id: user_id).present? ? true : false | |||
| end | |||
| end | |||
| @@ -0,0 +1,23 @@ | |||
| # == Schema Information | |||
| # | |||
| # Table name: system_notification_histories | |||
| # | |||
| # id :integer not null, primary key | |||
| # system_message_id :integer | |||
| # user_id :integer | |||
| # created_at :datetime not null | |||
| # updated_at :datetime not null | |||
| # | |||
| # Indexes | |||
| # | |||
| # index_system_notification_histories_on_system_message_id (system_message_id) | |||
| # index_system_notification_histories_on_user_id (user_id) | |||
| # | |||
| class SystemNotificationHistory < ApplicationRecord | |||
| belongs_to :system_notification | |||
| belongs_to :user | |||
| validates :system_notification_id, uniqueness: { scope: :user_id, message: '只能阅读一次'} | |||
| end | |||
| @@ -173,6 +173,9 @@ class User < Owner | |||
| has_one :user_template_message_setting, dependent: :destroy | |||
| has_many :system_notification_histories | |||
| has_many :system_notifications, through: :system_notification_histories | |||
| # Groups and active users | |||
| scope :active, lambda { where(status: STATUS_ACTIVE) } | |||
| scope :like, lambda { |keywords| | |||
| @@ -11,20 +11,45 @@ class Projects::ListQuery < ApplicationQuery | |||
| end | |||
| def call | |||
| q = params[:pinned].present? ? Project.pinned : Project | |||
| q = q.visible.by_name_or_identifier(params[:search]) | |||
| scope = q | |||
| .with_project_type(params[:project_type]) | |||
| .with_project_category(params[:category_id]) | |||
| .with_project_language(params[:language_id]) | |||
| collection = Project.all | |||
| collection = filter_projects(collection) | |||
| sort = params[:sort_by] || "updated_on" | |||
| sort_direction = params[:sort_direction] || "desc" | |||
| custom_sort(scope, sort, sort_direction) | |||
| custom_sort(collection, sort, sort_direction) | |||
| # scope = scope.reorder("projects.#{sort} #{sort_direction}") | |||
| # scope | |||
| end | |||
| def filter_projects(collection) | |||
| collection = by_pinned(collection) | |||
| collection = by_search(collection) | |||
| collection = by_project_type(collection) | |||
| collection = by_project_category(collection) | |||
| collection = by_project_language(collection) | |||
| collection | |||
| end | |||
| def by_search(items) | |||
| items.visible.by_name_or_identifier(params[:search]) | |||
| end | |||
| def by_project_type(items) | |||
| items.with_project_type(params[:project_type]) | |||
| end | |||
| def by_project_category(items) | |||
| items.with_project_category(params[:category_id]) | |||
| end | |||
| def by_project_language(items) | |||
| items.with_project_language(params[:language_id]) | |||
| end | |||
| def by_pinned(items) | |||
| (params[:pinned].present? && params[:category_id].present?) ? items.pinned : items | |||
| end | |||
| end | |||
| @@ -82,6 +82,8 @@ class Gitea::ClientService < ApplicationService | |||
| req.headers['Content-Type'] = 'application/json' | |||
| req.response :logger # 显示日志 | |||
| req.adapter Faraday.default_adapter | |||
| req.options.timeout = 100 # open/read timeout in seconds | |||
| req.options.open_timeout = 10 # connection open timeout in seconds | |||
| if token.blank? | |||
| req.basic_auth(username, secret) | |||
| else | |||
| @@ -0,0 +1,31 @@ | |||
| class Gitea::User::DeleteService < Gitea::ClientService | |||
| attr_reader :username | |||
| def initialize(username) | |||
| @username = username | |||
| end | |||
| def call | |||
| response = delete(request_url, params) | |||
| render_status(response) | |||
| end | |||
| private | |||
| def token | |||
| { | |||
| username: Gitea.gitea_config[:access_key_id], | |||
| password: Gitea.gitea_config[:access_key_secret] | |||
| } | |||
| end | |||
| def request_url | |||
| "/admin/users/#{username}" | |||
| end | |||
| def params | |||
| Hash.new.merge(token: token) | |||
| end | |||
| end | |||
| @@ -0,0 +1,58 @@ | |||
| class Users::RegisterService < ApplicationService | |||
| def initialize(params) | |||
| @login = params[:login] | |||
| @namespace = params[:namespace] | |||
| @password = params[:password] | |||
| @code = params[:code] | |||
| end | |||
| def call | |||
| code = strip(@code) | |||
| login = strip(@login) | |||
| namespace = strip(@namespace) | |||
| password = strip(@password) | |||
| Rails.logger.info "Users::RegisterService params: ##### #{params} " | |||
| email, phone = | |||
| if register_type == 1 | |||
| phone_register(login, code) | |||
| elsif register_type == 0 | |||
| mail_register(login, code) | |||
| end | |||
| user = User.new(admin: false, login: namespace, mail: email, phone: phone, type: "User") | |||
| user.password = password | |||
| user.activate # 现在因为是验证码,所以在注册的时候就可以激活 | |||
| user | |||
| end | |||
| private | |||
| # 手机注册 | |||
| def phone_register(login, code) | |||
| Rails.logger.info("start register by phone: phone is #{login}") | |||
| email = nil | |||
| phone = login | |||
| [email, phone] | |||
| end | |||
| # 邮箱注册 | |||
| def mail_register(login, code) | |||
| Rails.logger.info("start register by email: email is #{login}") | |||
| email = login | |||
| phone = nil | |||
| [email, phone] | |||
| end | |||
| def register_type | |||
| phone_mail_type(@login) | |||
| end | |||
| def phone_mail_type value | |||
| value =~ /^1\d{10}$/ ? 1 : 0 | |||
| end | |||
| end | |||
| @@ -60,6 +60,7 @@ json.setting do | |||
| if @top_system_notification.present? | |||
| json.system_notification do | |||
| json.(@top_system_notification, :id, :subject, :sub_subject, :content) | |||
| json.is_read @top_system_notification.read_member?(current_user&.id) | |||
| end | |||
| else | |||
| json.system_notification nil | |||
| @@ -1,7 +1,7 @@ | |||
| <html> | |||
| <head> | |||
| <meta charset="utf-8"> | |||
| <title>验证码发送</title> | |||
| <title>GitLink-验证码发送</title> | |||
| <style type="text/css"> | |||
| /* 验证链接页面 */ | |||
| body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{ margin:0; padding:0;} | |||
| @@ -27,8 +27,8 @@ | |||
| <div class="new_content"> | |||
| <div style="width: 598px; background:#fff; margin:20px auto; font-size:14px; "> | |||
| <div style="height:50px; width: 578px; background:#46484c; padding:9px 10px 6px;border:1px solid #ddd; border-bottom:none;"> | |||
| <a href="https://www.educoder.net"> | |||
| <img src="https://www.educoder.net/images/educoder/headNavLogo.png" width="36" style="float:left; margin-top: 8px;" > | |||
| <a href="https://www.gitlink.org.cn"> | |||
| <%= image_tag("logo.png", alt: "确实开源", width: '100', :style => "float:left; margin-top: 8px;") %> | |||
| </a> | |||
| <div style="clear:both; overflow:hidden;"></div> | |||
| </div> | |||
| @@ -37,7 +37,7 @@ | |||
| 您好! | |||
| </p> | |||
| <p style="color:#333;"> | |||
| 您正在注册Educoder,请在10分钟内在注册页输入此验证码,并进行下一步操作。 | |||
| 您正在注册GitLink,请在10分钟内在注册页输入此验证码,并进行下一步操作。 | |||
| 如非你本人操作,请忽略此邮件。 | |||
| </p> | |||
| <div style="text-align: center;"> | |||
| @@ -46,7 +46,7 @@ | |||
| </div> | |||
| <span style="font-weight: normal;color:#666;"> | |||
| 此邮件为系统所发,请勿直接回复。<br/> | |||
| 要解决问题或了解您的帐户详情,您可以访问 <a href="https://www.educoder.net/help?index=5" style="font-weight: normal; color:#ff7500;">帮助中心</a>。 | |||
| 要解决问题或了解您的帐户详情,您可以访问 <a href="https:///www.gitlink.org.cn/forums/1168/detail" style="font-weight: normal; color:#ff7500;">帮助中心</a>。 | |||
| </span> | |||
| </div> | |||
| <p style="color:#666; margin-top:30px;"> | |||
| @@ -54,7 +54,7 @@ | |||
| </p> | |||
| </div> | |||
| <div style="padding:20px; color:#333; line-height: 1.9;background:#46484c;border:1px solid #ddd; border-top:none; width: 558px;"> | |||
| <a href="https:///www.educoder.net/" style="font-weight: normal; color:#fff;">www.educoder.net</a> | |||
| <a href="https:///www.gitlink.org.cn" style="font-weight: normal; color:#fff;">www.gitlink.org.cn</a> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,6 @@ | |||
| zh-CN: | |||
| activerecord: | |||
| attributes: | |||
| system_notification_history: | |||
| system_notification: "系统通知" | |||
| system_notification_id: "系统通知" | |||
| @@ -202,6 +202,7 @@ Rails.application.routes.draw do | |||
| post :remote_login | |||
| post :remote_password | |||
| post :change_password | |||
| post :check | |||
| end | |||
| end | |||
| @@ -272,6 +273,7 @@ Rails.application.routes.draw do | |||
| scope module: :users do | |||
| get 'template_message_settings', to: 'template_message_settings#current_setting' | |||
| post 'template_message_settings/update_setting', to: 'template_message_settings#update_setting' | |||
| resources :system_notification_histories, only: [:create] | |||
| resources :applied_messages, only: [:index] | |||
| resources :applied_transfer_projects, only: [:index] do | |||
| member do | |||
| @@ -679,7 +681,11 @@ Rails.application.routes.draw do | |||
| resources :project_licenses | |||
| resources :project_ignores | |||
| resources :reversed_keywords | |||
| resources :system_notifications | |||
| resources :system_notifications do | |||
| member do | |||
| get :history | |||
| end | |||
| end | |||
| resources :message_templates, only: [:index, :edit, :update] do | |||
| collection do | |||
| get :init_data | |||
| @@ -0,0 +1,10 @@ | |||
| class CreateSystemNotificationHistories < ActiveRecord::Migration[5.2] | |||
| def change | |||
| create_table :system_notification_histories do |t| | |||
| t.references :system_notification | |||
| t.references :user | |||
| t.timestamps | |||
| end | |||
| end | |||
| end | |||
| @@ -348,6 +348,9 @@ | |||
| <li> | |||
| <a href="#5b752913ae" class="toc-h2 toc-link" data-title="用户消息列表">用户消息列表</a> | |||
| </li> | |||
| <li> | |||
| <a href="#6087e717ed" class="toc-h2 toc-link" data-title="用户阅读系统通知">用户阅读系统通知</a> | |||
| </li> | |||
| <li> | |||
| <a href="#94306b2fc3" class="toc-h2 toc-link" data-title="发送消息">发送消息</a> | |||
| </li> | |||
| @@ -1337,7 +1340,39 @@ Success — a happy kitten is an authenticated kitten! | |||
| <aside class="success"> | |||
| Success Data. | |||
| </aside> | |||
| <h2 id='94306b2fc3'>发送消息</h2> | |||
| <h2 id='6087e717ed'>用户阅读系统通知</h2> | |||
| <p>用户阅读系统通知</p> | |||
| <blockquote> | |||
| <p>示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/system_notification_histories.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/system_notification_histories.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-3'>HTTP 请求</h3> | |||
| <p><code>POST /api/users/:login/system_notification_histories.json</code></p> | |||
| <h3 id='aa883f5d52-2'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| <th>类型</th> | |||
| <th>字段说明</th> | |||
| </tr> | |||
| </thead><tbody> | |||
| <tr> | |||
| <td>system_notification_id</td> | |||
| <td>integer</td> | |||
| <td>阅读的系统通知id</td> | |||
| </tr> | |||
| </tbody></table> | |||
| <blockquote> | |||
| <p>返回的JSON示例:</p> | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight json tab-json"><code><span class="p">{</span><span class="w"> | |||
| </span><span class="nl">"status"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> | |||
| </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"success"</span><span class="w"> | |||
| </span><span class="p">}</span><span class="w"> | |||
| </span></code></pre></div><h2 id='94306b2fc3'>发送消息</h2> | |||
| <p>发送消息, 目前只支持atme</p> | |||
| <blockquote> | |||
| @@ -1345,9 +1380,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/:login/messages.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/users/:login/messages.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-3'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-4'>HTTP 请求</h3> | |||
| <p><code>POST api/users/yystopf/messages.json</code></p> | |||
| <h3 id='aa883f5d52-2'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-3'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -1406,9 +1441,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/:login/messages/read.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/users/:login/messages/read.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-4'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-5'>HTTP 请求</h3> | |||
| <p><code>POST api/users/yystopf/messages/read.json</code></p> | |||
| <h3 id='aa883f5d52-3'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-4'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -1447,9 +1482,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> DELETE http://localhost:3000/api/users/:login/messages.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">DELETE /api/users/:login/messages.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-5'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-6'>HTTP 请求</h3> | |||
| <p><code>DELETE api/users/yystopf/messages.json</code></p> | |||
| <h3 id='aa883f5d52-4'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-5'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -1488,9 +1523,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> PATCH/PUT http://localhost:3000/api/users/yystopf.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">PATCH/PUT /api/users/:login.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-6'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-7'>HTTP 请求</h3> | |||
| <p><code>PATCH/PUT /api/users/:login.json</code></p> | |||
| <h3 id='aa883f5d52-5'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-6'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -1586,7 +1621,7 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/template_message_settings.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/template_message_settings.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-7'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-8'>HTTP 请求</h3> | |||
| <p><code>GET /api/template_message_settings.json</code></p> | |||
| <h3 id='7447e4874e-3'>返回字段说明:</h3> | |||
| <table><thead> | |||
| @@ -1729,7 +1764,7 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/template_message_settings.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/uses/yystopf/template_message_settings.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-8'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-9'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:user_id/template_message_settings.json</code></p> | |||
| <h3 id='7447e4874e-4'>返回字段说明:</h3> | |||
| <table><thead> | |||
| @@ -1799,9 +1834,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/template_message_settings/update_setting.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">POST /api/uses/yystopf/template_message_settings/update_setting.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-9'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-10'>HTTP 请求</h3> | |||
| <p><code>POST /api/users/:user_id/template_message_settings/update_setting.json</code></p> | |||
| <h3 id='aa883f5d52-6'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-7'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -1918,7 +1953,7 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/is_pinned_projects.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/is_pinned_projects.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-10'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-11'>HTTP 请求</h3> | |||
| <p><code>GET api/users/:login/is_pinned_projects.json</code></p> | |||
| <h3 id='7447e4874e-6'>返回字段说明:</h3> | |||
| <table><thead> | |||
| @@ -2105,9 +2140,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/is_pinned_projects/pin.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/is_pinned_projects/pin.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-11'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-12'>HTTP 请求</h3> | |||
| <p><code>POST /api/users/:login/is_pinned_projects/pin.json</code></p> | |||
| <h3 id='aa883f5d52-7'>请求字段说明:</h3><h4 id='0ca7f0efb8'>同时设定多个星标项目</h4> | |||
| <h3 id='aa883f5d52-8'>请求字段说明:</h3><h4 id='0ca7f0efb8'>同时设定多个星标项目</h4> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2151,9 +2186,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> PATCH http://localhost:3000/api/users/yystopf/is_pinned_projects/11.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">PATCH/PUT /api/users/:login/is_pinned_projects/:id.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-12'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-13'>HTTP 请求</h3> | |||
| <p><code>PATCH/PUT /api/users/:login/is_pinned_projects/:id.json</code></p> | |||
| <h3 id='aa883f5d52-8'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-9'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2192,7 +2227,7 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/statistics/activity.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/statistics/activity.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-13'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-14'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/statistics/activity.json</code></p> | |||
| <h3 id='7447e4874e-7'>返回字段说明:</h3> | |||
| <table><thead> | |||
| @@ -2281,9 +2316,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/headmaps.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/headmaps.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-14'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-15'>HTTP 请求</h3> | |||
| <p><code>GET api/users/:login/headmaps.json</code></p> | |||
| <h3 id='aa883f5d52-9'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-10'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2426,9 +2461,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/project_trends.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/project_trends.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-15'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-16'>HTTP 请求</h3> | |||
| <p><code>GET api/users/:login/project_trends.json</code></p> | |||
| <h3 id='aa883f5d52-10'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-11'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2743,9 +2778,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/statistics/develop.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/statistics/develop.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-16'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-17'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/statistics/develop.json</code></p> | |||
| <h3 id='aa883f5d52-11'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-12'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2886,9 +2921,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/statistics/role.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/statistics/role.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-17'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-18'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/statistics/role.json</code></p> | |||
| <h3 id='aa883f5d52-12'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-13'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -2968,9 +3003,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/statistics/major.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/statistics/major.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-18'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-19'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/statistics/major.json</code></p> | |||
| <h3 id='aa883f5d52-13'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-14'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -3029,9 +3064,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/applied_messages.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_messages.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-19'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-20'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_messages.json</code></p> | |||
| <h3 id='aa883f5d52-14'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-15'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -3308,9 +3343,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/applied_transfer_projects.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_transfer_projects.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-20'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-21'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_transfer_projects.json</code></p> | |||
| <h3 id='aa883f5d52-15'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-16'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -3500,9 +3535,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/accept.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_transfer_projects/:id/accept.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-21'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-22'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_transfer_projects/:id/accept.json</code></p> | |||
| <h3 id='aa883f5d52-16'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-17'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -3691,9 +3726,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/applied_transfer_projects/2/refuse.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_transfer_projects/:id/refuse.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-22'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-23'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_transfer_projects/:id/refuse.json</code></p> | |||
| <h3 id='aa883f5d52-17'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-18'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -3882,9 +3917,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> GET http://localhost:3000/api/users/yystopf/applied_projects.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_projects.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-23'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-24'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_projects.json</code></p> | |||
| <h3 id='aa883f5d52-18'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-19'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -4042,9 +4077,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/applied_projects/2/accept.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_projects/:id/accept.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-24'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-25'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_projects/:id/accept.json</code></p> | |||
| <h3 id='aa883f5d52-19'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-20'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||
| @@ -4201,9 +4236,9 @@ Success — a happy kitten is an authenticated kitten! | |||
| </blockquote> | |||
| <div class="highlight"><pre class="highlight shell tab-shell"><code>curl <span class="nt">-X</span> POST http://localhost:3000/api/users/yystopf/applied_projects/2/refuse.json | |||
| </code></pre></div><div class="highlight"><pre class="highlight javascript tab-javascript"><code><span class="k">await</span> <span class="nx">octokit</span><span class="p">.</span><span class="nx">request</span><span class="p">(</span><span class="dl">'</span><span class="s1">GET /api/users/:login/applied_projects/:id/refuse.json</span><span class="dl">'</span><span class="p">)</span> | |||
| </code></pre></div><h3 id='http-25'>HTTP 请求</h3> | |||
| </code></pre></div><h3 id='http-26'>HTTP 请求</h3> | |||
| <p><code>GET /api/users/:login/applied_projects/:id/refuse.json</code></p> | |||
| <h3 id='aa883f5d52-20'>请求字段说明:</h3> | |||
| <h3 id='aa883f5d52-21'>请求字段说明:</h3> | |||
| <table><thead> | |||
| <tr> | |||
| <th>参数</th> | |||