| <template> | 
|   <LoadingLayout :loading="state.loading"> | 
|     <AppContainer> | 
|       <ProTableQueryFilterBar @on-reset="reset"> | 
|         <template #query> | 
|           <QueryFilterItem tip-content="录用状态"> | 
|             <FieldRadio | 
|               v-model="extraParamState.hireStatus" | 
|               :value-enum="EnumTaskUserHireStatusText" | 
|               buttonStyle | 
|               showAllBtn | 
|               @change="getList()" | 
|             /> | 
|           </QueryFilterItem> | 
|           <QueryFilterItem tip-content="实名状态"> | 
|             <FieldRadio | 
|               v-model="extraParamState.isReal" | 
|               :value-enum="[ | 
|                 { label: '已实名', value: true }, | 
|                 { label: '未实名', value: false }, | 
|               ]" | 
|               buttonStyle | 
|               showAllBtn | 
|               :all-btn-value="null" | 
|               @change="getList()" | 
|             /> | 
|           </QueryFilterItem> | 
|           <QueryFilterItem tip-content="灵工签约状态"> | 
|             <FieldSelect | 
|               v-model="extraParamState.userSignContractStatus" | 
|               :value-enum="EnumTaskUserSignContractStatusText" | 
|               placeholder="请选择灵工签约状态" | 
|               clearable | 
|               @change="getList()" | 
|             /> | 
|           </QueryFilterItem> | 
|           <QueryFilterItem tip-content="企业签约状态"> | 
|             <FieldSelect | 
|               v-model="extraParamState.enterpriseSignContractStatus" | 
|               :value-enum="EnumTaskUserSignContractStatusText" | 
|               placeholder="请选择企业签约状态" | 
|               clearable | 
|               @change="getList()" | 
|             /> | 
|           </QueryFilterItem> | 
|           <QueryFilterItem> | 
|             <FieldDatePicker | 
|               v-model="extraParamState.createdTime" | 
|               type="daterange" | 
|               range-separator="~" | 
|               start-placeholder="起始日期" | 
|               end-placeholder="截止日期" | 
|               clearable | 
|               @change="getList()" | 
|               tooltipContent="登记时间" | 
|             ></FieldDatePicker> | 
|           </QueryFilterItem> | 
|           <QueryFilterItem> | 
|             <FieldDatePicker | 
|               v-model="extraParamState.signContractTime" | 
|               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> | 
|         <template #btn> | 
|           <el-button @click="handleDownloadTemplate()" type="primary" link>模板下载</el-button> | 
|           <el-button @click="handleBatchImportAdd()" type="primary">批量导入</el-button> | 
|           <el-button @click="handleBatchUnSign()" type="primary">批量解约</el-button> | 
|           <el-button @click="handleSendShotMessage()" type="primary">短信发送</el-button> | 
|           <el-button @click="handleBatchSign()" type="primary">批量签约</el-button> | 
|           <el-button @click="handleEnterpriseBatchSign()" type="primary">批量企业签约</el-button> | 
|         </template> | 
|       </ProTableQueryFilterBar> | 
|       <ProTableV2 | 
|         v-bind="proTableProps" | 
|         :columns="FlexJobManageColumns" | 
|         :operationBtns="operationBtns" | 
|         show-column-check | 
|         ref="proTable" | 
|         :table-props="{ | 
|           rowKey: 'id', | 
|         }" | 
|       > | 
|       </ProTableV2> | 
|     </AppContainer> | 
|     <StaffInfoDialog v-bind="dialogStaffInfoProps" /> | 
|     <StaffDetailInfoDialog v-bind="dialogStaffDetailProps" /> | 
|     <BatchImportDialog | 
|       v-bind="dialogBatchImportProps" | 
|       @onDownloadTemplate="handleDownloadTemplate" | 
|     /> | 
|     <SendShotMessageDialog v-bind="dialogShotMessageProps" /> | 
|     <SignDialog v-bind="dialogSignProps" /> | 
|   </LoadingLayout> | 
| </template> | 
|   | 
| <script setup lang="ts"> | 
| import { | 
|   ProTableQueryFilterBar, | 
|   OperationBtnType, | 
|   ProTableV2, | 
|   SearchInput, | 
|   LoadingLayout, | 
|   AppContainer, | 
|   QueryFilterItem, | 
|   useTable, | 
|   FieldDatePicker, | 
|   FieldRadio, | 
|   FieldSelect, | 
|   defineOperationBtns, | 
|   useFormDialog, | 
|   UploadUserFile, | 
|   XLSXUtils, | 
| } from '@bole-core/components'; | 
| import { FlexJobManageColumns } from './constants'; | 
| import { EnumTaskUserHireStatusText, EnumTaskUserSignContractStatusText } from '@/constants'; | 
| import { Message } from '@bole-core/core'; | 
| import { convertApi2FormUrlOnlyOne, downloadFileByUrl, format } from '@/utils'; | 
| import StaffInfoDialog from './components/StaffInfoDialog.vue'; | 
| import BatchImportDialog from './components/BatchImportDialog.vue'; | 
| import SendShotMessageDialog from './components/SendShotMessageDialog.vue'; | 
| import StaffDetailInfoDialog from './components/StaffDetailInfoDialog.vue'; | 
| import SignDialog from './components/SignDialog.vue'; | 
| import * as enterpriseEmployeeServices from '@/services/api/enterpriseEmployee'; | 
| import { ModelValueType } from 'element-plus'; | 
|   | 
| defineOptions({ | 
|   name: 'FlexJobManageList', | 
| }); | 
|   | 
| const operationBtns = defineOperationBtns([ | 
|   { | 
|     data: { | 
|       enCode: 'editBtn', | 
|       name: '编辑', | 
|     }, | 
|     emits: { | 
|       onClick: (role) => openDialog(role), | 
|     }, | 
|   }, | 
|   { | 
|     data: { | 
|       enCode: 'detailBtn', | 
|       name: '详情', | 
|     }, | 
|     emits: { | 
|       onClick: (role: API.GetEnterpriseEmployeesQueryResultItem) => | 
|         handleStaffDetailEdit({ id: role.id, tabType: 'info' }), | 
|     }, | 
|   }, | 
|   { | 
|     data: { | 
|       enCode: 'enterpriseSignBtn', | 
|       name: '企业签约', | 
|     }, | 
|     emits: { | 
|       onClick: (role) => handleEnterpriseSign(role), | 
|     }, | 
|     extraProps: { | 
|       hide: (row: API.GetEnterpriseEmployeesQueryResultItem) => | 
|         !( | 
|           row.userSignContractStatus === EnumTaskUserSignContractStatus.Pass && | 
|           row.enterpriseSignContractStatus === EnumTaskUserSignContractStatus.Wait | 
|         ), | 
|     }, | 
|   }, | 
|   { | 
|     data: { | 
|       enCode: 'inviteSignBtn', | 
|       name: '邀请签约', | 
|     }, | 
|     emits: { | 
|       onClick: (role) => handleInviteSign(role), | 
|     }, | 
|     extraProps: { | 
|       hide: (row: API.GetEnterpriseEmployeesQueryResultItem) => | 
|         !( | 
|           row.userSignContractStatus !== EnumTaskUserSignContractStatus.Pass && | 
|           row.hireStatus === EnumTaskUserHireStatus.Pass | 
|         ), | 
|     }, | 
|   }, | 
|   { | 
|     data: { | 
|       enCode: 'unSignBtn', | 
|       name: '解约', | 
|     }, | 
|     emits: { | 
|       onClick: (role) => handleUnSign(role), | 
|     }, | 
|     extraProps: { | 
|       hide: (row: API.GetEnterpriseEmployeesQueryResultItem) => | 
|         !( | 
|           row.userSignContractStatus === EnumTaskUserSignContractStatus.Pass && | 
|           row.enterpriseSignContractStatus === EnumTaskUserSignContractStatus.Pass | 
|         ), | 
|     }, | 
|   }, | 
|   // { | 
|   //   data: { | 
|   //     enCode: 'delBtn', | 
|   //     name: '删除', | 
|   //   }, | 
|   //   props: { type: 'danger' }, | 
|   //   emits: { | 
|   //     onClick: (role) => handleDelete(role), | 
|   //   }, | 
|   // }, | 
| ]); | 
|   | 
| 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.GetEnterpriseEmployeesQuery = { | 
|         pageModel: { | 
|           rows: pageSize, | 
|           page: pageIndex, | 
|           orderInput: extraParamState.orderInput, | 
|         }, | 
|         keywords: extraParamState.searchWord, | 
|         createdTimeStart: format(extraParamState.createdTime?.[0] ?? '', 'YYYY-MM-DD 00:00:00'), | 
|         createdTimeEnd: format(extraParamState.createdTime?.[1] ?? '', 'YYYY-MM-DD 23:59:59'), | 
|         signContractTimeStart: format( | 
|           extraParamState.signContractTime?.[0] ?? '', | 
|           'YYYY-MM-DD 00:00:00' | 
|         ), | 
|         signContractTimeEnd: format( | 
|           extraParamState.signContractTime?.[1] ?? '', | 
|           'YYYY-MM-DD 23:59:59' | 
|         ), | 
|         hireStatus: extraParamState.hireStatus, | 
|         isReal: extraParamState.isReal, | 
|         userSignContractStatus: extraParamState.userSignContractStatus, | 
|         enterpriseSignContractStatus: extraParamState.enterpriseSignContractStatus, | 
|       }; | 
|   | 
|       let res = await enterpriseEmployeeServices.getEnterpriseEmployees(params, { | 
|         showLoading: !state.loading, | 
|       }); | 
|       return res; | 
|     } catch (error) { | 
|       console.log('error: ', error); | 
|     } | 
|   }, | 
|   { | 
|     defaultExtraParams: { | 
|       searchWord: '', | 
|       orderInput: [{ property: 'createdTime', order: EnumPagedListOrder.Desc }], | 
|       createdTime: [] as unknown as ModelValueType, | 
|       signContractTime: [] as unknown as ModelValueType, | 
|       hireStatus: '' as any as EnumTaskUserHireStatus, | 
|       isReal: null as any as boolean, | 
|       userSignContractStatus: '' as any as EnumTaskUserSignContractStatus, | 
|       enterpriseSignContractStatus: '' as any as EnumTaskUserSignContractStatus, | 
|     }, | 
|     queryKey: ['enterpriseEmployeeServices/getEnterpriseEmployees'], | 
|     columnsRenderProps: { | 
|       gender: { type: 'enum', valueEnum: EnumUserGenderTextForPerson }, | 
|       hireStatus: { type: 'enum', valueEnum: EnumTaskUserHireStatusText }, | 
|       userIsReal: { | 
|         formatter: (row: API.GetEnterpriseEmployeesQueryResultItem) => { | 
|           return row.userIsReal ? '已实名' : '未实名'; | 
|         }, | 
|       }, | 
|       userSignContractStatus: { type: 'enum', valueEnum: EnumTaskUserSignContractStatusText }, | 
|       hireTime: { type: 'date' }, | 
|       userRealTime: { type: 'date' }, | 
|       userSignContractTime: { type: 'date' }, | 
|       enterpriseSignContractStatus: { type: 'enum', valueEnum: EnumTaskUserSignContractStatusText }, | 
|       enterpriseSignContractTime: { type: 'date' }, | 
|     }, | 
|   } | 
| ); | 
|   | 
| const proTable = ref<InstanceType<typeof ProTableV2>>(); | 
|   | 
| function getSelectionRows() { | 
|   if (proTableProps.value.tableData.length) { | 
|     const res = proTable.value.innerTableRef.getSelectionRows(); | 
|     if (res.length > 0) { | 
|       return res; | 
|     } else { | 
|       Message.errorMessage('未选择数据'); | 
|     } | 
|   } else { | 
|     Message.errorMessage('暂无数据'); | 
|   } | 
| } | 
|   | 
| const { | 
|   dialogProps: dialogStaffInfoProps, | 
|   handleEdit: handleStaffInfoEdit, | 
|   editForm: staffInfoEditForm, | 
| } = useFormDialog({ | 
|   onConfirm: handleAddOrEdit, | 
|   defaultFormParams: { | 
|     id: '', | 
|     name: '', | 
|     identity: '', | 
|     contactPhoneNumber: '', | 
|     gender: EnumUserGender.Male, | 
|     age: null as any as number, | 
|     identityImg: [] as UploadUserFile[], | 
|     identityBackImg: [] as UploadUserFile[], | 
|     contractUrl: [] as UploadUserFile[], | 
|     regiterTime: '', | 
|     userRealTime: '', | 
|     userSignContractTime: '', | 
|     isDetail: false, | 
|   }, | 
| }); | 
|   | 
| async function openDialog(row: API.GetEnterpriseEmployeesQueryResultItem, isDetail = false) { | 
|   try { | 
|     let detail = await enterpriseEmployeeServices.getEnterpriseEmployee({ id: row.id }); | 
|     handleStaffInfoEdit({ | 
|       id: row.id, | 
|       name: row.name, | 
|       identity: row.identity, | 
|       contactPhoneNumber: row.contactPhoneNumber, | 
|       gender: detail.gender, | 
|       age: detail.age ?? null, | 
|       identityImg: convertApi2FormUrlOnlyOne(detail.identityImg), | 
|       identityBackImg: convertApi2FormUrlOnlyOne(detail.identityBackImg), | 
|       contractUrl: convertApi2FormUrlOnlyOne(detail.contractUrl, { | 
|         fileName: detail.contractUrl ? detail.contractUrl.split('/').pop() : '合同', | 
|       }), | 
|       regiterTime: detail.applyTime ?? '', | 
|       userRealTime: row.userRealTime ?? '', | 
|       userSignContractTime: row.userSignContractTime ?? '', | 
|       isDetail: isDetail, | 
|     }); | 
|   } catch (error) {} | 
| } | 
|   | 
| async function handleAddOrEdit() { | 
|   try { | 
|     let params: API.EditEnterpriseEmployeeCommand = { | 
|       name: staffInfoEditForm.name, | 
|       identity: staffInfoEditForm.identity, | 
|       contactPhoneNumber: staffInfoEditForm.contactPhoneNumber, | 
|       gender: staffInfoEditForm.gender, | 
|       age: staffInfoEditForm.age, | 
|       identityImg: staffInfoEditForm.identityImg[0]?.path ?? '', | 
|       identityBackImg: staffInfoEditForm.identityBackImg[0]?.path ?? '', | 
|       id: staffInfoEditForm.id, | 
|     }; | 
|     let res = await enterpriseEmployeeServices.editEnterpriseEmployee(params); | 
|     if (res) { | 
|       Message.successMessage('操作成功'); | 
|       getList(paginationState.pageIndex); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| const { | 
|   dialogProps: dialogBatchImportProps, | 
|   handleAdd: handleBatchImportAdd, | 
|   editForm: batchImportForm, | 
| } = useFormDialog({ | 
|   onConfirm: handleBatchImport, | 
|   defaultFormParams: { | 
|     url: [] as UploadUserFile[], | 
|   }, | 
| }); | 
|   | 
| async function handleBatchImport() { | 
|   try { | 
|     let params: API.ImportEnterpriseEmployeesCommand = { | 
|       excelUrl: batchImportForm.url[0]?.path ?? '', | 
|     }; | 
|     let res = await enterpriseEmployeeServices.importEnterpriseEmployees(params); | 
|     if (res.failCount > 0) { | 
|       await Message.tipMessage('存在错误数据,是否导出?'); | 
|       XLSXUtils.exportToXLSX({ | 
|         workbookDataList: res.errors, | 
|         fileName: '灵工批量导入-错误数据', | 
|         workbookHeaderMap: { | 
|           name: '姓名', | 
|           identity: '身份证号', | 
|           contactPhoneNumber: '手机号', | 
|           errorMessage: '备注', | 
|         }, | 
|       }); | 
|     } else { | 
|       Message.successMessage('导入成功'); | 
|       getList(); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| const { | 
|   dialogProps: dialogShotMessageProps, | 
|   handleAdd: handleShotMessageAdd, | 
|   editForm: editShotMessageForm, | 
| } = useFormDialog({ | 
|   onConfirm: sendMessageForSign, | 
|   defaultFormParams: { | 
|     ids: [] as string[], | 
|     customerId: '', | 
|     name: '', | 
|     contractTemplateId: '', | 
|   }, | 
| }); | 
|   | 
| async function handleSendShotMessage() { | 
|   try { | 
|     const selectionRows = getSelectionRows(); | 
|     if (selectionRows) { | 
|       if ( | 
|         selectionRows.some((x) => x.userSignContractStatus === EnumTaskUserSignContractStatus.Pass) | 
|       ) { | 
|         await Message.tipMessage('勾选人员中包含已签约完成人员,确认要继续发送短信通知吗?'); | 
|       } | 
|       handleShotMessageAdd({ | 
|         ids: selectionRows.map((x) => x.id), | 
|         name: '人员签约通道短信', | 
|       }); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| async function sendMessageForSign() { | 
|   try { | 
|     let params: API.SendInviteElectronSignSmsCommand = { | 
|       ids: editShotMessageForm.ids, | 
|       contractTemplateId: editShotMessageForm.contractTemplateId, | 
|     }; | 
|     let res = await enterpriseEmployeeServices.sendInviteElectronSignSms(params); | 
|     if (res) { | 
|       Message.successMessage('短信已发送'); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| function handleDownloadTemplate() { | 
|   downloadFileByUrl(ImportEnterpriseEmployeesTempPath, '批量导入模板'); | 
| } | 
|   | 
| const { | 
|   dialogProps: dialogSignProps, | 
|   handleAdd: handleSignAdd, | 
|   handleEdit: handleSignEdit, | 
|   editForm: signEditForm, | 
| } = useFormDialog({ | 
|   onConfirm: signContract, | 
|   defaultFormParams: { | 
|     ids: [] as string[], | 
|     contractTemplateId: '', | 
|   }, | 
| }); | 
|   | 
| function handleInviteSign(row: API.GetEnterpriseEmployeesQueryResultItem) { | 
|   if (row) { | 
|     handleSignEdit({ | 
|       ids: [row.id], | 
|       contractTemplateId: '', | 
|     }); | 
|   } | 
| } | 
| function handleBatchSign() { | 
|   const selectionRows = getSelectionRows(); | 
|   if (selectionRows) { | 
|     const hasSigned = selectionRows?.some( | 
|       (x) => | 
|         x.userSignContractStatus === EnumTaskUserSignContractStatus.Pass || | 
|         x.enterpriseSignContractStatus === EnumTaskUserSignContractStatus.Pass || | 
|         x.hireStatus === EnumTaskUserHireStatus.Wait | 
|     ); | 
|     if (hasSigned) { | 
|       Message.warnMessage('勾选人员中包含已签约完成或未录用人员'); | 
|       return; | 
|     } | 
|     handleSignAdd({ | 
|       ids: selectionRows.map((x) => x.id), | 
|       contractTemplateId: '', | 
|     }); | 
|   } | 
| } | 
|   | 
| function handleEnterpriseBatchSign() { | 
|   const selectionRows = getSelectionRows(); | 
|   if (selectionRows) { | 
|     const hasSigned = selectionRows?.some( | 
|       (x) => | 
|         !( | 
|           x.userSignContractStatus === EnumTaskUserSignContractStatus.Pass && | 
|           x.enterpriseSignContractStatus === EnumTaskUserSignContractStatus.Wait | 
|         ) | 
|     ); | 
|     if (hasSigned) { | 
|       Message.warnMessage('勾选人员中包含已企业签约、未录用人员或未签约完成人员'); | 
|       return; | 
|     } | 
|     const ids = selectionRows.map((x) => x.id); | 
|     handleBatchEnterpriseSign(ids); | 
|   } | 
| } | 
|   | 
| async function handleBatchEnterpriseSign(ids: string[]) { | 
|   try { | 
|     let res = await enterpriseEmployeeServices.batchEnterpriseSignContract({ ids: ids }); | 
|     if (res) { | 
|       Message.successMessage('操作成功'); | 
|       getList(paginationState.pageIndex); | 
|       if (res?.errors?.length > 0) { | 
|         Message.tipMessage('存在签约失败的灵工信息数据,是否导出?').then(() => { | 
|           XLSXUtils.exportToXLSX({ | 
|             workbookDataList: res.errors, | 
|             fileName: '签约失败灵工信息', | 
|             workbookHeaderMap: { | 
|               name: '姓名', | 
|               contactPhoneNumber: '手机号', | 
|               identity: '身份证号', | 
|               errorMessage: '错误信息', | 
|             }, | 
|           }); | 
|         }); | 
|       } | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| async function signContract() { | 
|   try { | 
|     let params: API.InviteElectronSignCommand = { | 
|       ids: signEditForm.ids, | 
|       contractTemplateId: signEditForm.contractTemplateId, | 
|     }; | 
|     let res = await enterpriseEmployeeServices.inviteElectronSign(params); | 
|     if (res) { | 
|       Message.successMessage('操作成功'); | 
|       getList(paginationState.pageIndex); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| async function handleEnterpriseSign(row: API.GetEnterpriseEmployeesQueryResultItem) { | 
|   try { | 
|     let res = await enterpriseEmployeeServices.enterpriseUserElectronSign({ id: row.id }); | 
|     if (res) { | 
|       window.open(res?.signContractLongUrl, '_blank'); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| function handleUnSign(row: API.GetEnterpriseEmployeesQueryResultItem) { | 
|   stopElectronSign([row.id]); | 
| } | 
|   | 
| function handleBatchUnSign() { | 
|   try { | 
|     const selectionRows = getSelectionRows(); | 
|     if (selectionRows) { | 
|       const hasUnSigned = selectionRows?.some( | 
|         (x) => x.enterpriseSignContractStatus !== EnumTaskUserSignContractStatus.Pass | 
|       ); | 
|       if (hasUnSigned) { | 
|         Message.warnMessage('勾选数据中包含企业未签约或已解约数据'); | 
|         return; | 
|       } | 
|       stopElectronSign(selectionRows.map((x) => x.id)); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| async function stopElectronSign(ids: string[]) { | 
|   try { | 
|     await Message.tipMessage('确定解约用户?'); | 
|     let res = await enterpriseEmployeeServices.stopElectronSign({ ids: ids }); | 
|     if (res) { | 
|       Message.successMessage('操作成功'); | 
|       getList(paginationState.pageIndex); | 
|     } | 
|   } catch (error) {} | 
| } | 
|   | 
| const { | 
|   dialogProps: dialogStaffDetailProps, | 
|   handleEdit: handleStaffDetailEdit, | 
|   editForm: staffDetailEditForm, | 
| } = useFormDialog({ | 
|   defaultFormParams: { | 
|     id: '', | 
|     tabType: 'info', | 
|   }, | 
| }); | 
|   | 
| async function handleDelete(row: API.GetEnterpriseEmployeesQueryResultItem) { | 
|   try { | 
|     await Message.deleteMessage(); | 
|   } catch (error) {} | 
| } | 
| </script> |