| @@ -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'); | |||