Browse Source

Merge pull request '合入统一搜索功能。' (#1788) from zouap into V20220328

Reviewed-on: https://git.openi.org.cn/OpenI/aiforge/pulls/1788
Reviewed-by: lewis <747342561@qq.com>
tags/v1.22.3.2^2
lewis 3 years ago
parent
commit
14ad273a41
22 changed files with 4055 additions and 90 deletions
  1. +0
    -70
      custom/public/css/git.openi.css
  2. +186
    -0
      models/dbsql/dataset_foreigntable_for_es.sql
  3. +215
    -0
      models/dbsql/issue_foreigntable_for_es.sql
  4. +532
    -0
      models/dbsql/repo_foreigntable_for_es.sql
  5. +308
    -0
      models/dbsql/user_foreigntable_for_es.sql
  6. +1
    -0
      models/models.go
  7. +2
    -1
      models/repo.go
  8. +7
    -3
      models/repo_list.go
  9. +83
    -0
      models/search_record.go
  10. +2
    -1
      modules/setting/setting.go
  11. +12
    -0
      options/locale/locale_en-US.ini
  12. +12
    -0
      options/locale/locale_zh-CN.ini
  13. +1281
    -0
      public/home/search.js
  14. +3
    -3
      public/self/dataset_preview.js
  15. +2
    -0
      routers/init.go
  16. +3
    -0
      routers/routes/routes.go
  17. +1190
    -0
      routers/search.go
  18. +4
    -4
      templates/base/head_navbar.tmpl
  19. +4
    -4
      templates/base/head_navbar_fluid.tmpl
  20. +4
    -4
      templates/base/head_navbar_pro.tmpl
  21. +95
    -0
      templates/explore/search_new.tmpl
  22. +109
    -0
      web_src/less/openi.less

+ 0
- 70
custom/public/css/git.openi.css View File

@@ -44,12 +44,6 @@
-webkit-line-clamp: 2; -webkit-line-clamp: 2;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
} }
.ui.label{
font-weight: normal;
}
.active {
color: #0366D6 !important;
}


.opacity5{ opacity:0.5;} .opacity5{ opacity:0.5;}
.radius15{ border-radius:1.5rem !important; } .radius15{ border-radius:1.5rem !important; }
@@ -287,70 +281,6 @@
position: relative; position: relative;
} }


/**seach**/
/**搜索导航条适配窄屏**/
.seachnav{
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.seachnav::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.ui.green.button, .ui.green.buttons .button{
background-color: #5BB973;
}
.seach .repos--seach{
padding-bottom: 0;
border-bottom: none;
}
.seach .ui.secondary.pointing.menu{
border-bottom: none;
}
.seach .ui.secondary.pointing.menu .item > i{
margin-right: 5px;
}
.seach .ui.secondary.pointing.menu .active.item{
border-bottom-width: 2px;
margin: 0 0 -1px;
}
.seach .ui.menu .active.item>.label {
background: #1684FC;
color: #FFF;
}
.seach .ui.menu .item>.label:not(.active.item>.label) {
background: #e8e8e8;
color: rgba(0,0,0,.6);
}

.highlight{
color: red;
}
.ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content {
width: calc(100% - 3.0em);
margin-left: 0;
}

.seach .ui.list .list>.item .header, .seach .ui.list>.item .header{
margin-bottom: 0.5em;
font-size: 1.4rem !important;
font-weight: normal;
}
.seach .time, .seach .time a{
font-size: 12px;
color: grey;
}

.seach .list .item.members .ui.avatar.image {
width: 3.2em;
height: 3.2em;
}
.ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content {
width: calc(100% - 4.0em);
margin-left: 0;
}

@media only screen and (max-width: 767px) { @media only screen and (max-width: 767px) {
.am-mt-30{ margin-top: 1.5rem !important;} .am-mt-30{ margin-top: 1.5rem !important;}
.ui.secondary.hometop.segment{ .ui.secondary.hometop.segment{


+ 186
- 0
models/dbsql/dataset_foreigntable_for_es.sql View File

@@ -0,0 +1,186 @@
DROP FOREIGN TABLE public.dataset_es;
CREATE FOREIGN TABLE public.dataset_es
(
id bigint NOT NULL,
title character varying(255),
status integer,
category character varying(255),
description text,
download_times bigint,
license character varying(255),
task character varying(255),
release_id bigint,
user_id bigint,
repo_id bigint,
created_unix bigint,
updated_unix bigint,
file_name text,
file_desc text
)SERVER multicorn_es
OPTIONS
(
host '192.168.207.94',
port '9200',
index 'dataset-es-index',
rowid_column 'id',
default_sort '_id'
)
;
DELETE FROM public.dataset_es;
INSERT INTO public.dataset_es(
id,
title,
status,
category,
description,
download_times,
license, task,
release_id,
user_id,
repo_id,
created_unix,
updated_unix,
file_name,
file_desc
)
SELECT
b.id,
b.title,
b.status,
b.category,
b.description,
b.download_times,
b.license,
b.task,
b.release_id,
b.user_id,
b.repo_id,
b.created_unix,
b.updated_unix,
(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false),
(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment a where a.dataset_id=b.id and a.is_private=false)
FROM public.dataset b,public.repository c where b.repo_id=c.id and c.is_private=false;


DROP TRIGGER IF EXISTS es_insert_dataset on public.dataset;

CREATE OR REPLACE FUNCTION public.insert_dataset_data() RETURNS trigger AS
$def$
DECLARE
privateValue boolean=false;
BEGIN
select into privateValue is_private from public.repository where id=NEW.repo_id;
if not privateValue then
INSERT INTO public.dataset_es(
id,
title,
status,
category,
description,
download_times,
license,
task,
release_id,
user_id,
repo_id,
created_unix,
updated_unix)
VALUES (
NEW.id,
NEW.title,
NEW.status,
NEW.category,
NEW.description,
NEW.download_times,
NEW.license,
NEW.task,
NEW.release_id,
NEW.user_id,
NEW.repo_id,
NEW.created_unix,
NEW.updated_unix
);
end if;
RETURN NEW;
END;
$def$
LANGUAGE plpgsql;



CREATE TRIGGER es_insert_dataset
AFTER INSERT ON public.dataset
FOR EACH ROW EXECUTE PROCEDURE insert_dataset_data();

ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_insert_dataset;


DROP TRIGGER IF EXISTS es_udpate_dataset_file_name on public.attachment;

CREATE OR REPLACE FUNCTION public.udpate_dataset_file_name() RETURNS trigger AS
$def$
BEGIN
if (TG_OP = 'UPDATE') then
update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id;
elsif (TG_OP = 'INSERT') then
update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.dataset_id and is_private=false) where id=NEW.dataset_id;
elsif (TG_OP = 'DELETE') then
update public.dataset_es SET file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id;
update public.dataset_es SET file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=OLD.dataset_id and is_private=false) where id=OLD.dataset_id;
end if;
return NEW;
END;
$def$
LANGUAGE plpgsql;


CREATE TRIGGER es_udpate_dataset_file_name
AFTER INSERT OR UPDATE OR DELETE ON public.attachment
FOR EACH ROW EXECUTE PROCEDURE udpate_dataset_file_name();

ALTER TABLE public.attachment ENABLE ALWAYS TRIGGER es_udpate_dataset_file_name;

DROP TRIGGER IF EXISTS es_update_dataset on public.dataset;

CREATE OR REPLACE FUNCTION public.update_dataset() RETURNS trigger AS
$def$
BEGIN
UPDATE public.dataset_es
SET description=NEW.description,
title=NEW.title,
category=NEW.category,
task=NEW.task,
download_times=NEW.download_times,
updated_unix=NEW.updated_unix,
file_name=(select array_to_string(array_agg(name order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false),
file_desc=(select array_to_string(array_agg(description order by created_unix desc),'-#,#-') from public.attachment where dataset_id=NEW.id and is_private=false)
where id=NEW.id;
return new;
END
$def$
LANGUAGE plpgsql;

CREATE TRIGGER es_update_dataset
AFTER UPDATE ON public.dataset
FOR EACH ROW EXECUTE PROCEDURE update_dataset();

ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_update_dataset;

DROP TRIGGER IF EXISTS es_delete_dataset on public.dataset;

CREATE OR REPLACE FUNCTION public.delete_dataset() RETURNS trigger AS
$def$
declare
BEGIN
DELETE FROM public.dataset_es where id=OLD.id;
return new;
END
$def$
LANGUAGE plpgsql;


CREATE TRIGGER es_delete_dataset
AFTER DELETE ON public.dataset
FOR EACH ROW EXECUTE PROCEDURE delete_dataset();

ALTER TABLE public.dataset ENABLE ALWAYS TRIGGER es_delete_dataset;

+ 215
- 0
models/dbsql/issue_foreigntable_for_es.sql View File

@@ -0,0 +1,215 @@
DROP FOREIGN TABLE public.issue_es;
CREATE FOREIGN TABLE public.issue_es
(
id bigint NOT NULL,
repo_id bigint,
index bigint,
poster_id bigint,
original_author character varying(255),
original_author_id bigint,
name character varying(255) ,
content text,
comment text,
milestone_id bigint,
priority integer,
is_closed boolean,
is_pull boolean,
pr_id bigint,
num_comments integer,
ref character varying(255),
deadline_unix bigint,
created_unix bigint,
updated_unix bigint,
closed_unix bigint,
is_locked boolean NOT NULL,
amount bigint,
is_transformed boolean NOT NULL
)SERVER multicorn_es
OPTIONS
(
host '192.168.207.94',
port '9200',
index 'issue-es-index',
rowid_column 'id',
default_sort '_id'
)
;

delete from public.issue_es;
INSERT INTO public.issue_es(
id,
repo_id,
index,
poster_id,
original_author,
original_author_id,
name,
content,
milestone_id,
priority,
is_closed,
is_pull,
num_comments,
ref,
deadline_unix,
created_unix,
updated_unix,
closed_unix,
is_locked,
amount,
is_transformed,comment,pr_id)
SELECT
b.id,
b.repo_id,
b.index,
b.poster_id,
b.original_author,
b.original_author_id,
b.name,
b.content,
b.milestone_id,
b.priority,
b.is_closed,
b.is_pull,
b.num_comments,
b.ref,
b.deadline_unix,
b.created_unix,
b.updated_unix,
b.closed_unix,
b.is_locked,
b.amount,
b.is_transformed,
(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id),
(select id from public.pull_request d where b.id=d.issue_id and b.is_pull=true)
FROM public.issue b,public.repository c where b.repo_id=c.id and c.is_private=false;


CREATE OR REPLACE FUNCTION public.insert_issue_data() RETURNS trigger AS
$def$
DECLARE
privateValue boolean=false;
BEGIN
select into privateValue is_private from public.repository where id=NEW.repo_id;
if not privateValue then
INSERT INTO public.issue_es(
id,
repo_id,
index,
poster_id,
original_author,
original_author_id,
name,
content,
milestone_id,
priority,
is_closed,
is_pull,
num_comments,
ref,
deadline_unix,
created_unix,
updated_unix,
closed_unix,
is_locked,
amount,
is_transformed)
VALUES (
NEW.id,
NEW.repo_id,
NEW.index,
NEW.poster_id,
NEW.original_author,
NEW.original_author_id,
NEW.name,
NEW.content,
NEW.milestone_id,
NEW.priority,
NEW.is_closed,
NEW.is_pull,
NEW.num_comments,
NEW.ref,
NEW.deadline_unix,
NEW.created_unix,
NEW.updated_unix,
NEW.closed_unix,
NEW.is_locked,
NEW.amount,
NEW.is_transformed
);
end if;
RETURN NEW;
END;
$def$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS es_insert_issue on public.issue;

CREATE TRIGGER es_insert_issue
AFTER INSERT ON public.issue
FOR EACH ROW EXECUTE PROCEDURE insert_issue_data();

ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_insert_issue;

CREATE OR REPLACE FUNCTION public.udpate_issue_comment() RETURNS trigger AS
$def$
BEGIN
if (TG_OP = 'DELETE') then
update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=OLD.issue_id) where id=OLD.issue_id;
elsif (TG_OP = 'UPDATE') then
update public.issue_es SET comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.issue_id) where id=NEW.issue_id;
end if;
return null;
END;
$def$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS es_udpate_issue_comment on public.comment;
CREATE TRIGGER es_udpate_issue_comment
AFTER DELETE OR UPDATE ON public.comment
FOR EACH ROW EXECUTE PROCEDURE udpate_issue_comment();

ALTER TABLE public.comment ENABLE ALWAYS TRIGGER es_udpate_issue_comment;


CREATE OR REPLACE FUNCTION public.update_issue() RETURNS trigger AS
$def$
declare
BEGIN
UPDATE public.issue_es
SET content=NEW.content,
name=NEW.name,
is_closed=NEW.is_closed,
num_comments=NEW.num_comments,
comment=(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment where issue_id=NEW.id)
where id=NEW.id;
return new;
END
$def$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS es_update_issue on public.issue;

CREATE TRIGGER es_update_issue
AFTER UPDATE ON public.issue
FOR EACH ROW EXECUTE PROCEDURE update_issue();

ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_update_issue;

CREATE OR REPLACE FUNCTION public.delete_issue() RETURNS trigger AS
$def$
declare
BEGIN
DELETE FROM public.issue_es where id=OLD.id;
return new;
END
$def$
LANGUAGE plpgsql;

DROP TRIGGER IF EXISTS es_delete_issue on public.issue;
CREATE TRIGGER es_delete_issue
AFTER DELETE ON public.issue
FOR EACH ROW EXECUTE PROCEDURE delete_issue();

ALTER TABLE public.issue ENABLE ALWAYS TRIGGER es_delete_issue;

+ 532
- 0
models/dbsql/repo_foreigntable_for_es.sql View File

@@ -0,0 +1,532 @@
-- 要处理项目从私有变为公有,并且从公有变成私有的情况
DROP FOREIGN table if exists public.repository_es;
CREATE FOREIGN TABLE public.repository_es (
id bigint NOT NULL,
owner_id bigint,
owner_name character varying(255),
lower_name character varying(255) NOT NULL,
name character varying(255) NOT NULL,
description text,
website character varying(2048),
original_service_type integer,
original_url character varying(2048),
default_branch character varying(255),
num_watches integer,
num_stars integer,
num_forks integer,
num_issues integer,
num_closed_issues integer,
num_pulls integer,
num_closed_pulls integer,
num_milestones integer DEFAULT 0 NOT NULL,
num_closed_milestones integer DEFAULT 0 NOT NULL,
is_private boolean,
is_empty boolean,
is_archived boolean,
is_mirror boolean,
status integer DEFAULT 0 NOT NULL,
is_fork boolean DEFAULT false NOT NULL,
fork_id bigint,
is_template boolean DEFAULT false NOT NULL,
template_id bigint,
size bigint DEFAULT 0 NOT NULL,
is_fsck_enabled boolean DEFAULT true NOT NULL,
close_issues_via_commit_in_any_branch boolean DEFAULT false NOT NULL,
topics text,
avatar character varying(64),
created_unix bigint,
updated_unix bigint,
contract_address character varying(255),
block_chain_status integer DEFAULT 0 NOT NULL,
balance character varying(255) DEFAULT '0'::character varying NOT NULL,
clone_cnt bigint DEFAULT 0 NOT NULL,
license character varying(100),
download_cnt bigint DEFAULT 0 NOT NULL,
num_commit bigint DEFAULT 0 NOT NULL,
git_clone_cnt bigint DEFAULT 0 NOT NULL,
creator_id bigint NOT NULL DEFAULT 0,
repo_type integer NOT NULL DEFAULT 0,
lang character varying(2048),
alias character varying(255),
lower_alias character varying(255)
) SERVER multicorn_es
OPTIONS
(
host '192.168.207.94',
port '9200',
index 'repository-es-index',
rowid_column 'id',
default_sort '_id'
)
;
delete from public.repository_es;
INSERT INTO public.repository_es (id,
owner_id,
owner_name,
lower_name,
name,
description,
website,
original_service_type,
original_url,
default_branch,
num_watches,
num_stars,
num_forks,
num_issues,
num_closed_issues,
num_pulls,
num_closed_pulls,
num_milestones,
num_closed_milestones,
is_private,
is_empty,
is_archived,
is_mirror,
status,
is_fork,
fork_id,
is_template,
template_id,
size,
is_fsck_enabled,
close_issues_via_commit_in_any_branch,
topics,
avatar,
created_unix,
updated_unix,
contract_address,
block_chain_status,
balance,
clone_cnt,
num_commit,
git_clone_cnt,
creator_id,
repo_type,
lang,
alias,
lower_alias
)
SELECT
id,
owner_id,
owner_name,
lower_name,
name,
description,
website,
original_service_type,
original_url,
default_branch,
num_watches,
num_stars,
num_forks,
num_issues,
num_closed_issues,
num_pulls,
num_closed_pulls,
num_milestones,
num_closed_milestones,
is_private,
is_empty,
is_archived,
is_mirror,
status,
is_fork,
fork_id,
is_template,
template_id,
size,
is_fsck_enabled,
close_issues_via_commit_in_any_branch,
topics,
avatar,
created_unix,
updated_unix,
contract_address,
block_chain_status,
balance,
clone_cnt,
num_commit,
git_clone_cnt,
creator_id,
repo_type,
(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id),
alias,
lower_alias
FROM public.repository b where b.is_private=false;

DROP TRIGGER IF EXISTS es_insert_repository on public.repository;

CREATE OR REPLACE FUNCTION public.insert_repository_data() RETURNS trigger AS
$def$
BEGIN
if not NEW.is_private then
INSERT INTO public.repository_es (id,
owner_id,
owner_name,
lower_name,
name,
description,
website,
original_service_type,
original_url,
default_branch,
num_watches,
num_stars,
num_forks,
num_issues,
num_closed_issues,
num_pulls,
num_closed_pulls,
num_milestones,
num_closed_milestones,
is_private,
is_empty,
is_archived,
is_mirror,
status,
is_fork,
fork_id,
is_template,
template_id,
size,
is_fsck_enabled,
close_issues_via_commit_in_any_branch,
topics,
avatar,
created_unix,
updated_unix,
contract_address,
block_chain_status,
balance,
clone_cnt,
num_commit,
git_clone_cnt,
creator_id,
repo_type,
alias,
lower_alias) VALUES
(NEW.id,
NEW.owner_id,
NEW.owner_name,
NEW.lower_name,
NEW.name,
NEW.description,
NEW.website,
NEW.original_service_type,
NEW.original_url,
NEW.default_branch,
NEW.num_watches,
NEW.num_stars,
NEW.num_forks,
NEW.num_issues,
NEW.num_closed_issues,
NEW.num_pulls,
NEW.num_closed_pulls,
NEW.num_milestones,
NEW.num_closed_milestones,
NEW.is_private,
NEW.is_empty,
NEW.is_archived,
NEW.is_mirror,
NEW.status,
NEW.is_fork,
NEW.fork_id,
NEW.is_template,
NEW.template_id,
NEW.size,
NEW.is_fsck_enabled,
NEW.close_issues_via_commit_in_any_branch,
NEW.topics,
NEW.avatar,
NEW.created_unix,
NEW.updated_unix,
NEW.contract_address,
NEW.block_chain_status,
NEW.balance,
NEW.clone_cnt,
NEW.num_commit,
NEW.git_clone_cnt,
NEW.creator_id,
NEW.repo_type,
NEW.alias,
NEW.lower_alias);
end if;
RETURN NEW;
END;
$def$
LANGUAGE plpgsql;


CREATE TRIGGER es_insert_repository
AFTER INSERT ON public.repository
FOR EACH ROW EXECUTE PROCEDURE insert_repository_data();

ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_insert_repository;

DROP TRIGGER IF EXISTS es_update_repository on public.repository;

CREATE OR REPLACE FUNCTION public.update_repository() RETURNS trigger AS
$def$
BEGIN
if OLD.is_private != NEW.is_private then
if OLD.is_private and not NEW.is_private then
--insert
INSERT INTO public.repository_es (id,
owner_id,
owner_name,
lower_name,
name,
description,
website,
original_service_type,
original_url,
default_branch,
num_watches,
num_stars,
num_forks,
num_issues,
num_closed_issues,
num_pulls,
num_closed_pulls,
num_milestones,
num_closed_milestones,
is_private,
is_empty,
is_archived,
is_mirror,
status,
is_fork,
fork_id,
is_template,
template_id,
size,
is_fsck_enabled,
close_issues_via_commit_in_any_branch,
topics,
avatar,
created_unix,
updated_unix,
contract_address,
block_chain_status,
balance,
clone_cnt,
num_commit,
git_clone_cnt,
creator_id,
repo_type,
lang,
alias,
lower_alias)
SELECT
id,
owner_id,
owner_name,
lower_name,
name,
description,
website,
original_service_type,
original_url,
default_branch,
num_watches,
num_stars,
num_forks,
num_issues,
num_closed_issues,
num_pulls,
num_closed_pulls,
num_milestones,
num_closed_milestones,
is_private,
is_empty,
is_archived,
is_mirror,
status,
is_fork,
fork_id,
is_template,
template_id,
size,
is_fsck_enabled,
close_issues_via_commit_in_any_branch,
topics,
avatar,
created_unix,
updated_unix,
contract_address,
block_chain_status,
balance,
clone_cnt,
num_commit,
git_clone_cnt,
creator_id,
repo_type,
(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat a where a.repo_id=b.id),
alias,
lower_alias
FROM public.repository b where b.id=NEW.id;
INSERT INTO public.dataset_es(
id,
title,
status,
category,
description,
download_times,
license, task,
release_id,
user_id,
repo_id,
created_unix,
updated_unix,file_name)
SELECT
b.id,
b.title,
b.status,
b.category,
b.description,
b.download_times,
b.license,
b.task,
b.release_id,
b.user_id,
b.repo_id,
b.created_unix,
b.updated_unix,(select array_to_string(array_agg(name order by created_unix desc),',') from public.attachment a where a.dataset_id=b.id and a.is_private=false)
FROM public.dataset b where b.repo_id=NEW.id;

INSERT INTO public.issue_es(
id,
repo_id,
index,
poster_id,
original_author,
original_author_id,
name,
content,
milestone_id,
priority,
is_closed,
is_pull,
num_comments,
ref,
deadline_unix,
created_unix,
updated_unix,
closed_unix,
is_locked,
amount,
is_transformed,comment,pr_id)
SELECT
b.id,
b.repo_id,
b.index,
b.poster_id,
b.original_author,
b.original_author_id,
b.name,
b.content,
b.milestone_id,
b.priority,
b.is_closed,
b.is_pull,
b.num_comments,
b.ref,
b.deadline_unix,
b.created_unix,
b.updated_unix,
b.closed_unix,
b.is_locked,
b.amount,
b.is_transformed,
(select array_to_string(array_agg(content order by created_unix desc),',') from public.comment a where a.issue_id=b.id),
(select id from public.pull_request d where d.issue_id=b.id)
FROM public.issue b where b.repo_id=NEW.id;
end if;

if not OLD.is_private and NEW.is_private then
delete from public.issue_es where repo_id=NEW.id;
delete from public.dataset_es where repo_id=NEW.id;
delete from public.repository_es where id=NEW.id;
end if;

end if;

if not NEW.is_private then
raise notice 'update repo,the updated_unix is %',NEW.updated_unix;
update public.repository_es SET description=NEW.description,
name=NEW.name,
lower_name=NEW.lower_name,
owner_name=NEW.owner_name,
website=NEW.website,
updated_unix=NEW.updated_unix,
num_watches=NEW.num_watches,
num_stars=NEW.num_stars,
num_forks=NEW.num_forks,
topics=NEW.topics,
alias = NEW.alias,
lower_alias = NEW.lower_alias,
avatar=NEW.avatar
where id=NEW.id;
end if;
return new;
END
$def$
LANGUAGE plpgsql;

CREATE TRIGGER es_update_repository
AFTER UPDATE ON public.repository
FOR EACH ROW EXECUTE PROCEDURE update_repository();

ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_update_repository;


DROP TRIGGER IF EXISTS es_delete_repository on public.repository;

CREATE OR REPLACE FUNCTION public.delete_repository() RETURNS trigger AS
$def$
declare
BEGIN
delete from public.issue_es where repo_id=OLD.id;
delete from public.dataset_es where repo_id=OLD.id;
DELETE FROM public.repository_es where id=OLD.id;
return new;
END
$def$
LANGUAGE plpgsql;


CREATE TRIGGER es_delete_repository
AFTER DELETE ON public.repository
FOR EACH ROW EXECUTE PROCEDURE delete_repository();

ALTER TABLE public.repository ENABLE ALWAYS TRIGGER es_delete_repository;



DROP TRIGGER IF EXISTS es_udpate_repository_lang on public.language_stat;

CREATE OR REPLACE FUNCTION public.udpate_repository_lang() RETURNS trigger AS
$def$
BEGIN
if (TG_OP = 'UPDATE') then
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id;
elsif (TG_OP = 'INSERT') then
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=NEW.repo_id) where id=NEW.repo_id;
elsif (TG_OP = 'DELETE') then
if exists(select 1 from public.repository where id=OLD.repo_id) then
update public.repository_es SET lang=(select array_to_string(array_agg(language order by percentage desc),',') from public.language_stat where repo_id=OLD.repo_id) where id=OLD.repo_id;
end if;
end if;
return null;
END;
$def$
LANGUAGE plpgsql;

CREATE TRIGGER es_udpate_repository_lang
AFTER INSERT OR UPDATE OR DELETE ON public.language_stat
FOR EACH ROW EXECUTE PROCEDURE udpate_repository_lang();

ALTER TABLE public.language_stat ENABLE ALWAYS TRIGGER es_udpate_repository_lang;

+ 308
- 0
models/dbsql/user_foreigntable_for_es.sql View File

@@ -0,0 +1,308 @@
DROP FOREIGN table if exists public.user_es;
CREATE FOREIGN TABLE public.user_es
(
id bigint NOT NULL ,
lower_name character varying(255) NULL,
name character varying(255) NULL,
full_name character varying(255),
email character varying(255),
keep_email_private boolean,
email_notifications_preference character varying(20) ,
passwd character varying(255) ,
passwd_hash_algo character varying(255) ,
must_change_password boolean NOT NULL DEFAULT false,
login_type integer,
login_source bigint NOT NULL DEFAULT 0,
login_name character varying(255) ,
type integer,
location character varying(255),
website character varying(255),
rands character varying(10),
salt character varying(10),
language character varying(5),
description character varying(255),
created_unix bigint,
updated_unix bigint,
last_login_unix bigint,
last_repo_visibility boolean,
max_repo_creation integer,
is_active boolean,
is_admin boolean,
is_restricted boolean NOT NULL DEFAULT false,
allow_git_hook boolean,
allow_import_local boolean,
allow_create_organization boolean DEFAULT true,
prohibit_login boolean NOT NULL DEFAULT false,
avatar character varying(2048) ,
avatar_email character varying(255),
use_custom_avatar boolean,
num_followers integer,
num_following integer NOT NULL DEFAULT 0,
num_stars integer,
num_repos integer,
num_teams integer,
num_members integer,
visibility integer NOT NULL DEFAULT 0,
repo_admin_change_team_access boolean NOT NULL DEFAULT false,
diff_view_style character varying(255),
theme character varying(255),
token character varying(1024) ,
public_key character varying(255),
private_key character varying(255),
is_operator boolean NOT NULL DEFAULT false,
num_dataset_stars integer NOT NULL DEFAULT 0
) SERVER multicorn_es
OPTIONS
(
host '192.168.207.94',
port '9200',
index 'user-es-index',
rowid_column 'id',
default_sort '_id'
)
;
delete from public.user_es;
INSERT INTO public.user_es(
id,
lower_name,
name,
full_name,
email,
keep_email_private,
email_notifications_preference,
must_change_password,
login_type,
login_source,
login_name,
type,
location,
website,
rands,
language,
description,
created_unix,
updated_unix,
last_login_unix,
last_repo_visibility,
max_repo_creation,
is_active,
is_restricted,
allow_git_hook,
allow_import_local,
allow_create_organization,
prohibit_login,
avatar,
avatar_email,
use_custom_avatar,
num_followers,
num_following,
num_stars,
num_repos,
num_teams,
num_members,
visibility,
repo_admin_change_team_access,
diff_view_style,
theme,
is_operator,
num_dataset_stars)
SELECT
id,
lower_name,
name,
full_name,
email,
keep_email_private,
email_notifications_preference,
must_change_password,
login_type,
login_source,
login_name,
type,
location,
website,
rands,
language,
description,
created_unix,
updated_unix,
last_login_unix,
last_repo_visibility,
max_repo_creation,
is_active,
is_restricted,
allow_git_hook,
allow_import_local,
allow_create_organization,
prohibit_login,
avatar,
avatar_email,
use_custom_avatar,
num_followers,
num_following,
num_stars,
num_repos,
num_teams,
num_members,
visibility,
repo_admin_change_team_access,
diff_view_style,
theme,
is_operator,
num_dataset_stars
FROM public.user;

DROP TRIGGER IF EXISTS es_insert_user on public.user;

CREATE OR REPLACE FUNCTION public.insert_user_data() RETURNS trigger AS
$def$
BEGIN
INSERT INTO public."user_es"(
id,
lower_name,
name,
full_name,
email,
keep_email_private,
email_notifications_preference,
must_change_password,
login_type,
login_source,
login_name,
type,
location,
website,
rands,
language,
description,
created_unix,
updated_unix,
last_login_unix,
last_repo_visibility,
max_repo_creation,
is_active,
is_restricted,
allow_git_hook,
allow_import_local,
allow_create_organization,
prohibit_login,
avatar,
avatar_email,
use_custom_avatar,
num_followers,
num_following,
num_stars,
num_repos,
num_teams,
num_members,
visibility,
repo_admin_change_team_access,
diff_view_style,
theme,
is_operator,
num_dataset_stars)
VALUES (
NEW.id,
NEW.lower_name,
NEW.name,
NEW.full_name,
NEW.email,
NEW.keep_email_private,
NEW.email_notifications_preference,
NEW.must_change_password,
NEW.login_type,
NEW.login_source,
NEW.login_name,
NEW.type,
NEW.location,
NEW.website,
NEW.rands,
NEW.language,
NEW.description,
NEW.created_unix,
NEW.updated_unix,
NEW.last_login_unix,
NEW.last_repo_visibility,
NEW.max_repo_creation,
NEW.is_active,
NEW.is_restricted,
NEW.allow_git_hook,
NEW.allow_import_local,
NEW.allow_create_organization,
NEW.prohibit_login,
NEW.avatar,
NEW.avatar_email,
NEW.use_custom_avatar,
NEW.num_followers,
NEW.num_following,
NEW.num_stars,
NEW.num_repos,
NEW.num_teams,
NEW.num_members,
NEW.visibility,
NEW.repo_admin_change_team_access,
NEW.diff_view_style,
NEW.theme,
NEW.is_operator,
NEW.num_dataset_stars
);

RETURN NEW;
END;
$def$
LANGUAGE plpgsql;



CREATE TRIGGER es_insert_user
AFTER INSERT ON public.user
FOR EACH ROW EXECUTE PROCEDURE insert_user_data();

ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_insert_user;

DROP TRIGGER IF EXISTS es_update_user on public.user;

CREATE OR REPLACE FUNCTION public.update_user() RETURNS trigger AS
$def$
BEGIN
UPDATE public.user_es
SET description=NEW.description,
name=NEW.name,
full_name=NEW.full_name,
location=NEW.location,
website=NEW.website,
email=NEW.email,
num_dataset_stars=NEW.num_dataset_stars,
updated_unix=NEW.updated_unix
where id=NEW.id;
return new;
END
$def$
LANGUAGE plpgsql;



CREATE TRIGGER es_update_user
AFTER UPDATE ON public.user
FOR EACH ROW EXECUTE PROCEDURE update_user();

ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_update_user;

DROP TRIGGER IF EXISTS es_delete_user on public.user;

CREATE OR REPLACE FUNCTION public.delete_user() RETURNS trigger AS
$def$
declare
BEGIN
DELETE FROM public.user_es where id=OLD.id;
return new;
END
$def$
LANGUAGE plpgsql;


CREATE TRIGGER es_delete_user
AFTER DELETE ON public.user
FOR EACH ROW EXECUTE PROCEDURE delete_user();
ALTER TABLE public.user ENABLE ALWAYS TRIGGER es_delete_user;

+ 1
- 0
models/models.go View File

@@ -138,6 +138,7 @@ func init() {
new(OfficialTag), new(OfficialTag),
new(OfficialTagRepos), new(OfficialTagRepos),
new(WechatBindLog), new(WechatBindLog),
new(SearchRecord),
) )


tablesStatistic = append(tablesStatistic, tablesStatistic = append(tablesStatistic,


+ 2
- 1
models/repo.go View File

@@ -6,13 +6,14 @@
package models package models


import ( import (
"code.gitea.io/gitea/modules/git"
"context" "context"
"crypto/md5" "crypto/md5"
"errors" "errors"
"fmt" "fmt"
"html/template" "html/template"
"math/rand" "math/rand"

"code.gitea.io/gitea/modules/git"
"xorm.io/xorm" "xorm.io/xorm"


"code.gitea.io/gitea/modules/blockchain" "code.gitea.io/gitea/modules/blockchain"


+ 7
- 3
models/repo_list.go View File

@@ -190,7 +190,8 @@ type SearchRepoOptions struct {
// None -> include all repos // None -> include all repos
// True -> include just courses // True -> include just courses
// False -> include just no courses // False -> include just no courses
Course util.OptionalBool
Course util.OptionalBool
OnlySearchPrivate bool
} }


//SearchOrderBy is used to sort the result //SearchOrderBy is used to sort the result
@@ -219,12 +220,15 @@ const (
SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC" SearchOrderByDownloadTimes SearchOrderBy = "download_times DESC"
SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC" SearchOrderByHot SearchOrderBy = "(num_watches + num_stars + num_forks + clone_cnt) DESC"
SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC" SearchOrderByActive SearchOrderBy = "(num_issues + num_pulls + num_commit) DESC"
SearchOrderByWatches SearchOrderBy = "num_watches DESC"
) )


// SearchRepositoryCondition creates a query condition according search repository options // SearchRepositoryCondition creates a query condition according search repository options
func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond { func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
var cond = builder.NewCond() var cond = builder.NewCond()

if opts.OnlySearchPrivate {
cond = cond.And(builder.Eq{"is_private": true})
}
if opts.Private { if opts.Private {
if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID { if opts.Actor != nil && !opts.Actor.IsAdmin && opts.Actor.ID != opts.OwnerID {
// OK we're in the context of a User // OK we're in the context of a User
@@ -337,7 +341,7 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
if !opts.TopicOnly { if !opts.TopicOnly {
var likes = builder.NewCond() var likes = builder.NewCond()
for _, v := range strings.Split(opts.Keyword, ",") { for _, v := range strings.Split(opts.Keyword, ",") {
likes = likes.Or(builder.Like{"lower_name", strings.ToLower(v)})
likes = likes.Or(builder.Like{"lower_alias", strings.ToLower(v)})
likes = likes.Or(builder.Like{"alias", v}) likes = likes.Or(builder.Like{"alias", v})
if opts.IncludeDescription { if opts.IncludeDescription {
likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)}) likes = likes.Or(builder.Like{"LOWER(description)", strings.ToLower(v)})


+ 83
- 0
models/search_record.go View File

@@ -0,0 +1,83 @@
package models

import (
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"xorm.io/xorm"
)

type SearchRecord struct {
ID int64 `xorm:"pk autoincr"`
//user
Keyword string `xorm:"NOT NULL"`
//
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
}

func SaveSearchKeywordToDb(keyword string) error {
record := &SearchRecord{
Keyword: keyword,
}
sess := x.NewSession()
defer sess.Close()
_, err := sess.Insert(record)
if err != nil {
log.Info("insert error." + err.Error())
return err
}
return nil
}

func setIssueQueryCondition(sess *xorm.Session, Keyword string, isPull bool, userId int64) {
sess.And("issue.poster_id=?", userId)
sess.And("issue.is_pull=?", isPull)
sess.And("(issue.name like '%" + Keyword + "%' or issue.content like '%" + Keyword + "%')")
sess.Join("INNER", "repository", "issue.repo_id = repository.id").And("repository.is_private = ?", true)
}

func SearchPrivateIssueOrPr(Page int, PageSize int, Keyword string, isPull bool, userId int64) ([]*Issue, int64, error) {
sess := x.NewSession()
defer sess.Close()
setIssueQueryCondition(sess, Keyword, isPull, userId)
count, err := sess.Count(new(Issue))
if err != nil {
return nil, 0, err
}

setIssueQueryCondition(sess, Keyword, isPull, userId)
sess.Desc("issue.created_unix")
sess.Limit(PageSize, (Page-1)*PageSize)
issues := make([]*Issue, 0)
if err := sess.Find(&issues); err != nil {
return nil, 0, err
} else {
return issues, count, nil
}
}

func setDataSetQueryCondition(sess *xorm.Session, Keyword string, userId int64) {
sess.And("dataset.user_id=?", userId)
sess.And("(dataset.title like '%" + Keyword + "%' or dataset.description like '%" + Keyword + "%')")
sess.Join("INNER", "repository", "dataset.repo_id = repository.id").And("repository.is_private = ?", true)
}

func SearchDatasetBySQL(Page int, PageSize int, Keyword string, userId int64) ([]*Dataset, int64, error) {
sess := x.NewSession()
defer sess.Close()
setDataSetQueryCondition(sess, Keyword, userId)
count, err := sess.Count(new(Dataset))
if err != nil {
return nil, 0, err
}

setDataSetQueryCondition(sess, Keyword, userId)
sess.Desc("dataset.created_unix")
sess.Limit(PageSize, (Page-1)*PageSize)
datasets := make([]*Dataset, 0)
if err := sess.Find(&datasets); err != nil {
return nil, 0, err
} else {
return datasets, count, nil
}

}

+ 2
- 1
modules/setting/setting.go View File

@@ -437,7 +437,7 @@ var (


//home page //home page
RecommentRepoAddr string RecommentRepoAddr string
ESSearchURL string
//notice config //notice config
UserNameOfNoticeRepo string UserNameOfNoticeRepo string
RepoNameOfNoticeRepo string RepoNameOfNoticeRepo string
@@ -1267,6 +1267,7 @@ func NewContext() {


sec = Cfg.Section("homepage") sec = Cfg.Section("homepage")
RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/") RecommentRepoAddr = sec.Key("Address").MustString("https://git.openi.org.cn/OpenIOSSG/promote/raw/branch/master/")
ESSearchURL = sec.Key("ESSearchURL").MustString("http://192.168.207.94:9200")


sec = Cfg.Section("notice") sec = Cfg.Section("notice")
UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG") UserNameOfNoticeRepo = sec.Key("USER_NAME").MustString("OpenIOSSG")


+ 12
- 0
options/locale/locale_en-US.ini View File

@@ -254,6 +254,18 @@ page_dev_yunlao_desc3=Developers can freely choose the corresponding computing r
page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately. page_dev_yunlao_desc4=If your model requires more computing resources, you can also apply for it separately.
page_dev_yunlao_apply=Apply Separately page_dev_yunlao_apply=Apply Separately


search=Search
search_repo=Repository
search_dataset=DataSet
search_issue=Issue
search_pr=Pull Request
search_user=User
search_org=Organization
search_finded=Find
search_related=related
search_maybe=maybe
search_ge=

[explore] [explore]
repos = Repositories repos = Repositories
select_repos = Select the project select_repos = Select the project


+ 12
- 0
options/locale/locale_zh-CN.ini View File

@@ -256,6 +256,18 @@ page_dev_yunlao_desc3=开发者可以根据使用需求,自由选择相应计
page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请 page_dev_yunlao_desc4=如果您的模型需要更多的计算资源,也可以单独申请
page_dev_yunlao_apply=单独申请 page_dev_yunlao_apply=单独申请


search=搜索
search_repo=项目
search_dataset=数据集
search_issue=任务
search_pr=合并请求
search_user=用户
search_org=组织
search_finded=找到
search_related=相关
search_maybe=约为
search_ge=个

[explore] [explore]
repos=项目 repos=项目
select_repos=精选项目 select_repos=精选项目


+ 1281
- 0
public/home/search.js
File diff suppressed because it is too large
View File


+ 3
- 3
public/self/dataset_preview.js View File

@@ -620,10 +620,10 @@ function showfilelist(){
for (var i=0;i<labeltastresult.length;i++){ for (var i=0;i<labeltastresult.length;i++){
var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1); var fname = labeltastresult[i].pic_image_field.substring(labeltastresult[i].pic_image_field.lastIndexOf('/') + 1);
console.log(labeltastresult[i])
//console.log(labeltastresult[i])
if(labeltastresult[i].pic_image_field.length > 70){ if(labeltastresult[i].pic_image_field.length > 70){
var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70); var tmpIndex = labeltastresult[i].pic_image_field.indexOf("/",70);
console.log(tmpIndex)
//console.log(tmpIndex)
if(tmpIndex != -1){ if(tmpIndex != -1){
fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1); fname = labeltastresult[i].pic_image_field.substring(tmpIndex + 1);
fname = fname.substring(fname.indexOf('/')+1); fname = fname.substring(fname.indexOf('/')+1);
@@ -679,7 +679,7 @@ function breadFiles(){
fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1); fname_full_path = tableData[fileindex].pic_image_field.substring(tmp_index + 1);
} }
var fname_path = fname_full_path.split('/') var fname_path = fname_full_path.split('/')
console.log(fname_path)
//console.log(fname_path)
// var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1) // var filename_text = tableData[fileindex].pic_image_field.substring(tableData[fileindex].pic_image_field.lastIndexOf('/')+1)
var html_breadFile = '' var html_breadFile = ''
// var source_name = filename_title+'.zip' // var source_name = filename_title+'.zip'


+ 2
- 0
routers/init.go View File

@@ -71,6 +71,8 @@ func NewServices() {
log.Info("decompression.NewContext() succeed.") log.Info("decompression.NewContext() succeed.")
labelmsg.Init() labelmsg.Init()
log.Info("labelmsg.Init() succeed.") log.Info("labelmsg.Init() succeed.")
InitESClient()
log.Info("ES Client succeed.")
} }


// In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology // In case of problems connecting to DB, retry connection. Eg, PGSQL in Docker Container on Synology


+ 3
- 0
routers/routes/routes.go View File

@@ -323,6 +323,9 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/action/notification", routers.ActionNotification) m.Get("/action/notification", routers.ActionNotification)
m.Get("/recommend/org", routers.RecommendOrgFromPromote) m.Get("/recommend/org", routers.RecommendOrgFromPromote)
m.Get("/recommend/repo", routers.RecommendRepoFromPromote) m.Get("/recommend/repo", routers.RecommendRepoFromPromote)
m.Post("/all/search/", routers.Search)
m.Get("/all/search/", routers.EmptySearch)
m.Get("/all/dosearch/", routers.SearchApi)
m.Get("/home/term", routers.HomeTerm) m.Get("/home/term", routers.HomeTerm)
m.Group("/explore", func() { m.Group("/explore", func() {
m.Get("", func(ctx *context.Context) { m.Get("", func(ctx *context.Context) {


+ 1190
- 0
routers/search.go
File diff suppressed because it is too large
View File


+ 4
- 4
templates/base/head_navbar.tmpl View File

@@ -95,9 +95,9 @@


{{if .IsSigned}} {{if .IsSigned}}
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="hot"> <input type="hidden" name="sort" value="hot">
@@ -199,9 +199,9 @@
<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a-->
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="hot"> <input type="hidden" name="sort" value="hot">


+ 4
- 4
templates/base/head_navbar_fluid.tmpl View File

@@ -93,9 +93,9 @@


{{if .IsSigned}} {{if .IsSigned}}
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="{{$.SortType}}"> <input type="hidden" name="sort" value="{{$.SortType}}">
@@ -196,9 +196,9 @@


<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a-->
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="{{$.SortType}}"> <input type="hidden" name="sort" value="{{$.SortType}}">


+ 4
- 4
templates/base/head_navbar_pro.tmpl View File

@@ -96,9 +96,9 @@


{{if .IsSigned}} {{if .IsSigned}}
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="{{$.SortType}}"> <input type="hidden" name="sort" value="{{$.SortType}}">
@@ -199,9 +199,9 @@


<!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a--> <!--a class="item" target="_blank" rel="noopener noreferrer" href="https://docs.gitea.io">{{.i18n.Tr "help"}}</a-->
<div class="right stackable menu"> <div class="right stackable menu">
<form class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/explore/repos">
<form id="searchForm" class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin:auto" action="/all/search/" method="post">
<div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;"> <div class="ui fluid action input" style="background:#363840 ;border-radius: 5px;width: 200px;height:30px;border: #888888 solid 1px;">
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search_pro"}}..."
<input name="q" value="{{.Keyword}}" placeholder="{{.i18n.Tr "explore.search"}}..."
style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;"> style="transition: background-color 5000s ease-in-out 0s;-webkit-text-fill-color:#888888;background:#363840 ;color:#888888;border: none;outline: none;">
<input type="hidden" name="tab" value="{{$.TabName}}"> <input type="hidden" name="tab" value="{{$.TabName}}">
<input type="hidden" name="sort" value="{{$.SortType}}"> <input type="hidden" name="sort" value="{{$.SortType}}">


+ 95
- 0
templates/explore/search_new.tmpl View File

@@ -0,0 +1,95 @@
{{template "base/head" .}}

<div class="explore seach">
<div class="repos--seach">
<div class="ui container">
<div id="search_div" class="ui two column centered grid">
<div class="fourteen wide mobile ten wide tablet ten wide computer column ui form ignore-dirty" style="margin-top:1.2rem;margin-bottom: 1.2rem;">
<div class="ui fluid action input">
<input name="q" id="keyword_input" value="{{.Keyword}}" placeholder="{{.i18n.Tr "home.search"}}..." autofocus="">
<input type="hidden" name="topic" value="">
<input type="hidden" name="tab" value="">
<input type="hidden" name="sort" value="hot">
<button class="ui green button" onclick="search()">{{.i18n.Tr "home.search"}}</button>
</div>
</div>
</div>
<div id="search_label_div" style="display:none">
</div>
</div>

<div class="ui container seachnav">
<div class="ui secondary pointing menu">
<a id="repo_item" class="item" href="javascript:searchItem(1,10);">
{{.i18n.Tr "home.search_repo"}}
<span class="ui circular mini label" id="repo_total"></span>
</a>
<a id="dataset_item" class="item" href="javascript:searchItem(5,50);">
{{.i18n.Tr "home.search_dataset"}}
<span class="ui circular mini label" id="dataset_total"></span>
</a>
<a id="issue_item" class="item" href="javascript:searchItem(2,20);">
{{.i18n.Tr "home.search_issue"}}
<span class="ui circular mini label" id="issue_total"></span>
</a>
<a id="pr_item" class="item" href="javascript:searchItem(6,60);">
{{.i18n.Tr "home.search_pr"}}
<span class="ui circular mini label" id="pr_total"></span>
</a>
<a id="user_item" class="item" href="javascript:searchItem(3,30);">
{{.i18n.Tr "home.search_user"}}
<span class="ui circular mini label" id="user_total"></span>
</a>
<a id="org_item" class="item" href="javascript:searchItem(4,40);">
{{.i18n.Tr "home.search_org"}} <span class="ui circular mini label" id="org_total"></span>
</a>
</div>
</div>
</div>

<div class="ui container">
<span id="find_id">{{.i18n.Tr "home.search_finded"}}</span><span id="find_title"></span>
<div class="ui right floated secondary filter menu">
<!-- Sort -->
<div class="ui right dropdown type jump item">
<span class="text">
{{.i18n.Tr "repo.issues.filter_sort"}}
<i class="dropdown icon"></i>
</span>
<div class="menu" id="sort_type">
</div>
</div>

</div>
<div class="ui divider" style="margin-top: 1.25rem;"></div>

<div class="ui very relaxed divided list" id="child_search_item">

</div><!--seach list end-->
<div class="center page buttons" style="margin: 0px auto 15px">
<div class="ui borderless mini pagination menu" id="page_menu">
</div>
</div>
<div id="tipmsg"></div>
</div>

</div>
<script src="/self/js/jquery.min.js" type="text/javascript"></script>
<script src="/home/search.js?v={{MD5 AppVer}}" type="text/javascript"></script>
<div class="am-mt-30"></div>


{{template "base/footer" .}}

+ 109
- 0
web_src/less/openi.less View File

@@ -628,6 +628,32 @@ display: block;
.a_margin{ .a_margin{
margin: 0px !important; margin: 0px !important;
} }

/*pages*/
.ui.borderless.pagination {border:none}
.ui.pagination.menu .item {
min-width: 32px;
text-align: center;
height: 32px;
border-radius: .28571429rem;
margin: 0 5px;
background-color: #F2F2F2;
}
.ui.pagination.menu>.item:first-child, .ui.pagination.menu .item:last-child {
background-color: #FFF !important;
}
.ui.ui.menu .item.disabled{
background-color: #F2F2F2;
}
.ui.pagination.menu .active.item {
background-color: #3291F8;
color: #FFF;
}
.ui.pagination.menu .item>.input {
margin: 0em .5em;
width: 3em;
height: 32px;
}
@media only screen and (max-width: 767px) { @media only screen and (max-width: 767px) {
.following.bar #navbar .brand{ .following.bar #navbar .brand{
padding-top: 6px; padding-top: 6px;
@@ -783,4 +809,87 @@ display: block;
border: none !important; border: none !important;
color: #0366d6 !important; color: #0366d6 !important;
box-shadow: -15px 0px 10px #fff; box-shadow: -15px 0px 10px #fff;
}

/**seach**/
/**搜索导航条适配窄屏**/
.seachnav{
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: none; /* firefox */
-ms-overflow-style: none; /* IE 10+ */
}
.seachnav::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
.ui.green.button, .ui.green.buttons .button{
background-color: #5BB973;
}
.seach .repos--seach{
padding-bottom: 0;
border-bottom: none;
}
.seach .ui.secondary.pointing.menu{
border-bottom: none;
}
.seach .ui.secondary.pointing.menu .item > i{
margin-right: 5px;
}
.seach .ui.secondary.pointing.menu .active.item{
border-bottom-width: 2px;
margin: 0 0 -1px;
}
.seach .ui.menu .active.item>.label {
background: #1684FC;
color: #FFF;
}
.seach .ui.menu .item>.label:not(.active.item>.label) {
background: #e8e8e8;
color: rgba(0,0,0,.6);
}
.highlight{
color: red;
}
.ui.list .list>.item>img.image+.content, .ui.list>.item>img.image+.content {
width: calc(100% - 4.0em);
margin-left: 0;
}
.seach .ui.list .list>.item .header, .seach .ui.list>.item .header{
margin-bottom: 0.5em;
font-size: 1.4rem !important;
font-weight: normal;
}
.seach .time, .seach .time a{
font-size: 12px;
color: grey;
}
.seach .list .item.members .ui.avatar.image {
width: 3.2em;
height: 3.2em;
}
.ui.list .list>.item.members>img.image+.content, .ui.list>.item.members>img.image+.content {
width: calc(100% - 4.0em);
margin-left: 0;
}

.searchlabel{
color: rgba(16, 16, 16, 100);
font-size: 24px;
text-align: left;
font-family: SourceHanSansSC-medium;
}

.hiddenSearch{
margin: auto;
display: none;
}

#tipmsg {
display: none;
z-index: 9999;
width:150;
height: 80;
} }

Loading…
Cancel
Save