电子签基础功能
This commit is contained in:
@@ -4,8 +4,59 @@ 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<string, unknown>,
|
||||
fallbackMessage: string
|
||||
) {
|
||||
let response: any;
|
||||
try {
|
||||
response = await contractDocumentHttp.post<any>(
|
||||
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;
|
||||
@@ -59,6 +110,62 @@ export interface OnboardingPreparedContract {
|
||||
generatedAt?: string;
|
||||
}
|
||||
|
||||
/** 一次电子签流程中的单份合同文件。 */
|
||||
export interface OnboardingElectronicSignDocument {
|
||||
id: number;
|
||||
taskContractId: number;
|
||||
providerDocumentId?: string;
|
||||
documentName: string;
|
||||
documentSort: number;
|
||||
originalDocxFileId?: number;
|
||||
signedPdfFileId?: number;
|
||||
}
|
||||
|
||||
/** 管理端查看的入职电子签流程详情。 */
|
||||
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;
|
||||
@@ -282,48 +389,22 @@ export const onboardingTaskApi = {
|
||||
return response;
|
||||
},
|
||||
|
||||
/** 创建任务前生成并下载单份临时 DOCX 合同预览。 */
|
||||
/** 创建任务前生成并下载指定的一份临时 DOCX 合同预览。 */
|
||||
async previewContractBeforeCreate(params: Record<string, unknown>) {
|
||||
let response: any;
|
||||
try {
|
||||
response = await contractDocumentHttp.post<any>(
|
||||
"preview-before-create",
|
||||
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 || "合同预览生成失败");
|
||||
} catch (parseError) {
|
||||
if (!(parseError instanceof SyntaxError)) throw parseError;
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
const blob = response?.data;
|
||||
const contentType = String(
|
||||
response?.headers?.["content-type"] || blob?.type || ""
|
||||
return requestContractPreview(
|
||||
"preview-before-create",
|
||||
params,
|
||||
"合同预览生成失败"
|
||||
);
|
||||
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 合同预览,并以 ZIP 下载。 */
|
||||
async previewAllContractsBeforeCreate(params: Record<string, unknown>) {
|
||||
return requestContractPreview(
|
||||
"preview-all-before-create",
|
||||
params,
|
||||
"合同预览打包生成失败"
|
||||
);
|
||||
},
|
||||
|
||||
create(params: Record<string, unknown>) {
|
||||
@@ -359,6 +440,52 @@ export const onboardingTaskApi = {
|
||||
);
|
||||
},
|
||||
|
||||
/** 查询任务当前电子签流程和全部合同文件。 */
|
||||
electronicSignDetail(taskId: number) {
|
||||
return electronicSignHttp.get<OnboardingElectronicSignDetail>("detail", {
|
||||
id: taskId
|
||||
});
|
||||
},
|
||||
|
||||
/** 手动发起;失败流程会从已保存的本地断点继续。 */
|
||||
initiateElectronicSign(taskId: number) {
|
||||
return electronicSignHttp.post<OnboardingElectronicSignDetail>("initiate", {
|
||||
taskId
|
||||
});
|
||||
},
|
||||
|
||||
/** 保留旧流程记录,并以新的业务编号重新发起一次签约。 */
|
||||
reinitiateElectronicSign(taskId: number, reason: string) {
|
||||
return electronicSignHttp.post<OnboardingElectronicSignDetail>("reinitiate", {
|
||||
taskId,
|
||||
reason
|
||||
});
|
||||
},
|
||||
|
||||
/** 主动同步签署状态,完成时后端自动执行归档。 */
|
||||
syncElectronicSign(taskId: number) {
|
||||
return electronicSignHttp.post<OnboardingElectronicSignDetail>("sync", {
|
||||
taskId
|
||||
});
|
||||
},
|
||||
|
||||
/** 获取有效的员工签署链接,旧链接失效时由后端重新生成。 */
|
||||
getElectronicSignLink(taskId: number) {
|
||||
return electronicSignHttp.post<OnboardingElectronicSignDetail>("get-link", {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user