From 0ca66ba6d5f5d5502211b9d9c7bff036ebd3f1aa Mon Sep 17 00:00:00 2001 From: zhengyiming <540361168@qq.com> Date: 星期四, 14 八月 2025 16:38:32 +0800 Subject: [PATCH] fix: 验收管理 --- src/services/api/enterpriseEmployee.ts | 19 ++- src/views/FlexJobManage/components/BatchImportDialog.vue | 30 ----- src/views/FlexJobManage/components/StaffInfoDialog.vue | 24 +++- .eslintrc-auto-import.json | 1 src/services/api/typings.d.ts | 77 ++++++++++++++ src/services/api/taskUser.ts | 18 +++ src/utils/request/index.ts | 3 src/views/FlexJobManage/FlexJobManage.vue | 60 +++++++++-- src/services/api/index.ts | 8 src/utils/common/deepClone.ts | 52 ++++++++++ src/utils/common/index.ts | 1 auto-imports.d.ts | 2 src/constants/enterpriseEmployee.ts | 2 src/views/EmploymentManage/CheckReceiveTaskDetail.vue | 2 14 files changed, 236 insertions(+), 63 deletions(-) diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 1005d17..4757881 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -75,6 +75,7 @@ "GlobalEventContext": true, "GlobalEventListener": true, "IdentityCodeEnum": true, + "ImportEnterpriseEmployeesTempPath": true, "InjectionKey": true, "MaybeRef": true, "MaybeRefOrGetter": true, diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 3da2f7f..a0e5fac 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -78,6 +78,7 @@ const GetTaskInfoQueryResultApplyButton: typeof import('./src/constants/apiEnum')['GetTaskInfoQueryResultApplyButton'] const GetTaskInfoQueryResultHireButton: typeof import('./src/constants/apiEnum')['GetTaskInfoQueryResultHireButton'] const IdentityCodeEnum: typeof import('./src/constants/dic')['IdentityCodeEnum'] + const ImportEnterpriseEmployeesTempPath: typeof import('./src/constants/enterpriseEmployee')['ImportEnterpriseEmployeesTempPath'] const MenuSvgIconMap: typeof import('./src/constants/menu')['MenuSvgIconMap'] const ModuleColumns: typeof import('./src/constants/module')['ModuleColumns'] const MyRegExp: typeof import('./src/constants/regExp')['MyRegExp'] @@ -302,6 +303,7 @@ readonly GetTaskInfoQueryResultApplyButton: UnwrapRef<typeof import('./src/constants/apiEnum')['GetTaskInfoQueryResultApplyButton']> readonly GetTaskInfoQueryResultHireButton: UnwrapRef<typeof import('./src/constants/apiEnum')['GetTaskInfoQueryResultHireButton']> readonly IdentityCodeEnum: UnwrapRef<typeof import('./src/constants/dic')['IdentityCodeEnum']> + readonly ImportEnterpriseEmployeesTempPath: UnwrapRef<typeof import('./src/constants/enterpriseEmployee')['ImportEnterpriseEmployeesTempPath']> readonly MenuSvgIconMap: UnwrapRef<typeof import('./src/constants/menu')['MenuSvgIconMap']> readonly ModuleColumns: UnwrapRef<typeof import('./src/constants/module')['ModuleColumns']> readonly MyRegExp: UnwrapRef<typeof import('./src/constants/regExp')['MyRegExp']> diff --git a/src/constants/enterpriseEmployee.ts b/src/constants/enterpriseEmployee.ts index 5db63ff..5b07048 100644 --- a/src/constants/enterpriseEmployee.ts +++ b/src/constants/enterpriseEmployee.ts @@ -11,3 +11,5 @@ [EnumTaskUserSignContractStatus.Pass]: '宸茬绾�', [EnumTaskUserSignContractStatus.Refuse]: '宸茶阿缁�', }; + +export const ImportEnterpriseEmployeesTempPath = `${TempFolderPath}/%E7%81%B5%E5%B7%A5%E5%AF%BC%E5%85%A5%E6%A8%A1%E6%9D%BF.xlsx`; diff --git a/src/services/api/enterpriseEmployee.ts b/src/services/api/enterpriseEmployee.ts index cb2c49a..dfe7822 100644 --- a/src/services/api/enterpriseEmployee.ts +++ b/src/services/api/enterpriseEmployee.ts @@ -58,12 +58,15 @@ body: API.ImportEnterpriseEmployeesCommand, options?: API.RequestConfig ) { - return request<number>('/api/user/enterpriseEmployee/importEnterpriseEmployees', { - method: 'POST', - headers: { - 'Content-Type': 'application/json-patch+json', - }, - data: body, - ...(options || {}), - }); + return request<API.ImportEnterpriseEmployeesCommandResult>( + '/api/user/enterpriseEmployee/importEnterpriseEmployees', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json-patch+json', + }, + data: body, + ...(options || {}), + } + ); } diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 2300abd..9cabf40 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -3,27 +3,27 @@ // API 鏇存柊鏃堕棿锛� // API 鍞竴鏍囪瘑锛� import * as enterpriseEmployee from './enterpriseEmployee'; +import * as user from './user'; import * as role from './role'; import * as enterprise from './enterprise'; import * as task from './task'; -import * as taskCheckReceive from './taskCheckReceive'; import * as dictionary from './dictionary'; -import * as user from './user'; import * as userResume from './userResume'; import * as auth from './auth'; +import * as taskCheckReceive from './taskCheckReceive'; import * as resource from './resource'; import * as taskUser from './taskUser'; import * as menu from './menu'; export default { enterpriseEmployee, + user, role, enterprise, task, - taskCheckReceive, dictionary, - user, userResume, auth, + taskCheckReceive, resource, taskUser, menu, diff --git a/src/services/api/taskUser.ts b/src/services/api/taskUser.ts index af03cc7..a23742d 100644 --- a/src/services/api/taskUser.ts +++ b/src/services/api/taskUser.ts @@ -41,6 +41,24 @@ }); } +/** 鏌ヨ搴旇仒鎶ュ悕浜哄憳褰曠敤鐘舵�� GET /api/flexjob/taskUser/getTaskUserHireStatus */ +export async function getTaskUserHireStatus( + // 鍙犲姞鐢熸垚鐨凱aram绫诲瀷 (闈瀊ody鍙傛暟swagger榛樿娌℃湁鐢熸垚瀵硅薄) + params: API.APIgetTaskUserHireStatusParams, + options?: API.RequestConfig +) { + return request<API.GetTaskUserHireStatusQueryResult>( + '/api/flexjob/taskUser/getTaskUserHireStatus', + { + method: 'GET', + params: { + ...params, + }, + ...(options || {}), + } + ); +} + /** B绔煡璇㈠簲鑱樻姤鍚嶅垎椤靛垪琛ㄤ俊鎭� POST /api/flexjob/taskUser/getTaskUsers */ export async function getTaskUsers(body: API.GetTaskUsersQuery, options?: API.RequestConfig) { return request<API.GetTaskUsersQueryResult>('/api/flexjob/taskUser/getTaskUsers', { diff --git a/src/services/api/typings.d.ts b/src/services/api/typings.d.ts index cca7c16..fa14135 100644 --- a/src/services/api/typings.d.ts +++ b/src/services/api/typings.d.ts @@ -133,6 +133,13 @@ id?: string; } + interface APIgetTaskUserHireStatusParams { + /** 浠诲姟Id */ + taskInfoId?: string; + /** 鐢ㄦ埛Id锛圕绔敤鎴峰彲涓嶅~锛� */ + userId?: string; + } + interface APIgetUserInfoRolesParams { /** 鐢ㄦ埛Id */ userInfoId?: string; @@ -247,11 +254,11 @@ interface EditEnterpriseEmployeeCommand { /** 濮撳悕 */ - name?: string; + name: string; /** 韬唤璇佸彿 */ - identity?: string; + identity: string; /** 鎵嬫満鍙� */ - contactPhoneNumber?: string; + contactPhoneNumber: string; gender?: EnumUserGender; /** 骞撮緞 */ age?: number; @@ -913,6 +920,24 @@ timestamp?: number; } + interface FriendlyResultGetTaskUserHireStatusQueryResult { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + data?: GetTaskUserHireStatusQueryResult; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + interface FriendlyResultGetTaskUsersQueryResult { /** 璺熻釜Id */ traceId?: string; @@ -1066,6 +1091,24 @@ errorCode?: string; /** 鏁版嵁 */ data?: string; + /** 鎵ц鎴愬姛 */ + success?: boolean; + /** 閿欒淇℃伅 */ + msg?: any; + /** 闄勫姞鏁版嵁 */ + extras?: any; + /** 鏃堕棿鎴� */ + timestamp?: number; + } + + interface FriendlyResultImportEnterpriseEmployeesCommandResult { + /** 璺熻釜Id */ + traceId?: string; + /** 鐘舵�佺爜 */ + code?: number; + /** 閿欒鐮� */ + errorCode?: string; + data?: ImportEnterpriseEmployeesCommandResult; /** 鎵ц鎴愬姛 */ success?: boolean; /** 閿欒淇℃伅 */ @@ -1586,6 +1629,8 @@ interface GetCheckReceiveTaskUserSubmitsQuery { /** 浠诲姟浜哄憳Id */ id?: string; + /** 浠诲姟Id */ + taskInfoId?: string; pageModel?: PagedListQueryPageModel; } @@ -2582,6 +2627,10 @@ stoppedReleaseCount?: number; } + interface GetTaskUserHireStatusQueryResult { + hireStatus?: EnumTaskUserHireStatus; + } + interface GetTaskUsersQuery { /** 浠诲姟Id */ id?: string; @@ -2908,6 +2957,28 @@ excelUrl?: string; } + interface ImportEnterpriseEmployeesCommandResult { + /** 鎬绘暟 */ + totalCount?: number; + /** 鎴愬姛鏁伴噺 */ + successCount?: number; + /** 澶辫触鏁伴噺 */ + failCount?: number; + /** 閿欒淇℃伅 */ + errors?: ImportEnterpriseEmployeesCommandResultError[]; + } + + interface ImportEnterpriseEmployeesCommandResultError { + /** 閿欒淇℃伅 */ + errorMessage?: string; + /** 濮撳悕 */ + name?: string; + /** 鎵嬫満鍙� */ + contactPhoneNumber?: string; + /** 韬唤璇佸彿 */ + identity?: string; + } + interface LoginCommandCallback { /** 鐢ㄦ埛Id */ id?: string; diff --git a/src/utils/common/deepClone.ts b/src/utils/common/deepClone.ts new file mode 100644 index 0000000..39c445f --- /dev/null +++ b/src/utils/common/deepClone.ts @@ -0,0 +1,52 @@ +/** + * 娣卞害鎷疯礉鍑芥暟锛屾敮鎸佸绉嶆暟鎹被鍨嬪拰寰幆寮曠敤 + * @param target 闇�瑕佹嫹璐濈殑鐩爣鍊� + * @param map 鐢ㄤ簬澶勭悊寰幆寮曠敤鐨勬槧灏勮〃锛堝唴閮ㄤ娇鐢級 + * @returns 鎷疯礉鍚庣殑鏂板�� + */ +export function deepClone<T>(target: T, map = new WeakMap<any, any>()): T { + // 鍩烘湰绫诲瀷鐩存帴杩斿洖锛坣ull 鐗规畩澶勭悊锛� + if (target === null || typeof target !== 'object') { + return target; + } + + // 澶勭悊寰幆寮曠敤 + if (map.has(target)) { + return map.get(target); + } + + let cloneResult: any; + const Constructor = target.constructor; + + // 澶勭悊鏃ユ湡 + if (target instanceof Date) { + //@ts-ignore + cloneResult = new Constructor(target) as Date; + map.set(target, cloneResult); + return cloneResult as unknown as T; + } + + // 澶勭悊姝e垯 + if (target instanceof RegExp) { + //@ts-ignore + cloneResult = new Constructor(target.source, target.flags) as RegExp; + cloneResult.lastIndex = target.lastIndex; // 澶嶅埗lastIndex灞炴�� + map.set(target, cloneResult); + return cloneResult as unknown as T; + } + + // 澶勭悊鏁扮粍鍜屽璞� + //@ts-ignore + cloneResult = new Constructor() as T; + map.set(target, cloneResult); // 瀛樺偍鏄犲皠鍏崇郴锛岄槻姝㈠惊鐜紩鐢� + + // 閬嶅巻瀵硅薄灞炴�э紙鍖呮嫭Symbol閿級 + Reflect.ownKeys(target).forEach((key) => { + // 鍙嫹璐濊嚜韬睘鎬э紝涓嶆嫹璐濆師鍨嬮摼涓婄殑灞炴�� + if (Object.prototype.hasOwnProperty.call(target, key)) { + cloneResult[key] = deepClone((target as any)[key], map); + } + }); + + return cloneResult; +} diff --git a/src/utils/common/index.ts b/src/utils/common/index.ts index 8959df3..b03c034 100644 --- a/src/utils/common/index.ts +++ b/src/utils/common/index.ts @@ -14,3 +14,4 @@ export * from './vueHelper'; export * from './categoryUtils'; export * from './encrypt'; +export * from './deepClone'; diff --git a/src/utils/request/index.ts b/src/utils/request/index.ts index e4d4068..e11bb12 100644 --- a/src/utils/request/index.ts +++ b/src/utils/request/index.ts @@ -120,6 +120,9 @@ const errorInfo: ErrorInfo | undefined = (error as any).info; if (errorInfo) { const { errorMessage, errorCode } = errorInfo; + if (Number(errorCode) === 401) { + handleLogout(); + } switch (errorInfo.showType) { case ErrorShowType.SILENT: // do nothing diff --git a/src/views/EmploymentManage/CheckReceiveTaskDetail.vue b/src/views/EmploymentManage/CheckReceiveTaskDetail.vue index d52653d..a84d677 100644 --- a/src/views/EmploymentManage/CheckReceiveTaskDetail.vue +++ b/src/views/EmploymentManage/CheckReceiveTaskDetail.vue @@ -32,7 +32,7 @@ </ProFormItemV2> </ProFormColItem> <ProFormColItem :span="8"> - <ProFormItemV2 label="鍙戝竷鏃ユ湡:"> + <ProFormItemV2 label="缁撴潫鏃ユ湡:"> {{ dayjs(taskInfo.endTime ?? '').format('YYYY-MM-DD') }} </ProFormItemV2> </ProFormColItem> diff --git a/src/views/FlexJobManage/FlexJobManage.vue b/src/views/FlexJobManage/FlexJobManage.vue index c012902..02de3db 100644 --- a/src/views/FlexJobManage/FlexJobManage.vue +++ b/src/views/FlexJobManage/FlexJobManage.vue @@ -123,6 +123,7 @@ defineOperationBtns, useFormDialog, UploadUserFile, + XLSXUtils, } from '@bole-core/components'; import { FlexJobManageColumns } from './constants'; import { EnumTaskUserHireStatusText, EnumTaskUserSignContractStatusText } from '@/constants'; @@ -312,8 +313,8 @@ contactPhoneNumber: '', gender: EnumUserGender.Male, age: null as any as number, - idFrontUrl: [] as UploadUserFile[], - idBackUrl: [] as UploadUserFile[], + identityImg: [] as UploadUserFile[], + identityBackImg: [] as UploadUserFile[], contractUrl: [] as UploadUserFile[], regiterTime: '', userRealTime: '', @@ -332,8 +333,8 @@ contactPhoneNumber: row.contactPhoneNumber, gender: detail.gender, age: detail.age ?? null, - idFrontUrl: convertApi2FormUrlOnlyOne(detail.identityImg), - idBackUrl: convertApi2FormUrlOnlyOne(detail.identityBackImg), + identityImg: convertApi2FormUrlOnlyOne(detail.identityImg), + identityBackImg: convertApi2FormUrlOnlyOne(detail.identityBackImg), contractUrl: convertApi2FormUrlOnlyOne(detail.contractUrl, { fileName: detail.contractUrl ? detail.contractUrl.split('/').pop() : '鍚堝悓', }), @@ -345,7 +346,25 @@ } catch (error) {} } -async function handleAddOrEdit() {} +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, @@ -354,15 +373,34 @@ } = useFormDialog({ onConfirm: handleBatchImport, defaultFormParams: { - customerId: '', - contractTemplateId: '', - templateDataId: '', url: [] as UploadUserFile[], - userList: [], }, }); -async function handleBatchImport() {} +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, @@ -398,7 +436,7 @@ } function handleDownloadTemplate() { - downloadFileByUrl('', '鎵归噺瀵煎叆妯℃澘'); + downloadFileByUrl(ImportEnterpriseEmployeesTempPath, '鎵归噺瀵煎叆妯℃澘'); } function handleBatchUnSign() {} diff --git a/src/views/FlexJobManage/components/BatchImportDialog.vue b/src/views/FlexJobManage/components/BatchImportDialog.vue index 6a311dc..120f882 100644 --- a/src/views/FlexJobManage/components/BatchImportDialog.vue +++ b/src/views/FlexJobManage/components/BatchImportDialog.vue @@ -3,8 +3,8 @@ <ProForm :model="form" ref="dialogForm" label-width="100px"> <ProFormItemV2 label="閫夋嫨鏂囦欢:" - prop="userList" - :check-rules="[{ message: '璇蜂笂浼犱汉鍛樺悕鍗�', type: 'array' }]" + prop="url" + :check-rules="[{ message: '璇蜂笂浼犱汉鍛樺悕鍗�', type: 'upload' }]" > <div style="display: flex"> <ProFormUpload @@ -12,8 +12,6 @@ :limit="1" :limitFileSize="10" accept="xlsx,xls" - :needUploadOss="false" - :on-success="handleImport" ></ProFormUpload> <el-button type="primary" @@ -53,11 +51,7 @@ type Form = { title?: string; - customerId: string; - contractTemplateId: string; - templateDataId: string; url: UploadUserFile[]; - userList: any[]; }; const visible = defineModel({ type: Boolean }); @@ -68,8 +62,6 @@ (e: 'onConfirm'): void; (e: 'onCancel'): void; }>(); - -const { user } = useUser(); const dialogForm = ref<FormInstance>(); @@ -86,24 +78,6 @@ } else { return; } - }); -} - -const XLSXHeaderMap = { - name: '濮撳悕', - phone: '鎵嬫満鍙�', -}; - -function handleImport(response: UploadUserFile) { - XLSXUtils.resloveXLSXFromUploadInput<typeof XLSXHeaderMap>({ - //@ts-ignore - file: response.file, - resloveKeyList: Object.keys(XLSXHeaderMap), - onSuccess: async (worksheetList) => { - const userXLSXList = worksheetList[0]; - form.value.userList = userXLSXList; - dialogForm.value?.validateField?.('userList'); - }, }); } </script> diff --git a/src/views/FlexJobManage/components/StaffInfoDialog.vue b/src/views/FlexJobManage/components/StaffInfoDialog.vue index 3abf0f0..f7367a0 100644 --- a/src/views/FlexJobManage/components/StaffInfoDialog.vue +++ b/src/views/FlexJobManage/components/StaffInfoDialog.vue @@ -97,18 +97,26 @@ </ProFormCol> <ProFormItemV2 label="韬唤璇佹闈細" - prop="idFrontUrl" + prop="identityImg" :check-rules="[{ message: '璇蜂笂浼犺韩浠借瘉姝i潰', type: 'upload' }]" > - <ProFormImageUpload v-model:file-url="form.idFrontUrl" :limitFileSize="10" :showTip="false"> + <ProFormImageUpload + v-model:file-url="form.identityImg" + :limitFileSize="10" + :showTip="false" + > </ProFormImageUpload> </ProFormItemV2> <ProFormItemV2 label="韬唤璇佸弽闈細" - prop="idBackUrl" + prop="identityBackImg" :check-rules="[{ message: '璇蜂笂浼犺韩浠借瘉鍙嶉潰', type: 'upload' }]" > - <ProFormImageUpload v-model:file-url="form.idBackUrl" :limitFileSize="10" :showTip="false"> + <ProFormImageUpload + v-model:file-url="form.identityBackImg" + :limitFileSize="10" + :showTip="false" + > </ProFormImageUpload> </ProFormItemV2> </ProForm> @@ -140,7 +148,7 @@ ProFormUpload, ProFormInputNumber, } from '@bole-core/components'; -import { format } from '@/utils'; +import { deepClone, format } from '@/utils'; import { EnumUserGender, EnumUserGenderTextForPerson } from '@/constants'; defineOptions({ @@ -155,8 +163,8 @@ contactPhoneNumber: string; gender: EnumUserGender; age: number; - idFrontUrl: UploadUserFile[]; - idBackUrl: UploadUserFile[]; + identityImg: UploadUserFile[]; + identityBackImg: UploadUserFile[]; contractUrl: UploadUserFile[]; regiterTime: string; userRealTime: string; @@ -173,7 +181,7 @@ visible, (visible) => { if (visible) { - defaultForm = { ...unref(form) }; + defaultForm = deepClone(unref(form)); } }, { -- Gitblit v1.9.1