wupengfei
2025-07-30 717f5388cf9c802ed76e87758c49fe78ad9ae5f8
feat: 页面
2个文件已添加
1 文件已重命名
6个文件已修改
525 ■■■■ 已修改文件
src/hooks/useEvent.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/CheckManage.vue 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/EmploymentManageArrange.vue 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/EmploymentSignList.vue 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/TaskManage.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/components/AddOrEditEmploymentView.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/components/CheckManageDialog.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/EmploymentManage/constants/columns.ts 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/hooks/useEvent.ts
@@ -3,8 +3,8 @@
export type GlobalEvent = {
  'home:add': any;
  'employment:add': any;
  'employment:edit': any;
  'taskManage:add': any;
  'taskManage:edit': any;
};
export type GlobalEventListener<T extends keyof GlobalEvent> = (payload: GlobalEvent[T]) => any;
src/router/index.ts
@@ -137,14 +137,14 @@
    },
    children: [
      {
        path: '/EmploymentManageList',
        name: 'EmploymentManageList',
        path: '/TaskManage',
        name: 'TaskManage',
        hidden: false,
        alwaysShow: true,
        component: () => import('@/views/EmploymentManage/EmploymentManage.vue'),
        component: () => import('@/views/EmploymentManage/TaskManage.vue'),
        meta: {
          rank: 10021,
          title: '用人管理',
          title: '任务管理',
          // rootMenu: true,
          icon: 'home',
        },
@@ -191,8 +191,8 @@
      {
        path: '/EmploymentManageArrange',
        name: 'EmploymentManageArrange',
        hidden: false,
        alwaysShow: true,
        hidden: true,
        alwaysShow: false,
        component: () => import('@/views/EmploymentManage/EmploymentManageArrange.vue'),
        meta: {
          rank: 10025,
@@ -201,6 +201,20 @@
          icon: 'home',
        },
      },
      {
        path: '/CheckManage',
        name: 'CheckManage',
        hidden: false,
        alwaysShow: true,
        component: () => import('@/views/EmploymentManage/CheckManage.vue'),
        meta: {
          rank: 10030,
          title: '验收管理',
          // rootMenu: true,
          icon: 'home',
        },
      },
    ],
  },
  {
src/views/EmploymentManage/CheckManage.vue
New file
@@ -0,0 +1,166 @@
<template>
  <LoadingLayout :loading="state.loading">
    <AppContainer>
      <ProTableQueryFilterBar @on-reset="reset">
        <template #query>
          <QueryFilterItem tip-content="验收状态">
            <FieldRadio
              v-model="extraParamState.flexEnterpriseSettingStatus"
              :value-enum="[
                { label: '已安排', value: 1 },
                { label: '待安排', value: 0 },
              ]"
              buttonStyle
              showAllBtn
              @change="getList()"
            />
          </QueryFilterItem>
          <QueryFilterItem>
            <FieldDatePicker
              v-model="extraParamState.flexEnterpriseSettingStatus"
              type="daterange"
              range-separator="~"
              start-placeholder="起始日期"
              end-placeholder="截止日期"
              clearable
              @change="getList()"
              tooltipContent="验收日期"
            ></FieldDatePicker>
          </QueryFilterItem>
          <QueryFilterItem>
            <SearchInput
              v-model="extraParamState.searchWord"
              style="width: 300px"
              placeholder="姓名/手机/身份证号/客户"
              @on-click-search="getList"
              @keyup.enter="getList()"
            >
            </SearchInput>
          </QueryFilterItem>
        </template>
      </ProTableQueryFilterBar>
      <ProTableV2
        v-bind="proTableProps"
        :columns="CheckManageColumns"
        :operationBtns="operationBtns"
      >
      </ProTableV2>
    </AppContainer>
    <CheckManageDialog v-bind="dialogProps" @check="handleCheck" />
  </LoadingLayout>
</template>
<script setup lang="ts">
import {
  ProTableQueryFilterBar,
  ProTableV2,
  SearchInput,
  LoadingLayout,
  AppContainer,
  QueryFilterItem,
  useTable,
  FieldDatePicker,
  FieldRadio,
  defineOperationBtns,
  useFormDialog,
} from '@bole-core/components';
import * as flexEnterpriseServices from '@/services/api/FlexEnterprise';
import { CheckManageColumns } from './constants';
import { FlexEnterpriseSettingStatus, Gender } from '@/constants';
import { OrderInputType } from '@bole-core/core';
import CheckManageDialog from './components/CheckManageDialog.vue';
defineOptions({
  name: 'CheckManage',
});
const operationBtns = defineOperationBtns([
  {
    data: {
      enCode: 'checkBtn',
      name: '验收',
    },
    emits: {
      onClick: (role) => openDialog(role, 'check'),
    },
  },
  {
    data: {
      enCode: 'detailBtn',
      name: '详情',
    },
    emits: {
      onClick: (role) => openDialog(role, 'detail'),
    },
  },
]);
const router = useRouter();
const BaseState = {
  loading: true,
};
const state = reactive({ ...BaseState });
onMounted(async () => {
  await getList();
  state.loading = false;
});
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetFlexEnterpriseInput = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
        flexEnterpriseSettingStatus: extraParamState.flexEnterpriseSettingStatus,
        searchWord: extraParamState.searchWord,
      };
      let res = await flexEnterpriseServices.getFlexEnterpriseList(params, {
        showLoading: !state.loading,
      });
      return res;
    } catch (error) {
      console.log('error: ', error);
    }
  },
  {
    defaultExtraParams: {
      searchWord: '',
      orderInput: [{ property: 'id', order: OrderInputType.Desc }],
      flexEnterpriseSettingStatus: '' as any as FlexEnterpriseSettingStatus,
    },
    queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'],
    columnsRenderProps: {},
  }
);
const { dialogProps, handleEdit, editForm } = useFormDialog({
  defaultFormParams: {
    id: '',
    type: '',
  },
});
function openDialog(row, type: string) {
  handleEdit({
    id: row.id,
    type: type,
  });
}
function handleCheck(val) {
  console.log('val: ', val);
}
</script>
src/views/EmploymentManage/EmploymentManageArrange.vue
@@ -50,9 +50,6 @@
            </SearchInput>
          </QueryFilterItem>
        </template>
        <template #btn>
          <el-button @click="goAddOrEdit()" type="primary">发布</el-button>
        </template>
      </ProTableQueryFilterBar>
      <ProTableV2
        v-bind="proTableProps"
@@ -80,7 +77,6 @@
import * as flexEnterpriseServices from '@/services/api/FlexEnterprise';
import { EmploymentArrangeColumns } from './constants';
import { OrderInputType, Message } from '@bole-core/core';
import { useGlobalEventContext } from '@/hooks';
import { FlexEnterpriseSettingStatus } from '@/constants';
defineOptions({
@@ -90,52 +86,9 @@
const operationBtns = defineOperationBtns([
  {
    data: {
      enCode: 'editBtn',
      name: '编辑',
    },
    emits: {
      onClick: (role) => goAddOrEdit(role),
    },
  },
  {
    data: {
      enCode: 'detailBtn',
      name: '详情',
    },
    emits: {
      onClick: (role) => goDetail(role),
    },
  },
  {
    data: {
      enCode: 'publishBtn',
      name: '发布',
    },
    emits: {
      onClick: (role) => handlePublish(role),
    },
    extraProps: {
      hide: (row) => false,
    },
  },
  {
    data: {
      enCode: 'unPublishBtn',
      name: '停止发布',
    },
    emits: {
      onClick: (role) => handleUnPublish(role),
    },
    extraProps: {
      hide: (row) => false,
    },
  },
  {
    data: {
      enCode: 'arrangeBtn',
      name: '安排',
    },
    props: { type: 'danger' },
    emits: {
      onClick: (role) => handleArrange(role),
    },
@@ -149,16 +102,6 @@
};
const state = reactive({ ...BaseState });
const eventContext = useGlobalEventContext();
eventContext.addEvent('employment:add', () => {
  getList();
});
eventContext.addEvent('employment:edit', () => {
  getList(paginationState.pageIndex);
});
onMounted(async () => {
  await getList();
@@ -203,32 +146,9 @@
  }
);
function handlePublish(row) {
  console.log(row);
}
function handleUnPublish(row) {
  console.log(row);
}
function handleArrange(row) {
  router.push({
    name: 'EmploymentManageArrange',
    params: {
      id: row?.id ?? '',
    },
  });
}
function goAddOrEdit(row?) {
  router.push({
    name: 'AddOrEditEmployment',
    params: {
      id: row?.id ?? '',
    },
  });
}
function goDetail(row) {
  router.push({
    name: 'EmploymentManageDetail',
    params: {
      id: row?.id ?? '',
    },
src/views/EmploymentManage/EmploymentSignList.vue
@@ -19,7 +19,7 @@
            <SearchInput
              v-model="extraParamState.searchWord"
              style="width: 250px"
              placeholder="任务名称"
              placeholder="姓名/身份证号/电话"
              @on-click-search="getList"
              @keyup.enter="getList()"
            >
@@ -34,6 +34,7 @@
      >
      </ProTableV2>
    </AppContainer>
    <StaffInfoDialog v-bind="dialogStaffInfoProps" />
  </LoadingLayout>
</template>
@@ -46,16 +47,17 @@
  AppContainer,
  QueryFilterItem,
  useTable,
  FieldDatePicker,
  FieldRadio,
  defineOperationBtns,
  useFormDialog,
  UploadUserFile,
} from '@bole-core/components';
import * as flexEnterpriseServices from '@/services/api/FlexEnterprise';
import { EmploymentSignColumns } from './constants/columns';
import { OrderInputType, Message } from '@bole-core/core';
import { useGlobalEventContext } from '@/hooks';
import { FlexEnterpriseSettingStatus } from '@/constants';
import { FlexEnterpriseSettingStatus, Gender } from '@/constants';
import StaffInfoDialog from '@/views/FlexJobManage/components/StaffInfoDialog.vue';
import { convertApi2FormUrlOnlyOne } from '@/utils';
defineOptions({
  name: 'EmploymentSignList',
@@ -105,16 +107,6 @@
const state = reactive({ ...BaseState });
const eventContext = useGlobalEventContext();
eventContext.addEvent('employment:add', () => {
  getList();
});
eventContext.addEvent('employment:edit', () => {
  getList(paginationState.pageIndex);
});
onMounted(async () => {
  await getList();
  state.loading = false;
@@ -158,6 +150,52 @@
  }
);
const {
  dialogProps: dialogStaffInfoProps,
  handleEdit: handleStaffInfoEdit,
  editForm: staffInfoEditForm,
} = useFormDialog({
  defaultFormParams: {
    id: '',
    name: '',
    idNumber: '',
    phoneNumber: '',
    genderType: Gender.Male,
    age: 0,
    companyId: '',
    customerId: '',
    idFrontUrl: [] as UploadUserFile[],
    idBackUrl: [] as UploadUserFile[],
    contractUrl: [] as UploadUserFile[],
    regiterTime: '',
    realVerifyTime: '',
    signTime: '',
    isDetail: false,
  },
});
function openDialog(row) {
  handleStaffInfoEdit({
    id: row.id,
    name: row.name,
    idNumber: row.idNumber,
    phoneNumber: row.phoneNumber,
    genderType: Gender.Male,
    age: row.age ?? 0,
    companyId: row.companyId,
    customerId: row.customerId,
    idFrontUrl: convertApi2FormUrlOnlyOne(row.idFrontUrl),
    idBackUrl: convertApi2FormUrlOnlyOne(row.idBackUrl),
    contractUrl: convertApi2FormUrlOnlyOne(row.contractUrl, {
      fileName: row.contractUrl ? row.contractUrl.split('/').pop() : '合同',
    }),
    regiterTime: row.regiterTime,
    realVerifyTime: row.realVerifyTime,
    signTime: row.signTime,
    isDetail: true,
  });
}
function handleRecruit(row) {}
function handleRefuse(row) {}
</script>
src/views/EmploymentManage/TaskManage.vue
File was renamed from src/views/EmploymentManage/EmploymentManage.vue
@@ -87,7 +87,7 @@
import { useGlobalEventContext } from '@/hooks';
defineOptions({
  name: 'EmploymentManageList',
  name: 'TaskManage',
});
const operationBtns = defineOperationBtns([
@@ -138,7 +138,6 @@
      enCode: 'arrangeBtn',
      name: '安排',
    },
    props: { type: 'danger' },
    emits: {
      onClick: (role) => handleArrange(role),
    },
@@ -155,11 +154,11 @@
const eventContext = useGlobalEventContext();
eventContext.addEvent('employment:add', () => {
eventContext.addEvent('taskManage:add', () => {
  getList();
});
eventContext.addEvent('employment:edit', () => {
eventContext.addEvent('taskManage:edit', () => {
  getList(paginationState.pageIndex);
});
src/views/EmploymentManage/components/AddOrEditEmploymentView.vue
@@ -170,7 +170,7 @@
function handleBack() {
  closeViewPush(route, {
    name: 'EmploymentManageList',
    name: 'TaskManage',
  });
}
const productFormRef = ref<FormInstance>();
@@ -190,7 +190,7 @@
    let res;
    if (res) {
      Message.successMessage('操作成功');
      eventContext.emit(isEdit ? 'employment:edit' : 'employment:add');
      eventContext.emit(isEdit ? 'taskManage:edit' : 'taskManage:add');
      handleBack();
    }
  } catch (error) {}
src/views/EmploymentManage/components/CheckManageDialog.vue
New file
@@ -0,0 +1,123 @@
<template>
  <ProDialog :title="title" v-model="visible" destroy-on-close draggable>
    <ProDialogTableWrapper :height="400">
      <ProTableV2 v-bind="proTableProps" :columns="columns" :operationBtns="operationBtns">
      </ProTableV2>
    </ProDialogTableWrapper>
    <template #footer>
      <span class="dialog-footer">
        <el-button v-if="form.type === 'detail'" @click="emit('onCancel')" type="primary"
          >确定</el-button
        >
        <template v-if="form.type === 'check'">
          <el-button @click="emit('check', false)">验收未通过</el-button>
          <el-button type="primary" @click="emit('check', true)">验收通过</el-button>
        </template>
      </span>
    </template>
  </ProDialog>
</template>
<script setup lang="ts">
import {
  ProDialog,
  ProTableV2,
  ProDialogTableWrapper,
  defineColumns,
  defineOperationBtns,
  useTable,
} from '@bole-core/components';
import { OrderInputType } from '@bole-core/core';
import * as flexEnterpriseServices from '@/services/api/FlexEnterprise';
defineOptions({
  name: 'EnterpriseConsumptionDetailDialog',
});
type Form = {
  id: string;
  type: string;
};
const visible = defineModel({ type: Boolean });
const form = defineModel<Form>('form');
const title = computed(() => (form.value.type === 'check' ? '验收' : '详情'));
const emit = defineEmits<{
  (e: 'onCancel'): void;
  (e: 'check', value: boolean): void;
}>();
const columns = defineColumns([
  {
    id: '1',
    enCode: 'creationTime',
    name: '提交时间',
  },
  {
    id: '2',
    enCode: 'type',
    name: '验收照片',
  },
]);
const operationBtns = defineOperationBtns([
  {
    data: {
      enCode: 'downloadBtn',
      name: '下载',
    },
    emits: {
      onClick: (role) => handleDownload(role),
    },
  },
]);
watch(
  () => visible.value,
  (val) => {
    if (val) {
      getList();
    }
  },
  {
    immediate: true,
  }
);
const {
  getDataSource: getList,
  proTableProps,
  paginationState,
  extraParamState,
  reset,
} = useTable(
  async ({ pageIndex, pageSize }, extraParamState) => {
    try {
      let params: API.GetFlexEnterpriseInput = {
        pageModel: {
          rows: pageSize,
          page: pageIndex,
          orderInput: extraParamState.orderInput,
        },
      };
      let res = await flexEnterpriseServices.getFlexEnterpriseList(params);
      return res;
    } catch (error) {
      console.log('error: ', error);
    }
  },
  {
    defaultExtraParams: {
      orderInput: [{ property: 'id', order: OrderInputType.Desc }],
    },
    queryKey: ['flexEnterpriseServices/getFlexEnterpriseList'],
    columnsRenderProps: {},
  }
);
function handleDownload(row) {}
</script>
<style lang="scss" scoped>
@use '@/style/common.scss' as *;
</style>
src/views/EmploymentManage/constants/columns.ts
@@ -152,3 +152,52 @@
    width: 140,
  },
]);
export const CheckManageColumns = defineColumns([
  {
    id: '1',
    enCode: 'name',
    name: '姓名',
    width: 180,
  },
  {
    id: '2',
    enCode: 'name',
    name: '身份证号',
    width: 180,
  },
  {
    id: '3',
    enCode: 'name',
    name: '性别',
  },
  {
    id: '4',
    enCode: 'name',
    name: '年龄',
  },
  {
    id: '5',
    enCode: 'name',
    name: '手机号',
    width: 140,
  },
  {
    id: '6',
    enCode: 'name',
    name: '所属客户',
    width: 140,
  },
  {
    id: '7',
    enCode: 'name',
    name: '提交时间',
    width: 140,
  },
  {
    id: '8',
    enCode: 'name',
    name: '验收状态',
    width: 140,
  },
]);