Explorar el Código

feat: add account center page (#86)

chen-xt hace 4 años
padre
commit
78d4d41c85

+ 1 - 1
mock/demo/account.ts

@@ -2,7 +2,7 @@ import { MockMethod } from 'vite-plugin-mock';
 import { resultSuccess } from '../_util';
 
 const userInfo = {
-  name: 'Serati Ma',
+  name: 'Vben',
   userid: '00000001',
   email: 'antdesign@alipay.com',
   signature: '海纳百川,有容乃大',

BIN
src/assets/images/demo.png


+ 11 - 0
src/router/menus/modules/demo/page.ts

@@ -1,3 +1,10 @@
+/*
+ * @description: Do not edit
+ * @author: cxiaoting
+ * @Date: 2020-11-13 14:00:37
+ * @LastEditors: cxiaoting
+ * @LastEditTime: 2020-11-13 18:07:11
+ */
 import type { MenuModule } from '/@/router/types.d';
 const menu: MenuModule = {
   orderNo: 20,
@@ -59,6 +66,10 @@ const menu: MenuModule = {
         },
         children: [
           {
+            path: 'center',
+            name: '个人中心',
+          },
+          {
             path: 'setting',
             name: '个人设置',
           },

+ 8 - 0
src/router/routes/modules/demo/page.ts

@@ -127,6 +127,14 @@ const page: AppRouteModule = {
       },
       children: [
         {
+          path: 'center',
+          name: 'AccountCenterPage',
+          component: () => import('/@/views/demo/page/account/center/index.vue'),
+          meta: {
+            title: '个人中心',
+          },
+        },
+        {
           path: 'setting',
           name: 'AccountSettingPage',
           component: () => import('/@/views/demo/page/account/setting/index.vue'),

+ 93 - 0
src/views/demo/page/account/center/Application.vue

@@ -0,0 +1,93 @@
+<template>
+  <List :class="prefixCls">
+    <Row :gutter="16">
+      <template v-for="(item, index) in list" :key="index">
+        <Col :span="6">
+          <ListItem>
+            <Card :hoverable="true" :class="`${prefixCls}__card`">
+              <div :class="`${prefixCls}__card-title`">
+                <Icon class="icon" v-if="item.icon" :icon="item.icon" :color="item.color" />
+                {{ item.title }}
+              </div>
+              <div :class="`${prefixCls}__card-num`">
+                活跃用户:<span>{{ item.active }}</span> 万
+              </div>
+              <div :class="`${prefixCls}__card-num`">
+                新增用户:<span>{{ item.new }}</span>
+              </div>
+              <Icon
+                :class="`${prefixCls}__card-download`"
+                v-if="item.download"
+                :icon="item.download"
+              />
+            </Card>
+          </ListItem>
+        </Col>
+      </template>
+    </Row>
+  </List>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { List, Card, Row, Col } from 'ant-design-vue';
+  import Icon from '/@/components/Icon/index';
+  import { applicationList } from './data';
+
+  export default defineComponent({
+    components: {
+      List,
+      ListItem: List.Item,
+      Card,
+      Row,
+      Col,
+      Icon,
+    },
+    setup() {
+      return {
+        prefixCls: 'account-center-application',
+        list: applicationList,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .account-center-application {
+    &__card {
+      width: 100%;
+
+      /deep/ .ant-card-body {
+        padding: 16px;
+      }
+
+      &-title {
+        margin-bottom: 5px;
+        font-size: 16px;
+        font-weight: 500;
+        color: rgba(0, 0, 0, 0.85);
+
+        .icon {
+          margin-top: -5px;
+          font-size: 22px;
+        }
+      }
+
+      &-num {
+        margin-left: 24px;
+        line-height: 36px;
+        color: #7d7a7a;
+
+        span {
+          margin-left: 5px;
+          font-size: 18px;
+          color: #000;
+        }
+      }
+
+      &-download {
+        float: right;
+        font-size: 20px !important;
+        color: #1890ff;
+      }
+    }
+  }
+</style>

+ 90 - 0
src/views/demo/page/account/center/Article.vue

@@ -0,0 +1,90 @@
+<template>
+  <List item-layout="vertical" :class="prefixCls">
+    <template v-for="(item, index) in list" :key="index">
+      <ListItem>
+        <ListItemMeta>
+          <template #description>
+            <div :class="`${prefixCls}__content`">{{ item.content }}</div>
+          </template>
+          <template #title>
+            <p :class="`${prefixCls}__title`"> {{ item.title }}</p>
+            <div>
+              <template v-for="(tag, index) in item.description" :key="index">
+                <Tag class="mb-2">{{ tag }}</Tag>
+              </template>
+            </div>
+          </template>
+        </ListItemMeta>
+        <div>
+          <template v-for="(action, index) in actions" :key="index">
+            <div :class="`${prefixCls}__action`">
+              <Icon
+                v-if="action.icon"
+                :class="`${prefixCls}__action-icon`"
+                :icon="action.icon"
+                :color="action.color"
+              />
+              {{ action.text }}
+            </div>
+          </template>
+          <span :class="`${prefixCls}__time`">{{ item.time }}</span>
+        </div>
+      </ListItem>
+    </template>
+  </List>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { List, Tag } from 'ant-design-vue';
+  import Icon from '/@/components/Icon/index';
+  import { actions, articleList } from './data';
+
+  export default defineComponent({
+    components: {
+      List,
+      ListItem: List.Item,
+      ListItemMeta: List.Item.Meta,
+      Tag,
+      Icon,
+    },
+    setup() {
+      return {
+        prefixCls: 'account-center-article',
+        list: articleList,
+        actions,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .account-center-article {
+    &__title {
+      margin-bottom: 12px;
+      font-size: 18px;
+    }
+
+    &__content {
+      color: rgba(0, 0, 0, 0.65);
+    }
+
+    &__action {
+      display: inline-block;
+      padding: 0 16px;
+      color: rgba(0, 0, 0, 0.45);
+
+      &:not(:last-child) {
+        border-right: 1px solid rgba(206, 206, 206, 0.4);
+      }
+
+      &-icon {
+        margin-right: 3px;
+      }
+    }
+
+    &__time {
+      position: absolute;
+      right: 20px;
+      color: rgba(0, 0, 0, 0.45);
+    }
+  }
+</style>

+ 69 - 0
src/views/demo/page/account/center/Project.vue

@@ -0,0 +1,69 @@
+<template>
+  <List :class="prefixCls">
+    <Row :gutter="16">
+      <template v-for="(item, index) in list" :key="index">
+        <Col :span="6">
+          <ListItem>
+            <Card :hoverable="true" :class="`${prefixCls}__card`">
+              <img :src="demoImg" />
+              <div :class="`${prefixCls}__card-title`">
+                {{ item.title }}
+              </div>
+              <div :class="`${prefixCls}__card-content`"> {{ item.content }}</div>
+            </Card>
+          </ListItem>
+        </Col>
+      </template>
+    </Row>
+  </List>
+</template>
+<script lang="ts">
+  import { defineComponent } from 'vue';
+  import { List, Card, Row, Col } from 'ant-design-vue';
+  import demoImg from '/@/assets/images/demo.png';
+  import { projectList } from './data';
+
+  export default defineComponent({
+    components: {
+      List,
+      ListItem: List.Item,
+      Card,
+      Row,
+      Col,
+    },
+    setup() {
+      return {
+        prefixCls: 'account-center-project',
+        list: projectList,
+        demoImg,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .account-center-project {
+    &__card {
+      width: 100%;
+
+      /deep/ .ant-card-body {
+        padding: 0 0 24px 0;
+      }
+
+      img {
+        width: 100%;
+        height: 100px;
+      }
+
+      &-title {
+        margin: 5px 10px;
+        font-size: 16px;
+        font-weight: 500;
+        color: rgba(0, 0, 0, 0.85);
+      }
+
+      &-content {
+        margin: 5px 10px;
+      }
+    }
+  }
+</style>

+ 133 - 0
src/views/demo/page/account/center/data.tsx

@@ -0,0 +1,133 @@
+export interface ListItem {
+  title: string;
+  icon: string;
+  color?: string;
+}
+
+export interface TabItem {
+  key: string;
+  name: string;
+  component: string;
+}
+
+export const tags: string[] = [
+  '很有想法的',
+  '专注设计',
+  '川妹子',
+  '大长腿',
+  '海纳百川',
+  '前端开发',
+  'vue3',
+];
+
+export const teams: ListItem[] = [
+  {
+    icon: 'ant-design:alipay-circle-outlined',
+    title: '科学搬砖组',
+    color: '#ff4000',
+  },
+  {
+    icon: 'emojione-monotone:letter-a',
+    title: '中二少年团',
+    color: '#7c51b8',
+  },
+  {
+    icon: 'ant-design:alipay-circle-outlined',
+    title: '高逼格设计',
+    color: '#00adf7',
+  },
+  {
+    icon: 'ant-design:codepen-circle-filled',
+    title: '程序员日常',
+    color: '#00adf7',
+  },
+  {
+    icon: 'ant-design:dribbble-circle-filled',
+    title: '科学搬砖组',
+    color: '#ff4000',
+  },
+  {
+    icon: 'ant-design:behance-square-filled',
+    title: '程序员日常',
+    color: '#7c51b8',
+  },
+];
+
+export const details: ListItem[] = [
+  {
+    icon: 'ant-design:contacts-outlined',
+    title: '交互专家',
+  },
+  {
+    icon: 'ant-design:cluster-outlined',
+    title: '蚂蚁金服-某某某事业群',
+  },
+  {
+    icon: 'ant-design:home-outlined',
+    title: '福建省厦门市',
+  },
+];
+
+export const achieveList: TabItem[] = [
+  {
+    key: '1',
+    name: '文章',
+    component: 'Article',
+  },
+  {
+    key: '2',
+    name: '应用',
+    component: 'Application',
+  },
+  {
+    key: '3',
+    name: '项目',
+    component: 'Project',
+  },
+];
+
+export const actions: any[] = [
+  { icon: 'ant-design:star-outlined', text: '156', color: '#018ffb' },
+  { icon: 'ant-design:like-filled', text: '156', color: '#459ae8' },
+  { icon: 'ant-design:message-filled', text: '2', color: '#42d27d' },
+];
+
+export const articleList = (() => {
+  const result: any[] = [];
+  for (let i = 0; i < 4; i++) {
+    result.push({
+      title: 'Ant Design',
+      description: ['Ant Design', '设计语言', '蚂蚁金服'],
+      content:
+        '段落示意:蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案。蚂蚁金服设计平台 ant.design,用最小的工作量,无缝接入蚂蚁金服生态,提供跨越设计与开发的体验解决方案',
+      time: '2020-11-14 11:20',
+    });
+  }
+  return result;
+})();
+
+export const applicationList = (() => {
+  const result: any[] = [];
+  for (let i = 0; i < 8; i++) {
+    result.push({
+      title: 'Ant Design',
+      icon: 'emojione-monotone:letter-a',
+      color: '#7c51b8',
+      active: '100',
+      new: '1,799',
+      download: 'bx:bx-download',
+    });
+  }
+  return result;
+})();
+
+export const projectList = (() => {
+  const result: any[] = [];
+  for (let i = 0; i < 8; i++) {
+    result.push({
+      title: 'Angular',
+      content: '那是一种内在的东西, 他们到达不了,',
+    });
+  }
+  return result;
+})();

+ 149 - 0
src/views/demo/page/account/center/index.vue

@@ -0,0 +1,149 @@
+<template>
+  <div :class="prefixCls">
+    <Row :class="`${prefixCls}-top`">
+      <Col :span="9" :class="`${prefixCls}-col`">
+        <Row>
+          <Col :span="8">
+            <div :class="`${prefixCls}-top__avatar`">
+              <img width="70" :src="headerImg" />
+              <span>Serati Ma</span>
+              <div>海纳百川,有容乃大</div>
+            </div>
+          </Col>
+          <Col :span="16">
+            <div :class="`${prefixCls}-top__detail`">
+              <template v-for="(detail, index) in details" :key="index">
+                <p>
+                  <Icon :icon="detail.icon" />
+                  {{ detail.title }}
+                </p>
+              </template>
+            </div>
+          </Col>
+        </Row>
+      </Col>
+      <Col :span="7" :class="`${prefixCls}-col`">
+        <CollapseContainer title="标签" :canExpan="false">
+          <template v-for="(tag, index) in tags" :key="index">
+            <Tag class="mb-2">{{ tag }}</Tag>
+          </template>
+        </CollapseContainer>
+      </Col>
+      <Col :span="8" :class="`${prefixCls}-col`">
+        <CollapseContainer :class="`${prefixCls}-top__team`" title="团队" :canExpan="false">
+          <div v-for="(team, index) in teams" :key="index" :class="`${prefixCls}-top__team-item`">
+            <Icon :icon="team.icon" :color="team.color" />
+            <span>{{ team.title }}</span>
+          </div>
+        </CollapseContainer>
+      </Col>
+    </Row>
+    <div :class="`${prefixCls}-bottom`">
+      <Tabs>
+        <template v-for="item in achieveList" :key="item.key">
+          <TabPane :tab="item.name">
+            <component :is="item.component" />
+          </TabPane>
+        </template>
+      </Tabs>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+  import { Row, Col, Tag, Tabs } from 'ant-design-vue';
+  import { defineComponent } from 'vue';
+  import { CollapseContainer } from '/@/components/Container/index';
+  import Icon from '/@/components/Icon/index';
+  import Article from './Article.vue';
+  import Application from './Application.vue';
+  import Project from './Project.vue';
+
+  import headerImg from '/@/assets/images/header.jpg';
+  import { tags, teams, details, achieveList } from './data';
+
+  export default defineComponent({
+    components: {
+      CollapseContainer,
+      Icon,
+      Row,
+      Col,
+      Tag,
+      Tabs,
+      TabPane: Tabs.TabPane,
+      Article,
+      Application,
+      Project,
+    },
+    setup() {
+      return {
+        prefixCls: 'account-center',
+        headerImg,
+        tags,
+        teams,
+        details,
+        achieveList,
+      };
+    },
+  });
+</script>
+<style lang="less" scoped>
+  .account-center {
+    &-col:not(:last-child) {
+      padding: 0 10px;
+
+      &:not(:last-child) {
+        border-right: 1px dashed rgb(206, 206, 206, 0.5);
+      }
+    }
+
+    &-top {
+      padding: 10px;
+      margin: 16px 16px 12px 16px;
+      background: #fff;
+      border-radius: 3px;
+
+      &__avatar {
+        text-align: center;
+
+        img {
+          border-radius: 50%;
+        }
+
+        span {
+          display: block;
+          font-size: 20px;
+          font-weight: 500;
+        }
+
+        div {
+          margin-top: 3px;
+          font-size: 12px;
+        }
+      }
+
+      &__detail {
+        padding-left: 20px;
+        margin-top: 15px;
+      }
+
+      &__team {
+        &-item {
+          display: inline-block;
+          padding: 4px 18px;
+        }
+
+        span {
+          margin-left: 3px;
+        }
+      }
+    }
+
+    &-bottom {
+      padding: 10px;
+      margin: 0 16px 16px 16px;
+      background: #fff;
+      border-radius: 3px;
+    }
+  }
+</style>

+ 1 - 1
src/views/demo/page/account/setting/AccountBind.vue

@@ -22,7 +22,7 @@
 </template>
 <script lang="ts">
   import { List } from 'ant-design-vue';
-  import { defineComponent, onMounted } from 'vue';
+  import { defineComponent } from 'vue';
   import { CollapseContainer } from '/@/components/Container/index';
   import Icon from '/@/components/Icon/index';
 

+ 1 - 1
src/views/demo/page/account/setting/MsgNotify.vue

@@ -24,7 +24,7 @@
 </template>
 <script lang="ts">
   import { List, Switch } from 'ant-design-vue';
-  import { defineComponent, onMounted } from 'vue';
+  import { defineComponent } from 'vue';
   import { CollapseContainer } from '/@/components/Container/index';
 
   import { msgNotifyList } from './data';

+ 1 - 1
src/views/demo/page/account/setting/SecureSetting.vue

@@ -19,7 +19,7 @@
 </template>
 <script lang="ts">
   import { List } from 'ant-design-vue';
-  import { defineComponent, onMounted } from 'vue';
+  import { defineComponent } from 'vue';
   import { CollapseContainer } from '/@/components/Container/index';
 
   import { secureSettingList } from './data';