Browse Source

add repos square

tags/v1.22.12.1^2
chenshihai 2 years ago
parent
commit
5eb02595b9
23 changed files with 1642 additions and 15 deletions
  1. +3
    -3
      templates/base/head_navbar.tmpl
  2. +3
    -3
      templates/base/head_navbar_fluid.tmpl
  3. +3
    -3
      templates/base/head_navbar_home.tmpl
  4. +2
    -2
      templates/base/head_navbar_pro.tmpl
  5. +2
    -2
      templates/explore/navbar.tmpl
  6. +6
    -0
      templates/explore/repos/search.tmpl
  7. +6
    -0
      templates/explore/repos/square.tmpl
  8. +1
    -1
      templates/user/dashboard/dashboard.tmpl
  9. +1
    -1
      web_src/js/index.js
  10. +12
    -0
      web_src/vuepages/apis/modules/common.js
  11. +69
    -0
      web_src/vuepages/apis/modules/repos.js
  12. +113
    -0
      web_src/vuepages/pages/repos/components/ActiveOrgs.vue
  13. +138
    -0
      web_src/vuepages/pages/repos/components/ActiveUsers.vue
  14. +135
    -0
      web_src/vuepages/pages/repos/components/RecommendRepos.vue
  15. +111
    -0
      web_src/vuepages/pages/repos/components/ReposFilters.vue
  16. +266
    -0
      web_src/vuepages/pages/repos/components/ReposItem.vue
  17. +94
    -0
      web_src/vuepages/pages/repos/components/ReposList.vue
  18. +155
    -0
      web_src/vuepages/pages/repos/components/SearchBar.vue
  19. +343
    -0
      web_src/vuepages/pages/repos/components/SquareTop.vue
  20. +59
    -0
      web_src/vuepages/pages/repos/search/index.vue
  21. +17
    -0
      web_src/vuepages/pages/repos/search/vp-repos-search.js
  22. +86
    -0
      web_src/vuepages/pages/repos/square/index.vue
  23. +17
    -0
      web_src/vuepages/pages/repos/square/vp-repos-square.js

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

@@ -32,7 +32,7 @@
</div>
</div>
</div>
<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -72,7 +72,7 @@
</div>
</div>

<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -97,7 +97,7 @@
</div>
</div>
{{else if .IsLandingPageExplore}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "home"}}</a>
{{else if .IsLandingPageOrganizations}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
{{end}}


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

@@ -32,7 +32,7 @@
</div>
</div>
</div>
<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -71,7 +71,7 @@
</div>
</div>
</div>
<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -95,7 +95,7 @@
</div>
</div>
{{else if .IsLandingPageExplore}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "home"}}</a>
{{else if .IsLandingPageOrganizations}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
{{end}}


+ 3
- 3
templates/base/head_navbar_home.tmpl View File

@@ -24,7 +24,7 @@
</div>
</div>
</div>
<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -64,7 +64,7 @@
</div>
</div>

<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -88,7 +88,7 @@
</div>
</div>
{{else if .IsLandingPageExplore}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "home"}}</a>
{{else if .IsLandingPageOrganizations}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
{{end}}


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

@@ -34,7 +34,7 @@
</div>
</div>

<a class="item" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "custom.head.project"}}</a>
<a class="item" href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "custom.head.dataset"}}</a>
<div class="ui simple dropdown item" >
{{.i18n.Tr "repo.model_manager"}}
@@ -98,7 +98,7 @@
</div>
</div>
{{else if .IsLandingPageExplore}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos">{{.i18n.Tr "home"}}</a>
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/repos/square">{{.i18n.Tr "home"}}</a>
{{else if .IsLandingPageOrganizations}}
<a class="item {{if .PageIsExplore}}active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{.i18n.Tr "home"}}</a>
{{end}}


+ 2
- 2
templates/explore/navbar.tmpl View File

@@ -1,6 +1,6 @@
<div class="tablet only mobile only sixteen wide mobile sixteen wide tablet column row">
<div class="ui secondary pointing tabular top attached borderless menu navbar">
<a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos">
<a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos/square">
{{svg "octicon-repo" 16}} {{.i18n.Tr "explore.repos"}}
</a>
<a class="{{if .PageIsDatasets}}active{{end}} item" href="{{AppSubUrl}}/explore/datasets">
@@ -24,7 +24,7 @@
<div class="computer only three wide computer column">
<div class="ui grid">
<div class="sixteen wide column ui secondary sticky pointing tabular vertical menu">
<a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos">
<a class="{{if .PageIsExploreRepositories}}active{{end}} item" href="{{AppSubUrl}}/explore/repos/square">
{{svg "octicon-repo" 16}} {{.i18n.Tr "explore.repos"}}
</a>
<a class="{{if .PageIsDatasets}}active{{end}} item" href="{{AppSubUrl}}/explore/datasets">


+ 6
- 0
templates/explore/repos/search.tmpl View File

@@ -0,0 +1,6 @@
{{template "base/head_home" .}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-repos-search.css?v={{MD5 AppVer}}" />
<div id="__vue-root">
</div>
<script src="{{StaticUrlPrefix}}/js/vp-repos-search.js?v={{MD5 AppVer}}"></script>
{{template "base/footer" .}}

+ 6
- 0
templates/explore/repos/square.tmpl View File

@@ -0,0 +1,6 @@
{{template "base/head_home" .}}
<link rel="stylesheet" href="{{StaticUrlPrefix}}/css/vp-repos-square.css?v={{MD5 AppVer}}" />
<div id="__vue-root">
</div>
<script src="{{StaticUrlPrefix}}/js/vp-repos-square.js?v={{MD5 AppVer}}"></script>
{{template "base/footer" .}}

+ 1
- 1
templates/user/dashboard/dashboard.tmpl View File

@@ -10,7 +10,7 @@
{{.i18n.Tr "home.wecome_AI_plt"}}
</div>
<div class="content">
<p class="ui text grey">{{.i18n.Tr "home.explore_AI"}} <a href="{{AppSubUrl}}/explore/repos"> {{.i18n.Tr "home.repositories"}}</a> {{.i18n.Tr "home.or_t"}} <a href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "home.datasets"}}</a></p>
<p class="ui text grey">{{.i18n.Tr "home.explore_AI"}} <a href="{{AppSubUrl}}/explore/repos/square"> {{.i18n.Tr "home.repositories"}}</a> {{.i18n.Tr "home.or_t"}} <a href="{{AppSubUrl}}/explore/datasets">{{.i18n.Tr "home.datasets"}}</a></p>
<p><span class="ui text grey">{{.i18n.Tr "home.use_plt__fuction"}}</span>&nbsp;<a class="mini ui blue button" href="{{AppSubUrl}}/repo/create{{if .ContextUser.IsOrganization}}?org={{.ContextUser.ID}}{{end}}" >{{.i18n.Tr "repo.create_repo"}}</a></p>
<p class="ui text grey">{{.i18n.Tr "home.provide_resoure"}}</p>
</div>


+ 1
- 1
web_src/js/index.js View File

@@ -50,7 +50,7 @@ import initImage from "./features/images.js";
import selectDataset from "./components/dataset/selectDataset.vue";
import referenceDataset from "./components/dataset/referenceDataset.vue";
// import $ from 'jquery.js'
import router from "./router/index.js";
// import router from "./router/index.js";
import { Message } from "element-ui";

import { i18nVue } from "./features/i18nVue.js";


+ 12
- 0
web_src/vuepages/apis/modules/common.js View File

@@ -0,0 +1,12 @@
import service from '../service';

// 获取promote配置数据
export const getPromoteData = (filePathName) => {
return service({
url: '/dashboard/invitation',
method: 'get',
params: {
filename: filePathName
},
});
}

+ 69
- 0
web_src/vuepages/apis/modules/repos.js View File

@@ -0,0 +1,69 @@
import service from '../service';

// 获取首页数据
export const getHomePageData = () => {
return service({
url: '/recommend/home',
method: 'get',
params: {},
});
}

// 获取项目广场上方tab数据 tab=preferred 项目优选|incubation 启智孵化管道|hot-paper 热门论文项目
export const getReposSquareTabData = (tab) => {
return service({
url: '/explore/repos/square/tab',
method: 'get',
params: {
type: tab
},
});
}

// 搜索项目
// q string 否 关键词
// topic string 否 标签名
// sort string 是 mostpopular 近期热门 | mostactive 近期活跃 | recentupdate 最近更新 | newest 最近创建
// moststars 点赞最多 | mostforks 派生最多 | mostdatasets 数据集最多 | mostaitasks AI任务最多 | mostmodels 模型最多
// pageSize int 是 每页大小,可选值为15 | 30 | 50
// page int 是 页码
export const getReposListData = (params) => {
return service({
url: '/explore/repos/search',
method: 'get',
params: {
q: params.q || '',
topic: params.topic || '',
sort: params.sort || 'mostpopular',
pageSize: params.pageSize || 15,
page: params.page || 1,
},
});
}

// 获取活跃用户列表
export const getActiveUsers = () => {
return service({
url: '/explore/repos/square/active-user',
method: 'get',
params: {},
});
}

// 关注用户
export const followingUsers = (userName, isFollowing) => {
return service({
url: `/api/v1/user/following/${userName}`,
method: isFollowing ? 'put' : 'delete',
params: {},
});
}

// 获取活跃组织列表
export const getActiveOrgs = () => {
return service({
url: '/explore/repos/square/active-org',
method: 'get',
params: {},
});
}

+ 113
- 0
web_src/vuepages/pages/repos/components/ActiveOrgs.vue View File

@@ -0,0 +1,113 @@
<template>
<div>
<div class="container">
<div class="title">
<i style="margin-left:10px;margin-right:8px;font-size:20px;" class="ri-blaze-line"></i>
<span>活跃组织</span>
</div>
<div class="content">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="item-l">
<img class="avatar" :src="item.RelAvatarLink">
<div class="name-c"><a class="name" :href="`/${item.Name}`" :title="item.Name">{{ item.Name }}</a></div>
</div>
<div class="item-r">
<i class="ri-user-2-line" style="color:rgb(250, 140, 22);margin-right:4px;"></i>
<span>{{ item.NumMembers }}</span>
</div>
</div>
</div>
</div>
</div>
</template>

<script>

import { getActiveOrgs } from '~/apis/modules/repos';

export default {
name: "ActiveOrgs",
props: {},
components: {},
data() {
return {
list: [],
};
},
methods: {},
mounted() {
getActiveOrgs().then(res => {
res = res.data;
if (res.Code == 0) {
this.list = res.Data.Orgs || [];
}
}).catch(err => {
console.log(err);
});
},
};
</script>
<style scoped lang="less">
.title {
height: 43px;
border-color: rgba(16, 16, 16, 0.05);
border-width: 1px 0px;
border-style: solid;
display: flex;
align-items: center;
font-size: 18px;
color: rgba(47, 9, 69, 0.74);
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(-1.007%2C%200.0010000000000001494%2C%20-0.000018400023883213844%2C%20-1.007%2C%201.003%2C%200.008)%22%3E%3Cstop%20stop-color%3D%22%23eee9da%22%20stop-opacity%3D%220%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23f3e7f7%22%20stop-opacity%3D%220.26%22%20offset%3D%220.29%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23d0e7ff%22%20stop-opacity%3D%220.3%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}

.content {
padding: 6px 0;
}

.item {
display: flex;
align-items: center;
height: 48px;
padding: 0 8px;
font-size: 14px;
color: rgba(16, 16, 16, 1);
}

.item>div {
display: flex;
align-items: center;
}

.item-l {
flex: 1;
overflow: hidden;
}

.item-r {
width: 80px;
justify-content: flex-end;
}

.item .avatar {
width: 32px;
height: 32px;
border-radius: 50%;
margin-right: 10px;
}

.item .name-c {
flex: 1;
overflow: hidden;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
}

.item .name {
color: rgba(16, 16, 16, 1);

&:hover {
opacity: 0.8;
}
}
</style>

+ 138
- 0
web_src/vuepages/pages/repos/components/ActiveUsers.vue View File

@@ -0,0 +1,138 @@
<template>
<div>
<div class="container">
<div class="title">
<i style="margin-left:10px;margin-right:8px;font-size:20px;" class="ri-account-pin-circle-line"></i>
<span>活跃用户</span>
</div>
<div class="content">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="item-l">
<img class="avatar" :src="item.User.RelAvatarLink">
<div class="name-c"><a class="name" :href="`/${item.User.Name}`"
:title="(item.User.FullName || item.User.Name)">{{ item.User.FullName || item.User.Name
}}</a></div>
</div>
<div class="item-r">
<template v-if="item.ShowButton">
<a class="op-btn" v-if="!item.Followed" href="javascript:;" @click="following(item, index, true)">关注</a>
<a class="op-btn" v-if="item.Followed" href="javascript:;" @click="following(item, index, false)">取消关注</a>
</template>
</div>
</div>
</div>
</div>
</div>
</template>
<script>

import { getActiveUsers, followingUsers } from '~/apis/modules/repos';

export default {
name: "ActiveUsers",
props: {},
components: {},
data() {
return {
list: [],
};
},
methods: {
following(userInfo, index, followingOrNot) {
followingUsers(userInfo.User.Name, followingOrNot).then(res => {
if (res.status == 204) { // 成功
userInfo.Followed = !userInfo.Followed;
}
}).catch(err => {
if (err.response.status == 401) { // 未登陆
window.location.href = '/user/login';
}
});
}
},
mounted() {
getActiveUsers().then(res => {
res = res.data;
if (res.Code == 0) {
this.list = res.Data.Users || [];
}
}).catch(err => {
console.log(err);
});
},
};
</script>
<style scoped lang="less">
.title {
height: 43px;
border-color: rgba(16, 16, 16, 0.05);
border-width: 1px 0px;
border-style: solid;
display: flex;
align-items: center;
font-size: 18px;
color: rgba(47, 9, 69, 0.74);
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(-1.007%2C%200.0010000000000001494%2C%20-0.000018400023883213844%2C%20-1.007%2C%201.003%2C%200.008)%22%3E%3Cstop%20stop-color%3D%22%23eee9da%22%20stop-opacity%3D%220%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23f3e7f7%22%20stop-opacity%3D%220.26%22%20offset%3D%220.29%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23d0e7ff%22%20stop-opacity%3D%220.3%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}

.content {
padding: 6px 0;
}

.item {
display: flex;
align-items: center;
height: 48px;
padding: 0 8px;
font-size: 14px;
color: rgba(16, 16, 16, 1);
}

.item>div {
display: flex;
align-items: center;
}

.item-l {
flex: 1;
overflow: hidden;
}

.item-r {
width: 80px;
justify-content: flex-end;
}

.item .avatar {
width: 32px;
height: 32px;
border-radius: 50%;
margin-right: 10px;
}

.item .name-c {
flex: 1;
overflow: hidden;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
}

.item .name {
color: rgba(16, 16, 16, 1);

&:hover {
opacity: 0.8;
}
}

.item .op-btn {
border-color: rgb(50, 145, 248);
border-width: 1px;
border-style: solid;
color: rgb(50, 145, 248);
font-size: 12px;
padding: 0px 6px;
border-radius: 3px;
}
</style>

+ 135
- 0
web_src/vuepages/pages/repos/components/RecommendRepos.vue View File

@@ -0,0 +1,135 @@
<template>
<div class="repo-selected-bg">
<div class="ui container _repo_container _repo-selected-container" style="padding-top:3rem;padding-bottom:4rem;">
<div class="_repo_title"><span>精选领域</span></div>
<div class="_repo-selected-list">
<div class="swiper-wrapper" id="_repo-selected"></div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
</template>
<script>

import { getHomePageData } from '~/apis/modules/repos';
// import { CLUSTERS, AI_CENTER, COMPUTER_RESOURCES, ACC_CARD_TYPE } from '~/const';

export default {
name: "RecommendRepos",
props: {
// visible: { type: Boolean, default: false },
},
components: {},
data() {
return {
swiperHandler: null,
};
},
methods: {
renderRepos(json) {
var selectedRepoEl = document.getElementById("_repo-selected");
var html = "";
if (json != null && json.length > 0) {
var repoMap = {};
for (var i = 0, iLen = json.length; i < iLen; i++) {
var repo = json[i];
var label = repo.Label;
if (repoMap[label]) {
repoMap[label].push(repo);
} else {
repoMap[label] = [repo];
}
}
for (var label in repoMap) {
var repos = repoMap[label];
var labelSearch = repos[0].Label;
html += `<div class="swiper-slide"><div><a style="color:rgb(50, 145, 248);font-size:16px;font-weight:550;" href="/explore/repos?q=&topic=${labelSearch}&sort=hot"># ${label}</a></div>`;
for (var i = 0, iLen = repos.length; i < iLen; i++) {
if (i >= 4) break;
var repo = repos[i];
html += `<div class="ui fluid card">
<div class="content">
${repo["Avatar"] ? `<img class="left floated mini ui image" src="${repo["Avatar"]}">` : `<img class="left floated mini ui image" avatar="${repo["OwnerName"]}">`}
<a class="header nowrap" style="color:rgb(50, 145, 248);font-size:14px;" href="/${repo["OwnerName"]}/${repo["Name"]}" title="${repo["Alias"]}">${repo["Alias"]}</a>
<div class="description nowrap-2" style="rgba(136,136,136,1);;font-size:12px;" title="${repo["Description"]}">${repo["Description"]}</div>
</div>
</div>`;
}
html += '</div>'
}
this.swiperHandler = new Swiper("._repo-selected-list", {
slidesPerView: 1,
spaceBetween: 20,
pagination: {
el: ".swiper-pagination",
clickable: true,
},
autoplay: {
delay: 2500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: 3,
},
1024: {
slidesPerView: 4,
},
1200: {
slidesPerView: 4,
},
1600: {
slidesPerView: 4,
}
},
});
selectedRepoEl.innerHTML = html;
this.swiperHandler.updateSlides();
this.swiperHandler.updateProgress();
this.$nextTick(() => {
if (typeof LetterAvatar != undefined) {
LetterAvatar && LetterAvatar.transform();
}
});
}
}
},
mounted() {
getHomePageData().then(res => {
this.renderRepos(res.data.repo);
}).catch(err => {
console.log(err);
});
},
};
</script>
<style scoped lang="less">
.repo-selected-bg {
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(0.11899999999999993%2C%201.217%2C%20-0.24039506172839506%2C%200.11899999999999993%2C%200.269%2C%20-0.22)%22%3E%3Cstop%20stop-color%3D%22%23ffffff%22%20stop-opacity%3D%220.47%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23e5e7eb%22%20stop-opacity%3D%220.3%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}

._repo_title {
font-size: 18px;
color: rgb(16, 16, 16);
text-align: center;
margin-bottom: 1em;
font-weight: bold;
}

._repo-selected-list {
overflow: hidden;
padding: 1em;
text-align: left;
}

/deep/ ._repo-selected-list .card {
border-radius: 6px;
background-color: #FFF;
box-shadow: 0px 5px 10px 0px rgba(105, 192, 255, .3);
border: 1px solid rgba(105, 192, 255, .4);
}

/deep/ ._repo-selected-list .header {
line-height: 40px !important;
}
</style>

+ 111
- 0
web_src/vuepages/pages/repos/components/ReposFilters.vue View File

@@ -0,0 +1,111 @@
<template>
<div>
<div class="item" :class="(focusIndex == index) ? 'item-focus' : ''" v-for="(item, index) in list" :key="item.key">
<a href="javascript:;" @click="changeFilters(item, index)">{{ item.label }}</a>
</div>
</div>
</template>
<script>

// import { addResQueue, updateResQueue } from '~/apis/modules/resources';
// import { CLUSTERS, AI_CENTER, COMPUTER_RESOURCES, ACC_CARD_TYPE } from '~/const';

export default {
name: "ReposFilters",
props: {
// visible: { type: Boolean, default: false },
},
components: {},
data() {
return {
focusIndex: 0,
list: [{
key: 'mostpopular',
label: '近期热门',
}, {
key: 'mostactive',
label: '近期活跃',
}, {
key: 'recentupdate',
label: '最近更新',
}, {
key: 'newest',
label: '点赞最多',
}, {
key: 'moststars',
label: '派生最多',
}, {
key: 'mostforks',
label: '数据集最多',
}, {
key: 'mostdatasets',
label: 'AI任务最多',
}, {
key: 'mostaitasks',
label: '模型最多',
}]
};
},
methods: {
changeFilters(item, index) {
this.focusIndex = index;
this.$emit('change', this.list[this.focusIndex]);
}
},
mounted() {

},
};
</script>
<style scoped lang="less">
.item {
height: 40px;
border-color: rgba(16, 16, 16, 0.05);
border-width: 0px 0px 1px;
border-style: solid;
color: rgba(16, 16, 16, 0.8);
font-size: 14px;
padding: 0px;
display: flex;
align-items: center;
justify-content: flex-end;
position: relative;
}

.item a {
color: inherit;
height: 100%;
display: flex;
align-items: center;

&:hover {
opacity: 0.8;
}
}

.item-focus {
font-weight: bold;
border-color: rgba(0, 108, 205, 0.3);
color: rgb(50, 145, 248);

a {
cursor: default;

&:hover {
opacity: 1;
}
}

}

.item-focus:before {
content: "";
position: absolute;
width: 7px;
height: 7px;
bottom: -4px;
background: rgb(178, 211, 240);
left: 0;
border-radius: 100%;
}
</style>

+ 266
- 0
web_src/vuepages/pages/repos/components/ReposItem.vue View File

@@ -0,0 +1,266 @@
<template>
<div>
<div class="item">
<div class="item-top">
<img v-if="data.RelAvatarLink" class="avatar" :src="data.RelAvatarLink" />
<img v-else class="avatar" :avatar="data.OwnerName" />
<div class="content">
<div class="title">
<div class="title-l">
<a :href="`/${data.OwnerName}/${data.Name}`">
<span class="title-1">{{ data.OwnerName }}</span>
<span class="title-1"> / </span>
<span class="title-2">{{ data.Name }}</span>
</a>
</div>
<span class="title-r">
<span class="t-item"><i class="ri-eye-line"></i><span>{{ data.NumWatches }}</span></span>
<span class="t-item"><i class="ri-star-line"></i><span>{{ data.NumStars }}</span></span>
<span class="t-item"><i class="ri-git-pull-request-line"></i><span>{{ data.NumForks }}</span></span>
</span>
</div>
<div class="descr">{{ data.Description }}</div>
<div class="tags" v-if="data.Topics">
<a v-for="(item, index) in data.Topics" :key="index" class="tag"
:href="`/explore/repos?q=&topic=${item}&sort=hot`">{{ item }}</a>
</div>
<div class="repo-datas">
<span class="repo-datas-item" v-show="(data.DatasetCnt > 0)">
<i class="ri-stack-line"></i>
<span class="label">数据集:</span>
<span class="value">{{ data.DatasetCnt }}</span>
</span>
<span class="repo-datas-item" v-show="(data.ModelCnt > 0)">
<i class="ri-send-plane-2-line"></i>
<span class="label">模型:</span>
<span class="value">{{ data.ModelCnt }}</span>
</span>
<span class="repo-datas-item" v-show="(data.AiTaskCnt > 0)">
<i class="ri-order-play-line"></i>
<span class="label">AI任务:</span>
<span class="value">{{ data.AiTaskCnt }}</span>
</span>
</div>
</div>
</div>
<div class="item-bottom">
<div>
<span>最后更新于</span>
<el-tooltip effect="dark" :content="dateFormat(data.UpdatedUnix)" placement="top-start">
<span>{{ calcFromNow(data.UpdatedUnix) }}</span>
</el-tooltip>
<span style="margin-left:8px;" v-if="data.PrimaryLanguage"><i class="color-icon"
:style="{ backgroundColor: data.PrimaryLanguage.Color }"></i>{{ data.PrimaryLanguage.Language }}</span>
</div>
<div class="contributors">
<span class="contributors-count">贡献者</span><span> 17+ </span>
<span class="contributors-avatar">
<img class="avatar" src="/user/avatar/Itx003/-1">
<img class="avatar" src="/user/avatar/Itx003/-1">
<img class="avatar" src="/user/avatar/Itx003/-1">
<img class="avatar" src="/user/avatar/Itx003/-1">
<img class="avatar" src="/user/avatar/Itx003/-1">
</span>
</div>
</div>
</div>
</div>
</template>
<script>

// import { addResQueue, updateResQueue } from '~/apis/modules/resources';
// import { CLUSTERS, AI_CENTER, COMPUTER_RESOURCES, ACC_CARD_TYPE } from '~/const';
import relativeTime from 'dayjs/plugin/relativeTime';
import localizedFormat from 'dayjs/plugin/localizedFormat';
import 'dayjs/locale/zh-cn';
import 'dayjs/locale/en';
import dayjs from 'dayjs';
import { lang } from '~/langs';

dayjs.locale(lang == 'zh-CN' ? 'zh-cn' : 'en');
dayjs.extend(relativeTime);
dayjs.extend(localizedFormat);

export default {
name: "ReposItem",
props: {
// visible: { type: Boolean, default: false },
data: { type: Object, default: () => ({}) },
},
components: {},
data() {
return {
aaa: false,
contributors: [],
};
},
methods: {
calcFromNow(unix) {
return dayjs(unix * 1000).fromNow();
},
dateFormat(unix) {
return lang == 'zh-CN' ? dayjs(unix * 1000).format('YYYY年MM月DD日 hh时mm分ss秒') :
dayjs(unix * 1000).format('ddd, D MMM YYYY hh:mm:ss [CST]');
}
},
mounted() {
},
};
</script>
<style scoped lang="less">
.item {
width: 100%;
border-color: rgba(157, 197, 226, 0.4);
border-width: 1px;
border-style: solid;
box-shadow: rgb(157 197 226 / 20%) 0px 5px 10px 0px;
border-radius: 15px;
font-size: 14px;
padding: 20px 26px 10px 26px;
margin-bottom: 40px;
}

.item-top {
display: flex;
}

.item-top .avatar {
width: 38px;
height: 38px;
margin-right: 10px;
}

.content {
flex: 1;
overflow: hidden;
}

.content .title {
display: flex;
align-items: center;
height: 30px;
margin: 4px 0 8px;
}

.content .title-l {
flex: 1;
overflow: hidden;
width: 100%;
text-overflow: ellipsis;
white-space: nowrap;
}

.content .title-1 {
font-size: 18px;
color: rgba(16, 16, 16, 0.6);
}

.content .title-2 {
font-size: 18px;
color: rgba(16, 16, 16, 1);
font-weight: bold;
}

.content .title-r {
width: 240px;
display: flex;
align-items: center;
font-size: 12px;
font-weight: bold;
color: rgb(26, 40, 51, 0.9);
justify-content: flex-end;
}

.content .t-item {
margin-left: 12px;
display: flex;
align-items: center;
}

.content .t-item i {
margin-right: 4px;
}

.content .descr {
font-size: 14px;
color: rgba(16, 16, 16, 0.8);
margin-bottom: 12px;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 6;
max-height: 120px;
white-space: break-spaces;
}

.content .tags {
margin-bottom: 16px;
}

.content .tag {
color: rgba(16, 16, 16, 0.8);
border-radius: 4px;
font-size: 14px;
background: rgba(232, 232, 232, 0.6);
padding: 2px 6px;
margin-right: 8px;
}

.content .repo-datas {
display: flex;
align-items: center;
margin: 24px 0;
}

.content .repo-datas-item {
display: flex;
align-items: center;
margin-right: 24px;
}

.content .repo-datas-item i {
color: rgba(2, 107, 251, 0.54);
margin-right: 4px;
font-size: 16px;
}

.content .repo-datas-item .label {
color: rgba(2, 107, 251, 0.54);
margin-right: 4px;
}

.content .repo-datas-item .value {
font-weight: bold;
}

.item-bottom {
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px solid rgba(157, 197, 226, 0.2);
padding-top: 10px;
font-size: 12px;
color: rgba(16, 16, 16, 0.6);
}

.item-bottom .contributors {
display: flex;
align-items: center;
}

.item-bottom .contributors-avatar {
display: flex;
align-items: center;
margin-left: 16px;
}

.item-bottom .avatar {
width: 25px;
height: 25px;
margin-left: -6px;
border-radius: 100%;
border: 1px solid white;
}
</style>

+ 94
- 0
web_src/vuepages/pages/repos/components/ReposList.vue View File

@@ -0,0 +1,94 @@
<template>
<div class="list-container">
<div>
<div class="repos-item-container" v-for="(item, index) in list" :key="item.ID">
<ReposItem :data="item"></ReposItem>
</div>
</div>
<div class="center">
<el-pagination background @current-change="currentChange" @size-change="sizeChange" :current-page="page"
:page-sizes="pageSizes" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
</div>
</template>

<script>
import ReposItem from '../components/ReposItem.vue';
import { getReposListData } from '~/apis/modules/repos';

export default {
name: "ReposList",
props: {
q: { type: String, default: '' },
sort: { type: String, default: 'mostpopular' },
topic: { type: String, default: '' },
},
components: { ReposItem },
data() {
return {
list: [],
pageSizes: [15, 30, 50],
pageSize: 15,
page: 1,
total: 0,
};
},
methods: {
getListData() {
getReposListData({
q: this.q || '',
topic: this.topic || '',
sort: this.sort || 'mostpopular',
pageSize: this.pageSize || 15,
page: this.page || 1,
}).then(res => {
res = res.data;
if (res.Code == 0) {
this.list = res.Data.Repos || [];
this.total = res.Data.Total;
this.$nextTick(() => {
if (typeof LetterAvatar != undefined) {
LetterAvatar && LetterAvatar.transform();
}
});
}
}).catch(err => {
console.log(err);
});
},
currentChange(page) {
this.page = page;
this.getListData();
},
sizeChange(pageSize) {
this.pageSize = pageSize;
this.getListData();
}
},
watch: {
q(nVal, oVal) {
this.getListData();
},
topic(nVal, oVal) {
this.getListData();
},
sort: {
handler(nVal, oVal) {
this.getListData();
},
immediate: true,
},
},
mounted() { },
};
</script>
<style scoped lang="less">
.list-container {}

.repos-item-container {}

.center {
text-align: center;
}
</style>

+ 155
- 0
web_src/vuepages/pages/repos/components/SearchBar.vue View File

@@ -0,0 +1,155 @@
<template>
<div>
<div class="_repo_search">
<div class="_repo_search_input_c">
<div class="_repo_search_input">
<input type="text" v-model="searchInputValue" placeholder="搜项目" />
</div>
<div class="_repo_search_btn">
<svg xmlns="http://www.w3.org/2000/svg"
class="styles__StyledSVGIconPathComponent-sc-16fsqc8-0 kdvdTY svg-icon-path-icon fill" viewBox="0 0 32 32"
width="24" height="24">
<defs data-reactroot="">
<linearGradient id="ilac9fwnydq3lcx1,1,rs,1,f0dwf0xj,ezu9f0dw,f000,00lwrsktrs,rs1bhv8urs" x1="0" x2="100%"
y1="0" y2="0"
gradientTransform="matrix(-0.7069999999999999, -0.707, 0.707, -0.7069999999999999, 16, 38.624)"
gradientUnits="userSpaceOnUse">
<stop stop-color="#c9ffbf" stop-opacity="1" offset="0"></stop>
<stop stop-color="#0ca451" stop-opacity="1" offset="1"></stop>
</linearGradient>
</defs>
<g>
<path fill="url(#ilac9fwnydq3lcx1,1,rs,1,f0dwf0xj,ezu9f0dw,f000,00lwrsktrs,rs1bhv8urs)"
d="M14.667 2.667c6.624 0 12 5.376 12 12s-5.376 12-12 12-12-5.376-12-12 5.376-12 12-12zM14.667 24c5.156 0 9.333-4.177 9.333-9.333 0-5.157-4.177-9.333-9.333-9.333-5.157 0-9.333 4.176-9.333 9.333 0 5.156 4.176 9.333 9.333 9.333zM25.98 24.095l3.772 3.771-1.887 1.887-3.771-3.772 1.885-1.885z">
</path>
</g>
</svg>
<span style="margin-left:10px;">搜索</span>
</div>
</div>
<div class="_repo_search_label">
<a :href="`/explore/repos?q=&topic=${item}&sort=hot`"
:style="{ backgroundColor: topicColors[index % topicColors.length] }" v-for="(item, index) in topics"
:key="index">{{ item }}</a>
</div>
</div>
</div>
</template>
<script>

import { getPromoteData } from '~/apis/modules/common';
// import { CLUSTERS, AI_CENTER, COMPUTER_RESOURCES, ACC_CARD_TYPE } from '~/const';
const COLOR_LIST = [
'rgb(255, 104, 104)',
'rgb(22, 132, 252)',
'rgb(2, 202, 253)',
'rgb(164, 145, 215)',
'rgb(232, 64, 247)',
'rgb(245, 182, 110)',
'rgb(54, 187, 166)',
'rgb(123, 50, 178)'
];
export default {
name: "SearchBar",
props: {
// visible: { type: Boolean, default: false },
},
components: {},
data() {
return {
searchInputValue: '',
topicColors: COLOR_LIST,
topics: [],
};
},
methods: {
xxx() {
}
},
mounted() {
getPromoteData('/repos/recommend_topics').then(res => {
const data = res.data;
try {
const topics = JSON.parse(data);
this.topics = topics;
} catch (err) {
console.log(err);
}
}).catch(err => {
console.log(err);
});
},
};
</script>
<style scoped lang="less">
._repo_search {
margin: 54px 0;
}

._repo_search_input_c {
margin: 0 0 35px;
display: flex;
justify-content: center;
align-items: center;
}

._repo_search_input {
display: flex;
align-items: center;
width: 437px;
height: 41px;
border-color: rgba(47, 9, 69, 0.64);
border-width: 1px;
border-style: solid;
color: rgba(16, 16, 16, 0.5);
border-radius: 20px;
font-size: 14px;
padding: 20px;
text-align: left;
line-height: 20px;
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736765e-17%2C%20-0.9999999999999999%2C%200.008802475794500678%2C%206.123233995736765e-17%2C%201%2C%201.003)%22%3E%3Cstop%20stop-color%3D%22%23eeeade%22%20stop-opacity%3D%220.2%22%20offset%3D%220.76%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23ece0e9%22%20stop-opacity%3D%221%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
}

._repo_search_input input {
width: 100%;
height: 30px;
border: none;
background: transparent;
outline: none;
}

._repo_search_btn {
margin-left: 10px;
width: 110px;
height: 40px;
border-style: none;
border-color: unset;
color: rgb(255, 255, 255);
border-radius: 21px;
font-size: 14px;
text-align: center;
font-weight: normal;
font-style: normal;
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(6.123233995736766e-17%2C%201%2C%20-0.17728531855955676%2C%206.123233995736766e-17%2C%201%2C%200)%22%3E%3Cstop%20stop-color%3D%22%232f0945%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23341a7b%22%20stop-opacity%3D%221%22%20offset%3D%221%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}

._repo_search_label {
display: flex;
justify-content: center;
flex-wrap: wrap;
}

._repo_search_label a {
background-color: rgb(2, 202, 253);
color: rgb(255, 255, 255);
border-radius: 5px;
margin: 0 5px 10px 5px;
padding: 5px 10px;
cursor: pointer;
font-size: 12px;
}
</style>

+ 343
- 0
web_src/vuepages/pages/repos/components/SquareTop.vue View File

@@ -0,0 +1,343 @@
<template>
<div class="ui _repo_container_bg">
<div class="ui container _repo_container _content_container">
<div class="_repo_top_left">
<a :href="bannerData[0] ? bannerData[0].url : ''">
<div class="_repo_top_left_img">
<img :src="bannerData[0] ? bannerData[0].src : ''">
</div>
</a>
</div>
<div class="_repo_top_middle">
<div class="_repo_top_middle_header">
<div class="_repo_top_mid_item" :class="(tabIndex == index) ? '_foucs' : ''" v-for="(item, index) in tabs"
:key="index" @click="changeTab(item, index)">
<i :class="item.icon"></i>
<span>{{ item.label }}</span>
</div>
</div>
<div class="_repo_top_middle_content">
<div class="_repo_top_mid_repo_list">
<div class="swiper-wrapper" id="_repo_top_mid_repo"></div>
<div class="swiper-pagination"></div>
</div>
</div>
</div>
<div class="_repo_top_right">
<a :href="bannerData[1] ? bannerData[1].url : ''">
<div class="_repo_top_right_img">
<img :src="bannerData[1] ? bannerData[1].src : ''">
</div>
</a>
</div>
</div>
</div>
</template>
<script>

import { getPromoteData } from '~/apis/modules/common';
import { getReposSquareTabData } from '~/apis/modules/repos';
// import { CLUSTERS, AI_CENTER, COMPUTER_RESOURCES, ACC_CARD_TYPE } from '~/const';

export default {
name: "SquareTop",
props: {
// visible: { type: Boolean, default: false },
},
components: {},
data() {
return {
swiperHandler: null,
tabIndex: 0,
tabs: [{
key: 'preferred',
icon: 'ri-fire-line',
label: '项目优选',
}, {
key: 'incubation',
icon: 'ri-award-line',
label: '启智孵化管道',
}, {
key: 'hot-paper',
icon: 'ri-file-damage-line',
label: '热门论文项目',
}],
bannerData: [],
};
},
methods: {
initSwiper() {
this.swiperHandler = new Swiper("._repo_top_mid_repo_list", {
slidesPerView: 1,
spaceBetween: 20,
pagination: {
el: "._repo_top_mid_repo_list .swiper-pagination",
clickable: true,
},
autoplay: {
delay: 4500,
disableOnInteraction: false,
},
breakpoints: {
768: {
slidesPerView: 2,
},
1024: {
slidesPerView: 2,
},
1200: {
slidesPerView: 3,
},
},
});
},
renderSwiper(data) {
const swiperEl = document.getElementById("_repo_top_mid_repo");
let html = '';
for (let i = 0, iLen = data.length; i < iLen; i++) {
html += `<div class="swiper-slide">`;
for (let j = i; j < i + 2; j++) {
let dataJ = data[j];
if (dataJ === undefined) break;
html += `<div class="_repo_sw_card">
<div class="_repo_sw_card_title _repo_nowrap"><a href="/${dataJ.OwnerName}/${dataJ.Name}" title="${dataJ.Name}">${dataJ.Name}</a></div>
<div class="_repo_sw_card_descr _repo_nowrap_line_2">${dataJ.Description}</div>
<div class="_repo_sw_card_label _repo_nowrap">`
const topics = dataJ.Topics || [];
for (let k = 0, kLen = topics.length; k < kLen; k++) {
html += `<span><a href="/explore/repos?q=&topic=${topics[k]}&sort=hot">${topics[k]}</a></span>`
}
html += `</div>
</div>`;
}
html += `</div>`;
i++;
}
this.swiperHandler.removeAllSlides();
swiperEl.innerHTML = html;
this.swiperHandler.updateSlides();
this.swiperHandler.updateProgress();
},
getBannerData() {
getPromoteData('/repos/square_banner').then(res => {
const data = res.data;
try {
const list = JSON.parse(data);
this.bannerData = list;
} catch (err) {
console.log(err);
}
}).catch(err => {
console.log(err);
});
},
getTabData() {
getReposSquareTabData(this.tabs[this.tabIndex].key).then(res => {
res = res.data;
if (res.Code == 0) {
const data = res.Data.Repos || [];
this.renderSwiper(data);
}
}).catch(err => {
console.log(err);
});
},
changeTab(item, index) {
this.tabIndex = index;
this.getTabData();
},
},
mounted() {
this.initSwiper();
this.getBannerData();
this.getTabData();
},
};
</script>
<style scoped lang="less">
._repo_container_bg {
width: 100%;
height: 450px;
background: url("data:image/svg+xml;charset=utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%20version%3D%221.1%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%221%22%20x1%3D%220%22%20x2%3D%221%22%20y1%3D%220%22%20y2%3D%220%22%20gradientTransform%3D%22matrix(0.4999999999999999%2C%20-0.8660000000000001%2C%200.07722000385802469%2C%200.4999999999999999%2C%20-0.183%2C%200.683)%22%3E%3Cstop%20stop-color%3D%22%239aceec%22%20stop-opacity%3D%221%22%20offset%3D%220%22%3E%3C%2Fstop%3E%3Cstop%20stop-color%3D%22%23eeeeee%22%20stop-opacity%3D%221%22%20offset%3D%220.99%22%3E%3C%2Fstop%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20fill%3D%22url(%231)%22%3E%3C%2Frect%3E%3C%2Fsvg%3E");
position: relative;
}

._content_container {
display: flex !important;
margin: 0 auto !important;
height: 100% !important;
}

._repo_top_left {
width: 243px;
height: 100%;
position: relative;
}

._repo_top_left_img {
width: 100%;
height: 346px;
position: absolute;
bottom: 0;
border-top-left-radius: 10px;
overflow: hidden;
}

._repo_top_left_img img {
height: 100%;
width: 100%;
}

._content_container img[src=""],
img:not([src]) {
opacity: 0;
}

._repo_top_right {
width: 243px;
height: 100%;
position: relative;
}

._repo_top_right_img {
width: 100%;
height: 346px;
position: absolute;
bottom: 0;
border-top-right-radius: 10px;
overflow: hidden;
}

._repo_top_right_img img {
height: 100%;
width: 100%;
}

._repo_top_middle {
flex: 1;
height: 100%;
position: relative;

}

._repo_top_middle_header {
width: 100%;
height: 42px;
position: absolute;
bottom: 346px;
display: flex;
align-items: center;
background: raba(0, 0, 255, 0.3);
padding: 0 20px;
}

._repo_top_mid_item {
padding: 0px 16px;
font-size: 18px;
color: rgba(47, 9, 69, 0.64);
height: 100%;
display: flex;
align-items: center;
cursor: pointer;
box-sizing: border-box;
border-bottom: 3px solid transparent;
}

._repo_top_mid_item i {
margin-right: 5px;
}

._repo_top_mid_item._foucs {
background-color: rgba(255, 255, 255, 0.3);
color: rgb(16, 16, 16);
cursor: default;
border-bottom: 3px solid rgba(16, 16, 16, 0.8);
}

._repo_top_middle_content {
width: 100%;
height: 346px;
position: absolute;
bottom: 0;
background: rgba(255, 255, 255, 0.3);
padding: 20px 20px;
overflow: hidden;
}

._repo_top_mid_repo_list {
overflow: hidden;
}

/deep/._repo_sw_card {
height: 128px;
border-color: rgb(255, 255, 255);
border-width: 1px;
border-style: solid;
font-size: 14px;
padding: 10px;
background: rgba(255, 255, 255, 0.6);
margin-bottom: 20px;
box-sizing: border-box;
}

/deep/._repo_nowrap {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

/deep/._repo_nowrap_line_2 {
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
font-size: 12px;
color: rgb(136, 136, 136);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
max-height: 45px;
white-space: break-spaces;
}

/deep/._repo_sw_card a {
color: inherit;
}

/deep/._repo_sw_card_title {
font-weight: 700;
font-size: 16px;
color: rgba(26, 40, 51, 1);
margin-bottom: 10px;
}

/deep/._repo_sw_card_descr {
font-size: 14px;
color: rgba(80, 85, 89, 1);
margin-bottom: 10px;
min-height: 42px;
}

/deep/._repo_sw_card_label {
color: rgb(26, 40, 51);
font-size: 14px;
}

/deep/._repo_sw_card_label span {
border-radius: 4px;
background: rgba(232, 232, 232, 0.6);
padding: 0px 6px 2px;
margin-right: 10px;
}

/deep/._repo_top_mid_repo_list .swiper-pagination-bullet {
width: 8px;
height: 8px;
border-radius: 100%;
background: #76cbed;
}

/deep/._repo_top_mid_repo_list .swiper-pagination-bullet-active {
width: 40px;
border-radius: 4px;
}
</style>

+ 59
- 0
web_src/vuepages/pages/repos/search/index.vue View File

@@ -0,0 +1,59 @@
<template>
<div>
search
</div>
</template>

<script>

// import { saveLocalModel, getModelInfoByName, modifyModel } from '~/apis/modules/modelmanage';
import { getUrlSearchParams } from '~/utils';
// import { MODEL_ENGINES } from '~/const'

export default {
data() {
return {
type: '0', // 1-修改,其它-新增
loading: false,
state: {
type: 0,
name: '',
version: '0.0.1',
engine: '0',
label: '',
description: '',
},
nameErr: false,
isShowVersion: false,
};
},
components: {},
methods: {
checkName() {
this.nameErr = !this.state.name;
return !this.nameErr;
},
submit() {

},
cancel() {

},
goDetail() {

}
},
mounted() {
const urlParams = getUrlSearchParams();
if (urlParams.type == '1' && urlParams.name && urlParams.id) {

}
},
beforeDestroy() {
},
};
</script>

<style scoped lang="less">

</style>

+ 17
- 0
web_src/vuepages/pages/repos/search/vp-repos-search.js View File

@@ -0,0 +1,17 @@
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import localeEn from 'element-ui/lib/locale/lang/en';
import localeZh from 'element-ui/lib/locale/lang/zh-CN';
import { i18n, lang } from '~/langs';
import App from './index.vue';

Vue.use(ElementUI, {
locale: lang === 'zh-CN' ? localeZh : localeEn,
size: 'small',
});

new Vue({
i18n,
render: (h) => h(App),
}).$mount('#__vue-root');

+ 86
- 0
web_src/vuepages/pages/repos/square/index.vue View File

@@ -0,0 +1,86 @@
<template>
<div>
<div>
<SquareTop></SquareTop>
</div>
<div class="ui container">
<SearchBar></SearchBar>
</div>
<div class="recommend-repos-c">
<RecommendRepos></RecommendRepos>
</div>
<div class="ui container">
<div class="ui grid">
<div class="computer only ui two wide computer column">
<ReposFilters @change="changeFilters"></ReposFilters>
</div>
<div class="ui sixteen wide mobile twelve wide tablet ten wide computer column">
<ReposList :sort="reposListSortType" :q="reposListQurey"></ReposList>
</div>
<div class="computer only ui four wide computer column">
<div>
<ActiveUsers></ActiveUsers>
</div>
<div class="active-org-c">
<ActiveOrgs></ActiveOrgs>
</div>
</div>
</div>
</div>
</div>
</template>

<script>

import SquareTop from '../components/SquareTop.vue';
import SearchBar from '../components/SearchBar.vue';
import RecommendRepos from '../components/RecommendRepos.vue';
import ReposFilters from '../components/ReposFilters.vue';
import ReposList from '../components/ReposList.vue';
import ActiveUsers from '../components/ActiveUsers.vue';
import ActiveOrgs from '../components/ActiveOrgs.vue';

// import { saveLocalModel, getModelInfoByName, modifyModel } from '~/apis/modules/modelmanage';
import { getUrlSearchParams } from '~/utils';

export default {
data() {
return {
reposListSortType: 'mostpopular',
reposListQurey: '',
};
},
components: {
SquareTop,
SearchBar,
RecommendRepos,
ReposFilters,
ReposList,
ActiveUsers,
ActiveOrgs,
},
methods: {
changeFilters(condition) {
this.reposListSortType = condition.key;
}
},
mounted() {
const urlParams = getUrlSearchParams();
if (urlParams.type == '1' && urlParams.name && urlParams.id) {

}
},
beforeDestroy() {
},
};
</script>

<style scoped lang="less">
.recommend-repos-c {
margin: 0 0 54px;
}

.active-org-c {
margin-top: 32px;
}
</style>

+ 17
- 0
web_src/vuepages/pages/repos/square/vp-repos-square.js View File

@@ -0,0 +1,17 @@
import Vue from 'vue';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import localeEn from 'element-ui/lib/locale/lang/en';
import localeZh from 'element-ui/lib/locale/lang/zh-CN';
import { i18n, lang } from '~/langs';
import App from './index.vue';

Vue.use(ElementUI, {
locale: lang === 'zh-CN' ? localeZh : localeEn,
size: 'small',
});

new Vue({
i18n,
render: (h) => h(App),
}).$mount('#__vue-root');

Loading…
Cancel
Save