import { moduleRequest } from "@/api/request"; import type { ReqId, ResPage } from "@/api/interface"; const taskHttp = moduleRequest("/biz/onboarding/task/"); const auditHttp = moduleRequest("/biz/onboarding/audit/"); const contractDocumentHttp = moduleRequest("/biz/onboarding/contract-document/"); const electronicSignHttp = moduleRequest("/biz/onboarding/electronic-sign/"); const fileHttp = moduleRequest("/sys/dev/file/"); /** * 下载创建任务前的合同预览,并将统一响应中的 JSON 错误转换成可读异常。 */ async function requestContractPreview( action: string, params: Record, fallbackMessage: string ) { let response: any; try { response = await contractDocumentHttp.post( action, params, { responseType: "blob", loading: false, cancel: false } ); } catch (error: any) { const errorBlob = error?.response?.data; if (errorBlob instanceof Blob) { try { const result = JSON.parse(await errorBlob.text()); throw new Error(result?.msg || fallbackMessage); } catch (parseError) { if (!(parseError instanceof SyntaxError)) throw parseError; } } throw error; } const blob = response?.data; const contentType = String( response?.headers?.["content-type"] || blob?.type || "" ); if ( blob instanceof Blob && contentType.toLowerCase().includes("application/json") ) { try { const result = JSON.parse(await blob.text()); throw new Error(result?.msg || fallbackMessage); } catch (error) { if (error instanceof SyntaxError) { throw new Error(fallbackMessage); } throw error; } } return response; } export interface OnboardingTask { id: number; taskNo: string; companyId: number; companyName?: string; departmentId?: number; departmentName?: string; positionId: number; positionName?: string; onboardingTemplateId?: number; onboardingTemplateName?: string; taskStatus: string; rejectReason?: string; linkExpireAt?: string; submitCount: number; createTime: string; remark?: string; } /** 当前查询条件下、不受状态筛选影响的任务统计。 */ export interface OnboardingTaskStatistics { pendingFill: number; reviewing: number; rejected: number; approved: number; } /** 带状态统计的入职任务分页结果。 */ export interface OnboardingTaskPage extends ResPage { statistics: OnboardingTaskStatistics; } /** 批量复制任务返回的单条新任务链接。 */ export interface OnboardingTaskCreatedResult { taskId: number; taskNo: string; linkToken: string; expiresAt: string; } /** 批量复制任务结果。 */ export interface OnboardingTaskCopyResult { tasks: OnboardingTaskCreatedResult[]; } /** 员工端完成合同准备后返回的当前文件版本。 */ export interface OnboardingPreparedContract { /** 当前生成合同对应的系统文件 Id,同时作为下载缓存版本。 */ fileId: number; /** 当前合同文件生成时间。 */ generatedAt?: string; } /** 一次电子签流程中的单份合同文件。 */ export interface OnboardingElectronicSignDocument { id: number; taskContractId: number; providerDocumentId?: string; documentName: string; documentSort: number; originalDocxFileId?: number; signedPdfFileId?: number; employeeSignedPreviewed: boolean; } /** 员工已签、企业未盖章文件的契约锁只读预览。 */ export interface OnboardingElectronicSignPreview { signDocumentId: number; previewUrl: string; } /** 管理端查看的入职电子签流程详情。 */ export interface OnboardingElectronicSignDetail { taskId: number; taskNo: string; canInitiate: boolean; cannotInitiateReason?: string; canReinitiate: boolean; cannotReinitiateReason?: string; hasProcess: boolean; processId?: number; providerContractId?: string; bizId?: string; subject?: string; signStatus?: string; providerStatus?: string; employeeName?: string; employeeMobile?: string; signUrl?: string; signUrlExpireAt?: string; signUrlValid: boolean; startedAt?: string; sentAt?: string; completedAt?: string; archivedAt?: string; archiveFileId?: number; lastError?: string; documents: OnboardingElectronicSignDocument[]; historyProcesses: OnboardingElectronicSignHistory[]; } /** 已被新流程替代的电子签历史记录。 */ export interface OnboardingElectronicSignHistory { processId: number; bizId: string; providerContractId?: string; signStatus?: string; providerStatus?: string; employeeName?: string; employeeMobile?: string; startedAt?: string; reissuedAt?: string; reissueReason?: string; lastError?: string; } export interface OnboardingCompanyOption { id: number; companyName: string; } export interface OnboardingDepartmentOption { id: number; departmentName: string; } export interface OnboardingPositionOption { id: number; positionName: string; } export interface OnboardingCompany extends OnboardingCompanyOption { companyCode: string; legalName: string; unifiedSocialCreditCode?: string; legalRepresentative?: string; registeredAddress?: string; contactPhone?: string; qiyuesuoCategoryId?: string; qiyuesuoSealId?: string; remark?: string; status: string; } export interface OnboardingDepartment extends OnboardingDepartmentOption { companyId: number; companyName?: string; departmentCode: string; sortCode: number; remark?: string; status: string; createTime?: string; } export interface OnboardingPosition extends OnboardingPositionOption { companyId: number; companyName?: string; departmentId?: number; departmentName?: string; positionCode: string; defaultContractYears?: number; defaultProbationMonths?: number; remark?: string; status: string; } export interface OnboardingContractTemplate { id: number; companyId?: number; companyName?: string; departmentId?: number; departmentName?: string; positionIds: number[]; positionNames?: string[]; templateCode: string; templateName: string; contractType: string; description?: string; status: string; } export interface OnboardingContractVersion { id: number; templateId: number; versionNo: string; sourceDocxFileId: number; effectiveDate?: string; expiryDate?: string; versionStatus: string; remark?: string; } export interface OnboardingTemplateVariable { id: number; templateVersionId: number; variableCode: string; variableName: string; variableType: string; dataType: string; employeeField?: string; defaultValue?: string; required: boolean; hrEditable: boolean; sortCode?: number; remark?: string; } export interface OnboardingTaskContractVariableItem { id: number; variableCode: string; variableName: string; variableType: string; dataType: string; sortCode: number; variableValue?: string | number; required: boolean; hrEditable: boolean; editable: boolean; } export interface OnboardingTaskContractVariableGroup { taskContractId: number; contractName: string; contractType: string; variables: OnboardingTaskContractVariableItem[]; } export interface OnboardingEmployee { id: number; employeeNo?: string; employeeName: string; companyId: number; companyName?: string; departmentId?: number; departmentName?: string; positionId: number; positionName?: string; phone: string; idCardNumber: string; entryDate?: string; createTime?: string; } export interface OnboardingFormField { id: number; fieldCode: string; fieldName: string; dataType: string; optionsJson?: string; validationRule?: string; placeholder?: string; status: string; } export interface OnboardingMaterialType { id: number; materialCode: string; materialName: string; allowedExtensions?: string; maxFileCount: number; maxFileSizeMb?: number; status: string; } export interface OnboardingTemplateContractConfig { contractTemplateId: number; contractTemplateVersionId: number; required: boolean; printCopies: number; sortCode?: number; } export interface OnboardingTemplateFieldConfig { fieldId: number; required: boolean; sortCode?: number; } export interface OnboardingTemplateMaterialConfig { materialTypeId: number; required: boolean; sortCode?: number; } export interface OnboardingTemplate { id: number; templateCode: string; templateName: string; companyId: number; companyName?: string; departmentId: number; departmentName?: string; positionIds: number[]; positionNames?: string[]; contracts: OnboardingTemplateContractConfig[]; formFields: OnboardingTemplateFieldConfig[]; materials: OnboardingTemplateMaterialConfig[]; contractCount?: number; formFieldCount?: number; materialCount?: number; status: string; description?: string; } export const onboardingTaskApi = { page(params: Record) { return taskHttp.get("page", params); }, detail(params: ReqId) { return taskHttp.get("detail", params); }, getTaskLink(params: ReqId) { return taskHttp.get("get-link", params); }, /** 使用后台登录令牌读取文件流,供入职材料下载和图片预览使用。 */ async downloadFile(fileId: number) { const response: any = await fileHttp.get( "download", { id: fileId }, { responseType: "blob", loading: false, cancel: false } ); const blob = response?.data; const contentType = String(response?.headers?.["content-type"] || blob?.type || ""); if (blob instanceof Blob && contentType.toLowerCase().includes("application/json")) { try { const result = JSON.parse(await blob.text()); throw new Error(result?.msg || "文件下载失败"); } catch (error) { if (error instanceof SyntaxError) { throw new Error("文件下载失败"); } throw error; } } return response; }, /** 创建任务前生成并下载指定的一份临时 DOCX 合同预览。 */ async previewContractBeforeCreate(params: Record) { return requestContractPreview( "preview-before-create", params, "合同预览生成失败" ); }, /** 创建任务前生成全部临时 DOCX 合同预览,并以 ZIP 下载。 */ async previewAllContractsBeforeCreate(params: Record) { return requestContractPreview( "preview-all-before-create", params, "合同预览打包生成失败" ); }, create(params: Record) { return taskHttp.post("create", params); }, copy(params: { sourceTaskId: number; count: number; items: Array<{ remark: string }>; }) { return taskHttp.post("copy", params); }, approve(params: { taskId: number; auditOpinion?: string; }) { return auditHttp.post("approve", params); }, reject(params: { taskId: number; auditOpinion: string; }) { return auditHttp.post("reject", params); }, generateContract(taskContractId: number) { return moduleRequest("/biz/onboarding/contract-document/").post( "generate", { taskContractId } ); }, /** 查询任务当前电子签流程和全部合同文件。 */ electronicSignDetail(taskId: number) { return electronicSignHttp.get("detail", { id: taskId }); }, /** 手动发起;失败流程会从已保存的本地断点继续。 */ initiateElectronicSign(taskId: number) { return electronicSignHttp.post("initiate", { taskId }); }, /** 保留旧流程记录,并以新的业务编号重新发起一次签约。 */ reinitiateElectronicSign(taskId: number, reason: string) { return electronicSignHttp.post("reinitiate", { taskId, reason }); }, /** 主动同步签署状态,完成时后端自动执行归档。 */ syncElectronicSign(taskId: number) { return electronicSignHttp.post("sync", { taskId }); }, /** 获取有效的员工签署链接,旧链接失效时由后端重新生成。 */ getElectronicSignLink(taskId: number) { return electronicSignHttp.post("get-link", { taskId }); }, /** 获取一份员工已签合同的契约锁只读浏览页面。 */ previewEmployeeSignedDocument(taskId: number, signDocumentId: number) { return electronicSignHttp.post( "preview-employee-signed", { taskId, signDocumentId } ); }, /** 全部合同核对完成后,由后台管理员确认企业盖章。 */ companySealElectronicSign(taskId: number) { return electronicSignHttp.post("company-seal", { taskId }); }, /** 催办当前待签员工。 */ noticeElectronicSign(taskId: number) { return electronicSignHttp.post("notice", { taskId }); }, /** 作废尚未完成的电子签流程。 */ invalidElectronicSign(taskId: number, reason: string) { return electronicSignHttp.post("invalid", { taskId, reason }); }, archive(params: { taskId: number; auditOpinion?: string; }) { return taskHttp.post("archive", params); }, revoke(params: { taskId: number; auditOpinion?: string; }) { return taskHttp.post("revoke", params); }, deleteTask(id: number) { return taskHttp.post("delete", { id }); }, reviewMaterial(params: { taskMaterialId: number; reviewStatus: string; reviewRemark?: string; }) { return moduleRequest("/biz/onboarding/material/").post( "review", params ); }, listCompanies() { return moduleRequest("/biz/onboarding/company/").get< OnboardingCompanyOption[] >("list-enabled"); }, listDepartments(companyId: number) { return moduleRequest("/biz/onboarding/department/").get< OnboardingDepartmentOption[] >("list-enabled", { companyId }); }, listPositions(companyId: number) { return moduleRequest("/biz/onboarding/position/").get< OnboardingPositionOption[] >("list-enabled", { companyId }); }, companyPage(params: Record) { return moduleRequest("/biz/onboarding/company/").get< ResPage >("page", params); }, companyDetail(params: ReqId) { return moduleRequest("/biz/onboarding/company/").get( "detail", params ); }, saveCompany( params: Partial, edit = false ) { return moduleRequest("/biz/onboarding/company/").post( edit ? "edit" : "add", params ); }, deleteCompany(ids: number[]) { return moduleRequest("/biz/onboarding/company/").post( "delete", { ids } ); }, departmentPage(params: Record) { return moduleRequest("/biz/onboarding/department/").get< ResPage >("page", params); }, departmentDetail(params: ReqId) { return moduleRequest("/biz/onboarding/department/").get( "detail", params ); }, saveDepartment( params: Partial, edit = false ) { return moduleRequest("/biz/onboarding/department/").post( edit ? "edit" : "add", params ); }, deleteDepartment(ids: number[]) { return moduleRequest("/biz/onboarding/department/").post( "delete", { ids } ); }, positionPage(params: Record) { return moduleRequest("/biz/onboarding/position/").get< ResPage >("page", params); }, listPositionsByDepartment(departmentId: number) { return moduleRequest("/biz/onboarding/position/").get< OnboardingPosition[] >("list-by-department", { departmentId }); }, positionDetail(params: ReqId) { return moduleRequest("/biz/onboarding/position/").get( "detail", params ); }, savePosition( params: Partial, edit = false ) { return moduleRequest("/biz/onboarding/position/").post( edit ? "edit" : "add", params ); }, deletePosition(ids: number[]) { return moduleRequest("/biz/onboarding/position/").post( "delete", { ids } ); }, onboardingTemplatePage(params: Record) { return moduleRequest("/biz/onboarding/template/").get< ResPage >("page", params); }, onboardingTemplateDetail(params: ReqId) { return moduleRequest("/biz/onboarding/template/").get( "detail", params ); }, saveOnboardingTemplate(params: Partial) { return moduleRequest("/biz/onboarding/template/").post( "save", params ); }, deleteOnboardingTemplate(ids: number[]) { return moduleRequest("/biz/onboarding/template/").post( "delete", { ids } ); }, listEnabledOnboardingTemplates( companyId: number, departmentId: number, positionId: number ) { return moduleRequest("/biz/onboarding/template/").get( "list-enabled", { companyId, departmentId, positionId } ); }, listAvailableContractTemplates(params: { companyId: number; departmentId: number; positionIds: number[]; }) { return moduleRequest("/biz/onboarding/contract-template/").post< OnboardingContractTemplate[] >("list-available", params); }, templatePage(params: Record) { return moduleRequest("/biz/onboarding/contract-template/").get< ResPage >("page", params); }, templateDetail(params: ReqId) { return moduleRequest("/biz/onboarding/contract-template/").get< OnboardingContractTemplate >("detail", params); }, saveTemplate( params: Partial, edit = false ) { return moduleRequest("/biz/onboarding/contract-template/").post( edit ? "edit" : "add", params ); }, deleteTemplate(ids: number[]) { return moduleRequest("/biz/onboarding/contract-template/").post( "delete", { ids } ); }, versionPage(params: { templateId: number; pageNum: number; pageSize: number; }) { return moduleRequest("/biz/onboarding/contract-template/").get< ResPage >("version/page", params); }, addVersion(params: Partial) { return moduleRequest("/biz/onboarding/contract-template/").post( "version/add", params ); }, setVersionStatus(params: { id: number; versionStatus: string; }) { return moduleRequest("/biz/onboarding/contract-template/").post( "version/set-status", params ); }, deleteVersion(id: number) { return moduleRequest("/biz/onboarding/contract-template/").post( "version/delete", { id } ); }, variablePage(params: { templateVersionId: number; pageNum: number; pageSize: number; }) { return moduleRequest("/biz/onboarding/contract-template/").get< ResPage >("variable/page", params); }, editVariable(params: Partial) { return moduleRequest("/biz/onboarding/contract-template/").post( "variable/edit", params ); }, uploadDocx(params: FormData) { return moduleRequest("/biz/onboarding/contract-template/").post( "file/upload-docx", params ); }, taskContractVariables(taskId: number) { return moduleRequest("/biz/onboarding/task-contract-variable/").get< OnboardingTaskContractVariableGroup[] >("list", { taskId }); }, saveTaskContractVariables(params: { taskContractId: number; values: Array<{ id: number; variableValue?: string; }>; }) { return moduleRequest("/biz/onboarding/task-contract-variable/").post( "save", params ); }, employeePage(params: Record) { return moduleRequest("/biz/onboarding/employee/").get< ResPage >("page", params); }, employeeDetail(params: ReqId) { return moduleRequest("/biz/onboarding/employee/").get( "detail", params ); }, listFormFields() { return moduleRequest("/biz/onboarding/entry-config/").get< OnboardingFormField[] >("form-field/list"); }, saveFormField(params: Partial) { return moduleRequest("/biz/onboarding/entry-config/").post( "form-field/save", params ); }, deleteFormFields(ids: number[]) { return moduleRequest("/biz/onboarding/entry-config/").post( "form-field/delete", { ids } ); }, listMaterialTypes() { return moduleRequest("/biz/onboarding/entry-config/").get< OnboardingMaterialType[] >("material-type/list"); }, saveMaterialType(params: Partial) { return moduleRequest("/biz/onboarding/entry-config/").post( "material-type/save", params ); }, deleteMaterialTypes(ids: number[]) { return moduleRequest("/biz/onboarding/entry-config/").post( "material-type/delete", { ids } ); }, // 合同变量字典定义 variableDefinitionPage(params: { keyword?: string; variableCategory?: string; pageNum: number; pageSize: number }) { return moduleRequest("/biz/onboarding/variable-definition/").get>("page", params); }, variableDefinitionList() { return moduleRequest("/biz/onboarding/variable-definition/").get("list"); }, addVariableDefinition(params: Record) { return moduleRequest("/biz/onboarding/variable-definition/").post("add", params); }, editVariableDefinition(params: Record) { return moduleRequest("/biz/onboarding/variable-definition/").post("edit", params); }, deleteVariableDefinitions(ids: number[]) { return moduleRequest("/biz/onboarding/variable-definition/").post("delete", { ids }); } }; const publicHttp = moduleRequest("/open/onboarding/"); export const onboardingPublicApi = { detail(params: { token: string }) { return publicHttp.post("detail", params); }, saveEmployeeInfo(params: Record) { return publicHttp.post("save-employee-info", params); }, confirmContract(params: { token: string; taskContractId: number }) { return publicHttp.post("confirm-contract", params); }, submit(params: { token: string }) { return publicHttp.post("submit", params); }, prepareContract(params: { token: string; taskContractId: number }) { return publicHttp.post("prepare-contract", params); }, contractSourceUrl(params: { token: string; taskContractId: number; fileVersion?: number }) { const version = params.fileVersion ? `&version=${params.fileVersion}` : `&_t=${Date.now()}`; return `/api/open/onboarding/contract-source?token=${encodeURIComponent(params.token)}&taskContractId=${params.taskContractId}${version}`; }, materialSourceUrl(params: { token: string; taskMaterialId: number; fileId?: number }) { const version = params.fileId ? `&v=${params.fileId}` : ""; return `/api/open/onboarding/material-source?token=${encodeURIComponent(params.token)}&taskMaterialId=${params.taskMaterialId}${version}`; }, deleteMaterial(params: { token: string; taskMaterialId: number }) { return publicHttp.post("delete-material", params); } };