diff --git a/.env.production b/.env.production index 418dc12b34809c827258bdb970ef0bd5940dcf12..a35287ba3f72332178b95e0c81599902834a8075 100644 --- a/.env.production +++ b/.env.production @@ -1,3 +1,4 @@ VITE_LOGIN_URL = https://id.openeuler.org VITE_XSRF_COOKIE_NAME = '_U_T_' -VITE_XSRF_HEADER_NAME = 'Token' \ No newline at end of file +VITE_XSRF_HEADER_NAME = 'Token' +VITE_COOKIE_DOMAIN = .openeuler.org \ No newline at end of file diff --git a/components.d.ts b/components.d.ts index 297264da157ff7cb5866141243d34880260b2e80..d8e78a008cfbb991fe65adc8dfee06eed282493c 100644 --- a/components.d.ts +++ b/components.d.ts @@ -17,6 +17,7 @@ declare module 'vue' { AppPagination: typeof import('./src/components/AppPagination.vue')['default'] AppSection: typeof import('./src/components/AppSection.vue')['default'] AppTableToggle: typeof import('./src/components/AppTableToggle.vue')['default'] + CBreadcrumb: typeof import('./src/components/collaboration/CBreadcrumb.vue')['default'] ContentWrapper: typeof import('./src/components/ContentWrapper.vue')['default'] DetailAside: typeof import('./src/components/detail/DetailAside.vue')['default'] DetailBasicInfo: typeof import('./src/components/detail/DetailBasicInfo.vue')['default'] @@ -29,6 +30,8 @@ declare module 'vue' { ExternalLink: typeof import('./src/components/ExternalLink.vue')['default'] FeedbackHistory: typeof import('./src/components/feedbackHistory/FeedbackHistory.vue')['default'] FeedbackHistoryItem: typeof import('./src/components/feedbackHistory/FeedbackHistoryItem.vue')['default'] + FeedbackHistroy: typeof import('./src/components/collaboration/FeedbackHistroy.vue')['default'] + FilterableCheckboxes: typeof import('./src/components/FilterableCheckboxes.vue')['default'] FilterCheckbox: typeof import('./src/components/filter/FilterCheckbox.vue')['default'] FilterHeader: typeof import('./src/components/filter/FilterHeader.vue')['default'] FilterItemSkeleton: typeof import('./src/components/skeleton/FilterItemSkeleton.vue')['default'] @@ -37,11 +40,13 @@ declare module 'vue' { HeaderNav: typeof import('./src/components/header/HeaderNav.vue')['default'] HeaderTheme: typeof import('./src/components/header/HeaderTheme.vue')['default'] HomeSkeleton: typeof import('./src/components/skeleton/HomeSkeleton.vue')['default'] + Indicators: typeof import('./src/components/collaboration/Indicators.vue')['default'] OCardItem: typeof import('./src/components/OCardItem.vue')['default'] OCardItemSkeleton: typeof import('./src/components/skeleton/OCardItemSkeleton.vue')['default'] OCodeCopy: typeof import('./src/components/OCodeCopy.vue')['default'] OCodeDown: typeof import('./src/components/OCodeDown.vue')['default'] OTableItemNew: typeof import('./src/components/OTableItemNew.vue')['default'] + Result404: typeof import('./src/components/Result404.vue')['default'] ResultNoApp: typeof import('./src/components/ResultNoApp.vue')['default'] ResultNotFound: typeof import('./src/components/ResultNotFound.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] @@ -49,8 +54,7 @@ declare module 'vue' { SearchFilter: typeof import('./src/components/search/SearchFilter.vue')['default'] SearchRecommend: typeof import('./src/components/search/SearchRecommend.vue')['default'] SearchTab: typeof import('./src/components/search/SearchTab.vue')['default'] - } - export interface ComponentCustomProperties { - vLoading: typeof import('element-plus/es')['ElLoadingDirective'] + StatusFeedback: typeof import('./src/components/collaboration/StatusFeedback.vue')['default'] + TableShowOverflowTips: typeof import('./src/components/collaboration/TableShowOverflowTips.vue')['default'] } } diff --git a/src/@types/collaboration.ts b/src/@types/collaboration.ts new file mode 100644 index 0000000000000000000000000000000000000000..a083e11b766728185fd3117314d1bd76160dcf07 --- /dev/null +++ b/src/@types/collaboration.ts @@ -0,0 +1,23 @@ +export interface CollaborationT { + name?: string; + pageSize?: number; + pageNum?: number; +} + +export interface AdminAppryT extends CollaborationT { + applyId?: string | number; + applyIdString?: string; + applyStatus?: string; + repo?: string; + metric?: string; + timeOrder?: string; +} + +export interface CollaborationRepoT { + pageNum: number; + pageSize: number; + repo?: string; + kind?: string; + sigName?: string; + status?: string; +} diff --git a/src/@types/type-user.ts b/src/@types/type-user.ts index b36272651fbaf29fc04dffc7cf763af957e8b7f3..f7459da71107b24cc7d78f1457d54e5be0da6abb 100644 --- a/src/@types/type-user.ts +++ b/src/@types/type-user.ts @@ -1,4 +1,18 @@ +export interface Identity { + login_name: string, + userIdInIdp: string, + identity: string, // 第三方平台类型,gitee/github + user_name: string, + accessToken: string +} + +// 用户账号数据类型 export interface UserInfoT { photo: string; // 头像 username: string; // 用户名 + email: string; // 邮箱 + phoneCountryCode: string, // 区号 + phone: string, // 手机号 + identities: Identity[]; // 绑定的第三方平台账号 + recipientId?: number; // 接收人id } \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 20e9bf464df168f9cf9db44c64faf7db888377b9..ecbacfc55452082cb8cac4180ef9e25c2c5c98eb 100644 --- a/src/App.vue +++ b/src/App.vue @@ -74,7 +74,7 @@ initSensor(); --layout-screen-height: 100vh; - --layout-content-min-height: calc(var(--layout-screen-height) - var(--layout-header-height)); + --layout-content-min-height: calc(var(--layout-screen-height) - var(--layout-header-height) - var(--layout-footer-height)); @include respond-to('<=laptop') { --layout-header-max-width: 100%; diff --git a/src/api/api-collaboration.ts b/src/api/api-collaboration.ts new file mode 100644 index 0000000000000000000000000000000000000000..6439f63a5bd8228030bba521617900c1c4d6803e --- /dev/null +++ b/src/api/api-collaboration.ts @@ -0,0 +1,96 @@ +import { request } from '@/shared/axios'; +import type { AxiosResponse } from '@/shared/axios'; +import type { AdminAppryT, CollaborationRepoT } from '@/@types/collaboration'; + +// 权限 +export function getCollaborationPermissions() { + const url = `/server/collaboration/maintainer/permissions`; + return request.get(url).then((res: AxiosResponse) => res?.data); +} + +// 软件维护详情 maintainer +export function getMaintainerRepos(params: CollaborationRepoT) { + const url = `/server/collaboration/maintainer/user/repos`; + return request.get(url, { params }).then((res: AxiosResponse) => res?.data); +} + +// 软件维护详情 admin +export function getAdminRepos(params: CollaborationRepoT) { + const url = `/server/collaboration/admin/user/repos`; + return request.get(url, { params }).then((res: AxiosResponse) => res?.data); +} + +/** + * 获取sig列表 + */ +export function getSigList() { + const url = `/api-dsapi/query/sig/name?community=openeuler`; + return request.get<{ data: Record<'openeuler', string[]> }>(url).then((res) => res.data.data.openeuler); +} + +/** + * 获取仓库列表 + */ +export function getRepoList() { + const url = `/api-dsapi/query/repo/sig/list?community=openeuler`; + return request.get<{ data: Record[] }>(url).then((res) => res.data.data.map((item) => Object.keys(item)[0])); +} + +// 待我审批 +export function getAdminApply(params: AdminAppryT) { + const url = `/server/collaboration/admin/query/apply`; + return request.get(url, { params }).then((res: AxiosResponse) => res?.data); +} + + +// 我的申请 +export function getMaintainerApply(params: AdminAppryT) { + const url = `/server/collaboration/maintainer/query/apply`; + return request.get(url, { params }).then((res: AxiosResponse) => res?.data); +} + +// 申请撤销 +interface RevokeT { + applyIdString: string; + applyStatus: string; +} +export function getMaintainerRevoke(params: RevokeT) { + const url = `/server/collaboration/maintainer/revoke`; + return request.post(url, { ...params }).then((res: AxiosResponse) => res?.data); +} + +/** 待办中心获取我的申请所有仓库 */ +export function getMaintainerApplyRepos() { + const url = `/server/collaboration/maintainer/apply/repos`; + return request.get<{ data: { total: number, list: string[] } }>(url).then((res) => res?.data.data); +} + +/** 待办中心获取待我审批/我审批过所有仓库 */ +export function getAdminApplyRepos() { + const url = `/server/collaboration/admin/apply/repos`; + return request.get<{ data: { total: number, list: string[] } }>(url).then((res) => res?.data.data); +} + +interface FeedbackT { + repo: string; + metric: string; + metricStatus: string; + description: string; + applyStatus: string; +} + +export function getApplyFeedback(params: FeedbackT) { + const url = `/server/collaboration/maintainer/apply?repo=${params.repo}`; + return request.post(url, { ...params }).then((res: AxiosResponse) => res?.data); +} + +interface ProcessT { + applyIdString: string; + comment: string; + applyStatus: string; +} + +export function getAdminProcess(params: ProcessT) { + const url = `/server/collaboration/admin/process`; + return request.post(url, { ...params }).then((res: AxiosResponse) => res?.data); +} diff --git a/src/api/api-user.ts b/src/api/api-user.ts index d13bb80b971ea9b6a7a5d7009aa4bd6c816b8675..7744af2e23cb3d0e9393d8f4f25150e43e17ba78 100644 --- a/src/api/api-user.ts +++ b/src/api/api-user.ts @@ -1,7 +1,6 @@ import type { ResponseT } from '@/@types/response'; import type { UserInfoT } from '@/@types/type-user'; import { request } from '@/shared/axios'; -import { getCsrfToken } from '@/shared/login'; interface UserPermissionResponseT { msg: string; @@ -14,16 +13,9 @@ interface UserPermissionResponseT { * @param community community字段,默认openeuler * @returns {Promise} 用户信息 */ -export function queryUserInfo(community = 'openeuler') { - const url = '/api-id/oneid/user/permission'; - const token = getCsrfToken(); - return request - .get(url, { - params: { community }, - global: true, - headers: { token }, - }) - .then((res) => res.data.data); +export function queryUserInfo() { + const url = '/api-id/oneid/personal/center/user?community=openeuler'; + return request.get(url).then((res) => res.data.data); } /** diff --git a/src/assets/default-logo-cover_dark.png b/src/assets/default-logo-cover_dark.png index 9bee7eb9174e5ffbb508b1edafc32f2fbcd9a33c..0d482aa1b4be713cf76933ea7dc9f4884fa498bc 100644 Binary files a/src/assets/default-logo-cover_dark.png and b/src/assets/default-logo-cover_dark.png differ diff --git a/src/assets/icon/icon-app-type.svg b/src/assets/icon/icon-app-type.svg index 63eeb0c3995406ebf27583b64cbb3295cc24698a..7e285fd6266f31bfd3c9d40da9e62a32d2795211 100644 --- a/src/assets/icon/icon-app-type.svg +++ b/src/assets/icon/icon-app-type.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/assets/icon/icon-outlink.svg b/src/assets/icon/icon-outlink.svg index b284beaa92f0eb4225f44682980ccfe2854b6e84..1b62f8d6a43ef9dd5e2fa01aee7177255a557ff3 100644 --- a/src/assets/icon/icon-outlink.svg +++ b/src/assets/icon/icon-outlink.svg @@ -1,4 +1,5 @@ - + + diff --git a/src/assets/icon/icon-state.svg b/src/assets/icon/icon-state.svg new file mode 100644 index 0000000000000000000000000000000000000000..a8c5b840468f64afb834b8608d2ac91153184ce4 --- /dev/null +++ b/src/assets/icon/icon-state.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icon/icon-status.svg b/src/assets/icon/icon-status.svg index c171d99f065606df1eae25e844284c5872164778..fb84165d6885c5eacbb17a715593968035b4e955 100644 --- a/src/assets/icon/icon-status.svg +++ b/src/assets/icon/icon-status.svg @@ -1 +1,4 @@ - \ No newline at end of file + + + + diff --git a/src/assets/solution/openhpc/img1-dark.png b/src/assets/solution/openhpc/img1-dark.png index 647c07e3b05223aa3e677b20ee49148d36c3ee34..af819dc1c23ede763a539d474a502118b9d531ca 100644 Binary files a/src/assets/solution/openhpc/img1-dark.png and b/src/assets/solution/openhpc/img1-dark.png differ diff --git a/src/assets/style/category/collaboration/index.scss b/src/assets/style/category/collaboration/index.scss new file mode 100644 index 0000000000000000000000000000000000000000..2337ba2be51a94de1315c0a1deaf0ca328a1e1cd --- /dev/null +++ b/src/assets/style/category/collaboration/index.scss @@ -0,0 +1,81 @@ +.repo-status { + :deep(.o-tag) { + --tag-color: var(--o-color-white); + --tag-bd-color: transparent; + min-width: 72px; + + &.type0 { + --tag-bg-color: var(--o-color-success1); + } + &.type1 { + --tag-bg-color: #03b5a5; + } + &.type2 { + --tag-bg-color: #f5cd05; + } + &.type3 { + --tag-bg-color: var(--o-color-warning1); + } + &.type4 { + --tag-bg-color: var(--o-color-danger1); + } + } +} +.indicators { + .repo-status { + :deep(.o-tag) { + min-width: 56px; + border-radius: 2px; + } + } +} + +.apply-status { + :deep(.o-tag) { + min-width: 72px; + color: var(--o-color-white); + &.open { + --tag-bg-color: var(--o-color-warning1); + --tag-bd-color: var(--o-color-warning1); + } + &.approved { + --tag-bg-color: var(--o-color-success1); + --tag-bd-color: var(--o-color-success1); + } + &.revoked { + --tag-bg-color: var(--o-color-control1); + --tag-bd-color: transparent; + } + + &.rejected { + --tag-bg-color: var(--o-color-danger1); + --tag-bd-color: var(--o-color-danger1); + } + } +} + +.bubble-content { + color: var(--o-color-info1); + max-width: 300px; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + line-clamp: 3; + overflow: hidden; + + .title { + font-weight: bold; + } +} + +.header-cell { + position: relative; + display: flex; + align-items: center; + + .filter-icon { + width: 16px; + cursor: pointer; + margin-left: 8px; + } +} diff --git a/src/assets/style/category/content/index.scss b/src/assets/style/category/content/index.scss index e574df736d13392967fe6b6db4956b943ed65140..5281051121df75ef3f29eea2cd5b49b7640309ab 100644 --- a/src/assets/style/category/content/index.scss +++ b/src/assets/style/category/content/index.scss @@ -79,7 +79,7 @@ display: flex; align-items: center; justify-content: flex-end; - margin: 40px 0; + margin: 32px 0; :deep(.el-input) { --el-input-text-color: var(--o-color-info1); } diff --git a/src/assets/style/category/detail/index.scss b/src/assets/style/category/detail/index.scss index 2a29aec58c1b2f50aecf081b933b9eba29dc309d..047f150305f91837a90100a32664315bb936442e 100644 --- a/src/assets/style/category/detail/index.scss +++ b/src/assets/style/category/detail/index.scss @@ -45,7 +45,7 @@ border-top: 1px solid var(--o-color-control4); } .label { - background: var(--o-color-fill3); + background: var(--o-color-control2-light); padding: 16px 24px; color: var(--o-color-info2); min-width: 150px; @@ -129,7 +129,7 @@ } .ver { - background: var(--o-color-fill3); + background: var(--o-color-control2-light); @include text2; border: none; border-radius: var(--layout-pkg-radius); diff --git a/src/assets/style/element-plus/input.scss b/src/assets/style/element-plus/input.scss index 1577222adec4bc135b2e1148b1daca58e8ec95dd..924139752653de437385c5d70b7698206c4d853e 100644 --- a/src/assets/style/element-plus/input.scss +++ b/src/assets/style/element-plus/input.scss @@ -1,4 +1,5 @@ .el-input { + --el-input-text-color: var(--o-color-info2); .el-input__wrapper { box-shadow: none !important; border: 1px solid var(--o-color-control1); diff --git a/src/assets/style/element-plus/pagination.scss b/src/assets/style/element-plus/pagination.scss index a8102f101ff0c04020520593157fbd984566a76c..a7439bf75e13309f3f9fd5c492b5173d8f55d71b 100644 --- a/src/assets/style/element-plus/pagination.scss +++ b/src/assets/style/element-plus/pagination.scss @@ -3,6 +3,9 @@ --el-pagination-button-bg-color: var(--o-color-fill2); --el-disabled-bg-color: var(--o-color-fill2); --el-pagination-button-color: var(--o-color-info1); + .el-pagination__total { + color: var(--o-color-info2); + } .el-pager { li { --el-pagination-button-color: var(--o-color-info1); diff --git a/src/assets/style/global.scss b/src/assets/style/global.scss index e140180983998a785dc0eea536939f18725cd0c6..a30bb9d5431bf5aa51f7a9fa20cfb7e3f58aa2c8 100644 --- a/src/assets/style/global.scss +++ b/src/assets/style/global.scss @@ -25,7 +25,7 @@ html { .o-tag { cursor: pointer; --tag-padding: 2px 4px; - --tag-bd-color: var(--o-color-control3-light); + --tag-bd-color: var(--o-color-control1-light); &.image-icon .o-icon { color: #007af0; } @@ -36,7 +36,7 @@ html { color: #00a7b3; } &:hover { - --tag-bg-color: var(--o-color-control1-light); + --tag-bg-color: var(--o-color-control2-light); } .o-tag-icon { height: 16px; @@ -61,3 +61,34 @@ html { .o-tab-nav-active { font-weight: 500; } + +.o-card-pkg { + .desc { + margin-top: 8px; + color: var(--o-color-info2); + overflow: hidden; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + position: relative; + word-break: break-all; + height: 48px; + --linear-gradient: var(--o-mixedgray-1); + &.dark { + --linear-gradient: var(--o-mixedgray-4); + } + @include text1; + &::after { + background-image: linear-gradient(90deg, rgba(var(--linear-gradient), 0), rgba(var(--linear-gradient), 0.8) 59%, var(--o-color-control-light) 100%); + bottom: 0; + content: ''; + height: 24px; + pointer-events: none; + position: absolute; + right: 0; + width: 4em; + } + span { + color: var(--o-color-primary1); + } + } +} diff --git a/src/assets/style/markdown.scss b/src/assets/style/markdown.scss index 326eb1bcab340998916140731bca2c4458a6af95..22f477c7a767dd7c254c49fed6a19706fd9d9511 100644 --- a/src/assets/style/markdown.scss +++ b/src/assets/style/markdown.scss @@ -47,7 +47,7 @@ } code { border-radius: var(--layout-pkg-radius); - background-color: var(--o-color-fill3); + background-color: var(--o-color-control2-light); margin: 0 4px; } p code:first-child { @@ -57,7 +57,7 @@ pre { position: relative; border-radius: var(--layout-pkg-radius); - background-color: var(--o-color-fill3); + background-color: var(--o-color-control2-light); padding: 0; overflow: hidden; @@ -119,7 +119,7 @@ position: absolute; top: 0; right: 0; - background-color: var(--o-color-fill3); + background-color: var(--o-color-control2-light); opacity: 1; padding: 12px 12px 0 0; .icon-copy { diff --git a/src/assets/style/theme/index.scss b/src/assets/style/theme/index.scss index 3aaaeb1f806d63b2d1801ca76c6d9e9056b81a76..dd6e7269fb267c850b93b442f8025ac3e5c28196 100644 --- a/src/assets/style/theme/index.scss +++ b/src/assets/style/theme/index.scss @@ -11,3 +11,4 @@ @use './popup.scss' as *; @use './tab.scss' as *; @use './rate.scss' as *; +@use './result.scss' as *; diff --git a/src/assets/style/theme/popup.scss b/src/assets/style/theme/popup.scss index d05b39eb82f91cb6d645bae853082a1edd1e9f2e..184129fd94f396c39232dcf17fb2c53894a64a80 100644 --- a/src/assets/style/theme/popup.scss +++ b/src/assets/style/theme/popup.scss @@ -1,3 +1,10 @@ .o-popup { --popup-shadow: var(--o-shadow-2); + .o-popup-wrap { + border: 1px solid var(--o-color-control4); + } + .o-popup-anchor { + border: 1px solid var(--o-color-control1); + border-width: 1px 0 0 1px; + } } diff --git a/src/assets/style/theme/rate.scss b/src/assets/style/theme/rate.scss index aa3c812e43b97716108be71bb02dbe7edceab05d..30ee6f61c561a557eeb931a07d1e38f26eb8aacf 100644 --- a/src/assets/style/theme/rate.scss +++ b/src/assets/style/theme/rate.scss @@ -1,4 +1,4 @@ .o-rate { - --rate-color: var(--o-color-control2); + --rate-color: var(--o-color-info4); --rate-size: 24px; } diff --git a/src/assets/style/theme/result.scss b/src/assets/style/theme/result.scss new file mode 100644 index 0000000000000000000000000000000000000000..274b722f7c7e9749bb99ee3eaac49b3c8bad83c8 --- /dev/null +++ b/src/assets/style/theme/result.scss @@ -0,0 +1,3 @@ +.o-result-content { + color: var(--o-color-info1); +} diff --git a/src/assets/style/theme/select.scss b/src/assets/style/theme/select.scss index 08e58b5a400ea82e6dcd81258557fbc44d25dd20..698f1d06d21c16c2258963ba6a1724abbb2c58ba 100644 --- a/src/assets/style/theme/select.scss +++ b/src/assets/style/theme/select.scss @@ -1,3 +1,4 @@ -.o-select-medium { +.o-select { --select-icon-size: 20px; + --select-radius: 4px; } diff --git a/src/assets/style/theme/table.scss b/src/assets/style/theme/table.scss index 88a4cea0ca4f9114428dbdf877f4bebb73485ee0..6745d7421ada38a06f66a577b4ba159c79db1f70 100644 --- a/src/assets/style/theme/table.scss +++ b/src/assets/style/theme/table.scss @@ -1,4 +1,8 @@ +@use '../mixin/font.scss' as *; .o-table { + --table-edge-padding: 32px; + --table-cell-padding: 16px 20px; + --table-head-cell-padding: 12px 20px; --table-head-bg: var(--o-color-control3-light); --table-color: var(--o-color-info1); th { @@ -14,4 +18,14 @@ td { word-break: break-word; } + &.o-table-small { + --table-cell-height: auto; + --table-cell-padding: 12px 16px; + --table-head-cell-padding: 9px 16px; + --table-edge-padding: 16px; + td, + th { + @include tip1; + } + } } diff --git a/src/assets/svg-icons/icon-outlink.svg b/src/assets/svg-icons/icon-outlink.svg index 1aca2b42223c76de8e1f451b37476e1160a62e96..743500c1fb12afdeeeea257286c30a5ca9594161 100644 --- a/src/assets/svg-icons/icon-outlink.svg +++ b/src/assets/svg-icons/icon-outlink.svg @@ -1,3 +1,4 @@ - + + diff --git a/src/components/AppPagination.vue b/src/components/AppPagination.vue index 1eaa155443a8923958d738c6d891d4a8954d572c..7db948bcb246b28aa11cfab07ba68d3e64d00f25 100644 --- a/src/components/AppPagination.vue +++ b/src/components/AppPagination.vue @@ -46,7 +46,7 @@ onMounted(() => { :current-page="current" :page-size="pagesize" background - layout="sizes, prev, pager, next, jumper" + layout="total ,sizes, prev, pager, next, jumper" :total="total" :page-sizes="isFieldPage ? COUNT_PAGESIZE_FIELD : COUNT_PAGESIZE" @size-change="handleSizeChange" diff --git a/src/components/ExternalLink.vue b/src/components/ExternalLink.vue index 423a70bc703aa6f40a716e85ce343850acf8b415..1a669549848b55ba735a290d656f460d68582c99 100644 --- a/src/components/ExternalLink.vue +++ b/src/components/ExternalLink.vue @@ -29,7 +29,7 @@ const onChange = () => {