初始化 ui.
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
<template>
|
||||
<a-card class="general-card" :title="$t('userInfo.title.latestActivity')">
|
||||
<template #extra>
|
||||
<a-link>{{ $t('userInfo.viewAll') }}</a-link>
|
||||
</template>
|
||||
<a-list :bordered="false">
|
||||
<a-list-item
|
||||
v-for="activity in activityList"
|
||||
:key="activity.id"
|
||||
action-layout="horizontal"
|
||||
>
|
||||
<a-skeleton
|
||||
v-if="loading"
|
||||
:loading="loading"
|
||||
:animation="true"
|
||||
class="skeleton-item"
|
||||
>
|
||||
<a-row :gutter="6">
|
||||
<a-col :span="2">
|
||||
<a-skeleton-shape shape="circle" />
|
||||
</a-col>
|
||||
<a-col :span="22">
|
||||
<a-skeleton-line :widths="['40%', '100%']" :rows="2" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-skeleton>
|
||||
<a-list-item-meta
|
||||
v-else
|
||||
:title="activity.title"
|
||||
:description="activity.description"
|
||||
>
|
||||
<template #avatar>
|
||||
<a-avatar>
|
||||
<img :src="activity.avatar" />
|
||||
</a-avatar>
|
||||
</template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { queryLatestActivity, LatestActivity } from '@/api/user-center';
|
||||
import useLoading from '@/hooks/loading';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
const activityList = ref<LatestActivity[]>(new Array(7).fill({}));
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const { data } = await queryLatestActivity();
|
||||
activityList.value = data;
|
||||
} catch (err) {
|
||||
// you can report use errorHandler or other
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
fetchData();
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.latest-activity {
|
||||
&-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
}
|
||||
.general-card :deep(.arco-list-item) {
|
||||
padding-left: 0;
|
||||
border-bottom: none;
|
||||
.arco-list-item-meta-content {
|
||||
flex: 1;
|
||||
padding-bottom: 27px;
|
||||
border-bottom: 1px solid var(--color-neutral-3);
|
||||
}
|
||||
.arco-list-item-meta-avatar {
|
||||
padding-bottom: 27px;
|
||||
}
|
||||
.skeleton-item {
|
||||
margin-top: 10px;
|
||||
padding-bottom: 20px;
|
||||
border-bottom: 1px solid var(--color-neutral-3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +0,0 @@
|
||||
<template>
|
||||
<a-card class="general-card" :title="$t('userInfo.title.latestNotification')">
|
||||
<a-skeleton v-if="loading" :animation="true">
|
||||
<a-skeleton-line :rows="3" />
|
||||
</a-skeleton>
|
||||
<a-result v-else status="404">
|
||||
<template #subtitle>
|
||||
{{ $t('userInfo.nodata') }}
|
||||
</template>
|
||||
</a-result>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import useLoading from '@/hooks/loading';
|
||||
|
||||
const { loading, setLoading } = useLoading(true);
|
||||
setTimeout(() => {
|
||||
setLoading(false);
|
||||
}, 500);
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
:deep(.arco-result) {
|
||||
padding: 40px 32px 108px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,91 +0,0 @@
|
||||
<template>
|
||||
<a-card class="general-card" :title="$t('userInfo.title.myProject')">
|
||||
<template #extra>
|
||||
<a-link>{{ $t('userInfo.showMore') }}</a-link>
|
||||
</template>
|
||||
<a-row :gutter="16">
|
||||
<a-col
|
||||
v-for="(project, index) in projectList"
|
||||
:key="index"
|
||||
:xs="12"
|
||||
:sm="12"
|
||||
:md="12"
|
||||
:lg="12"
|
||||
:xl="8"
|
||||
:xxl="8"
|
||||
class="my-project-item"
|
||||
>
|
||||
<a-card>
|
||||
<a-skeleton v-if="loading" :loading="loading" :animation="true">
|
||||
<a-skeleton-line :rows="3" />
|
||||
</a-skeleton>
|
||||
<a-space v-else direction="vertical">
|
||||
<a-typography-text bold>{{ project.name }}</a-typography-text>
|
||||
<a-typography-text type="secondary">
|
||||
{{ project.description }}
|
||||
</a-typography-text>
|
||||
<a-space>
|
||||
<a-avatar-group :size="24">
|
||||
{{ project.contributors }}
|
||||
<a-avatar
|
||||
v-for="(contributor, idx) in project.contributors"
|
||||
:key="idx"
|
||||
:size="32"
|
||||
>
|
||||
<img alt="avatar" :src="contributor.avatar" />
|
||||
</a-avatar>
|
||||
</a-avatar-group>
|
||||
<a-typography-text type="secondary">
|
||||
等{{ project.peopleNumber }}人
|
||||
</a-typography-text>
|
||||
</a-space>
|
||||
</a-space>
|
||||
</a-card>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { queryMyProjectList, MyProjectRecord } from '@/api/user-center';
|
||||
import useRequest from '@/hooks/request';
|
||||
|
||||
const defaultValue = Array(6).fill({} as MyProjectRecord);
|
||||
const { loading, response: projectList } = useRequest<MyProjectRecord[]>(
|
||||
queryMyProjectList,
|
||||
defaultValue
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.arco-card-body) {
|
||||
min-height: 128px;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.my-project {
|
||||
&-header {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 18px !important;
|
||||
}
|
||||
|
||||
&-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&-item {
|
||||
// padding-right: 16px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
&:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,64 +0,0 @@
|
||||
<template>
|
||||
<a-card
|
||||
class="general-card"
|
||||
:title="$t('userInfo.tab.title.team')"
|
||||
:header-style="{ paddingBottom: '18px' }"
|
||||
:body-style="{ paddingBottom: '12px' }"
|
||||
>
|
||||
<a-list :bordered="false">
|
||||
<a-list-item
|
||||
v-for="team in teamList"
|
||||
:key="team.id"
|
||||
action-layout="horizontal"
|
||||
>
|
||||
<a-skeleton v-if="loading" :loading="loading" :animation="true">
|
||||
<a-row :gutter="6">
|
||||
<a-col :span="6">
|
||||
<a-skeleton-shape shape="circle" />
|
||||
</a-col>
|
||||
<a-col :span="16">
|
||||
<a-skeleton-line :widths="['100%', '40%']" :rows="2" />
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-skeleton>
|
||||
<a-list-item-meta v-else :title="team.name">
|
||||
<template #avatar>
|
||||
<a-avatar>
|
||||
<img :src="team.avatar" />
|
||||
</a-avatar>
|
||||
</template>
|
||||
<template #description> 共{{ team.peopleNumber }}人 </template>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { queryMyTeamList, MyTeamRecord } from '@/api/user-center';
|
||||
import useRequest from '@/hooks/request';
|
||||
|
||||
const defaultValue: MyTeamRecord[] = new Array(4).fill({});
|
||||
const { loading, response: teamList } = useRequest<MyTeamRecord[]>(
|
||||
queryMyTeamList,
|
||||
defaultValue
|
||||
);
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.general-card {
|
||||
height: 356px;
|
||||
.arco-list-item {
|
||||
height: 72px;
|
||||
padding-left: 0;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px solid var(--color-neutral-3);
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.arco-list-item-meta {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,69 +0,0 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<a-space :size="12" direction="vertical" align="center">
|
||||
<a-avatar :size="64">
|
||||
<template #trigger-icon>
|
||||
<icon-camera />
|
||||
</template>
|
||||
<img :src="userInfo.avatar" />
|
||||
</a-avatar>
|
||||
<a-typography-title :heading="6" style="margin: 0">
|
||||
{{ userInfo.name }}
|
||||
</a-typography-title>
|
||||
<div class="user-msg">
|
||||
<a-space :size="18">
|
||||
<div>
|
||||
<icon-user />
|
||||
<a-typography-text>{{ userInfo.jobName }}</a-typography-text>
|
||||
</div>
|
||||
<div>
|
||||
<icon-home />
|
||||
<a-typography-text>
|
||||
{{ userInfo.organizationName }}
|
||||
</a-typography-text>
|
||||
</div>
|
||||
<div>
|
||||
<icon-location />
|
||||
<a-typography-text>{{ userInfo.locationName }}</a-typography-text>
|
||||
</div>
|
||||
</a-space>
|
||||
</div>
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useUserStore } from '@/store';
|
||||
|
||||
const userInfo = useUserStore();
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 204px;
|
||||
color: var(--gray-10);
|
||||
background: url(//p3-armor.byteimg.com/tos-cn-i-49unhts6dw/41c6b125cc2e27021bf7fcc9a9b1897c.svg~tplv-49unhts6dw-image.image)
|
||||
no-repeat;
|
||||
background-size: cover;
|
||||
border-radius: 4px;
|
||||
|
||||
:deep(.arco-avatar-trigger-icon-button) {
|
||||
color: rgb(var(--arcoblue-6));
|
||||
|
||||
:deep(.arco-icon) {
|
||||
vertical-align: -1px;
|
||||
}
|
||||
}
|
||||
.user-msg {
|
||||
.arco-icon {
|
||||
color: rgb(var(--gray-10));
|
||||
}
|
||||
.arco-typography {
|
||||
margin-left: 6px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<Breadcrumb :items="['menu.user', 'menu.user.info']" />
|
||||
<UserInfoHeader />
|
||||
<div class="content">
|
||||
<div class="content-left">
|
||||
<a-grid :cols="24" :col-gap="16" :row-gap="16">
|
||||
<a-grid-item :span="24">
|
||||
<MyProject />
|
||||
</a-grid-item>
|
||||
<a-grid-item :span="24">
|
||||
<LatestActivity />
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
</div>
|
||||
<div class="content-right">
|
||||
<a-grid :cols="24" :row-gap="16">
|
||||
<a-grid-item :span="24">
|
||||
<MyTeam />
|
||||
</a-grid-item>
|
||||
<a-grid-item class="panel" :span="24">
|
||||
<LatestNotification />
|
||||
</a-grid-item>
|
||||
</a-grid>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import UserInfoHeader from './components/user-info-header.vue';
|
||||
import LatestNotification from './components/latest-notification.vue';
|
||||
import MyProject from './components/my-project.vue';
|
||||
import LatestActivity from './components/latest-activity.vue';
|
||||
import MyTeam from './components/my-team.vue';
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Info',
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.container {
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
margin-top: 12px;
|
||||
|
||||
&-left {
|
||||
flex: 1;
|
||||
margin-right: 16px;
|
||||
overflow: hidden;
|
||||
// background-color: var(--color-bg-2);
|
||||
|
||||
:deep(.arco-tabs-nav-tab) {
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&-right {
|
||||
width: 332px;
|
||||
}
|
||||
|
||||
.tab-pane-wrapper {
|
||||
padding: 0 16px 16px 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.mobile {
|
||||
.content {
|
||||
display: block;
|
||||
&-left {
|
||||
margin-right: 0;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
&-right {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +0,0 @@
|
||||
export default {
|
||||
'menu.user.info': 'User Info',
|
||||
'userInfo.editUserInfo': 'Edit Info',
|
||||
'userInfo.tab.title.overview': 'Overview',
|
||||
'userInfo.tab.title.project': 'Project',
|
||||
'userInfo.tab.title.team': 'My Team',
|
||||
'userInfo.title.latestActivity': 'Latest Activity',
|
||||
'userInfo.title.latestNotification': 'In-site Notification',
|
||||
'userInfo.title.myProject': 'My Project',
|
||||
'userInfo.showMore': 'Show More',
|
||||
'userInfo.viewAll': 'View All',
|
||||
'userInfo.nodata': 'No Data',
|
||||
'userInfo.visits.unit': 'times',
|
||||
'userInfo.visits.lastMonth': 'Last Month',
|
||||
};
|
||||
@@ -1,15 +0,0 @@
|
||||
export default {
|
||||
'menu.user.info': '用户信息',
|
||||
'userInfo.editUserInfo': '编辑信息',
|
||||
'userInfo.tab.title.overview': '总览',
|
||||
'userInfo.tab.title.project': '项目',
|
||||
'userInfo.tab.title.team': '我的团队',
|
||||
'userInfo.title.latestActivity': '最新动态',
|
||||
'userInfo.title.latestNotification': '站内通知',
|
||||
'userInfo.title.myProject': '我的项目',
|
||||
'userInfo.showMore': '查看更多',
|
||||
'userInfo.viewAll': '查看全部',
|
||||
'userInfo.nodata': '暂无数据',
|
||||
'userInfo.visits.unit': '人次',
|
||||
'userInfo.visits.lastMonth': '较上月',
|
||||
};
|
||||
@@ -1,162 +0,0 @@
|
||||
import Mock from 'mockjs';
|
||||
import setupMock, { successResponseWrap } from '@/utils/setup-mock';
|
||||
|
||||
setupMock({
|
||||
setup() {
|
||||
// 最新项目
|
||||
Mock.mock(new RegExp('/api/user/my-project/list'), () => {
|
||||
const contributors = [
|
||||
{
|
||||
name: '秦臻宇',
|
||||
email: 'qingzhenyu@arco.design',
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp',
|
||||
},
|
||||
{
|
||||
name: '于涛',
|
||||
email: 'yuebao@arco.design',
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp',
|
||||
},
|
||||
{
|
||||
name: '宁波',
|
||||
email: 'ningbo@arco.design',
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp',
|
||||
},
|
||||
{
|
||||
name: '郑曦月',
|
||||
email: 'zhengxiyue@arco.design',
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/8361eeb82904210b4f55fab888fe8416.png~tplv-uwbnlip3yd-webp.webp',
|
||||
},
|
||||
{
|
||||
name: '宁波',
|
||||
email: 'ningbo@arco.design',
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp',
|
||||
},
|
||||
];
|
||||
const units = [
|
||||
{
|
||||
name: '企业级产品设计系统',
|
||||
description: 'Arco Design System',
|
||||
},
|
||||
{
|
||||
name: '火山引擎智能应用',
|
||||
description: 'The Volcano Engine',
|
||||
},
|
||||
{
|
||||
name: 'OCR文本识别',
|
||||
description: 'OCR text recognition',
|
||||
},
|
||||
{
|
||||
name: '内容资源管理',
|
||||
description: 'Content resource management ',
|
||||
},
|
||||
{
|
||||
name: '今日头条内容管理',
|
||||
description: 'Toutiao content management',
|
||||
},
|
||||
{
|
||||
name: '智能机器人',
|
||||
description: 'Intelligent Robot Project',
|
||||
},
|
||||
];
|
||||
return successResponseWrap(
|
||||
new Array(6).fill(null).map((_item, index) => ({
|
||||
id: index,
|
||||
name: units[index].name,
|
||||
description: units[index].description,
|
||||
peopleNumber: Mock.Random.natural(10, 1000),
|
||||
contributors,
|
||||
}))
|
||||
);
|
||||
});
|
||||
|
||||
// 最新动态
|
||||
Mock.mock(new RegExp('/api/user/latest-activity'), () => {
|
||||
return successResponseWrap(
|
||||
new Array(7).fill(null).map((_item, index) => ({
|
||||
id: index,
|
||||
title: '发布了项目 Arco Design System',
|
||||
description: '企业级产品设计系统',
|
||||
avatar:
|
||||
'//lf1-xgcdn-tos.pstatp.com/obj/vcloud/vadmin/start.8e0e4855ee346a46ccff8ff3e24db27b.png',
|
||||
}))
|
||||
);
|
||||
});
|
||||
|
||||
// 访问量
|
||||
Mock.mock(new RegExp('/api/user/visits'), () => {
|
||||
return successResponseWrap([
|
||||
{
|
||||
name: '主页访问量',
|
||||
visits: 5670,
|
||||
growth: 206.32,
|
||||
},
|
||||
{
|
||||
name: '项目访问量',
|
||||
visits: 5670,
|
||||
growth: 206.32,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
// 项目和团队列表
|
||||
Mock.mock(new RegExp('/api/user/project-and-team/list'), () => {
|
||||
return successResponseWrap([
|
||||
{
|
||||
id: 1,
|
||||
content: '他创建的项目',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
content: '他参与的项目',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
content: '他创建的团队',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
content: '他加入的团队',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
// 团队列表
|
||||
Mock.mock(new RegExp('/api/user/my-team/list'), () => {
|
||||
return successResponseWrap([
|
||||
{
|
||||
id: 1,
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/a8c8cdb109cb051163646151a4a5083b.png~tplv-uwbnlip3yd-webp.webp',
|
||||
name: '火山引擎智能应用团队',
|
||||
peopleNumber: Mock.Random.natural(10, 100),
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp',
|
||||
name: '企业级产品设计团队',
|
||||
peopleNumber: Mock.Random.natural(5000, 6000),
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/3ee5f13fb09879ecb5185e440cef6eb9.png~tplv-uwbnlip3yd-webp.webp',
|
||||
name: '前端/UE小分队',
|
||||
peopleNumber: Mock.Random.natural(10, 5000),
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
avatar:
|
||||
'//p1-arco.byteimg.com/tos-cn-i-uwbnlip3yd/8361eeb82904210b4f55fab888fe8416.png~tplv-uwbnlip3yd-webp.webp',
|
||||
name: '内容识别插件小分队',
|
||||
peopleNumber: Mock.Random.natural(10, 100),
|
||||
},
|
||||
]);
|
||||
});
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user