Procházet zdrojové kódy

feat: 添加account页面和用户信息填写模块

chenpeng před 1 dnem
rodič
revize
5e8a1441b5

+ 1 - 1
src/App.vue

@@ -10,7 +10,7 @@
     }"
   >
     <router-view />
-    <info-modal :visible="visible" v-if="visible" />
+    <!-- <info-modal :visible="visible" v-if="visible" /> -->
   </a-config-provider>
 </template>
 

+ 3 - 3
src/components/layout/MainLayout.vue

@@ -3,7 +3,7 @@
     <BaseHeader />
     <div class="main-container flex flex-1">
       <!-- <BaseSideNav /> -->
-      <div class="main-view py-32px px-20px flex-1 overflow-auto">
+      <div class="main-view py-32px px-40px flex-1 overflow-auto">
         <router-view />
       </div>
     </div>
@@ -13,10 +13,10 @@
 import BaseHeader from './BaseHeader.vue'
 // import BaseSideNav from './BaseSideNav.vue'
 </script>
-<style lang="less">
+<style lang="less">  
 .main-layout {
   min-width: 1440px;
-  background-color: #F3F3F3;
+  background-color: #f3f3f3;
   .main-container {
     height: calc(100% - 80px);
   }

+ 1 - 1
src/components/modal/userInfo.vue

@@ -182,7 +182,7 @@ const onSubmit = async () => {
         <!-- 银行卡 --- end -->
         <a-form-item label="">
           <a-button class="w-full !bg-#0068FF !b-rd-6px text-#fff !fw-700 !h-56px !hover:text-#fff" @click="onSubmit" size="large"
-            >立即注册
+            >Submit
           </a-button>
         </a-form-item>
       </a-form>

+ 24 - 0
src/routes/index.ts

@@ -17,6 +17,30 @@ export default [
     children: [{ path: 'dashboard', component: () => import('Views/dashboard/index.vue') }],
   },
 
+  {
+    path: '/account',
+    name: 'Account',
+    icon: '',
+    show: true,
+    meta: { title: '账号' },
+    component: MainLayout,
+    redirect: '/account/index',
+    children: [
+      { path: 'index', component: () => import('Views/account/index.vue') },
+    ],
+  },
+  {
+    path: '/resources',
+    name: 'Resources',
+    icon: '',
+    show: true,
+    meta: { title: '资源' },
+    component: MainLayout,
+    redirect: '/resources/index',
+    children: [
+      { path: 'index', component: () => import('Views/resources/index.vue') },
+    ],
+  },
   {
     path: '/overSea',
     name: 'OverSea',

+ 85 - 0
src/views/account/_components/list.vue

@@ -0,0 +1,85 @@
+<template>
+  <div class="page">
+    <div v-for="(item, index) in list" :key="index" class="mb-20px">
+      <div class="flex justify-between bg-#fff b-rd-12px p-24">
+        <div class="flex">
+          <img v-if="item.type === 'customer'" src="@/assets/images/people_single.png" class="w-30px mt-20px h-30px" alt="" srcset="" />
+          <img v-if="item.type === 'order'" src="@/assets/images/bill.png" class="w-30px mt-20px h-30px" alt="" srcset="" />
+          <div class="ml-16px">
+            <div class="text-20px fw-700 mb-14px">{{ getTitle(item) }}</div>
+            <div class="text-14px c-#999 mb-8px">Creation Time:{{ item.createTime }}</div>
+            <div class="text-14px fw-500 c-#333">Distribution details</div>
+            <div
+              v-if="isOpen === index"
+              class="flex gap-40px c-#999 text-14px mt-10px max-h-0 h-0 overflow-hidden transition-all duration-300"
+              :class="{ 'h-auto': isOpen === index }"
+            >
+              <div>Customer Name:XXXXX</div>
+              <div>{{ item.type === 'customer' ? 'Clue Encoding' : 'Order code' }}:XXXXXXX</div>
+            </div>
+          </div>
+        </div>
+        <div class="flex items-center flex-col">
+          <div class="text-36px c-#000 fw-700">{{ item.value }}</div>
+          <div class="text-20px c-#000 mt-14px cursor-pointer" :class="{ 'rotate-180': isOpen === index }" @click="handleClick(index)">
+            <DownOutlined />
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="flex justify-end">
+      <a-pagination v-model:current="current" :show-size-changer="false" :total="total" :show-less-items="true" />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { DownOutlined } from '@ant-design/icons-vue'
+import { ref } from 'vue'
+const isOpen = ref<number | null>(null)
+const current = ref(1)
+const total = ref(100)
+const getTitle = (item: any) => {
+  return item.type === 'customer'
+    ? 'Unissued-Customer Commission'
+    : item.orderType === 'Unissued'
+      ? 'Unissued-Order Commission'
+      : 'Issued-Order Commission'
+}
+const list = ref<any[]>([
+  {
+    type: 'customer',
+    name: 'Customer Name',
+    value: '100',
+    createTime: '2024-04-05',
+  },
+  {
+    type: 'order',
+    name: 'Order Name',
+    value: '100',
+    createTime: '2024-04-05',
+    orderType: 'Unissued',
+  },
+  {
+    type: 'order',
+    name: 'Order Name',
+    value: '100',
+    createTime: '2024-04-05',
+    orderType: 'Issued',
+  },
+])
+
+const handleClick = (index: number) => {
+  isOpen.value = isOpen.value === index ? null : index
+}
+</script>
+<style scoped lang="less">
+.rotate-180 {
+  transform: rotate(180deg);
+  transform-origin: center center;
+  transition: all 0.3s ease-in-out;
+}
+.h-auto {
+  max-height: 200px;
+}
+</style>

+ 50 - 0
src/views/account/_components/statisticalData.vue

@@ -0,0 +1,50 @@
+<template>
+    <div>
+        <div class="grid grid-cols-3 gap-30">
+            <div class="bg-#fff b-rd-12px p-24">
+                <div class="flex items-center">
+                    <img src="@/assets/images/data_img.png" class="w-30px h-30px mt-16px mb-14px" alt="" srcset="" />
+                    <div class="ml-16px">
+                        <div class="text-16px mb-10px">Total Commission</div>
+                        <div class="flex items-end">
+                            <span class="text-20px fw-700">48.0</span>
+                            <span class="text-14px c-#999 ml-4px">USD</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="bg-#fff b-rd-12px p-24">
+                <div class="flex items-center">
+                    <img src="@/assets/images/data_img.png" class="w-30px h-30px mt-16px mb-14px" alt="" srcset="" />
+                    <div class="ml-16px">
+                        <div class="text-16px  mb-10px">Accumulated Distribution</div>
+                        <div class="flex items-end">
+                            <span class="text-20px fw-700">48.0</span>
+                            <span class="text-14px c-#999 ml-4px">USD</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="bg-#fff b-rd-12px p-24">
+                <div class="flex items-center">
+                    <img src="@/assets/images/data_img.png" class="w-30px h-30px mt-16px mb-14px" alt="" srcset="" />
+                    <div class="ml-16px">
+                        <div class="text-16px mb-10px">
+                            To be Distributed</div>
+                        <div class="flex items-end">
+                            <span class="text-20px fw-700">48.0</span>
+                            <span class="text-14px c-#999 ml-4px">USD</span>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+
+
+
+</script>
+<style scoped lang="less"></style>

+ 20 - 0
src/views/account/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <div class="page">
+    <div class="mb-30 flex items-center">
+      <div class="flex items-center cursor-pointer">
+        <LeftOutlined class="text-24px pt-4px" />
+        <span class="text-30px fw-700 !mb-0 ml-12">Account</span>
+      </div>
+    </div>
+    <StatisticalData />
+    <h2 class="text-20px fw-700 !my-20">Account Details</h2>
+    <List />
+  </div>
+</template>
+
+<script setup lang="ts">
+import { LeftOutlined } from '@ant-design/icons-vue'
+import StatisticalData from './_components/statisticalData.vue'
+import List from './_components/list.vue'
+</script>
+<style scoped lang="less"></style>

+ 263 - 0
src/views/resources/index.vue

@@ -0,0 +1,263 @@
+<template>
+  <div class="page py-24 px-32">
+    <h1 class="text-30px fw-700 !mb-12">出海服务</h1>
+    <a-breadcrumb separator=">">
+      <a-breadcrumb-item>
+        <a href="/dashboard">
+          <img src="@/assets/images/home.png" class="w-12 h-12" alt="" srcset="" />
+        </a>
+      </a-breadcrumb-item>
+      <a-breadcrumb-item>出海服务</a-breadcrumb-item>
+    </a-breadcrumb>
+    <div class="mt-24">
+      <div class="p-24 mb-24 flex bg-#fff b-rd-6px">
+        <img src="@/assets/images/oversea.jpg" class="w-600 h-340 b-rd-6px mr-36" alt="" srcset="" />
+        <div>
+          <h3 class="text-24px fw-700 text-#3d3d3d">去海外,书写一个时代</h3>
+          <div class="mt-24 mb-40px text-14px text-#555">
+            <p>易杰出海是易杰集团旗下专注供应链品牌出海的内容媒体和全链路服务平台。</p>
+            <p>易杰出海的使命是,成为中国企业跨境出海的忠实记录者与有力推动者。</p>
+            <p>
+              我们时刻关注全球市场的动向,为您透视海外市场情况,将提供有价值的资讯、深入的分析和切实可行的解决方案视为己任,尽力抹平海外信息差,与您共同寻找和探索下一个市场机遇。
+            </p>
+            <p>
+              我们深耕跨境,聚集了工厂主、品牌方、海外客户、采购商、投资人、行业协会代表、媒体等优质的人脉资源,诚邀您加入易杰出海圈,与我们抱团取暖,共享圈层资源,建立更多合作,拓展更多业务。
+            </p>
+            <p>我们将为您提供品牌出海的内容信息、出海营销运营、海外资源对接、采购订单合作等全链路服务,助力您在海外扎根发展,乘风破浪。</p>
+          </div>
+          <div class="flex gap-16">
+            <a-popover trigger="hover">
+              <template #content>
+                <img src="@/assets/images/contact_office.jpg" class="w-240 h-240 object-cover" alt="" srcset="" />
+              </template>
+              <div flex items-center justify-center py-6 w-100 b-rd-4px class="bg-#F2F2F2 text-#3D3D3D cursor-pointer">
+                <img src="@/assets/images/wx_office.png" alt="" mr-5 w-24 h-24 srcset="" />
+                公众号
+              </div>
+            </a-popover>
+            <a-popover trigger="hover">
+              <template #content>
+                <img src="@/assets/images/contact_video.jpg" class="w-240" alt="" srcset="" />
+              </template>
+              <div flex items-center justify-center py-6 w-100 b-rd-4px class="bg-#F2F2F2 text-#3D3D3D cursor-pointer">
+                <img src="@/assets/images/wx_video.png" alt="" mr-5 w-24 h-24 srcset="" />
+                视频号
+              </div>
+            </a-popover>
+            <a-popover trigger="hover">
+              <template #content>
+                <img src="@/assets/images/contact_dy.jpg" class="w-240" alt="" srcset="" />
+              </template>
+              <div flex items-center justify-center py-6 w-100 b-rd-4px class="bg-#F2F2F2 text-#3D3D3D cursor-pointer">
+                <img src="@/assets/images/dy.png" alt="" mr-5 w-24 h-24 srcset="" />
+                抖音
+              </div>
+            </a-popover>
+            <a-popover trigger="hover">
+              <template #content>
+                <img src="@/assets/images/contact_xhs.jpg" class="w-240" alt="" srcset="" />
+              </template>
+              <div flex items-center justify-center py-6 w-100 b-rd-4px class="bg-#F2F2F2 text-#3D3D3D cursor-pointer">
+                <img src="@/assets/images/xhs.png" alt="" mr-5 w-24 h-24 srcset="" />
+                小红书
+              </div>
+            </a-popover>
+          </div>
+        </div>
+      </div>
+      <div class="p-24 mb-24 bg-#fff b-rd-6px">
+        <h3 class="text-16px !fw-600 text-#020202 title">地区解读</h3>
+        <div class="mt-20px flex gap-20">
+          <div
+            v-for="item in areaList"
+            @click="onAreaClick(item)"
+            :class="activeId === item.id && 'bg-#0068FF text-#fff b-rd-4px'"
+            :key="item.id"
+            class="text-#666 py-5 px-12 cursor-pointer text-14px"
+          >
+            {{ item.name }}
+          </div>
+        </div>
+        <div class="mt-24 grid grid-cols-4 grid-gap-x-24 grid-gap-y-24" v-if="articles.length">
+          <div v-for="item in articles" :key="item.key" class="bg-#fff b-rd-4px overflow-hidden article-item">
+            <img :src="item.pic" class="w-300px h-300px object-cover m-0" alt="" srcset="" />
+            <div class="py-20 px-16">
+              <h3 class="text-16px !fw-600 text-#020202">{{ item.title }}</h3>
+              <a :href="item.url" target="_blank" class="text-#3D3D3D break-all text-14px line-clamp-2 cursor-pointer hover:underline">{{
+                item.url
+              }}</a>
+            </div>
+          </div>
+        </div>
+        <div v-else class="py-120">
+          <a-empty :image="simpleImage" />
+        </div>
+        <div class="mt-24 text-center custom-pagination" v-if="params.total > 0">
+          <a-pagination v-model:current="params.pageNo" :total="params.total" @change="onChangePage" :show-size-changer="false">
+            <template #itemRender="{ type, originalElement }">
+              <a v-if="type === 'prev'">上一页</a>
+              <a v-else-if="type === 'next'">下一页</a>
+              <component :is="originalElement" v-else></component>
+            </template>
+          </a-pagination>
+        </div>
+      </div>
+      <div class="p-24 mb-24 bg-#fff b-rd-6px">
+        <h3 class="text-16px !fw-600 text-#020202 title">出海白皮书</h3>
+        <div class="mt-28px" v-if="filesList.length">
+          <div v-for="item in filesList" :key="item.id" class="flex items-center w-full justify-between mb-24px">
+            <div class="flex items-center">
+              <img src="@/assets/images/pdf.png" class="w-24 h-24 mr-16" alt="" srcset="" />
+              <div class="text-#020202">{{ item.name }}</div>
+            </div>
+            <div class="flex items-center">
+              <div class="text-#666">{{ item.createTime }}</div>
+              <img @click="onDownload(item)" src="@/assets/images/download.png" class="w-24 h-24 ml-12 cursor-pointer" alt="" srcset="" />
+            </div>
+          </div>
+        </div>
+        <div v-else>
+          <a-empty :image="simpleImage" />
+        </div>
+        <div class="mt-24 text-center custom-pagination" v-if="filesParams.total > 0">
+          <a-pagination v-model:current="filesParams.pageNo" @change="onChangeFilePage" :total="filesParams.total" :show-size-changer="false">
+            <template #itemRender="{ type, originalElement }">
+              <a v-if="type === 'prev'">上一页</a>
+              <a v-else-if="type === 'next'">下一页</a>
+              <component :is="originalElement" v-else></component>
+            </template>
+          </a-pagination>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { message } from 'ant-design-vue'
+import { getAreaListApi, getArticlesListApi, getDownloadCountApi, getPdfListApi } from '@/api/oversea'
+import { downloadFileByA } from '@/utils'
+import { Empty } from 'ant-design-vue'
+const simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
+
+const areaList = ref<any>([])
+const activeId = ref()
+const articles = ref<any>([])
+const filesList = ref<any>([])
+const params = ref({
+  pageNo: 1,
+  pageSize: 12,
+  total: 0,
+  category: '',
+})
+const filesParams = ref({
+  pageNo: 1,
+  pageSize: 20,
+  total: 0,
+})
+const onDownload = (item: any) => {
+  downloadFileByA(item.url, item.name)
+  getDownloadCountApi({ id: item.id })
+}
+const onAreaClick = (item: any) => {
+  activeId.value = item.id
+  params.value.pageNo = 1
+  getArticlesList()
+}
+const onChangePage = (page: number) => {
+  params.value.pageNo = page
+  getArticlesList()
+}
+const onChangeFilePage = (page: number) => {
+  filesParams.value.pageNo = page
+  getPdfList()
+}
+const getAreaList = async () => {
+  try {
+    const { data } = await getAreaListApi({ pageNo: 1, pageSize: 9999 })
+    areaList.value = data.result.records
+    activeId.value = data.result.records[0].id
+  } catch (error) {
+    console.log(error)
+  }
+}
+const getArticlesList = async () => {
+  try {
+    params.value.category = activeId.value
+    console.log('params', params.value)
+    const { data } = await getArticlesListApi(params.value)
+    console.log(data.result, 'res')
+    articles.value = data.result.records
+    params.value.total = data.result.total
+  } catch (error) {
+    console.log(error)
+  }
+}
+const getPdfList = async () => {
+  try {
+    const { data } = await getPdfListApi(filesParams.value)
+    console.log(data.result, 'res')
+    filesList.value = data.result.records
+    filesParams.value.total = data.result.total
+  } catch (error) {
+    console.log(error)
+  }
+}
+onMounted(async () => {
+  await getAreaList()
+  await getArticlesList()
+  await getPdfList()
+})
+</script>
+<style lang="less" scoped>
+.title {
+  position: relative;
+  &::before {
+    position: absolute;
+    content: '';
+    display: inline-block;
+    width: 4px;
+    top: -5px;
+    left: -24px;
+    bottom: -5px;
+    background: linear-gradient(176deg, #0068ff 0%, #0ff6cd 102%);
+    margin-right: 8px;
+    border-radius: 0px 2px 2px 0px;
+  }
+}
+.article-item {
+  cursor: pointer;
+  transition: all 0.3s;
+  box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.1);
+}
+::v-deep(.custom-pagination) {
+  font-size: 14px;
+  .ant-pagination {
+    .ant-pagination-prev,
+    .ant-pagination-next {
+      border: 1px solid #dcdfe6;
+      border-radius: 4px;
+      padding: 5px 12px;
+      height: unset !important;
+      line-height: unset !important;
+      margin-right: 12px;
+    }
+    .ant-pagination-item {
+      border-radius: 4px;
+      border: 1px solid #dcdfe6;
+      margin-right: 12px;
+      &.ant-pagination-item-active {
+        border: 1px solid #0068ff;
+        background: rgba(0, 104, 255, 0.08);
+        a {
+          color: #0068ff !important;
+        }
+      }
+    }
+    .ant-pagination-jump-prev,
+    .ant-pagination-jump-next {
+      line-height: 32px !important;
+    }
+  }
+}
+</style>