wupengfei
8 天以前 3c7cbba6d64ca8bf7b1307023072b505414f7d5d
feat: 名片
15个文件已添加
4个文件已修改
485 ■■■■■ 已修改文件
apps/bMiniApp/project.private.config.json 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/app.config.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/assets/businessCard/icon-address.png 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/assets/businessCard/icon-company.png 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/assets/businessCard/icon-email.png 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/assets/businessCard/icon-position.png 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/assets/businessCard/icon-wechat.png 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/constants/router.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/pages/mine/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCard/businessCard.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCard/businessCard.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/InnerPage.vue 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/businessCardEdit.config.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/businessCardEdit.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
apps/bMiniApp/project.private.config.json
@@ -77,6 +77,13 @@
                    "query": "",
                    "launchMode": "default",
                    "scene": null
                },
                {
                    "name": "",
                    "pathName": "subpackages/businessCard/businessCard/businessCard",
                    "query": "",
                    "launchMode": "default",
                    "scene": null
                }
            ]
        }
apps/bMiniApp/src/app.config.ts
@@ -75,6 +75,10 @@
      ],
    },
    {
      root: 'subpackages/businessCard',
      pages: ['businessCard/businessCard', 'businessCardEdit/businessCardEdit'],
    },
    {
      root: 'subpackages/task',
      pages: [
        'publishTask/publishTask',
apps/bMiniApp/src/assets/businessCard/icon-address.png
apps/bMiniApp/src/assets/businessCard/icon-company.png
apps/bMiniApp/src/assets/businessCard/icon-email.png
apps/bMiniApp/src/assets/businessCard/icon-position.png
apps/bMiniApp/src/assets/businessCard/icon-wechat.png
apps/bMiniApp/src/constants/router.ts
@@ -33,6 +33,9 @@
  mineFavorites = '/subpackages/mine/mineFavorites/mineFavorites',
  mineContactRecord = '/subpackages/mine/mineContactRecord/mineContactRecord',
  businessCard = '/subpackages/businessCard/businessCard/businessCard',
  businessCardEdit = '/subpackages/businessCard/businessCardEdit/businessCardEdit',
  publishTask = '/subpackages/task/publishTask/publishTask',
  taskCheck = '/subpackages/task/taskCheck/taskCheck',
  taskCheckDetail = '/subpackages/task/taskCheckDetail/taskCheckDetail',
apps/bMiniApp/src/pages/mine/index.vue
@@ -43,7 +43,7 @@
          </div>
        </template>
        <div class="mine-business-card">
          <div class="mine-business-card-item">
          <div class="mine-business-card-item" @click="goBusinessCard">
            <img class="mine-business-card-item-icon" :src="IconBusinessCard" alt="" />
            <div class="mine-business-card-item-text">我的电子名片</div>
          </div>
@@ -152,6 +152,10 @@
  goPage(RouterPath.mineContactRecord);
}
function goBusinessCard() {
  goPage(RouterPath.businessCard);
}
async function handleLoginout() {
  try {
    await Message.confirm({
apps/bMiniApp/src/subpackages/businessCard/businessCard/InnerPage.vue
New file
@@ -0,0 +1,39 @@
<template>
  <ProTabs
    v-model="businessCardType"
    name="home-tab"
    class="home-tabs"
    isTransparent
    title-gutter="12"
    title-scroll
  >
    <ProTabPane :title="`我的名片`" pane-key="1">
      <BusinessCardView></BusinessCardView>
    </ProTabPane>
    <ProTabPane :title="`我的名片夹`" pane-key="2">
      <BusinessCardHolderView></BusinessCardHolderView>
    </ProTabPane>
  </ProTabs>
</template>
<script setup lang="ts">
import { ProTabs, ProTabPane } from '@12333/components';
import BusinessCardView from '../components/BusinessCardView.vue';
import BusinessCardHolderView from '../components/BusinessCardHolderView.vue';
defineOptions({
  name: 'InnerPage',
});
const businessCardType = ref('1');
</script>
<style lang="scss">
@import '@/styles/common.scss';
.businessCard-page-wrapper {
  .nut-tab-pane {
    background-color: transparent;
  }
}
</style>
apps/bMiniApp/src/subpackages/businessCard/businessCard/businessCard.config.ts
New file
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/bMiniApp/src/subpackages/businessCard/businessCard/businessCard.vue
New file
@@ -0,0 +1,17 @@
<template>
  <PageLayoutWithBg class="businessCard-page-wrapper" :title="'电子名片'">
    <InnerPage></InnerPage>
  </PageLayoutWithBg>
</template>
<script setup lang="ts">
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'businessCard',
});
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/InnerPage.vue
New file
@@ -0,0 +1,137 @@
<template>
  <ContentScrollView :paddingH="false">
    <nut-form :model-value="form" ref="formRef" :rules="rules">
      <nut-form-item label="头像:" class="bole-form-item" prop="avatarUrl">
        <Uploader v-model:file-list="form.avatarUrl" :maximum="1" class="bole-uploader"> </Uploader>
      </nut-form-item>
      <nut-form-item label="姓名:" class="bole-form-item" prop="name">
        <nut-input v-model="form.name" placeholder="请输入您的姓名"> </nut-input>
      </nut-form-item>
      <nut-form-item label="微信号:" class="bole-form-item" prop="name">
        <nut-input v-model="form.name" placeholder="请输入您的微信号"> </nut-input>
      </nut-form-item>
      <nut-form-item label="职位:" class="bole-form-item" prop="name">
        <nut-input v-model="form.name" placeholder="请输入您的职位"> </nut-input>
      </nut-form-item>
      <nut-form-item label="邮箱:" class="bole-form-item" prop="name">
        <nut-input v-model="form.name" placeholder="请输入您的邮箱"> </nut-input>
      </nut-form-item>
      <nut-form-item label="公司名:" class="bole-form-item" prop="name">
        <nut-input v-model="form.name" placeholder="请输入您的公司名"> </nut-input>
      </nut-form-item>
      <nut-form-item label="公司所在地" class="bole-form-item" prop="areaList" required>
        <ChooseInputWithAreaPicker
          :columns="areaTreeList"
          v-model="form.areaList"
          placeholder="请选择您公司的所在地"
        ></ChooseInputWithAreaPicker>
      </nut-form-item>
      <nut-form-item label="公司简介:" class="bole-form-item alignTop" prop="name">
        <nut-textarea
          placeholder="请输入公司简介"
          placeholderClass="bole-input-text-placeholder"
          autoSize
          class="bole-input-textarea"
          v-model="form.name"
          :max-length="500"
          show-word-limit
        >
        </nut-textarea>
      </nut-form-item>
    </nut-form>
  </ContentScrollView>
  <PageFooter>
    <PageFooterBtn type="primary" plain @click="handleCancel">取消</PageFooterBtn>
    <PageFooterBtn type="primary" @click="handleConfirm">确认</PageFooterBtn>
  </PageFooter>
</template>
<script setup lang="ts">
import { useUser } from '@/hooks';
import { ChooseInputWithAreaPicker } from '@12333/components';
import { FormValidator, Message } from '@12333/utils';
import * as flexWorkerServices from '@12333/services/api/FlexWorker';
import { FormRules } from '@nutui/nutui-taro/dist/types/__VUE/form/types';
import Taro from '@tarojs/taro';
import { goBack } from '@/utils';
import { useAllAreaList } from '@12333/hooks';
import { useQuery } from '@tanstack/vue-query';
defineOptions({
  name: 'InnerPage',
});
const { userDetail } = useUser();
const { areaTreeList } = useAllAreaList();
const router = Taro.useRouter();
const taskId = router.params?.taskId ?? '';
const form = reactive({
  avatarUrl: [],
  name: '',
  areaList: [] as number[],
});
const rules = reactive<FormRules>({
  name: [{ required: true, message: '请输入姓名' }],
  areaList: [
    { required: true, message: '请选择公司所在地', validator: FormValidator.validatorArray },
  ],
});
const {
  isLoading,
  isError,
  data: detail,
  refetch,
} = useQuery({
  queryKey: ['flexWorkerServices/getFlexTaskDto', taskId],
  queryFn: async () => {
    return await flexWorkerServices.getFlexTaskDto(
      { id: taskId },
      {
        showLoading: false,
      }
    );
  },
  placeholderData: () => ({} as API.GetFlexTaskDtoOutput),
  onSuccess(data) {},
});
const formRef = ref<any>(null);
function handleConfirm() {
  if (!formRef.value) return;
  formRef.value.validate().then(({ valid, errors }: any) => {
    if (valid) {
      confirm();
    }
  });
}
async function confirm() {
  try {
    let params: {};
    let res = await flexWorkerServices.addEidtFlexTask(params);
    if (res) {
      Message.success('编辑成功', {
        onClosed() {
          goBack();
        },
      });
    }
  } catch (error) {}
}
function handleCancel() {
  Taro.navigateBack();
}
</script>
<style lang="scss">
@import '@/styles/common.scss';
.businessCardEdit-page-wrapper {
  //
}
</style>
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/businessCardEdit.config.ts
New file
@@ -0,0 +1,3 @@
export default definePageConfig({
  disableScroll: true,
});
apps/bMiniApp/src/subpackages/businessCard/businessCardEdit/businessCardEdit.vue
New file
@@ -0,0 +1,17 @@
<template>
  <PageLayout class="businessCardEdit-page-wrapper" :title="'电子名片'" has-border>
    <InnerPage></InnerPage>
  </PageLayout>
</template>
<script setup lang="ts">
import InnerPage from './InnerPage.vue';
defineOptions({
  name: 'businessCardEdit',
});
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailInfoView.vue
New file
@@ -0,0 +1,82 @@
<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>
  </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">
import TaskCheckPersonalView from '../../task/components/TaskCheckPersonalView.vue';
import BusinessCardDetailItem from './BusinessCardDetailItem.vue';
import IconWechat from '@/assets/businessCard/icon-wechat.png';
import IconPosition from '@/assets/businessCard/icon-position.png';
import IconEmail from '@/assets/businessCard/icon-email.png';
import IconCompany from '@/assets/businessCard/icon-company.png';
import IconAddress from '@/assets/businessCard/icon-address.png';
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;
  .flexJob-card-top-wrapper {
    padding-top: 40px;
    padding-bottom: 32px;
    border-bottom: 1px solid #d9d9d9;
  }
  .business-card-detail {
    padding: 20px 0 10px;
  }
}
.business-card-detail-company-intro {
  background-color: #ffffff;
  margin-top: 30px;
  padding: 30px 24px;
  .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;
  }
}
</style>
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardDetailItem.vue
New file
@@ -0,0 +1,42 @@
<template>
  <div class="business-card-detail-item">
    <img :src="icon" class="business-card-detail-item-icon" />
    <div class="business-card-detail-item-value">{{ value }}</div>
  </div>
</template>
<script setup lang="ts">
defineOptions({
  name: 'BusinessCardDetailItem',
});
type Props = {
  icon?: string;
  value?: string;
};
const props = withDefaults(defineProps<Props>(), {});
</script>
<style lang="scss">
@import '@/styles/common.scss';
.business-card-detail-item {
  margin-bottom: 24px;
  display: flex;
  align-items: center;
  .business-card-detail-item-icon {
    width: 32px;
    height: 32px;
    margin-right: 14px;
  }
  .business-card-detail-item-value {
    font-weight: 400;
    font-size: 24px;
    color: #4e5969;
    line-height: 36px;
  }
}
</style>
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardHolderView.vue
New file
@@ -0,0 +1,65 @@
<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"
      >
        <template #footerLeft>
          <div class="flexJob-card-footer-text">{{ FlexTaskWorkerHireEnum[item.hireStatus] }}</div>
        </template>
        <template #footerRight>
          <nut-button type="primary" @click="handleDelete()">删除</nut-button>
          <nut-button type="primary" @click="goForward()">转发</nut-button>
        </template>
      </FlexJobCard>
    </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 Taro from '@tarojs/taro';
defineOptions({
  name: 'BusinessCardHolderView',
});
const router = Taro.useRouter();
const id = router.params?.id ?? '';
const { infiniteLoadingProps } = useInfiniteLoading(
  ({ pageParam }) => {
    let params: API.GetFlexTaskWorkerApplyListInput = {
      // flexTaskId: id,
      pageModel: {
        rows: 20,
        page: pageParam,
        orderInput: [{ property: 'creationTime', order: OrderInputType.Desc }],
      },
    };
    return flexWorkerServices.getFlexTaskWorkerApplyList(params, {
      showLoading: false,
    });
  },
  {
    queryKey: ['flexWorkerServices/getFlexTaskWorkerApplyList'],
  }
);
function handleDelete() {}
function goForward() {}
</script>
<style lang="scss">
@import '@/styles/common.scss';
</style>
apps/bMiniApp/src/subpackages/businessCard/components/BusinessCardView.vue
New file
@@ -0,0 +1,60 @@
<template>
  <LoadingLayout :loading="isLoading" :error="isError" :loadError="refetch">
    <BusinessCardDetailInfoView @edit="goEditBusinessCard"></BusinessCardDetailInfoView>
    <PageFooterBtn type="primary" class="business-card-btn">递名片</PageFooterBtn>
  </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 './BusinessCardDetailInfoView.vue';
defineOptions({
  name: 'BusinessCardView',
});
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) {},
});
function goEditBusinessCard() {
  Taro.navigateTo({
    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;
  }
}
</style>