forked from Gitlink/forgeplus
Merge pull request '区块链版本' (#319) from Nigel/forgeplus:master into dev_nanda
This commit is contained in:
commit
a8ae755af3
|
@ -532,4 +532,4 @@ DEPENDENCIES
|
||||||
wkhtmltopdf-binary
|
wkhtmltopdf-binary
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.2.3
|
||||||
|
|
|
@ -894,6 +894,651 @@ class ApplicationController < ActionController::Base
|
||||||
HotSearchKeyword.add(keyword)
|
HotSearchKeyword.add(keyword)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# blockchain存证api
|
||||||
|
#def invoke_blockchain_api(uri, params)
|
||||||
|
# begin
|
||||||
|
# uri = URI.parse(URI.encode(uri.strip))
|
||||||
|
# res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||||
|
# req = Net::HTTP::Post.new(uri)
|
||||||
|
# req['Content-Type'] = 'application/json'
|
||||||
|
# req.body = params
|
||||||
|
# http.request(req)
|
||||||
|
# end
|
||||||
|
# if res.code.to_i != 200
|
||||||
|
# puts '区块链接口请求失败.'
|
||||||
|
# return false
|
||||||
|
# else
|
||||||
|
# res_body = JSON.parse(res.body)
|
||||||
|
# if res_body.has_key?("data") && JSON.parse(res_body["data"]).has_key?("status") && JSON.parse(res_body["data"])['status'] == "Success"
|
||||||
|
# else
|
||||||
|
# puts '区块链接口请求出错.'
|
||||||
|
# return false
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# return true
|
||||||
|
# rescue Exception => e
|
||||||
|
# puts '区块链接口请求失败.'
|
||||||
|
# return false
|
||||||
|
# end
|
||||||
|
#end
|
||||||
|
|
||||||
|
def invoke_blockchain_api(uri, params)
|
||||||
|
begin
|
||||||
|
uri = URI.parse(URI.encode(uri.strip))
|
||||||
|
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||||
|
req = Net::HTTP::Post.new(uri)
|
||||||
|
req['Content-Type'] = 'application/json'
|
||||||
|
req.body = params
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
if res.code.to_i != 200
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
res_body = JSON.parse(res.body)
|
||||||
|
if res_body.has_key?("status") && res_body["status"] == 0
|
||||||
|
else
|
||||||
|
puts '区块链接口请求出错.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
rescue Exception => e
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# blockchain相关项目活动调用函数
|
||||||
|
# return true: 表示上链操作成功; return false: 表示上链操作失败
|
||||||
|
# 北大数瑞的被注释掉
|
||||||
|
#def push_activity_2_blockchain(activity_type, model)
|
||||||
|
# if activity_type == "issue_create"
|
||||||
|
#
|
||||||
|
# project_id = model['project_id']
|
||||||
|
# project = Project.find(project_id)
|
||||||
|
# if project['use_blockchain'] == 0
|
||||||
|
# # 无需执行上链操作
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# id = model['id']
|
||||||
|
#
|
||||||
|
# owner_id = project['user_id']
|
||||||
|
# owner = User.find(owner_id)
|
||||||
|
# ownername = owner['login']
|
||||||
|
# reponame = project['name']
|
||||||
|
#
|
||||||
|
# author_id = project['user_id']
|
||||||
|
# author = User.find(author_id)
|
||||||
|
# username = author['login']
|
||||||
|
#
|
||||||
|
# action = 'opened'
|
||||||
|
#
|
||||||
|
# title = model['subject']
|
||||||
|
# content = model['description']
|
||||||
|
# created_at = model['created_on']
|
||||||
|
# updated_at = model['updated_on']
|
||||||
|
#
|
||||||
|
# # 调用区块链接口
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB1",
|
||||||
|
# "operation": "putIssue",
|
||||||
|
# "arg": {
|
||||||
|
# "issue_id": id,
|
||||||
|
# "repo_id": project_id,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "title": title,
|
||||||
|
# "content": content,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# "updated_at": updated_at
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
# return success_blockchain
|
||||||
|
#
|
||||||
|
# elsif activity_type == "issue_comment_create"
|
||||||
|
# issue_comment_id = model['id']
|
||||||
|
# issue_id = model['journalized_id']
|
||||||
|
# parent_id = model['parent_id'].nil? ? "" : model['parent_id']
|
||||||
|
#
|
||||||
|
# issue = Issue.find(issue_id)
|
||||||
|
# issue_classify = issue['issue_classify'] # issue或pull_request
|
||||||
|
# project_id = issue['project_id']
|
||||||
|
# project = Project.find(project_id)
|
||||||
|
#
|
||||||
|
# if project['use_blockchain'] == 0
|
||||||
|
# # 无需执行上链操作
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# reponame = project['name']
|
||||||
|
# owner_id = project['user_id']
|
||||||
|
# owner = User.find(owner_id)
|
||||||
|
# ownername = owner['login']
|
||||||
|
#
|
||||||
|
# author_id = model['user_id']
|
||||||
|
# author = User.find(author_id)
|
||||||
|
# username = author['login']
|
||||||
|
#
|
||||||
|
# action = 'created'
|
||||||
|
#
|
||||||
|
# content = model['notes']
|
||||||
|
# created_at = model['created_on']
|
||||||
|
#
|
||||||
|
# if issue_classify == "issue"
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB1",
|
||||||
|
# "operation": "putIssueComment",
|
||||||
|
# "arg": {
|
||||||
|
# "issue_comment_id": issue_comment_id,
|
||||||
|
# "issue_id": issue_id,
|
||||||
|
# "parent_id": parent_id,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "content": content,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# elsif issue_classify == "pull_request"
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB0",
|
||||||
|
# "operation": "putPullRequestComment",
|
||||||
|
# "arg": {
|
||||||
|
# "pull_request_comment_id": issue_comment_id,
|
||||||
|
# "pull_request_id": issue_id,
|
||||||
|
# "parent_id": parent_id,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "content": content,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # 调用区块链接口
|
||||||
|
# success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
# return success_blockchain
|
||||||
|
# elsif activity_type == "pull_request_create"
|
||||||
|
# # 调用区块链接口
|
||||||
|
# project_id = model['project_id']
|
||||||
|
# project = Project.find(project_id)
|
||||||
|
# if project['use_blockchain'] == 0
|
||||||
|
# # 无需执行上链操作
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# pull_request_id = model['id']
|
||||||
|
# reponame = project['name']
|
||||||
|
# owner_id = project['user_id']
|
||||||
|
# owner = User.find(owner_id)
|
||||||
|
# ownername = owner['login']
|
||||||
|
#
|
||||||
|
# action = 'opened'
|
||||||
|
#
|
||||||
|
# title = model['title']
|
||||||
|
# content = model['body']
|
||||||
|
#
|
||||||
|
# source_branch = model['head']
|
||||||
|
# source_repo_id = model['fork_project_id'].nil? ? project_id : model['fork_project_id']
|
||||||
|
#
|
||||||
|
# target_branch = model['base']
|
||||||
|
# target_repo_id = project_id
|
||||||
|
#
|
||||||
|
# author_id = model['user_id']
|
||||||
|
# author = User.find(author_id)
|
||||||
|
# username = author['login']
|
||||||
|
#
|
||||||
|
# created_at = model['created_at']
|
||||||
|
# updated_at = model['updated_at']
|
||||||
|
#
|
||||||
|
# # 查询pull request对应的commit信息
|
||||||
|
# commits = Gitea::PullRequest::CommitsService.call(ownername, reponame, model['gpid'])
|
||||||
|
# commit_shas = []
|
||||||
|
# commits.each do |c|
|
||||||
|
# commit_shas << c["Sha"]
|
||||||
|
# end
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB0",
|
||||||
|
# "operation": "putPullRequest",
|
||||||
|
# "arg": {
|
||||||
|
# "pull_request_id": pull_request_id,
|
||||||
|
# "repo_id": project_id,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "title": title,
|
||||||
|
# "content": content,
|
||||||
|
# "source_branch": source_branch,
|
||||||
|
# "target_branch": target_branch,
|
||||||
|
# "commit_shas": commit_shas,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# "updated_at": updated_at
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
# return success_blockchain
|
||||||
|
# elsif activity_type == "pull_request_merge"
|
||||||
|
#
|
||||||
|
# # 调用区块链接口
|
||||||
|
# project_id = model['project_id']
|
||||||
|
# project = Project.find(project_id)
|
||||||
|
# if project['use_blockchain'] == 0
|
||||||
|
# # 无需执行上链操作
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# pull_request_id = model['id']
|
||||||
|
# reponame = project['name']
|
||||||
|
# owner_id = project['user_id']
|
||||||
|
# owner = User.find(owner_id)
|
||||||
|
# ownername = owner['login']
|
||||||
|
#
|
||||||
|
# action = 'merged'
|
||||||
|
#
|
||||||
|
# # 查询pull request对应的commit信息
|
||||||
|
# commits = Gitea::PullRequest::CommitsService.call(ownername, reponame, model['gpid'])
|
||||||
|
# commit_shas = []
|
||||||
|
# commits.each do |c|
|
||||||
|
# commit_shas << c["Sha"]
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# # 将pull request相关信息写入链上
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB0",
|
||||||
|
# "operation": "putPullRequest",
|
||||||
|
# "arg": {
|
||||||
|
# "pull_request_id": pull_request_id,
|
||||||
|
# "repo_id": project_id,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "title": title,
|
||||||
|
# "content": content,
|
||||||
|
# "source_branch": source_branch,
|
||||||
|
# "target_branch": target_branch,
|
||||||
|
# "commit_shas": commit_shas,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# "updated_at": updated_at
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # 将commit相关信息写入链上
|
||||||
|
# commit_shas.each do |commit_sha|
|
||||||
|
# commit_diff = Gitea::Commit::DiffService.call(ownername, reponame, commit_sha)
|
||||||
|
# commit = Gitea::Commit::InfoService.call(ownername, reponame, commit_sha)
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB1",
|
||||||
|
# "operation": "putCommit",
|
||||||
|
# "arg": {
|
||||||
|
# "commit_hash": commit_sha,
|
||||||
|
# "repo_id": project_id,
|
||||||
|
# "author": commit['author']['login'],
|
||||||
|
# "author_email": commit['author']['email'],
|
||||||
|
# "committer": commit['committer']['login'],
|
||||||
|
# "committer_email": commit['committer']['email'],
|
||||||
|
# "author_time": commit['commit']['author']['date'],
|
||||||
|
# "committer_time": commit['commit']['committer']['date'],
|
||||||
|
# "message": commit['commit']['message'],
|
||||||
|
# "diff": commit_diff['Files']
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# success_blockchain_commit = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
# success_blockchain = success_blockchain & success_blockchain_commit
|
||||||
|
# end
|
||||||
|
# return success_blockchain
|
||||||
|
#
|
||||||
|
# elsif activity_type == "pull_request_refuse"
|
||||||
|
#
|
||||||
|
# # 调用区块链接口
|
||||||
|
# project_id = model['project_id']
|
||||||
|
# project = Project.find(project_id)
|
||||||
|
# if project['use_blockchain'] == 0
|
||||||
|
# # 无需执行上链操作
|
||||||
|
# return true
|
||||||
|
# end
|
||||||
|
#
|
||||||
|
# pull_request_id = model['id']
|
||||||
|
# reponame = project['name']
|
||||||
|
# owner_id = project['user_id']
|
||||||
|
# owner = User.find(owner_id)
|
||||||
|
# ownername = owner['login']
|
||||||
|
#
|
||||||
|
# action = 'refused'
|
||||||
|
#
|
||||||
|
# # 将pull request相关信息写入链上
|
||||||
|
# param = {
|
||||||
|
# "action": "executeContract",
|
||||||
|
# "contractID": "RepositoryDB0",
|
||||||
|
# "operation": "putPullRequest",
|
||||||
|
# "arg": {
|
||||||
|
# "pull_request_id": pull_request_id,
|
||||||
|
# "repo_id": project_id,
|
||||||
|
# "ownername": ownername,
|
||||||
|
# "reponame": reponame,
|
||||||
|
# "username": username,
|
||||||
|
# "action": action,
|
||||||
|
# "title": title,
|
||||||
|
# "content": content,
|
||||||
|
# "source_branch": source_branch,
|
||||||
|
# "target_branch": target_branch,
|
||||||
|
# "created_at": created_at,
|
||||||
|
# "updated_at": updated_at
|
||||||
|
# }.to_json
|
||||||
|
# }.to_json
|
||||||
|
# success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
# return success_blockchain
|
||||||
|
# end
|
||||||
|
#end
|
||||||
|
|
||||||
|
|
||||||
|
def push_activity_2_blockchain(activity_type, model)
|
||||||
|
if activity_type == "issue_create"
|
||||||
|
|
||||||
|
project_id = model['project_id']
|
||||||
|
project = Project.find(project_id)
|
||||||
|
if project['use_blockchain'] == 0
|
||||||
|
# 无需执行上链操作
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
id = model['id']
|
||||||
|
|
||||||
|
owner_id = project['user_id']
|
||||||
|
owner = User.find(owner_id)
|
||||||
|
ownername = owner['login']
|
||||||
|
reponame = project['name']
|
||||||
|
|
||||||
|
author_id = project['user_id']
|
||||||
|
author = User.find(author_id)
|
||||||
|
username = author['login']
|
||||||
|
|
||||||
|
action = 'opened'
|
||||||
|
|
||||||
|
title = model['subject']
|
||||||
|
content = model['description']
|
||||||
|
created_at = model['created_on']
|
||||||
|
updated_at = model['updated_on']
|
||||||
|
|
||||||
|
# 调用区块链接口
|
||||||
|
param = {
|
||||||
|
"request-type": "upload issue info",
|
||||||
|
"issue_id": "trustie-" + id.to_s,
|
||||||
|
"repo_id": "trustie-" + project_id.to_s,
|
||||||
|
"issue_number": 0, # 暂时不需要改字段
|
||||||
|
"reponame": reponame,
|
||||||
|
"ownername": ownername,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"created_at": created_at,
|
||||||
|
"updated_at": updated_at
|
||||||
|
}.to_json
|
||||||
|
success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return success_blockchain
|
||||||
|
|
||||||
|
elsif activity_type == "issue_comment_create"
|
||||||
|
issue_comment_id = model['id']
|
||||||
|
issue_id = model['journalized_id']
|
||||||
|
parent_id = model['parent_id'].nil? ? "" : model['parent_id']
|
||||||
|
|
||||||
|
issue = Issue.find(issue_id)
|
||||||
|
issue_classify = issue['issue_classify'] # issue或pull_request
|
||||||
|
project_id = issue['project_id']
|
||||||
|
project = Project.find(project_id)
|
||||||
|
|
||||||
|
if project['use_blockchain'] == 0
|
||||||
|
# 无需执行上链操作
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
reponame = project['name']
|
||||||
|
owner_id = project['user_id']
|
||||||
|
owner = User.find(owner_id)
|
||||||
|
ownername = owner['login']
|
||||||
|
|
||||||
|
author_id = model['user_id']
|
||||||
|
author = User.find(author_id)
|
||||||
|
username = author['login']
|
||||||
|
|
||||||
|
action = 'created'
|
||||||
|
|
||||||
|
content = model['notes']
|
||||||
|
created_at = model['created_on']
|
||||||
|
|
||||||
|
if issue_classify == "issue"
|
||||||
|
param = {
|
||||||
|
"request-type": "upload issue comment info",
|
||||||
|
"issue_comment_id": "trustie-" + issue_comment_id.to_s,
|
||||||
|
"issue_comment_number": 0, # 暂时不需要
|
||||||
|
"issue_number": 0, # 暂时不需要
|
||||||
|
"issue_id": "trustie-" + issue_id.to_s,
|
||||||
|
"repo_id": "trustie-" + project.id.to_s,
|
||||||
|
"parent_id": parent_id.to_s,
|
||||||
|
"reponame": reponame,
|
||||||
|
"ownername": ownername,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"content": content,
|
||||||
|
"created_at": created_at,
|
||||||
|
}.to_json
|
||||||
|
elsif issue_classify == "pull_request"
|
||||||
|
param = {
|
||||||
|
"request-type": "upload pull request comment info",
|
||||||
|
"pull_request_comment_id": "trustie-" + issue_comment_id.to_s,
|
||||||
|
"pull_request_comment_number": 0, # 不考虑该字段
|
||||||
|
"pull_request_number": 0, # 不考虑该字段
|
||||||
|
"pull_request_id": "trustie-" + issue_id.to_s,
|
||||||
|
"parent_id": parent_id.to_s,
|
||||||
|
"repo_id": "trustie-" + project.id.to_s,
|
||||||
|
"reponame": reponame,
|
||||||
|
"ownername": ownername,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"content": content,
|
||||||
|
"created_at": created_at,
|
||||||
|
}.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
# 调用区块链接口
|
||||||
|
success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return success_blockchain
|
||||||
|
elsif activity_type == "pull_request_create"
|
||||||
|
# 调用区块链接口
|
||||||
|
project_id = model['project_id']
|
||||||
|
project = Project.find(project_id)
|
||||||
|
if project['use_blockchain'] == 0
|
||||||
|
# 无需执行上链操作
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
pull_request_id = model['id']
|
||||||
|
reponame = project['name']
|
||||||
|
owner_id = project['user_id']
|
||||||
|
owner = User.find(owner_id)
|
||||||
|
ownername = owner['login']
|
||||||
|
|
||||||
|
action = 'opened'
|
||||||
|
|
||||||
|
title = model['title']
|
||||||
|
content = model['body']
|
||||||
|
|
||||||
|
source_branch = model['head']
|
||||||
|
source_repo_id = model['fork_project_id'].nil? ? project_id : model['fork_project_id']
|
||||||
|
|
||||||
|
target_branch = model['base']
|
||||||
|
target_repo_id = project_id
|
||||||
|
|
||||||
|
author_id = model['user_id']
|
||||||
|
author = User.find(author_id)
|
||||||
|
username = author['login']
|
||||||
|
|
||||||
|
created_at = model['created_at']
|
||||||
|
updated_at = model['updated_at']
|
||||||
|
|
||||||
|
# 查询pull request对应的commit信息
|
||||||
|
commits = Gitea::PullRequest::CommitsService.call(ownername, reponame, model['gpid'])
|
||||||
|
commit_shas = []
|
||||||
|
commits.each do |c|
|
||||||
|
commit_shas << c["Sha"]
|
||||||
|
end
|
||||||
|
param = {
|
||||||
|
"request-type": "upload pull request info",
|
||||||
|
"pull_request_id": "trustie-" + pull_request_id.to_s,
|
||||||
|
"pull_request_number": 0, # trustie没有该字段
|
||||||
|
"repo_id": "trustie-" + project_id.to_s,
|
||||||
|
"ownername": ownername,
|
||||||
|
"reponame": reponame,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"source_branch": source_branch,
|
||||||
|
"target_branch": target_branch,
|
||||||
|
"reviewers": [], # trustie没有该字段
|
||||||
|
"commit_shas": commit_shas,
|
||||||
|
"merge_user": "", # trustie没有该字段
|
||||||
|
"created_at": created_at,
|
||||||
|
"updated_at": updated_at
|
||||||
|
}.to_json
|
||||||
|
success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return success_blockchain
|
||||||
|
elsif activity_type == "pull_request_merge"
|
||||||
|
|
||||||
|
# 调用区块链接口
|
||||||
|
project_id = model['project_id']
|
||||||
|
project = Project.find(project_id)
|
||||||
|
if project['use_blockchain'] == 0
|
||||||
|
# 无需执行上链操作
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
pull_request_id = model['id']
|
||||||
|
reponame = project['name']
|
||||||
|
owner_id = project['user_id']
|
||||||
|
owner = User.find(owner_id)
|
||||||
|
ownername = owner['login']
|
||||||
|
|
||||||
|
action = 'merged'
|
||||||
|
|
||||||
|
# 查询pull request对应的commit信息
|
||||||
|
commits = Gitea::PullRequest::CommitsService.call(ownername, reponame, model['gpid'])
|
||||||
|
commit_shas = []
|
||||||
|
commits.each do |c|
|
||||||
|
commit_shas << c["Sha"]
|
||||||
|
end
|
||||||
|
|
||||||
|
# 将pull request相关信息写入链上
|
||||||
|
param = {
|
||||||
|
"request-type": "upload pull request info",
|
||||||
|
"pull_request_id": "trustie-" + pull_request_id.to_s,
|
||||||
|
"pull_request_number": 0, # trustie没有该字段
|
||||||
|
"repo_id": "trustie-" + project_id.to_s,
|
||||||
|
"ownername": ownername,
|
||||||
|
"reponame": reponame,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"source_branch": source_branch,
|
||||||
|
"target_branch": target_branch,
|
||||||
|
"reviewers": [], # trustie没有该字段
|
||||||
|
"commit_shas": commit_shas,
|
||||||
|
"merge_user": "", # trustie没有该字段
|
||||||
|
"created_at": created_at,
|
||||||
|
"updated_at": updated_at
|
||||||
|
}.to_json
|
||||||
|
success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
|
||||||
|
|
||||||
|
# 将commit相关信息写入链上
|
||||||
|
commit_shas.each do |commit_sha|
|
||||||
|
commit_diff = Gitea::Commit::DiffService.call(ownername, reponame, commit_sha)
|
||||||
|
commit = Gitea::Commit::InfoService.call(ownername, reponame, commit_sha)
|
||||||
|
param = {
|
||||||
|
"request-type": "upload commit info",
|
||||||
|
"commit_hash": commit_sha,
|
||||||
|
"repo_id": "trustie-" + project_id.to_s,
|
||||||
|
"author": commit['author']['login'],
|
||||||
|
"author_email": commit['author']['email'],
|
||||||
|
"committer": commit['committer']['login'],
|
||||||
|
"committer_email": commit['committer']['email'],
|
||||||
|
"author_time": commit['commit']['author']['date'],
|
||||||
|
"committer_time": commit['commit']['committer']['date'],
|
||||||
|
"content": commit['commit']['message'],
|
||||||
|
"commit_diff": commit_diff['Files'].to_s
|
||||||
|
}.to_json
|
||||||
|
success_blockchain_commit = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
success_blockchain = success_blockchain & success_blockchain_commit
|
||||||
|
end
|
||||||
|
return success_blockchain
|
||||||
|
|
||||||
|
elsif activity_type == "pull_request_refuse"
|
||||||
|
|
||||||
|
# 调用区块链接口
|
||||||
|
project_id = model['project_id']
|
||||||
|
project = Project.find(project_id)
|
||||||
|
if project['use_blockchain'] == 0
|
||||||
|
# 无需执行上链操作
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
pull_request_id = model['id']
|
||||||
|
reponame = project['name']
|
||||||
|
owner_id = project['user_id']
|
||||||
|
owner = User.find(owner_id)
|
||||||
|
ownername = owner['login']
|
||||||
|
|
||||||
|
action = 'refused'
|
||||||
|
|
||||||
|
# 将pull request相关信息写入链上
|
||||||
|
param = {
|
||||||
|
"request-type": "upload pull request info",
|
||||||
|
"pull_request_id": "trustie-" + pull_request_id.to_s,
|
||||||
|
"pull_request_number": 0, # trustie没有该字段
|
||||||
|
"repo_id": "trustie-" + project_id.to_s,
|
||||||
|
"ownername": ownername,
|
||||||
|
"reponame": reponame,
|
||||||
|
"username": username,
|
||||||
|
"action": action,
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"source_branch": source_branch,
|
||||||
|
"target_branch": target_branch,
|
||||||
|
"reviewers": [], # trustie没有该字段
|
||||||
|
"commit_shas": commit_shas,
|
||||||
|
"merge_user": "", # trustie没有该字段
|
||||||
|
"created_at": created_at,
|
||||||
|
"updated_at": updated_at
|
||||||
|
}.to_json
|
||||||
|
success_blockchain = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return success_blockchain
|
||||||
|
end
|
||||||
|
end
|
||||||
def find_atme_receivers
|
def find_atme_receivers
|
||||||
@atme_receivers = User.where(login: params[:receivers_login])
|
@atme_receivers = User.where(login: params[:receivers_login])
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
class Blockchain::BaseController < ApplicationController
|
||||||
|
|
||||||
|
before_action :require_login
|
||||||
|
before_action :connect_to_ci_database, if: -> { current_user && !current_user.is_a?(AnonymousUser) && !current_user.devops_uninit? }
|
||||||
|
before_action :connect_to_ci_database, only: :load_repo
|
||||||
|
|
||||||
|
|
||||||
|
def load_repo
|
||||||
|
namespace = params[:owner]
|
||||||
|
id = params[:repo] || params[:id]
|
||||||
|
|
||||||
|
@ci_user, @repo = Ci::Repo.find_with_namespace(namespace, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def authorize_access_project!
|
||||||
|
unless @project.manager?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_manager!
|
||||||
|
unless @project.manager?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def authenticate_admin!
|
||||||
|
return render_forbidden unless current_user.admin?
|
||||||
|
end
|
||||||
|
|
||||||
|
def authorize_owner!
|
||||||
|
unless @project.owner?(current_user)
|
||||||
|
return render_forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_cloud_account
|
||||||
|
@cloud_account ||= current_user.ci_cloud_account
|
||||||
|
@cloud_account.blank? ? nil : @cloud_account
|
||||||
|
end
|
||||||
|
|
||||||
|
def load_ci_user
|
||||||
|
@ci_user ||= Ci::User.find_by(user_login: params[:owner])
|
||||||
|
@ci_user.blank? ? raise("未找到相关的记录") : @ci_user
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
class BlockchainController < ApplicationController
|
||||||
|
|
||||||
|
def get_issue_token_num
|
||||||
|
puts "pause"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -151,12 +151,31 @@ class IssuesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "create")
|
||||||
|
|
||||||
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
|
@issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: ProjectTrend::CLOSE) if params[:status_id].to_i == 5
|
||||||
|
|
||||||
|
|
||||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||||
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
|
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# 扣除发起人的token
|
||||||
|
blockchain_result = Blockchain::CreateIssue.call(user_id: @issue.author_id, project_id: @issue.project_id, token_num: @issue.blockchain_token_num)
|
||||||
|
if blockchain_result = false
|
||||||
|
normal_status(-1, "创建失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
end
|
||||||
|
#render json: {status: 0, message: "创建成功", id: @issue.id}
|
||||||
|
# 调用上链API存证
|
||||||
|
success_blockchain = push_activity_2_blockchain("issue_create", @issue)
|
||||||
|
if success_blockchain == false
|
||||||
|
normal_status(-1, "创建失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
render json: {status: 0, message: "创建成功", id: @issue.id}
|
||||||
|
end
|
||||||
|
|
||||||
render json: {status: 0, message: "创建成功", id: @issue.id}
|
render json: {status: 0, message: "创建成功", id: @issue.id}
|
||||||
else
|
else
|
||||||
normal_status(-1, "创建失败")
|
normal_status(-1, "创建失败")
|
||||||
|
@ -547,7 +566,8 @@ class IssuesController < ApplicationController
|
||||||
branch_name: params[:branch_name].to_s,
|
branch_name: params[:branch_name].to_s,
|
||||||
issue_classify: "issue",
|
issue_classify: "issue",
|
||||||
author_id: current_user.id,
|
author_id: current_user.id,
|
||||||
project_id: @project.id
|
project_id: @project.id,
|
||||||
|
blockchain_token_num: params[:blockchain_token_num]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -48,10 +48,22 @@ class JournalsController < ApplicationController
|
||||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||||
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
|
AtmeService.call(current_user, @atme_receivers, journal) if @atme_receivers.size > 0
|
||||||
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
|
# @issue.project_trends.create(user_id: current_user.id, project_id: @project.id, action_type: "journal")
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# 调用上链API
|
||||||
|
success_blockchain = push_activity_2_blockchain("issue_comment_create", journal)
|
||||||
|
if success_blockchain == false
|
||||||
|
normal_status(-1, "评论失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
render json: {status: 0, message: "评论成功", id: journal.id}
|
||||||
|
end
|
||||||
|
|
||||||
render :json => { status: 0, message: "评论成功", id: journal.id}
|
render :json => { status: 0, message: "评论成功", id: journal.id}
|
||||||
# normal_status(0, "评论成功")
|
# normal_status(0, "评论成功")
|
||||||
else
|
else
|
||||||
normal_status(-1, "评论失败")
|
normal_status(-1, "评论失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -273,7 +273,8 @@ class ProjectsController < ApplicationController
|
||||||
private
|
private
|
||||||
def project_params
|
def project_params
|
||||||
params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url, :default_branch, :identifier,
|
params.permit(:user_id, :name, :description, :repository_name, :website, :lesson_url, :default_branch, :identifier,
|
||||||
:project_category_id, :project_language_id, :license_id, :ignore_id, :private)
|
:project_category_id, :project_language_id, :license_id, :ignore_id, :private,
|
||||||
|
:blockchain, :blockchain_token_all, :blockchain_init_token)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mirror_params
|
def mirror_params
|
||||||
|
|
|
@ -75,6 +75,16 @@ class PullRequestsController < ApplicationController
|
||||||
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
SendTemplateMessageJob.perform_later('ProjectPullRequest', current_user.id, @pull_request&.id) if Site.has_notice_menu?
|
||||||
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
|
||||||
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
|
AtmeService.call(current_user, @atme_receivers, @pull_request) if @atme_receivers.size > 0
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# 调用上链API
|
||||||
|
success_blockchain = push_activity_2_blockchain("pull_request_create", @pull_request)
|
||||||
|
if success_blockchain == false
|
||||||
|
render_error("create pull request error: cannot save to blockchain")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
else
|
else
|
||||||
render_error("create pull request error: #{@gitea_pull_request[:status]}")
|
render_error("create pull request error: #{@gitea_pull_request[:status]}")
|
||||||
raise ActiveRecord::Rollback
|
raise ActiveRecord::Rollback
|
||||||
|
@ -156,7 +166,14 @@ class PullRequestsController < ApplicationController
|
||||||
ActiveRecord::Base.transaction do
|
ActiveRecord::Base.transaction do
|
||||||
begin
|
begin
|
||||||
colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user)
|
colsed = PullRequests::CloseService.call(@owner, @repository, @pull_request, current_user)
|
||||||
if colsed === true
|
# author: zxh
|
||||||
|
# 调用上链API
|
||||||
|
success_blockchain = push_activity_2_blockchain("pull_request_refuse", @pull_request)
|
||||||
|
if success_blockchain == false
|
||||||
|
normal_status(-1, "拒绝失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
if colsed === true
|
||||||
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE)
|
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::CLOSE)
|
||||||
# 合并请求下issue处理为关闭
|
# 合并请求下issue处理为关闭
|
||||||
@issue&.update_attributes!({status_id:5})
|
@issue&.update_attributes!({status_id:5})
|
||||||
|
@ -205,6 +222,53 @@ class PullRequestsController < ApplicationController
|
||||||
# @pull_request.project_trend_status!
|
# @pull_request.project_trend_status!
|
||||||
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE)
|
@pull_request.project_trends.create!(user: current_user, project: @project,action_type: ProjectTrend::MERGE)
|
||||||
@issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
|
@issue&.custom_journal_detail("merge", "", "该合并请求已被合并", current_user&.id)
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# 调用上链API
|
||||||
|
success_blockchain = push_activity_2_blockchain("pull_request_merge", @pull_request)
|
||||||
|
if success_blockchain == false
|
||||||
|
normal_status(-1, "合并失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# 查看是否fix了相关issue,如果fix就转账
|
||||||
|
if params["fix_issue_id"].nil? || params["fix_issue_id"] == ""
|
||||||
|
else
|
||||||
|
issue = Issue.find_by(id: params["fix_issue_id"])
|
||||||
|
if issue.nil?
|
||||||
|
normal_status(-1, "关联issue失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
token_num = issue.blockchain_token_num
|
||||||
|
token_num = token_num.nil? ? 0 : token_num
|
||||||
|
owner = User.find_by(login: params["owner"])
|
||||||
|
pr = PullRequest.find_by(id: params["pull_request"]["id"])
|
||||||
|
if owner.nil? || pr.nil?
|
||||||
|
normal_status(-1, "关联issue失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
project = Project.find_by(user_id: owner.id, name: params["project_id"])
|
||||||
|
if project.nil?
|
||||||
|
normal_status(-1, "关联issue失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
author_id = pr.user_id
|
||||||
|
result = Blockchain::FixIssue.call({user_id: author_id.to_s, project_id: project.id.to_s, token_num: token_num})
|
||||||
|
if result == false
|
||||||
|
normal_status(-1, "关联issue失败")
|
||||||
|
raise ActiveRecord::Rollback
|
||||||
|
else
|
||||||
|
# update issue to state 5
|
||||||
|
issue.update(status_id: 5)
|
||||||
|
normal_status(1, "合并成功")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# 合并请求下issue处理为关闭
|
# 合并请求下issue处理为关闭
|
||||||
@issue&.update_attributes!({status_id:5})
|
@issue&.update_attributes!({status_id:5})
|
||||||
SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu?
|
SendTemplateMessageJob.perform_later('PullRequestMerged', current_user.id, @pull_request.id) if Site.has_notice_menu?
|
||||||
|
|
|
@ -288,6 +288,250 @@ class UsersController < ApplicationController
|
||||||
@projects = paginate(scope)
|
@projects = paginate(scope)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# query all projects with tokens by a user
|
||||||
|
def blockchain_balance
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
results = Blockchain::BalanceQuery.call(params, is_current_admin_user)
|
||||||
|
if results[:status] == 0
|
||||||
|
@total_count = results[:projects].size
|
||||||
|
@projects = results[:projects]
|
||||||
|
else
|
||||||
|
@total_count = -1
|
||||||
|
@projects = []
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: { status: results[:status], projects: @projects, total_count: @total_count }
|
||||||
|
end
|
||||||
|
|
||||||
|
# query one balance
|
||||||
|
def blockchain_balance_one_project
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
owner = User.find_by(login: params['owner_login'])
|
||||||
|
if owner.nil?
|
||||||
|
normal_status(-1, "创建者无法找到")
|
||||||
|
else
|
||||||
|
p = Project.find_by(user_id: owner.id, name: params['project_name'])
|
||||||
|
results = Blockchain::BalanceQueryOneProject.call({"user_id": params['user_id'].to_i, "project_id": p.id.to_i})
|
||||||
|
render json: { status: results[:status], balance: results[:balance]}
|
||||||
|
end
|
||||||
|
else
|
||||||
|
puts "~!@~!@" + params['user_id'].to_s
|
||||||
|
puts current_user.id.to_s
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain_transfer
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['payer_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
results = Blockchain::TransferService.call(params)
|
||||||
|
if results == true
|
||||||
|
render json: { status: 2 } # 重新查询余额
|
||||||
|
else
|
||||||
|
normal_status(-1, "转账失败")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# exchange money
|
||||||
|
def blockchain_exchange
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
#require 'alipay'
|
||||||
|
## setup the client to communicate with either production API or sandbox API
|
||||||
|
## https://openapi.alipay.com/gateway.do (Production)
|
||||||
|
## https://openapi.alipaydev.com/gateway.do (Sandbox)
|
||||||
|
#api_url = 'https://openapi.alipay.com/gateway.do'
|
||||||
|
#
|
||||||
|
## setup your own credentials and certificates
|
||||||
|
#app_id = '2021002140631434'
|
||||||
|
#app_private_key="-----BEGIN RSA PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCPDsgc0n0RWRnbe9OMqtUbde8gu88OyjuZm8cJXeiSING18HX56C5zV4DsHQ6K9/JmQi/NYCc7/2Prh66Bei0L4Xm5TysJTPYi90+WlbJJESFF6fqULi8sSqZXUtaoMKRcUyeR144l2GQgXbZWBbVSQeZW5DqUDlurTF0I7vQ21wGqxQqBjQK8PSVw5hF+aIsNOfAY9M1tzdD5Jzo2Y3FJdsbXIJNMyhJJCZ+7KHFqma7lpjkXdCoyh/nOISkQdGtFI29gI94sqewI2AMU84uxuBIE3h90iLT+8xrd2dQKdBS7qfhQ3PgkBPVNs5jxsVBqSFdSFT6zcqFdHJzulCUJAgMBAAECggEAWocAGz0X5+J6emnhdSKluLrol85BORrAnHP3f/XtNouOKZQBFCPZQSQecUvx5/7/ZbZ8iXpPWahDkshJpaWq29nTLXDryvboyze1JZWVPKeaZqOp7htLvrt+h8PkEoq1d7cnUyMU0N4eflzPBaCXHXaWTGYgq5Bqcfvg48ZSxGBYeHt5WWU2+GW5fpsaVBBYkdyxxGMoy/bzYzGhvfSJkexqnl0XkAAODa02mu3WsHrzRid6Mf+3syYbq/MfUodU6Vng2tbCqwnWrHCyrD4RYl6rg1TKuAv2YAfBhLzwBxHYVC4SRqzjs+8AaOQoF+lCjr4JklPhEuRThzD31YwIAQKBgQDAg4S7ciMmxvbNxR+1eimoAYLLF9jPpPU6w3VFNPb4rDu4tX77bNf082YplfJX5TYtZKjKPKyYG87K6slGunyPL4AFRW81WPB9u1uP26dihyPCBSUE01jKRPPfRrQnnru5fpm8LL3L03V3yA6J+GyQ8wltRJJi1eBSSm+IWRsZewKBgQC+PBD9J1LYOEIVeK9KvN8BpkA1ZIkk//VuJaoGfVXn+1EzM1yFB05fnsEQkHFynisvuCIr7pH63HcdyffQhe1YOnw9iDCG1zPjsi5uTe9WAM0dnb7xdsaLPr/Q2LyoDOTN9344Qovy1AAnpWtGTn6omgHst5nZpp/mHOuBlKiqSwKBgBKRXM77fjpyPEGyfpFxW+0xYB0YirfUUDa/vWLUbfGkIwp4ruuvHtEoXLUsGjiyCdys9b6zxW3SWMqnhIxG1la1HSLlBInfryphVL52UBmnsSI4fs6NV+YCaocheaTMoYyNkmRc6F1tYsoPyJ80D7yXRFR+paPUvxMQzNsYxQ1bAoGAHd2uSSBQWFPUxCwzUQd/93FTaU6EXYO103okTGqG/ymsoN4ya0wvWMHCy8fxl64PV6mP69fDoV/Vb57SwjEUhyJ/eOWVwMWuhtPliDnCFn1/tmOao6wjFZ9fW/l6/OMxVMjDTy/bat8vuwm0YtBWAEBVhwV4KPyI5AasTqa5KCsCgYB/usnqhVx2zt+MxpBt2Q9Vxc0zXcZxMDs69UUdTY86gjcJyCFGe3bbumUcyfSJzIznC2hfFX5ZyS0oMwiAzWtslRMh9LRh3kofD/6BogL3RKOlBk3iekvQ8Gn0tbwk2Qzr4WJgfA7A4GTf5r7Y+bvOfazzsUQAfSK6nUTIlOj2Ew==\n-----END RSA PRIVATE KEY-----\n"
|
||||||
|
#alipay_public_key="-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgHXLD1BshMymbqqtZVKNyo95FNfxzXzaw3P1eI0KeO6RaL+JzrWxzIBFfTjkWv/8WM9u/NcXMOFt2QO9q5KIDx6PkqjRDTd1hgP/cTgdjOHQqnVSihCrQDVCDBSOXIujC8Lk/P4pFVRhQkYeZqEb1qb8b/2tzTY8g9PKKBSCQv7SfgL2TBcpAVbb+9xdJ6VainC/wYGk8T+c+st1hXnuBJSS0m7LFxJOsYkNk0wbA0tfdZLrO3us2F7sjC9t4h/05nr+gSuDkzo+1kCEefYLqScexN+vnQiLoylp/C82wNiP6okxfhmHz3EcYfUqUyGTN/oFaFcPFPpUtFNS8jFV9QIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||||
|
#
|
||||||
|
## initialize a client to communicate with the Alipay API
|
||||||
|
#@alipay_client = Alipay::Client.new(
|
||||||
|
# url: api_url,
|
||||||
|
# app_id: app_id,
|
||||||
|
# app_private_key: app_private_key,
|
||||||
|
# alipay_public_key: alipay_public_key
|
||||||
|
#)
|
||||||
|
#
|
||||||
|
#return_result = @alipay_client.page_execute_url(
|
||||||
|
# method: 'alipay.trade.page.pay',
|
||||||
|
# biz_content: JSON.generate({
|
||||||
|
# out_trade_no: '20210420104600',
|
||||||
|
# product_code: 'FAST_INSTANT_TRADE_PAY',
|
||||||
|
# total_amount: '0.01',
|
||||||
|
# subject: 'test'
|
||||||
|
# }, ascii_only: true), # ascii_only is important!
|
||||||
|
# timestamp: '2021-04-20 10:46:00'
|
||||||
|
#)
|
||||||
|
#render json: { pay_url: return_result }
|
||||||
|
#
|
||||||
|
|
||||||
|
# 替代解决方案
|
||||||
|
# 读取所有交易信息
|
||||||
|
end
|
||||||
|
|
||||||
|
def blockchain_create_trade
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
user_id = params['user_id'].to_i
|
||||||
|
project_id = params['project_id'].to_i
|
||||||
|
money = params['money'].to_f
|
||||||
|
#description = params['description']
|
||||||
|
token_num = params['token_num'].to_i
|
||||||
|
# 锁仓
|
||||||
|
result = Blockchain::CreateTrade.call({user_id: user_id, project_id: project_id, token_num: token_num})
|
||||||
|
if result == false
|
||||||
|
normal_status(-1, "创建交易失败")
|
||||||
|
else
|
||||||
|
bt = BlockchainTrade.new(user_id: user_id, project_id: project_id, token_num: token_num, money: money, state: 0) # state=0表示创建交易; state=1表示执行中; state=2表示执行完成
|
||||||
|
bt.save()
|
||||||
|
status = 2 # 交易创建成功
|
||||||
|
render json: { status: status }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain_get_trades
|
||||||
|
trades = BlockchainTrade.where(state: 0).all()
|
||||||
|
results = []
|
||||||
|
trades.each do |t|
|
||||||
|
project_id = t.project_id
|
||||||
|
project = Project.find_by(id: project_id)
|
||||||
|
if !project.nil?
|
||||||
|
owner = User.find_by(id: project.user_id)
|
||||||
|
else
|
||||||
|
owner = nil
|
||||||
|
end
|
||||||
|
user_id = t.user_id
|
||||||
|
creator = User.find_by(id: user_id)
|
||||||
|
if project.nil? || owner.nil? || creator.nil?
|
||||||
|
else
|
||||||
|
results << [creator, owner, project, t]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render json: { results: results }
|
||||||
|
end
|
||||||
|
|
||||||
|
def blockchain_trade
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
user_id2 = params['user_id2'].to_i
|
||||||
|
trade_id = params['trade_id'].to_i
|
||||||
|
BlockchainTrade.find(trade_id).update(user_id2: user_id2, state: 1) # state=1表示锁定了,等待线下卖家发货
|
||||||
|
render json: {status: 2} # window.location.reload()
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain_verify_trade
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
trade_id = params['trade_id'].to_i
|
||||||
|
BlockchainTrade.find(trade_id).update(state: 2) # state=2表示确认收货
|
||||||
|
render json: {status: 2} # window.location.reload()
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def blockchain_get_verify_trades
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
trades = BlockchainTrade.where(state: 1).all()
|
||||||
|
results = []
|
||||||
|
trades.each do |t|
|
||||||
|
project_id = t.project_id
|
||||||
|
project = Project.find_by(id: project_id)
|
||||||
|
if !project.nil?
|
||||||
|
owner = User.find_by(id: project.user_id)
|
||||||
|
else
|
||||||
|
owner = nil
|
||||||
|
end
|
||||||
|
user_id = t.user_id
|
||||||
|
creator = User.find_by(id: user_id)
|
||||||
|
user_id2 = t.user_id2
|
||||||
|
buyer = User.find_by(id: user_id2)
|
||||||
|
if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||||
|
else
|
||||||
|
results << [creator, owner, project, t, buyer]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render json: { results: results }
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def blockchain_get_history_trades
|
||||||
|
#is_current_admin_user = User.current.logged? && (current_user&.admin? || current_user.id == params['user_id'].to_i)
|
||||||
|
is_current_admin_user = true
|
||||||
|
if is_current_admin_user
|
||||||
|
trades = BlockchainTrade.where(state: 2).all()
|
||||||
|
results = []
|
||||||
|
trades.each do |t|
|
||||||
|
project_id = t.project_id
|
||||||
|
project = Project.find_by(id: project_id)
|
||||||
|
if !project.nil?
|
||||||
|
owner = User.find_by(id: project.user_id)
|
||||||
|
else
|
||||||
|
owner = nil
|
||||||
|
end
|
||||||
|
user_id = t.user_id
|
||||||
|
creator = User.find_by(id: user_id)
|
||||||
|
user_id2 = t.user_id2
|
||||||
|
buyer = User.find_by(id: user_id2)
|
||||||
|
if project.nil? || owner.nil? || creator.nil? || buyer.nil?
|
||||||
|
else
|
||||||
|
results << [creator, owner, project, t, buyer]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render json: { results: results }
|
||||||
|
else
|
||||||
|
normal_status(-1, "缺少权限")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain_get_issue_token_num
|
||||||
|
issue_id = params["issue_id"]['orderId'].to_i
|
||||||
|
issue = Issue.find_by(id: issue_id)
|
||||||
|
render json: {"blockchain_token_num": issue.blockchain_token_num}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def blockchain_get_unclosed_issue_list
|
||||||
|
ownername = params["ownername"]
|
||||||
|
reponame = params["reponame"]
|
||||||
|
owner = User.find_by(login: ownername)
|
||||||
|
project = Project.find_by(user_id: owner.id, name: reponame)
|
||||||
|
unclosed_issues = Issue.where(project_id: project.id, issue_classify: "issue").where.not(status_id: 5)
|
||||||
|
results = []
|
||||||
|
unclosed_issues.each do |i|
|
||||||
|
results << [i.id, i.subject]
|
||||||
|
end
|
||||||
|
render json: {unclosed_issues: results}
|
||||||
|
end
|
||||||
|
|
||||||
# TODO 其他平台登录时同步修改gitea平台对应用户的密码
|
# TODO 其他平台登录时同步修改gitea平台对应用户的密码
|
||||||
# 该方法主要用于:别的平台初次部署对接forge平台,同步用户后,gitea平台对应的用户密码与forge平台用户密码不一致是问题
|
# 该方法主要用于:别的平台初次部署对接forge平台,同步用户后,gitea平台对应的用户密码与forge平台用户密码不一致是问题
|
||||||
def sync_gitea_pwd
|
def sync_gitea_pwd
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
class Projects::CreateForm < BaseForm
|
class Projects::CreateForm < BaseForm
|
||||||
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
attr_accessor :user_id, :name, :description, :repository_name, :project_category_id,
|
||||||
:project_language_id, :ignore_id, :license_id, :private, :owner
|
:project_language_id, :ignore_id, :license_id, :private, :owner
|
||||||
|
:blockchain, :blockchain_token_all, :blockchain_init_token
|
||||||
|
|
||||||
validates :user_id, :name, :repository_name, presence: true
|
validates :user_id, :name, :repository_name, presence: true
|
||||||
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
validates :repository_name, format: { with: CustomRegexp::REPOSITORY_NAME_REGEX, multiline: true, message: "只能含有数字、字母、下划线且不能以下划线开头和结尾" }
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
class Blockchain
|
||||||
|
class << self
|
||||||
|
def blockchain_config
|
||||||
|
blockchain_config = {}
|
||||||
|
|
||||||
|
begin
|
||||||
|
config = Rails.application.config_for(:configuration).symbolize_keys!
|
||||||
|
blockchain_config = config[:blockchain].symbolize_keys!
|
||||||
|
raise 'blockchain config missing' if blockchain_config.blank?
|
||||||
|
rescue => ex
|
||||||
|
raise ex if Rails.env.production?
|
||||||
|
|
||||||
|
puts %Q{\033[33m [warning] blockchain config or configuration.yml missing,
|
||||||
|
please add it or execute 'cp config/configuration.yml.example config/configuration.yml' \033[0m}
|
||||||
|
blockchain_config = {}
|
||||||
|
end
|
||||||
|
blockchain_config
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: blockchain_trades
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# project_id :integer
|
||||||
|
# description :text(65535)
|
||||||
|
# money :float(24)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# user_id :integer
|
||||||
|
# state :integer
|
||||||
|
# user_id2 :integer
|
||||||
|
# token_num :integer
|
||||||
|
#
|
||||||
|
|
||||||
|
class BlockchainTrade < ApplicationRecord
|
||||||
|
end
|
|
@ -31,7 +31,7 @@
|
||||||
# IDX_webhook_updated_unix (updated_unix)
|
# IDX_webhook_updated_unix (updated_unix)
|
||||||
#
|
#
|
||||||
|
|
||||||
class Gitea::Webhook < Gitea::Base
|
class Gitea::Webhook < Gitea::Base
|
||||||
serialize :events, JSON
|
serialize :events, JSON
|
||||||
self.inheritance_column = nil
|
self.inheritance_column = nil
|
||||||
|
|
||||||
|
@ -43,4 +43,4 @@ class Gitea::Webhook < Gitea::Base
|
||||||
enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9}
|
enum hook_task_type: {gogs: 1, slack: 2, gitea: 3, discord: 4, dingtalk: 5, telegram: 6, msteams: 7, feishu: 8, matrix: 9}
|
||||||
enum last_status: {waiting: 0, succeed: 1, fail: 2}
|
enum last_status: {waiting: 0, succeed: 1, fail: 2}
|
||||||
enum content_type: {json: 1, form: 2}
|
enum content_type: {json: 1, form: 2}
|
||||||
end
|
end
|
|
@ -33,6 +33,7 @@
|
||||||
# issue_classify :string(255)
|
# issue_classify :string(255)
|
||||||
# ref_name :string(255)
|
# ref_name :string(255)
|
||||||
# branch_name :string(255)
|
# branch_name :string(255)
|
||||||
|
# blockchain_token_num :integer
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,3 +1,17 @@
|
||||||
|
# == Schema Information
|
||||||
|
#
|
||||||
|
# Table name: message_templates
|
||||||
|
#
|
||||||
|
# id :integer not null, primary key
|
||||||
|
# type :string(255)
|
||||||
|
# sys_notice :text(65535)
|
||||||
|
# email :text(65535)
|
||||||
|
# created_at :datetime not null
|
||||||
|
# updated_at :datetime not null
|
||||||
|
# notification_url :string(255)
|
||||||
|
# email_title :string(255)
|
||||||
|
#
|
||||||
|
|
||||||
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
class MessageTemplate::IssueCreatorExpire < MessageTemplate
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
#
|
#
|
||||||
# Table name: praise_treads
|
# Table name: praise_treads
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# user_id :integer not null
|
# user_id :integer not null
|
||||||
# praise_tread_object_id :integer
|
# praise_tread_object_id :integer
|
||||||
# praise_tread_object_type :string(255)
|
# praise_tread_object_type :string(255)
|
||||||
# praise_or_tread :integer default("1")
|
# praise_or_tread :integer default("1")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# praise_tread (praise_tread_object_id,praise_tread_object_type)
|
# praise_tread (praise_tread_object_id,praise_tread_object_type)
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class PraiseTread < ApplicationRecord
|
class PraiseTread < ApplicationRecord
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
# default_branch :string(255) default("master")
|
# default_branch :string(255) default("master")
|
||||||
# website :string(255)
|
# website :string(255)
|
||||||
# lesson_url :string(255)
|
# lesson_url :string(255)
|
||||||
|
# use_blockchain :boolean default("0")
|
||||||
# is_pinned :boolean default("0")
|
# is_pinned :boolean default("0")
|
||||||
# recommend_index :integer default("0")
|
# recommend_index :integer default("0")
|
||||||
#
|
#
|
||||||
|
@ -63,6 +64,7 @@
|
||||||
# index_projects_on_forked_from_project_id (forked_from_project_id)
|
# index_projects_on_forked_from_project_id (forked_from_project_id)
|
||||||
# index_projects_on_identifier (identifier)
|
# index_projects_on_identifier (identifier)
|
||||||
# index_projects_on_invite_code (invite_code)
|
# index_projects_on_invite_code (invite_code)
|
||||||
|
# index_projects_on_is_pinned (is_pinned)
|
||||||
# index_projects_on_is_public (is_public)
|
# index_projects_on_is_public (is_public)
|
||||||
# index_projects_on_lft (lft)
|
# index_projects_on_lft (lft)
|
||||||
# index_projects_on_license_id (license_id)
|
# index_projects_on_license_id (license_id)
|
||||||
|
@ -131,7 +133,7 @@ class Project < ApplicationRecord
|
||||||
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
|
before_save :set_invite_code, :reset_unmember_followed, :set_recommend_and_is_pinned, :reset_cache_data
|
||||||
before_destroy :decre_project_common, :decre_forked_from_project_count
|
before_destroy :decre_project_common, :decre_forked_from_project_count
|
||||||
after_destroy :decre_user_statistic, :decre_platform_statistic
|
after_destroy :decre_user_statistic, :decre_platform_statistic
|
||||||
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :description, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on)}
|
scope :project_statics_select, -> {select(:id,:name, :is_public, :identifier, :status, :project_type, :user_id, :forked_count, :description, :visits, :project_category_id, :project_language_id, :license_id, :ignore_id, :watchers_count, :created_on, :use_blockchain)}
|
||||||
scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)}
|
scope :no_anomory_projects, -> {where("projects.user_id is not null and projects.user_id != ?", 2)}
|
||||||
scope :recommend, -> { visible.project_statics_select.where(recommend: true) }
|
scope :recommend, -> { visible.project_statics_select.where(recommend: true) }
|
||||||
scope :pinned, -> {where(is_pinned: true)}
|
scope :pinned, -> {where(is_pinned: true)}
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
#
|
#
|
||||||
# Table name: system_notification_histories
|
# Table name: system_notification_histories
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# system_message_id :integer
|
# system_notification_id :integer
|
||||||
# user_id :integer
|
# user_id :integer
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
# Indexes
|
# Indexes
|
||||||
#
|
#
|
||||||
# index_system_notification_histories_on_system_message_id (system_message_id)
|
# index_system_notification_histories_on_system_notification_id (system_notification_id)
|
||||||
# index_system_notification_histories_on_user_id (user_id)
|
# index_system_notification_histories_on_user_id (user_id)
|
||||||
#
|
#
|
||||||
|
|
||||||
class SystemNotificationHistory < ApplicationRecord
|
class SystemNotificationHistory < ApplicationRecord
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# key :string(255)
|
# key :string(255)
|
||||||
# openning :boolean
|
# openning :boolean default("1")
|
||||||
# notification_disabled :boolean
|
# notification_disabled :boolean default("1")
|
||||||
# email_disabled :boolean
|
# email_disabled :boolean default("0")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# key :string(255)
|
# key :string(255)
|
||||||
# openning :boolean
|
# openning :boolean default("1")
|
||||||
# notification_disabled :boolean
|
# notification_disabled :boolean default("1")
|
||||||
# email_disabled :boolean
|
# email_disabled :boolean default("0")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# key :string(255)
|
# key :string(255)
|
||||||
# openning :boolean
|
# openning :boolean default("1")
|
||||||
# notification_disabled :boolean
|
# notification_disabled :boolean default("1")
|
||||||
# email_disabled :boolean
|
# email_disabled :boolean default("0")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# key :string(255)
|
# key :string(255)
|
||||||
# openning :boolean
|
# openning :boolean default("1")
|
||||||
# notification_disabled :boolean
|
# notification_disabled :boolean default("1")
|
||||||
# email_disabled :boolean
|
# email_disabled :boolean default("0")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,9 +6,9 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# name :string(255)
|
# name :string(255)
|
||||||
# key :string(255)
|
# key :string(255)
|
||||||
# openning :boolean
|
# openning :boolean default("1")
|
||||||
# notification_disabled :boolean
|
# notification_disabled :boolean default("1")
|
||||||
# email_disabled :boolean
|
# email_disabled :boolean default("0")
|
||||||
# created_at :datetime not null
|
# created_at :datetime not null
|
||||||
# updated_at :datetime not null
|
# updated_at :datetime not null
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
@ -14,4 +13,4 @@
|
||||||
# GLCC 新闻稿
|
# GLCC 新闻稿
|
||||||
class Topic::GlccNews < Topic
|
class Topic::GlccNews < Topic
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
# type :string(255)
|
# type :string(255)
|
||||||
# title :string(255)
|
# title :string(255)
|
||||||
# uuid :integer
|
# uuid :integer
|
||||||
# image_url :string(255)
|
|
||||||
# url :string(255)
|
# url :string(255)
|
||||||
# order_index :integer
|
# order_index :integer
|
||||||
#
|
#
|
||||||
|
|
|
@ -189,8 +189,8 @@ class User < Owner
|
||||||
has_many :system_notification_histories
|
has_many :system_notification_histories
|
||||||
has_many :system_notifications, through: :system_notification_histories
|
has_many :system_notifications, through: :system_notification_histories
|
||||||
has_one :trace_user, dependent: :destroy
|
has_one :trace_user, dependent: :destroy
|
||||||
has_many :user_trace_tasks, dependent: :destroy
|
has_many :user_trace_tasks, dependent: :destroy
|
||||||
|
|
||||||
has_many :feedbacks, dependent: :destroy
|
has_many :feedbacks, dependent: :destroy
|
||||||
# Groups and active users
|
# Groups and active users
|
||||||
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
|
scope :active, lambda { where(status: [STATUS_ACTIVE, STATUS_EDIT_INFO]) }
|
||||||
|
|
|
@ -6,4 +6,61 @@ class ApplicationQuery
|
||||||
def strip_param(key)
|
def strip_param(key)
|
||||||
params[key].to_s.strip.presence
|
params[key].to_s.strip.presence
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# add blockchain related functions in application_query
|
||||||
|
|
||||||
|
def invoke_blockchain_api(uri, params)
|
||||||
|
begin
|
||||||
|
uri = URI.parse(URI.encode(uri.strip))
|
||||||
|
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||||
|
req = Net::HTTP::Post.new(uri)
|
||||||
|
req['Content-Type'] = 'application/json'
|
||||||
|
req.body = params
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
if res.code.to_i != 200
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
res_body = JSON.parse(res.body)
|
||||||
|
if res_body.has_key?("status") && res_body["status"] == 0
|
||||||
|
else
|
||||||
|
puts '区块链接口请求出错.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return res_body
|
||||||
|
rescue Exception => e
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# find all the repos that a user has tokens
|
||||||
|
def find_repo_with_token(user_id)
|
||||||
|
param = {
|
||||||
|
"request-type": "query user balance of all repos",
|
||||||
|
"username": user_id.to_s
|
||||||
|
}.to_json
|
||||||
|
resp_body = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
token_list = resp_body['UserBalanceList'].nil? ? [] : resp_body['UserBalanceList']
|
||||||
|
return token_list
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# find one repo that a user has tokens
|
||||||
|
def find_one_balance(user_id, project_id)
|
||||||
|
param = {
|
||||||
|
"request-type": "query user balance of single repo",
|
||||||
|
"username": user_id.to_s,
|
||||||
|
"token_name": project_id.to_s
|
||||||
|
}.to_json
|
||||||
|
resp_body = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return resp_body
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -0,0 +1,31 @@
|
||||||
|
class Blockchain::BalanceQuery < ApplicationQuery
|
||||||
|
|
||||||
|
attr_reader :params, :is_current_admin_user
|
||||||
|
|
||||||
|
def initialize(params,is_current_admin_user)
|
||||||
|
@params = params
|
||||||
|
@is_current_admin_user = is_current_admin_user
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
if is_current_admin_user
|
||||||
|
token_list = find_repo_with_token(params["user_id"])
|
||||||
|
result_list = []
|
||||||
|
token_list.each do |t|
|
||||||
|
project = Project.find_by(id: t['token_name'].to_i)
|
||||||
|
if project.nil?
|
||||||
|
next
|
||||||
|
end
|
||||||
|
owner = User.find_by(id: project.user_id)
|
||||||
|
if owner.nil? || project.nil?
|
||||||
|
else
|
||||||
|
balance = t['balance']
|
||||||
|
result_list << [owner, project, balance]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
results = {"status": 0, "projects": result_list}
|
||||||
|
else
|
||||||
|
results = {"status": 1} # query failed
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Blockchain::BalanceQueryOneProject < ApplicationQuery
|
||||||
|
|
||||||
|
attr_reader :params, :is_current_admin_user
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
balance = find_one_balance(params[:user_id].to_s, params[:project_id].to_s)
|
||||||
|
if balance == false
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
results = {"status": balance['status'], "balance": balance['balance']}
|
||||||
|
results
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -38,6 +38,12 @@ class Projects::ListMyQuery < ApplicationQuery
|
||||||
# projects = projects.visible.joins(:members).where(members: { user_id: user.id })
|
# projects = projects.visible.joins(:members).where(members: { user_id: user.id })
|
||||||
# elsif params[:category].to_s == "private"
|
# elsif params[:category].to_s == "private"
|
||||||
# projects = projects.is_private.joins(:members).where(members: { user_id: user.id })
|
# projects = projects.is_private.joins(:members).where(members: { user_id: user.id })
|
||||||
|
elsif params[:category].to_s == "blockchain_token" # 所有钱包中有token的项目有哪些
|
||||||
|
token_list = find_repo_with_token(user.id)
|
||||||
|
project_names = token_list.map { |x| x['token_name'] }
|
||||||
|
projects = projects.where(name: project_names)
|
||||||
|
tokens = token_list.map { |x| x['balance'] }
|
||||||
|
puts "pause"
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:is_public].present?
|
if params[:is_public].present?
|
||||||
|
|
|
@ -19,6 +19,95 @@ class ApplicationService
|
||||||
ActiveModel::Type::Boolean.new.cast str
|
ActiveModel::Type::Boolean.new.cast str
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# author: zxh
|
||||||
|
# blockchain创建项目相关api
|
||||||
|
|
||||||
|
def invoke_blockchain_api(uri, params)
|
||||||
|
begin
|
||||||
|
uri = URI.parse(URI.encode(uri.strip))
|
||||||
|
res = Net::HTTP.start(uri.host, uri.port) do |http|
|
||||||
|
req = Net::HTTP::Post.new(uri)
|
||||||
|
req['Content-Type'] = 'application/json'
|
||||||
|
req.body = params
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
if res.code.to_i != 200
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
res_body = JSON.parse(res.body)
|
||||||
|
if res_body.has_key?("status") && res_body["status"] == 0
|
||||||
|
else
|
||||||
|
puts '区块链接口请求出错.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
rescue Exception => e
|
||||||
|
puts '区块链接口请求失败.'
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# params: params from index.js page
|
||||||
|
def create_repo_on_blockchain(params, project)
|
||||||
|
username = params['user_id'].to_s
|
||||||
|
token_name = project.id.to_s
|
||||||
|
total_supply = params['blockchain_token_all'].to_i
|
||||||
|
token_balance = [[username, (total_supply * params['blockchain_init_token'].to_i / 100).to_i]]
|
||||||
|
|
||||||
|
param = {
|
||||||
|
"request-type": "create repo",
|
||||||
|
"username": username,
|
||||||
|
"token_name": token_name,
|
||||||
|
"total_supply": total_supply,
|
||||||
|
"token_balance": token_balance
|
||||||
|
}.to_json
|
||||||
|
invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def transfer_balance_on_blockchain(payer, payee, token_name, amount)
|
||||||
|
|
||||||
|
param = {
|
||||||
|
"request-type": "transfer amount",
|
||||||
|
"payer": payer,
|
||||||
|
"payee": payee,
|
||||||
|
"token_name": token_name,
|
||||||
|
"amount": amount
|
||||||
|
}.to_json
|
||||||
|
results = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def lock_balance_on_blockchain(username, tokenname, amount)
|
||||||
|
|
||||||
|
param = {
|
||||||
|
"request-type": "lock user balance",
|
||||||
|
"username": username,
|
||||||
|
"token_name": tokenname,
|
||||||
|
"amount": amount
|
||||||
|
}.to_json
|
||||||
|
results = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def unlock_balance_on_blockchain(username, tokenname, amount)
|
||||||
|
|
||||||
|
param = {
|
||||||
|
"request-type": "unlock user balance",
|
||||||
|
"username": username,
|
||||||
|
"token_name": tokenname,
|
||||||
|
"amount": amount
|
||||||
|
}.to_json
|
||||||
|
results = invoke_blockchain_api(Blockchain.blockchain_config[:api_url], param)
|
||||||
|
return results
|
||||||
|
end
|
||||||
def phone_mail_type value
|
def phone_mail_type value
|
||||||
value =~ /^1\d{10}$/ ? 1 : 0
|
value =~ /^1\d{10}$/ ? 1 : 0
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
class Blockchain::CreateIssue < ApplicationService
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
username = @params[:user_id].to_s
|
||||||
|
token_name = @params[:project_id].to_s
|
||||||
|
amount = @params[:token_num].to_i
|
||||||
|
|
||||||
|
# 调用token锁仓函数
|
||||||
|
results = lock_balance_on_blockchain(username, token_name, amount)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
puts "转账失败: #{e.message}"
|
||||||
|
raise Error, e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_use
|
||||||
|
puts "this function does not have any usage"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
class Blockchain::CreateTrade < ApplicationService
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
username = @params[:user_id].to_s
|
||||||
|
token_name = @params[:project_id].to_s
|
||||||
|
amount = @params[:token_num].to_i
|
||||||
|
|
||||||
|
# 调用token锁仓函数
|
||||||
|
results = lock_balance_on_blockchain(username, token_name, amount)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
puts "转账失败: #{e.message}"
|
||||||
|
raise Error, e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_use
|
||||||
|
puts "this function does not have any usage"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
class Blockchain::FixIssue < ApplicationService
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
username = @params[:user_id].to_s
|
||||||
|
token_name = @params[:project_id].to_s
|
||||||
|
amount = @params[:token_num].to_i
|
||||||
|
|
||||||
|
# 调用token锁仓函数
|
||||||
|
results = unlock_balance_on_blockchain(username, token_name, amount)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
puts "关联issue失败: #{e.message}"
|
||||||
|
raise Error, e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_use
|
||||||
|
puts "this function does not have any usage"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,35 @@
|
||||||
|
class Blockchain::TransferService < ApplicationService
|
||||||
|
|
||||||
|
attr_reader :params
|
||||||
|
|
||||||
|
def initialize(params)
|
||||||
|
@params = params
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
transfer_amount = params['transfer_amount'].to_i
|
||||||
|
transfer_login = params['transfer_login']
|
||||||
|
payer = params['payer_id'].to_s
|
||||||
|
payee = User.find_by(login: transfer_login)
|
||||||
|
if payee.nil?
|
||||||
|
normal_status(-1, "未找到用户")
|
||||||
|
else
|
||||||
|
payee = payee.id.to_s
|
||||||
|
token_name = params['project_id'].to_s
|
||||||
|
# 调用token转移函数
|
||||||
|
results = transfer_balance_on_blockchain(payer, payee, token_name, transfer_amount)
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue => e
|
||||||
|
puts "转账失败: #{e.message}"
|
||||||
|
normal_status(-1, e.message)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_use
|
||||||
|
puts "this function does not have any usage"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
# get the diff info for the commit
|
||||||
|
class Gitea::Commit::DiffService < Gitea::ClientService
|
||||||
|
attr_reader :owner, :repo, :sha, :token
|
||||||
|
|
||||||
|
# GET /repos/{owner}/{repo}/commits/{sha}/diff
|
||||||
|
# owner: 用户
|
||||||
|
# repo: 仓库名称/标识
|
||||||
|
# sha: commit唯一标识
|
||||||
|
# eg:
|
||||||
|
# Gitea::Commit::DiffService.call('jasder', 'repo_identifier', 'sha value')
|
||||||
|
def initialize(owner, repo, sha, token=nil)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
@sha = sha
|
||||||
|
@token = token
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
response = get(url, params)
|
||||||
|
render_result(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def params
|
||||||
|
Hash.new.merge(token: owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
"/repos/#{owner}/#{repo}/commits/#{sha}/diff".freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_result(response)
|
||||||
|
case response.status
|
||||||
|
when 200
|
||||||
|
JSON.parse(response.body)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,40 @@
|
||||||
|
# get the detailed info of the commit
|
||||||
|
class Gitea::Commit::InfoService < Gitea::ClientService
|
||||||
|
attr_reader :owner, :repo, :sha, :token
|
||||||
|
|
||||||
|
# GET /repos/{owner}/{repo}/commits/{sha}/diff
|
||||||
|
# owner: 用户
|
||||||
|
# repo: 仓库名称/标识
|
||||||
|
# sha: commit唯一标识
|
||||||
|
# eg:
|
||||||
|
# Gitea::Commit::InfoService.call('jasder', 'repo_identifier', 'sha value')
|
||||||
|
def initialize(owner, repo, sha, token=nil)
|
||||||
|
@owner = owner
|
||||||
|
@repo = repo
|
||||||
|
@sha = sha
|
||||||
|
@token = token
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
response = get(url, params)
|
||||||
|
render_result(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def params
|
||||||
|
Hash.new.merge(token: owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
"/repos/#{owner}/#{repo}/git/commits/#{sha}".freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_result(response)
|
||||||
|
case response.status
|
||||||
|
when 200
|
||||||
|
JSON.parse(response.body)
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -29,7 +29,7 @@ class Projects::CreateService < ApplicationService
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def upgrade_project_category_private_projects_count
|
def upgrade_project_category_private_projects_count
|
||||||
# 如果为空或者项目为公有项目直接返回
|
# 如果为空或者项目为公有项目直接返回
|
||||||
return unless params[:project_category_id].present?
|
return unless params[:project_category_id].present?
|
||||||
return if repo_is_public
|
return if repo_is_public
|
||||||
|
@ -37,7 +37,7 @@ class Projects::CreateService < ApplicationService
|
||||||
project_category.increment!(:private_projects_count, 1)
|
project_category.increment!(:private_projects_count, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
def authroize_user_id_success
|
def authroize_user_id_success
|
||||||
(user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?)
|
(user.id == params[:user_id].to_i) || (user.organizations.find_by_id(params[:user_id]).present?)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -52,7 +52,8 @@ class Projects::CreateService < ApplicationService
|
||||||
ignore_id: params[:ignore_id],
|
ignore_id: params[:ignore_id],
|
||||||
license_id: params[:license_id],
|
license_id: params[:license_id],
|
||||||
website: params[:website],
|
website: params[:website],
|
||||||
identifier: params[:repository_name]
|
identifier: params[:repository_name],
|
||||||
|
use_blockchain: repo_use_blockchain # 新增,zxh
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -71,4 +72,8 @@ class Projects::CreateService < ApplicationService
|
||||||
def repo_is_public
|
def repo_is_public
|
||||||
params[:private].blank? ? true : !(ActiveModel::Type::Boolean.new.cast(params[:private]).nil? ? false : ActiveModel::Type::Boolean.new.cast(params[:private]))
|
params[:private].blank? ? true : !(ActiveModel::Type::Boolean.new.cast(params[:private]).nil? ? false : ActiveModel::Type::Boolean.new.cast(params[:private]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def repo_use_blockchain
|
||||||
|
params[:blockchain].blank? ? false : params[:blockchain]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -75,7 +75,8 @@ class Repositories::CreateService < ApplicationService
|
||||||
name: params[:identifier],
|
name: params[:identifier],
|
||||||
private: params[:hidden],
|
private: params[:hidden],
|
||||||
# readme: "ReadMe",
|
# readme: "ReadMe",
|
||||||
"auto_init": true,
|
auto_init: true,
|
||||||
|
description: @project.description
|
||||||
# "description": "string",
|
# "description": "string",
|
||||||
# "gitignores": "string",
|
# "gitignores": "string",
|
||||||
# "issue_labels": "string",
|
# "issue_labels": "string",
|
||||||
|
|
|
@ -1,103 +1,153 @@
|
||||||
default: &default
|
defaults: &defaults
|
||||||
# 用户登入的时候设置/登出的时候清空
|
# platform_url: 'http://47.96.87.25:81'
|
||||||
autologin_cookie_name: 'autologin_gitlink'
|
platform_url: 'https://testforgeplus.trustie.net'
|
||||||
platform_url: 'http://localhost:3000'
|
admin_statistics_url: 'https://test-statistics.trustie.net/admin/index'
|
||||||
sign_key: ''
|
aliyun_vod:
|
||||||
|
access_key_id: 'test'
|
||||||
#附件上传路径
|
access_key_secret: 'test'
|
||||||
attachment_folder: '/tmp'
|
base_url: 'http://vod.cn-shanghai.aliyuncs.com'
|
||||||
|
cate_id: '-1'
|
||||||
# webssh相关
|
callback_url: 'http://47.96.87.25:48080/api/callbacks/aliyun_vod.json'
|
||||||
tomcat_webssh: 'https://testwebssh.gitlink.org.cn'
|
signature_key: 'test12345678'
|
||||||
webssh_username: ''
|
wechat:
|
||||||
webssh_password: ''
|
appid: ''
|
||||||
|
secret: ''
|
||||||
# git服务地址
|
weapp:
|
||||||
git_address_ip: ''
|
appid: 'wx2402d86a6b534f77'
|
||||||
|
secret: 'ae30b06b66cefbb11f0b05e94385ca87'
|
||||||
#新版git服务地址
|
|
||||||
git_address_domain: ''
|
|
||||||
|
|
||||||
# git管理员用户名问题, 适用于git客户端的操作
|
|
||||||
git_username: ''
|
|
||||||
git_password: ''
|
|
||||||
|
|
||||||
ucloud:
|
|
||||||
public_key: ''
|
|
||||||
private_key: ''
|
|
||||||
public_bucket: ''
|
|
||||||
public_bucket_host: ''
|
|
||||||
public_cdn_host: ''
|
|
||||||
oauth:
|
oauth:
|
||||||
qq:
|
qq:
|
||||||
appid: 'test'
|
appid: '101508858'
|
||||||
secret: 'test123456'
|
secret: '9fbd7cabe2baab33ddf9619de552db0a'
|
||||||
wechat:
|
wechat:
|
||||||
appid: 'test'
|
appid: 'wx6b119e2d829c13fa'
|
||||||
secret: 'test'
|
secret: '0244ac003ea4d01fc768245839a97037'
|
||||||
scope: 'snsapi_login'
|
scope: 'snsapi_login'
|
||||||
base_url: 'https://api.weixin.qq.com'
|
base_url: 'https://api.weixin.qq.com'
|
||||||
aliyun_vod:
|
educoder:
|
||||||
access_key_id: 'test'
|
|
||||||
access_key_secret: 'test'
|
|
||||||
base_url: 'http://vod.cn-shanghai.aliyuncs.com'
|
|
||||||
cate_id: '-1'
|
|
||||||
callback_url: 'callback_url'
|
|
||||||
signature_key: 'test12345678'
|
|
||||||
educoder:
|
|
||||||
client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa'
|
client_id: 'e9ce4d5ba1698d6f7d01d8ee2959776c7a6d743ebe94da2341e288fd2fbf60aa'
|
||||||
client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012'
|
client_secret: '6ff84dd75eddd859c5bd0e7a791b58bc5ad1ba4fbb30bc9db37cb0baf9f33012'
|
||||||
base_url: 'https://test-data.educoder.net'
|
base_url: 'https://test-data.educoder.net'
|
||||||
redirect_uri: 'https://testforgeplus.trustie.net/api/auth/educoder/callback'
|
redirect_uri: 'https://testforgeplus.trustie.net/api/auth/educoder/callback'
|
||||||
|
mulan:
|
||||||
|
client_id: 'kK36Mg9pNFa2Car8lXuI'
|
||||||
|
client_secret: 'XMvb4DL7EaQ8G7FcUi64R08d2Bn3XfJf'
|
||||||
|
base_url: 'https://www.oschina.net'
|
||||||
|
redirect_uri: 'https://code.mulanos.cn/api/auth/mulanoss/callback'
|
||||||
|
github:
|
||||||
|
appid: 'e5bdd25c0a5e4d1fffdc'
|
||||||
|
secret: '88429c898522c60560250031721328180d6a3ccf'
|
||||||
|
gitee:
|
||||||
|
appid: '1cdbd111073abfaed4a6ab29d888d4583f646a8b4ad1eb5b60fbe03cdb2ac24f'
|
||||||
|
secret: 'd8d79434805c01f095d10d43432e880013cf95d7d6bf3ff4ccfe33a1157b654a'
|
||||||
|
# scope: 'snsapi_login'
|
||||||
|
# base_url: 'https://api.weixin.qq.com'
|
||||||
|
oauth_educoder:
|
||||||
|
access_key_secret: '0ea0c9926b0c80f285c393725ff65614'
|
||||||
|
callback_url_host: 'testforgeplus.trustie.net'
|
||||||
|
chain_base: "http://106.54.84.172:8000"
|
||||||
|
ci_db_server_trustie:
|
||||||
|
adapter: mysql2
|
||||||
|
host: "106.75.110.152"
|
||||||
|
port: "43306"
|
||||||
|
database: trustie_drone
|
||||||
|
pool: 5
|
||||||
|
username: "root"
|
||||||
|
password: "R?X:FLI6u,7;"
|
||||||
|
trustie_drone:
|
||||||
|
ip_num: "113.31.153.2"
|
||||||
|
secret: "Dron_123123'"
|
||||||
|
client_id: '2f445743-6d32-477c-963c-a31240c2927a'
|
||||||
|
admin_application_id: 184
|
||||||
|
admin_token: 'QcOBD2DMexbGXaYj9Toou7X13PEOHMtB'
|
||||||
|
email: 'drone@admin.com'
|
||||||
|
avatar_url: 'http://testgitea2.trustie.net/user/avatar/root/-1'
|
||||||
gitea:
|
gitea:
|
||||||
access_key_id: ''
|
access_key_id: 'root'
|
||||||
access_key_secret: ''
|
access_key_secret: '_Trustie_10010'
|
||||||
domain: 'https://testgit.trustie.net'
|
domain: 'https://testgitea2.trustie.net'
|
||||||
base_url: '/api/v1'
|
base_url: '/api/v1'
|
||||||
accelerator:
|
accelerator:
|
||||||
access_key_id: ''
|
access_key_id: 'testforgeroot'
|
||||||
access_key_secret: ''
|
access_key_secret: 'testforge@root123'
|
||||||
access_admin_uid: 1
|
access_admin_uid: 44619
|
||||||
domain: 'https://testgit.trustie.net'
|
domain: 'https://mirror.trustie.net'
|
||||||
base_url: '/api/v1'
|
base_url: '/api/v1'
|
||||||
|
notice:
|
||||||
notice:
|
platform: 'gitlink'
|
||||||
platform: ''
|
write_domain: 'http://106.75.31.211:58082'
|
||||||
write_domain: ''
|
read_domain: 'http://106.75.31.211:58080'
|
||||||
read_domain: ''
|
base_url: '/gns'
|
||||||
base_url: ''
|
|
||||||
|
|
||||||
trace:
|
|
||||||
domain: ''
|
|
||||||
base_url: ''
|
|
||||||
|
|
||||||
forum:
|
forum:
|
||||||
domain: ''
|
domain: 'https://forum.trustie.net/'
|
||||||
base_url: '/api'
|
base_url: '/api'
|
||||||
|
trace:
|
||||||
|
domain: 'http://153.35.182.228:8010'
|
||||||
|
base_url: '/v1'
|
||||||
|
ci_db_server:
|
||||||
|
adapter: mysql2
|
||||||
|
database: drone
|
||||||
|
port: 43306
|
||||||
|
host: 106.75.110.152
|
||||||
|
username: root
|
||||||
|
password: "R?X:FLI6u,7;"
|
||||||
|
encoding: utf8
|
||||||
|
development:
|
||||||
|
<<: *defaults
|
||||||
|
#同步到trustie的token和url
|
||||||
|
sync_token: "34c82f51e0b699d9d16d70fd6497c9b1e4821d6ea3e872558a6537a091076b8e"
|
||||||
|
sync_url: "http://127.0.0.1:3000"
|
||||||
|
|
||||||
|
test:
|
||||||
|
<<: *defaults
|
||||||
|
|
||||||
production:
|
production:
|
||||||
<<: *default
|
<<: *defaults
|
||||||
# 中间层地址
|
educoder:
|
||||||
|
main_site: http://test-newweb.educoder.net
|
||||||
|
token: hriEn3UwXfJs3PmyXnSH
|
||||||
|
base_url: api/sources
|
||||||
|
#同步到trustie的token和url
|
||||||
|
sync_token: "34c82f51e0b699d9d16d70fd6497c9b1e4821d6ea3e872558a6537a091076b8e"
|
||||||
|
sync_url: "https://ucloudtest.trustie.net"
|
||||||
|
|
||||||
cloud_bridge: ''
|
aliyun_vod:
|
||||||
cloud_tomcat_php: ''
|
access_key_id: 'LTAI4kRL1DxQPdM2'
|
||||||
bridge_secret_key: ''
|
access_key_secret: 'yiz68rxE6imziBTITggWcOeSqjUeUu'
|
||||||
cookie_domain: '.gitlink.org.cn'
|
cate_id: '1000068305'
|
||||||
|
base_url: 'http://vod.cn-shanghai.aliyuncs.com'
|
||||||
attachment_folder: ''
|
callback_url: 'https://pre-newweb.educoder.net/api/callbacks/aliyun_vod.json'
|
||||||
host_name: 'https://testeduplus2.gitlink.org.cn'
|
signature_key: 'sdgdfDGH14DHD5g465123'
|
||||||
old_edu_host: 'http://testbdweb.gitlink.org.cn'
|
wechat:
|
||||||
|
appid: 'wx0955caba88bc37eb'
|
||||||
development:
|
secret: '6cc80eef2e0b6f43fbf6c8b96b812858'
|
||||||
<<: *default
|
gitea:
|
||||||
|
access_key_id: 'root'
|
||||||
cloud_bridge: ''
|
access_key_secret: '_Trustie_10010'
|
||||||
cloud_tomcat_php: ''
|
domain: 'https://testgitea2.trustie.net'
|
||||||
host_name: ''
|
base_url: '/api/v1'
|
||||||
old_edu_host: ''
|
accelerator:
|
||||||
test:
|
access_key_id: 'testforgeroot'
|
||||||
<<: *default
|
access_key_secret: 'testforge@root123'
|
||||||
cloud_tomcat_php: 'http://10.9.63.225'
|
access_admin_uid: 44619
|
||||||
host_name: 'https://testeduplus2.gitlink.org.cn'
|
domain: 'https://mirror.trustie.net'
|
||||||
old_edu_host: 'http://testbdweb.gitlink.org.cn'
|
base_url: '/api/v1'
|
||||||
|
notice:
|
||||||
|
platform: 'gitlink'
|
||||||
|
write_domain: 'http://106.75.31.211:58082'
|
||||||
|
read_domain: 'http://106.75.31.211:58080'
|
||||||
|
base_url: '/gns'
|
||||||
|
forum:
|
||||||
|
domain: 'https://forum.trustie.net/'
|
||||||
|
base_url: '/api'
|
||||||
|
trace:
|
||||||
|
domain: 'http://153.35.182.228:8010'
|
||||||
|
base_url: '/v1'
|
||||||
|
ci_db_server:
|
||||||
|
adapter: mysql2
|
||||||
|
database: drone
|
||||||
|
port: 43306
|
||||||
|
host: 106.75.110.152
|
||||||
|
username: root
|
||||||
|
password: "R?X:FLI6u,7;"
|
||||||
|
encoding: utf8
|
|
@ -1,61 +1,101 @@
|
||||||
# MySQL. Versions 5.1.10 and up are supported.
|
# MySQL. Versions 5.1.10 and up are supported.
|
||||||
#
|
#
|
||||||
# Install the MySQL driver
|
# Install the MySQL driver
|
||||||
# gem install mysql2
|
# gem install mysql2
|
||||||
#
|
#
|
||||||
# Ensure the MySQL gem is defined in your Gemfile
|
# Ensure the MySQL gem is defined in your Gemfile
|
||||||
# gem 'mysql2'
|
# gem 'mysql2'
|
||||||
#
|
#
|
||||||
# And be sure to use new-style password hashing:
|
# And be sure to use new-style password hashing:
|
||||||
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
|
# https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html
|
||||||
#
|
#
|
||||||
default: &default
|
default: &default
|
||||||
adapter: mysql2
|
# adapter: mysql2
|
||||||
host: 127.0.0.1
|
# host: 127.0.0.1
|
||||||
encoding: utf8
|
# encoding: utf8
|
||||||
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
# pool: <%#= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
|
||||||
username: root
|
# username: root
|
||||||
password: 123456
|
# password: 123456
|
||||||
# socket: /var/run/mysqld/mysqld.sock
|
# socket: /var/run/mysqld/mysqld.sock
|
||||||
gitea_server:
|
# gitea_server:
|
||||||
adapter: mysql2
|
# adapter: mysql2
|
||||||
database: gitea_development
|
# database: gitea_development
|
||||||
host: 127.0.0.1
|
# host: 127.0.0.1
|
||||||
username: root
|
# username: root
|
||||||
password: "123456"
|
# password: "123456"
|
||||||
encoding: utf8
|
# encoding: utf8
|
||||||
|
|
||||||
development:
|
adapter: mysql2
|
||||||
<<: *default
|
database: testforgeplus
|
||||||
host: 127.0.0.1
|
# database: test_osredmweb
|
||||||
database: forge_development
|
# host: 10.9.70.25
|
||||||
|
host: 127.0.0.1
|
||||||
# Warning: The database defined as "test" will be erased and
|
username: root
|
||||||
# re-generated from your development database when you run "rake".
|
# password: "Trust_#%01"
|
||||||
# Do not set this db to the same as development or production.
|
password: "123456"
|
||||||
test:
|
encoding: utf8mb4
|
||||||
<<: *default
|
reconnect: true
|
||||||
database: forge_test
|
ci_server_db:
|
||||||
|
adapter: mysql2
|
||||||
# As with config/secrets.yml, you never want to store sensitive information,
|
database: drone
|
||||||
# like your database password, in your source code. If your source code is
|
port: 43306
|
||||||
# ever seen by anyone, they now have access to your database.
|
host: 106.75.110.152
|
||||||
#
|
username: root
|
||||||
# Instead, provide the password as a unix environment variable when you boot
|
password: "R?X:FLI6u,7;"
|
||||||
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
|
encoding: utf8
|
||||||
# for a full rundown on how to provide these environment variables in a
|
gitea_server:
|
||||||
# production deployment.
|
adapter: mysql2
|
||||||
#
|
database: testgitea8
|
||||||
# On Heroku and other platform providers, you may have a full connection URL
|
port: 3306
|
||||||
# available as an environment variable. For example:
|
# host: 10.9.70.25
|
||||||
#
|
host: 127.0.0.1
|
||||||
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
|
username: root
|
||||||
#
|
# password: "Trust_#%01"
|
||||||
# You can use this database configuration with:
|
password: "123456"
|
||||||
#
|
encoding: utf8
|
||||||
# production:
|
trustie_web_server:
|
||||||
# url: <%= ENV['DATABASE_URL'] %>
|
adapter: mysql2
|
||||||
#
|
database: trustietest
|
||||||
production:
|
port: 3306
|
||||||
<<: *default
|
# host: 10.9.70.25
|
||||||
database: forge_production
|
host: 127.0.0.1
|
||||||
|
username: root
|
||||||
|
# password: "Trust_#%01"
|
||||||
|
password: "123456"
|
||||||
|
encoding: utf8
|
||||||
|
|
||||||
|
|
||||||
|
development:
|
||||||
|
<<: *default
|
||||||
|
# host: 127.0.0.1
|
||||||
|
# database: testforgeplus
|
||||||
|
|
||||||
|
# Warning: The database defined as "test" will be erased and
|
||||||
|
# re-generated from your development database when you run "rake".
|
||||||
|
# Do not set this db to the same as development or production.
|
||||||
|
test:
|
||||||
|
<<: *default
|
||||||
|
database: forge_test
|
||||||
|
|
||||||
|
# As with config/secrets.yml, you never want to store sensitive information,
|
||||||
|
# like your database password, in your source code. If your source code is
|
||||||
|
# ever seen by anyone, they now have access to your database.
|
||||||
|
#
|
||||||
|
# Instead, provide the password as a unix environment variable when you boot
|
||||||
|
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
|
||||||
|
# for a full rundown on how to provide these environment variables in a
|
||||||
|
# production deployment.
|
||||||
|
#
|
||||||
|
# On Heroku and other platform providers, you may have a full connection URL
|
||||||
|
# available as an environment variable. For example:
|
||||||
|
#
|
||||||
|
# DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
|
||||||
|
#
|
||||||
|
# You can use this database configuration with:
|
||||||
|
#
|
||||||
|
# production:
|
||||||
|
# url: <%= ENV['DATABASE_URL'] %>
|
||||||
|
#
|
||||||
|
production:
|
||||||
|
<<: *default
|
||||||
|
database: testforgeplus
|
||||||
|
|
|
@ -145,6 +145,20 @@ Rails.application.routes.draw do
|
||||||
put 'commons/unhidden', to: 'commons#unhidden'
|
put 'commons/unhidden', to: 'commons#unhidden'
|
||||||
delete 'commons/delete', to: 'commons#delete'
|
delete 'commons/delete', to: 'commons#delete'
|
||||||
|
|
||||||
|
# blockchain related routes
|
||||||
|
get 'users/blockchain/balance', to: 'users#blockchain_balance'
|
||||||
|
post 'users/blockchain/balance_project', to: 'users#blockchain_balance_one_project'
|
||||||
|
post 'users/blockchain/transfer', to: 'users#blockchain_transfer'
|
||||||
|
post 'users/blockchain/exchange', to: 'users#blockchain_exchange'
|
||||||
|
post 'users/blockchain/create_trade', to: 'users#blockchain_create_trade'
|
||||||
|
get '/users/blockchain/get_trades', to: 'users#blockchain_get_trades'
|
||||||
|
post '/users/blockchain/trade', to: 'users#blockchain_trade'
|
||||||
|
get '/users/blockchain/get_verify_trades', to: 'users#blockchain_get_verify_trades'
|
||||||
|
post '/users/blockchain/verify_trade', to: 'users#blockchain_verify_trade'
|
||||||
|
get '/users/blockchain/get_history_trades', to: 'users#blockchain_get_history_trades'
|
||||||
|
post '/blockchain/issue/get_token_num', to: 'users#blockchain_get_issue_token_num'
|
||||||
|
get '/projects/blockchain/get_unclosed_issue_list', to: 'users#blockchain_get_unclosed_issue_list'
|
||||||
|
|
||||||
resources :owners, only: [:index, :show]
|
resources :owners, only: [:index, :show]
|
||||||
|
|
||||||
scope module: :organizations do
|
scope module: :organizations do
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddUseBlockchainToProjects < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :projects, :use_blockchain, :boolean, default: 0
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,11 @@
|
||||||
|
class CreateBlockchainTrades < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
create_table :blockchain_trades do |t|
|
||||||
|
t.integer :project_id
|
||||||
|
t.text :description
|
||||||
|
t.float :money
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddUserIdToBlockchainTrades < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :blockchain_trades, :user_id, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddStateToBlockchainTrades < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :blockchain_trades, :state, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddUserId2ToBlockchainTrades < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :blockchain_trades, :user_id2, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddTokenNumToBlockchainTrades < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :blockchain_trades, :token_num, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddBlockchainTokenNumToIssue < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :issues, :blockchain_token_num, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe BlockchainTrade, type: :model do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
Loading…
Reference in New Issue