From 6968fb6e41787d311addb804b29285aecc553f2d Mon Sep 17 00:00:00 2001
From: wupengfei <834520024@qq.com>
Date: 星期二, 05 八月 2025 17:03:47 +0800
Subject: [PATCH] feat: 名片

---
 apps/bMiniApp/src/assets/businessCard/icon-phone.png                                       |    0 
 apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue                      |    8 
 apps/bMiniApp/src/constants/router.ts                                                      |    2 
 apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.vue       |   17 ++
 apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue           |    2 
 apps/bMiniApp/project.private.config.json                                                  |    2 
 apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue                 |   25 +-
 apps/bMiniApp/src/app.config.ts                                                            |    7 
 apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.config.ts   |    3 
 apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue           |   47 +++--
 packages/components/src/Card/FlexJobTopView.vue                                            |    8 
 apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.config.ts |    3 
 packages/components/src/index.ts                                                           |    1 
 apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/InnerPage.vue                |   48 ++++++
 packages/components/src/Card/BusinessCardHolderCard.vue                                    |  114 ++++++++++++++
 apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.vue         |   17 ++
 apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue       |   97 +++++------
 apps/bMiniApp/src/subpackages/businessCard/businessCardShare/InnerPage.vue                 |   69 ++++++++
 18 files changed, 383 insertions(+), 87 deletions(-)

diff --git a/apps/bMiniApp/project.private.config.json b/apps/bMiniApp/project.private.config.json
index 34009f7..03021e0 100644
--- a/apps/bMiniApp/project.private.config.json
+++ b/apps/bMiniApp/project.private.config.json
@@ -80,7 +80,7 @@
                 },
                 {
                     "name": "",
-                    "pathName": "subpackages/businessCard/businessCard/businessCard",
+                    "pathName": "subpackages/businessCard/businessCardShare/businessCardShare",
                     "query": "",
                     "launchMode": "default",
                     "scene": null
diff --git a/apps/bMiniApp/src/app.config.ts b/apps/bMiniApp/src/app.config.ts
index 34f147c..8192a0b 100644
--- a/apps/bMiniApp/src/app.config.ts
+++ b/apps/bMiniApp/src/app.config.ts
@@ -76,7 +76,12 @@
     },
     {
       root: 'subpackages/businessCard',
-      pages: ['businessCard/businessCard', 'businessCardEdit/businessCardEdit'],
+      pages: [
+        'businessCard/businessCard',
+        'businessCardEdit/businessCardEdit',
+        'businessCardDetail/businessCardDetail',
+        'businessCardShare/businessCardShare',
+      ],
     },
     {
       root: 'subpackages/task',
diff --git a/apps/bMiniApp/src/assets/businessCard/icon-phone.png b/apps/bMiniApp/src/assets/businessCard/icon-phone.png
new file mode 100644
index 0000000..cd63698
--- /dev/null
+++ b/apps/bMiniApp/src/assets/businessCard/icon-phone.png
Binary files differ
diff --git a/apps/bMiniApp/src/constants/router.ts b/apps/bMiniApp/src/constants/router.ts
index 489c816..5130d44 100644
--- a/apps/bMiniApp/src/constants/router.ts
+++ b/apps/bMiniApp/src/constants/router.ts
@@ -35,6 +35,8 @@
 
   businessCard = '/subpackages/businessCard/businessCard/businessCard',
   businessCardEdit = '/subpackages/businessCard/businessCardEdit/businessCardEdit',
+  businessCardDetail = '/subpackages/businessCard/businessCardDetail/businessCardDetail',
+  businessCardShare = '/subpackages/businessCard/businessCardShare/businessCardShare',
 
   publishTask = '/subpackages/task/publishTask/publishTask',
   taskCheck = '/subpackages/task/taskCheck/taskCheck',
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue b/apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue
index 752d047..ce8150a 100644
--- a/apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue
@@ -5,7 +5,7 @@
     class="home-tabs"
     isTransparent
     title-gutter="12"
-    title-scroll
+    fullHeight
   >
     <ProTabPane :title="`鎴戠殑鍚嶇墖`" pane-key="1">
       <BusinessCardView></BusinessCardView>
@@ -30,10 +30,4 @@
 
 <style lang="scss">
 @import '@/styles/common.scss';
-
-.businessCard-page-wrapper {
-  .nut-tab-pane {
-    background-color: transparent;
-  }
-}
 </style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/InnerPage.vue b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/InnerPage.vue
new file mode 100644
index 0000000..f1f4e1e
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/InnerPage.vue
@@ -0,0 +1,48 @@
+<template>
+  <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch">
+    <BusinessCardDetailInfoView> </BusinessCardDetailInfoView>
+    <PageFooter>
+      <PageFooterBtn type="primary" class="business-card-btn">鏀朵笅鍚嶇墖</PageFooterBtn>
+      <PageFooterBtn type="primary" class="business-card-btn">鍒犻櫎鍚嶇墖</PageFooterBtn>
+      <PageFooterBtn type="primary" class="business-card-btn">杞彂鍚嶇墖</PageFooterBtn>
+    </PageFooter>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import { useQuery } from '@tanstack/vue-query';
+import Taro from '@tarojs/taro';
+import * as flexWorkerServices from '@12333/services/api/FlexWorker';
+import BusinessCardDetailInfoView from '../components/BusinessCardDetailInfoView.vue';
+
+defineOptions({
+  name: 'InnerPage',
+});
+
+const router = Taro.useRouter();
+
+const id = router.params?.id;
+
+const {
+  isLoading,
+  isError,
+  data: detail,
+  refetch,
+} = useQuery({
+  queryKey: ['flexWorkerServices/getFlexTaskDto', id],
+  queryFn: async () => {
+    return await flexWorkerServices.getFlexTaskDto(
+      { id: id },
+      {
+        showLoading: false,
+      }
+    );
+  },
+  placeholderData: () => ({} as API.GetFlexTaskDtoOutput),
+  onSuccess(data) {},
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.config.ts b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+  disableScroll: true,
+});
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.vue b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.vue
new file mode 100644
index 0000000..1c0c3c8
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardDetail/businessCardDetail.vue
@@ -0,0 +1,17 @@
+<template>
+  <PageLayoutWithBg class="businessCardDetail-page-wrapper" :title="'鍚嶇墖璇︽儏'">
+    <InnerPage></InnerPage>
+  </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+  name: 'businessCardDetail',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/InnerPage.vue b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/InnerPage.vue
new file mode 100644
index 0000000..f34d2f0
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/InnerPage.vue
@@ -0,0 +1,69 @@
+<template>
+  <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch">
+    <ContentScrollView>
+      <BusinessCardHolderCard
+        :name="'item.name'"
+        :age="20"
+        :genderType="1"
+        :isRealName="true"
+        :show-footer-left="false"
+        :show-footer-right="false"
+      >
+        <template #detail>
+          <div class="businessCardHolder-card-detail">
+            <BusinessCardDetailItem :icon="IconPhone" :value="`鎵嬫満锛�${'13333333333'}`" />
+            <BusinessCardDetailItem :icon="IconWechat" :value="`寰俊锛�${'13333333333'}`" />
+            <BusinessCardDetailItem :icon="IconCompany" :value="`鍏徃锛�${'鏉窞浜哄姏鏃犲咖绉戞妧'}`" />
+          </div>
+        </template>
+      </BusinessCardHolderCard>
+    </ContentScrollView>
+
+    <PageFooter>
+      <PageFooterBtn type="primary" class="business-card-btn">涓嬭浇鍥剧墖</PageFooterBtn>
+      <PageFooterBtn type="primary" class="business-card-btn">鍒嗕韩缁欏井淇″ソ鍙�</PageFooterBtn>
+    </PageFooter>
+  </LoadingLayout>
+</template>
+
+<script setup lang="ts">
+import { useQuery } from '@tanstack/vue-query';
+import Taro from '@tarojs/taro';
+import BusinessCardDetailItem from '../components/BusinessCardDetailItem.vue';
+import { BusinessCardHolderCard } from '@12333/components';
+import * as flexWorkerServices from '@12333/services/api/FlexWorker';
+import IconWechat from '@/assets/businessCard/icon-wechat.png';
+import IconCompany from '@/assets/businessCard/icon-company.png';
+import IconPhone from '@/assets/businessCard/icon-phone.png';
+
+defineOptions({
+  name: 'InnerPage',
+});
+
+const router = Taro.useRouter();
+
+const id = router.params?.id;
+
+const {
+  isLoading,
+  isError,
+  data: detail,
+  refetch,
+} = useQuery({
+  queryKey: ['flexWorkerServices/getFlexTaskDto', id],
+  queryFn: async () => {
+    return await flexWorkerServices.getFlexTaskDto(
+      { id: id },
+      {
+        showLoading: false,
+      }
+    );
+  },
+  placeholderData: () => ({} as API.GetFlexTaskDtoOutput),
+  onSuccess(data) {},
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.config.ts b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.config.ts
new file mode 100644
index 0000000..305fdb1
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.config.ts
@@ -0,0 +1,3 @@
+export default definePageConfig({
+  disableScroll: true,
+});
diff --git a/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.vue b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.vue
new file mode 100644
index 0000000..cbb1d85
--- /dev/null
+++ b/apps/bMiniApp/src/subpackages/businessCard/businessCardShare/businessCardShare.vue
@@ -0,0 +1,17 @@
+<template>
+  <PageLayoutWithBg class="businessCardShare-page-wrapper" :title="'鍒嗕韩鍚嶇墖'">
+    <InnerPage></InnerPage>
+  </PageLayoutWithBg>
+</template>
+
+<script setup lang="ts">
+import InnerPage from './InnerPage.vue';
+
+defineOptions({
+  name: 'businessCardShare',
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+</style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue
index 4b5c95d..dc7b383 100644
--- a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue
+++ b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue
@@ -1,26 +1,29 @@
 <template>
   <ContentScrollView class="business-card-detail-info-wrapper">
-    <TaskCheckPersonalView :name="'1231231'" :contactPhone="'133'">
-      <template #actions>
-        <nut-button type="primary" @click="emit('edit')">缂栬緫</nut-button>
-      </template>
-    </TaskCheckPersonalView>
-    <div class="business-card-detail">
-      <BusinessCardDetailItem :icon="IconWechat" :value="`寰俊锛�${'13333333333'}`" />
-      <BusinessCardDetailItem :icon="IconPosition" :value="`鑱屼綅锛�${'缁忕悊'}`" />
-      <BusinessCardDetailItem :icon="IconEmail" :value="`閭锛�${'yangyang@123.com'}`" />
-      <BusinessCardDetailItem :icon="IconCompany" :value="`鍏徃锛�${'鏉窞浜哄姏鏃犲咖绉戞妧'}`" />
-      <BusinessCardDetailItem :icon="IconAddress" :value="`鍦板潃锛�${'鏉窞甯備笂鍩庡尯'}`" />
+    <div class="business-card-detail-company-content">
+      <TaskCheckPersonalView :name="'1231231'" :contactPhone="'133'">
+        <template #actions>
+          <slot name="actions"></slot>
+        </template>
+      </TaskCheckPersonalView>
+      <div class="business-card-detail">
+        <BusinessCardDetailItem :icon="IconWechat" :value="`寰俊锛�${'13333333333'}`" />
+        <BusinessCardDetailItem :icon="IconPosition" :value="`鑱屼綅锛�${'缁忕悊'}`" />
+        <BusinessCardDetailItem :icon="IconEmail" :value="`閭锛�${'yangyang@123.com'}`" />
+        <BusinessCardDetailItem :icon="IconCompany" :value="`鍏徃锛�${'鏉窞浜哄姏鏃犲咖绉戞妧'}`" />
+        <BusinessCardDetailItem :icon="IconAddress" :value="`鍦板潃锛�${'鏉窞甯備笂鍩庡尯'}`" />
+      </div>
+    </div>
+
+    <div class="business-card-detail-company-content company-intro">
+      <div class="business-card-detail-company-intro-title">鍏徃绠�浠�</div>
+      <div class="business-card-detail-company-intro-content">
+        {{
+          '鎴戞槸鍏徃鐨勪笟鍔$畝浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠� 浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟 绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓� 鍔$畝浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠�'
+        }}
+      </div>
     </div>
   </ContentScrollView>
-  <div class="business-card-detail-company-intro">
-    <div class="business-card-detail-company-intro-title">鍏徃绠�浠�</div>
-    <div class="business-card-detail-company-intro-content">
-      {{
-        '鎴戞槸鍏徃鐨勪笟鍔$畝浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠� 浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟 绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓� 鍔$畝浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠嬫垜鏄叕鍙哥殑涓氬姟绠�浠�'
-      }}
-    </div>
-  </div>
 </template>
 
 <script setup lang="ts">
@@ -35,48 +38,42 @@
 defineOptions({
   name: 'BusinessCardDetailInfoView',
 });
-
-const emit = defineEmits<{
-  (e: 'edit'): void;
-}>();
 </script>
 
 <style lang="scss">
 @import '@/styles/common.scss';
 
 .business-card-detail-info-wrapper {
-  background-color: #ffffff;
-  padding-top: 20px;
+  background-color: transparent;
 
-  .flexJob-card-top-wrapper {
-    padding-top: 40px;
-    padding-bottom: 32px;
-    border-bottom: 1px solid #d9d9d9;
-  }
+  .business-card-detail-company-content {
+    background-color: #ffffff;
+    border-radius: 12px;
+    padding: 30px 24px;
 
-  .business-card-detail {
-    padding: 20px 0 10px;
-  }
-}
+    .flexJob-card-top-wrapper {
+      padding-bottom: 32px;
+      border-bottom: 1px solid #d9d9d9;
+    }
 
-.business-card-detail-company-intro {
-  background-color: #ffffff;
-  margin-top: 30px;
-  padding: 30px 24px;
+    &.company-intro {
+      margin-top: 30px;
 
-  .business-card-detail-company-intro-title {
-    font-size: 28px;
-    line-height: 40px;
-    color: boleGetCssVar('text-color', 'primary');
-    font-weight: 600;
-    margin-bottom: 10px;
-  }
+      .business-card-detail-company-intro-title {
+        font-size: 28px;
+        line-height: 40px;
+        color: boleGetCssVar('text-color', 'primary');
+        font-weight: 600;
+        margin-bottom: 10px;
+      }
 
-  .business-card-detail-company-intro-content {
-    font-size: 24px;
-    line-height: 36px;
-    color: #4e5969;
-    font-weight: 400;
+      .business-card-detail-company-intro-content {
+        font-size: 24px;
+        line-height: 36px;
+        color: #4e5969;
+        font-weight: 400;
+      }
+    }
   }
 }
 </style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue
index 4586ecd..685a0cf 100644
--- a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue
+++ b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue
@@ -22,7 +22,7 @@
 @import '@/styles/common.scss';
 
 .business-card-detail-item {
-  margin-bottom: 24px;
+  margin-top: 24px;
   display: flex;
   align-items: center;
 
diff --git a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue
index 7072562..3cec948 100644
--- a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue
+++ b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue
@@ -1,31 +1,35 @@
 <template>
   <InfiniteLoading scrollViewClassName="common-infinite-scroll-list" v-bind="infiniteLoadingProps">
     <template #renderItem="{ item }">
-      <FlexJobCard
-        :name="item.name"
-        :age="item.age"
-        :genderType="item.genderType"
-        :workExperience="item.workExperience"
+      <BusinessCardHolderCard
+        :name="'item.name'"
+        :age="20"
+        :genderType="1"
+        :isRealName="true"
+        :show-footer-left="false"
       >
-        <template #footerLeft>
-          <div class="flexJob-card-footer-text">{{ FlexTaskWorkerHireEnum[item.hireStatus] }}</div>
+        <template #detail>
+          <div class="businessCardHolder-card-detail">
+            <div class="businessCardHolder-card-detail-item">{{ `寰俊锛�${'13333333333'}` }}</div>
+            <div class="businessCardHolder-card-detail-item">
+              {{ `鍏徃锛�${'鏉窞浜哄姏鏃犲咖绉戞妧'}` }}
+            </div>
+          </div>
         </template>
         <template #footerRight>
-          <nut-button type="primary" @click="handleDelete()">鍒犻櫎</nut-button>
+          <nut-button type="danger" plain @click="handleDelete()">鍒犻櫎</nut-button>
           <nut-button type="primary" @click="goForward()">杞彂</nut-button>
         </template>
-      </FlexJobCard>
+      </BusinessCardHolderCard>
     </template>
   </InfiniteLoading>
 </template>
 
 <script setup lang="ts">
 import { OrderInputType } from '@12333/constants';
-import { RouterPath } from '@/constants';
-import { FlexTaskWorkerHireEnum } from '@12333/constants/task';
 import { useInfiniteLoading } from '@12333/hooks';
-import * as flexWorkerServices from '@12333/services/api/FlexWorker';
-import { FlexJobCard } from '@12333/components';
+import * as flexEnterpriseServices from '@12333/services/api/FlexEnterprise';
+import { BusinessCardHolderCard } from '@12333/components';
 import Taro from '@tarojs/taro';
 
 defineOptions({
@@ -42,16 +46,16 @@
       pageModel: {
         rows: 20,
         page: pageParam,
-        orderInput: [{ property: 'creationTime', order: OrderInputType.Desc }],
+        orderInput: [{ property: 'id', order: OrderInputType.Desc }],
       },
     };
 
-    return flexWorkerServices.getFlexTaskWorkerApplyList(params, {
+    return flexEnterpriseServices.getFlexEnterpriseList(params, {
       showLoading: false,
     });
   },
   {
-    queryKey: ['flexWorkerServices/getFlexTaskWorkerApplyList'],
+    queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'],
   }
 );
 
@@ -62,4 +66,15 @@
 
 <style lang="scss">
 @import '@/styles/common.scss';
+
+.businessCardHolder-card-detail {
+  margin-top: 10px;
+
+  .businessCardHolder-card-detail-item {
+    font-size: 24px;
+    font-weight: 400;
+    color: boleGetCssVar('text-color', 'regular');
+    line-height: 36px;
+  }
+}
 </style>
diff --git a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue
index aa1186c..b933c79 100644
--- a/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue
+++ b/apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue
@@ -1,7 +1,18 @@
 <template>
   <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch">
-    <BusinessCardDetailInfoView @edit="goEditBusinessCard"></BusinessCardDetailInfoView>
-    <PageFooterBtn type="primary" class="business-card-btn">閫掑悕鐗�</PageFooterBtn>
+    <BusinessCardDetailInfoView>
+      <template #actions>
+        <nut-button
+          class="business-card-detail-info-edit-button"
+          type="primary"
+          @click="goEditBusinessCard"
+          >缂栬緫</nut-button
+        >
+      </template>
+    </BusinessCardDetailInfoView>
+    <PageFooter>
+      <PageFooterBtn type="primary" class="business-card-btn">閫掑悕鐗�</PageFooterBtn>
+    </PageFooter>
   </LoadingLayout>
 </template>
 
@@ -43,18 +54,12 @@
     url: `${RouterPath.businessCardEdit}?id=${id}`,
   });
 }
-
-function handleBusinessCard() {}
 </script>
 
 <style lang="scss">
 @import '@/styles/common.scss';
 
-.businessCard-page-wrapper {
-  .business-card-btn {
-    width: 100%;
-    margin: 40px auto 0;
-    font-size: 28px;
-  }
+.business-card-detail-info-edit-button {
+  height: 52px;
 }
 </style>
diff --git a/packages/components/src/Card/BusinessCardHolderCard.vue b/packages/components/src/Card/BusinessCardHolderCard.vue
new file mode 100644
index 0000000..72cc153
--- /dev/null
+++ b/packages/components/src/Card/BusinessCardHolderCard.vue
@@ -0,0 +1,114 @@
+<template>
+  <div class="businessCardHolder-card-wrapper">
+    <FlexJobTopView
+      :name="name"
+      :age="age"
+      :genderType="genderType"
+      :isRealName="isRealName"
+      :arrangeCount="arrangeCount"
+      :educationalLevel="educationalLevel"
+    >
+      <template #detail>
+        <slot name="detail"> </slot>
+      </template>
+    </FlexJobTopView>
+
+    <div class="businessCardHolder-card-footer">
+      <div class="businessCardHolder-card-footer-left-wrapper">
+        <div class="businessCardHolder-card-footer-left" v-if="showFooterLeft">
+          <slot name="footerLeft"> </slot>
+        </div>
+      </div>
+      <div class="businessCardHolder-card-footer-right" v-if="showFooterRight">
+        <slot name="footerRight"> </slot>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { CommonTaskCardProps } from './card';
+import FlexJobTopView from './FlexJobTopView.vue';
+import { Gender } from '@12333/constants';
+
+defineOptions({
+  name: 'BusinessCardHolderCard',
+});
+
+type Props = CommonTaskCardProps & {
+  showFooterLeft?: boolean;
+  showFooterRight?: boolean;
+  showDoneDetail?: boolean;
+
+  name?: string;
+  genderType?: Gender;
+  age?: number;
+  isRealName?: boolean;
+  educationalLevel?: string;
+  arrangeCount?: number;
+};
+
+const props = withDefaults(defineProps<Props>(), {
+  showFooterLeft: true,
+  showFooterRight: true,
+  showDoneDetail: true,
+});
+</script>
+
+<style lang="scss">
+@import '@/styles/common.scss';
+
+.businessCardHolder-card-wrapper {
+  padding: 32px 24px 20px;
+  margin-bottom: 24px;
+  background-color: #fff;
+  border-radius: 12px;
+
+  &:last-child {
+    margin-bottom: 0;
+  }
+
+  .businessCardHolder-card-top-wrapper {
+    margin-bottom: 38px;
+  }
+
+  .businessCardHolder-card-done-list {
+    font-size: 24px;
+    line-height: 36px;
+    color: boleGetCssVar('text-color', 'primary');
+    margin-bottom: 12px;
+    @include ellipsis;
+  }
+
+  .businessCardHolder-card-footer {
+    display: flex;
+    align-items: center;
+    border-top: #d9d9d9 1px solid;
+    padding-top: 24px;
+    margin-top: 18px;
+
+    .businessCardHolder-card-footer-left-wrapper {
+      flex: 1;
+      min-width: 0;
+    }
+
+    .businessCardHolder-card-footer-left {
+      .businessCardHolder-card-footer-text {
+        font-size: 24px;
+        line-height: 36px;
+        color: boleGetCssVar('color', 'primary');
+      }
+    }
+
+    .businessCardHolder-card-footer-right {
+      --nut-button-default-font-size: 24px;
+      --nut-button-default-height: 52px;
+      --nut-button-default-line-height: 49px;
+
+      .nut-button {
+        min-width: 144rpx;
+      }
+    }
+  }
+}
+</style>
diff --git a/packages/components/src/Card/FlexJobTopView.vue b/packages/components/src/Card/FlexJobTopView.vue
index ba2b4fd..35f10ac 100644
--- a/packages/components/src/Card/FlexJobTopView.vue
+++ b/packages/components/src/Card/FlexJobTopView.vue
@@ -12,7 +12,9 @@
           />
           <img v-else :src="IconFemale" class="flexJob-card-top-info-gender-icon" />
         </div>
-        <div class="flexJob-card-top-info-auth">{{ isRealName ? '宸插疄鍚�' : '鏈疄鍚�' }}</div>
+        <div class="flexJob-card-top-info-auth" :class="{ 'is-real-name': isRealName }">
+          {{ isRealName ? '宸插疄鍚�' : '鏈疄鍚�' }}
+        </div>
       </div>
       <slot name="detail">
         <div class="flexJob-card-top-info-detail">
@@ -97,6 +99,10 @@
         font-size: 28px;
         line-height: 34px;
         flex-shrink: 0;
+
+        &.is-real-name {
+          color: #2a9e1b;
+        }
       }
     }
 
diff --git a/packages/components/src/index.ts b/packages/components/src/index.ts
index 8702eca..e05bd94 100644
--- a/packages/components/src/index.ts
+++ b/packages/components/src/index.ts
@@ -27,6 +27,7 @@
 export { default as MyTaskCard } from './Card/MyTaskCard.vue';
 export { default as SignCard } from './Card/SignCard.vue';
 export { default as FlexJobCard } from './Card/FlexJobCard.vue';
+export { default as BusinessCardHolderCard } from './Card/BusinessCardHolderCard.vue';
 export { default as TaskPrice } from './Card/TaskPrice.vue';
 export { default as TaskDetailWelfareItem } from './Card/TaskDetailWelfareItem.vue';
 export { default as FlexJobTopView } from './Card/FlexJobTopView.vue';

--
Gitblit v1.9.1