@@ -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}} | |||
@@ -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}} | |||
@@ -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}} | |||
@@ -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}} | |||
@@ -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"> | |||
@@ -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" .}} |
@@ -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" .}} |
@@ -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> <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> | |||
@@ -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"; | |||
@@ -0,0 +1,12 @@ | |||
import service from '../service'; | |||
// 获取promote配置数据 | |||
export const getPromoteData = (filePathName) => { | |||
return service({ | |||
url: '/dashboard/invitation', | |||
method: 'get', | |||
params: { | |||
filename: filePathName | |||
}, | |||
}); | |||
} |
@@ -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: {}, | |||
}); | |||
} |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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> |
@@ -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'); |
@@ -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> |
@@ -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'); |