diff --git a/src/api/project/constructionUser/index.ts b/src/api/project/constructionUser/index.ts index f86ff14..6f8fe98 100644 --- a/src/api/project/constructionUser/index.ts +++ b/src/api/project/constructionUser/index.ts @@ -1,6 +1,16 @@ import request from '@/utils/request'; import { AxiosPromise } from 'axios'; -import { ConstructionUserForm, ConstructionUserQuery, ConstructionUserVO, skipType } from '@/api/project/constructionUser/types'; +import { + ConstructionUserForm, + ConstructionUserQuery, + ConstructionUserVO, + skipType, + ConstructionUserStatusForm, + ConstructionUserPlayCardForm, + ConstructionUserSalaryForm, + ConstructionUserExitForm, + ConstructionUserTemplateForm +} from '@/api/project/constructionUser/types'; /** * 查询施工人员列表 @@ -83,3 +93,75 @@ export const delConstructionUser = (id: string | number | Array method: 'delete' }); }; + +/** + * 修改施工人员在职状态 + * @param data + */ +export const updateConstructionUserStatus = (data: ConstructionUserStatusForm) => { + return request({ + url: '/project/constructionUser/batch/status', + method: 'put', + data: data + }); +}; + +/** + * 根据项目id批量修改施工人员打卡状态 + * @param data + */ +export const updateConstructionUserPlayCardStatus = (data: ConstructionUserPlayCardForm) => { + return request({ + url: '/project/constructionUser/batch/clock', + method: 'put', + data: data + }); +}; + +/** + * 修改施工人员打卡状态 + * @param data + */ +export const updateConstructionUserPlayCardOneStatus = (data: ConstructionUserPlayCardForm) => { + return request({ + url: '/project/constructionUser/clock', + method: 'put', + data: data + }); +}; + +/** + * 修改施工人员工资 + * @param data + */ +export const updateConstructionUserSalary = (data: ConstructionUserSalaryForm) => { + return request({ + url: '/project/constructionUser/salary', + method: 'put', + data: data + }); +}; + +/** + * 查询施工人员入退场记录 + * @param query + */ +export const getConstructionUserExit = (query: ConstructionUserExitForm) => { + return request({ + url: '/project/constructionUserExit/list', + method: 'get', + params: query + }); +}; + +/** + * 下载施工人员文件存储模板 + * @param query + */ +export const dowloadConstructionUserTemplate = (query: ConstructionUserTemplateForm) => { + return request({ + url: '/project/constructionUserFile/exportFileTemplate', + method: 'get', + params: query + }); +}; diff --git a/src/api/project/constructionUser/types.ts b/src/api/project/constructionUser/types.ts index 502fb62..51e9075 100644 --- a/src/api/project/constructionUser/types.ts +++ b/src/api/project/constructionUser/types.ts @@ -1,5 +1,6 @@ import { ContractorVO } from '@/api/project/contractor/types'; import { ProjectTeamVO } from '@/api/project/projectTeam/types'; +import { S } from 'node_modules/vite/dist/node/types.d-aGj9QkWt'; export interface ConstructionUserVO { /** @@ -196,6 +197,47 @@ export interface skipType { id: string | number; } +export interface ConstructionUserTemplateForm { + /** + * 项目id + */ + projectId: string | number; +} + +export interface ConstructionUserExitForm { + /** + * userId + */ + userId: number | string; +} + +export interface ConstructionUserSalaryForm { + /** + * 列表 + */ + id: number | string; + + /** + * 工资 + */ + salary?: number | string; +} + +export interface ConstructionUserPlayCardForm { + /** + * 项目 + */ + projectId?: string | number; + /** + * 用户id + */ + id?: string | number; + /** + * 打卡状态 + */ + clock: number | string; +} + export interface skipOptionType { /** * 名称 @@ -385,6 +427,11 @@ export interface ConstructionUserForm extends BaseEntity { remark?: string; } +export interface ConstructionUserStatusForm { + status: number | string; + idList: Array; +} + export interface ConstructionUserQuery extends PageQuery { /** * 微信id diff --git a/src/api/project/constructionUserFile/index.ts b/src/api/project/constructionUserFile/index.ts new file mode 100644 index 0000000..ef40d02 --- /dev/null +++ b/src/api/project/constructionUserFile/index.ts @@ -0,0 +1,40 @@ +import request from '@/utils/request'; +import { AxiosPromise } from 'axios'; +import { ConstructionUserFileVO, ConstructionUserFileForm, ConstructionUserFileQuery } from '@/api/project/constructionUserFile/types'; + +/** + * 查询施工人员文件存储列表 + * @param query + * @returns {*} + */ + +export const listConstructionUserFile = (query?: ConstructionUserFileQuery): AxiosPromise => { + return request({ + url: '/project/constructionUserFile/list', + method: 'get', + params: query + }); +}; + +/** + * 查询施工人员文件存储详细 + * @param data + */ +export const setConstructionUserFile = (data: ConstructionUserFileForm): AxiosPromise => { + return request({ + url: '/project/constructionUserFile/save', + method: 'post', + data + }); +}; + +/** + * 删除施工人员文件存储 + * @param id + */ +export const delConstructionUserFile = (id: string | number | Array) => { + return request({ + url: '/project/constructionUserFile/' + id, + method: 'delete' + }); +}; diff --git a/src/api/project/constructionUserFile/types.ts b/src/api/project/constructionUserFile/types.ts new file mode 100644 index 0000000..75a9851 --- /dev/null +++ b/src/api/project/constructionUserFile/types.ts @@ -0,0 +1,133 @@ +export interface ConstructionUserFileVO { + /** + * 主键id + */ + id: string | number; + + /** + * 用户id + */ + userId: string | number; + + /** + * 文件类型 + */ + fileType: string; + + /** + * 文件名称 + */ + fileName: string; + + /** + * 文件路径 + */ + path: string; + + /** + * 备注 + */ + remark: string; +} + +export interface ConstructionUserExitVO { + /** + * 主键id + */ + id: string | number; + + /** + * 用户id + */ + userId: string | number; + + /** + * 身份证号码 + + */ + sfzNumber: string; + + /** + * 项目id + */ + projectId: string; + /** + * 班组id + */ + teamId: string; + /** + * 入场时间 + + */ + entryDate: string; + /** + * 退场时间 + + */ + leaveDate: string; + + /** + * 退场文件 + + */ + path: string; + + /** + * 备注 + */ + remark: string; +} + +export interface ConstructionUserFileForm extends BaseEntity { + /** + * 用户id + */ + userId?: string | number; + + /** + * 文件类型 + */ + fileList?: Array; +} + +interface fileListType { + fileId: string | number; + fileType: string | number; +} + +export interface ConstructionUserFileQuery { + /** + * 主键id + */ + id?: string | number; + + /** + * 用户id + */ + userId?: string | number; + + /** + * 文件类型 + */ + fileType?: string; + + /** + * 文件名称 + */ + fileName?: string; + + /** + * 文件路径 + */ + path?: string; + + /** + * 备注 + */ + remark?: string; + + /** + * 日期范围参数 + */ + params?: any; +} diff --git a/src/assets/icons/svg/PDF.png b/src/assets/icons/svg/PDF.png new file mode 100644 index 0000000..5cea735 Binary files /dev/null and b/src/assets/icons/svg/PDF.png differ diff --git a/src/components/FileUpload/index.vue b/src/components/FileUpload/index.vue index b22d09a..2dc5933 100644 --- a/src/components/FileUpload/index.vue +++ b/src/components/FileUpload/index.vue @@ -10,12 +10,30 @@ :on-error="handleUploadError" :on-exceed="handleExceed" :on-success="handleUploadSuccess" - :show-file-list="false" + :show-file-list="isConstruction" :headers="headers" class="upload-file-uploader" + :list-type="isConstruction ? 'picture-card' : 'text'" > - 选取文件 + 选取文件 + +
@@ -29,7 +47,7 @@ 的文件
- +
  • {{ getFileName(file.name) }} @@ -59,7 +77,9 @@ const props = defineProps({ // 文件类型, 例如['png', 'jpg', 'jpeg'] fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']), // 是否显示提示 - isShowTip: propTypes.bool.def(true) + isShowTip: propTypes.bool.def(true), + //是否为施工人员上传 + isConstruction: propTypes.bool.def(false) }); const { proxy } = getCurrentInstance() as ComponentInternalInstance; @@ -168,10 +188,16 @@ const handleUploadSuccess = (res: any, file: UploadFile) => { }; // 删除文件 -const handleDelete = (index: number) => { - let ossId = fileList.value[index].ossId; - delOss(ossId); - fileList.value.splice(index, 1); +const handleDelete = (index: string | number, type?: string) => { + if (type === 'ossId') { + delOss(index); + fileList.value = fileList.value.filter((f) => f.ossId !== index); + } else { + let ossId = fileList.value[index].ossId; + delOss(ossId); + index = parseInt(index as string); + fileList.value.splice(index, 1); + } emit('update:modelValue', listToString(fileList.value)); }; @@ -179,8 +205,10 @@ const handleDelete = (index: number) => { const uploadedSuccessfully = () => { if (number.value > 0 && uploadList.value.length === number.value) { fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value); + console.log('🚀 ~ uploadedSuccessfully ~ fileList.value:', fileList.value); uploadList.value = []; number.value = 0; + emit('update:modelValue', listToString(fileList.value)); proxy?.$modal.closeLoading(); } @@ -210,6 +238,27 @@ const listToString = (list: any[], separator?: string) => { diff --git a/src/views/project/constructionUser/index.vue b/src/views/project/constructionUser/index.vue index 0797240..f013c48 100644 --- a/src/views/project/constructionUser/index.vue +++ b/src/views/project/constructionUser/index.vue @@ -62,6 +62,33 @@ 导出 + + 用户状态编辑 + + + + + + + 员工资料 + + + 下载资料模板 + + + 导入员工资料 + + + @@ -91,7 +118,24 @@ + + + @@ -115,12 +159,17 @@ 黑名单 - - 人员迁移 - + 切换人脸 + 人员迁移 + 入退场记录 删除 + + + 文件上传 + + @@ -286,6 +335,69 @@ + +
    +
    {{ item.label }}
    +
    + +
    +
    + +
    + +
    + +
    + +
    + + + + + + + + + + 请输入薪资(元/月) + + + + +
    + + + {{ item.entryDate }} + + +
    + + +
    @@ -297,7 +409,13 @@ import { listConstructionUser, updateConstructionUser, getProjectContractorList, - transferConstructionUser + transferConstructionUser, + updateConstructionUserStatus, + updateConstructionUserPlayCardStatus, + updateConstructionUserPlayCardOneStatus, + updateConstructionUserSalary, + getConstructionUserExit, + dowloadConstructionUserTemplate } from '@/api/project/constructionUser'; import { ConstructionUserForm, @@ -314,10 +432,19 @@ import { ContractorVO } from '@/api/project/contractor/types'; import { ProjectTeamVO } from '@/api/project/projectTeam/types'; import ConstructionUserDetail from '@/views/project/constructionUser/component/ConstructionUserDetail.vue'; import { addConstructionBlacklist } from '@/api/project/constructionBlacklist'; +import { listConstructionUserFile, setConstructionUserFile } from '@/api/project/constructionUserFile'; +import { + ConstructionUserFileVO, + ConstructionUserExitVO, + ConstructionUserFileForm, + ConstructionUserFileQuery +} from '@/api/project/constructionUserFile/types'; +import { ElLoadingService } from 'element-plus'; const { proxy } = getCurrentInstance() as ComponentInternalInstance; -const { type_of_work, user_sex_type, user_clock_type } = toRefs(proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type')); - +const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type } = toRefs( + proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type') +); // 获取用户 store const userStore = useUserStoreHook(); // 从 store 中获取项目列表和当前选中的项目 @@ -331,6 +458,18 @@ const single = ref(true); const multiple = ref(true); const total = ref(0); const skip = ref(false); +const fileStatus = ref(false); +const showFaceDrawer = ref(false); +const statusDialog = ref(false); +const playCardStatus = ref(false); +const playCardLoding = ref(false); +const salaryStatus = ref(false); +const exitStatus = ref(false); +const informationStatus = ref(false); +const exitList = ref([]); +const changeSalary = ref(''); +const vocationalStatus = ref(null); +const fileList = ref([]); const queryFormRef = ref(); const constructionUserFormRef = ref(); const skipName = ref(''); @@ -421,6 +560,27 @@ const data = reactive>({ } }); +/** 返回遍历文件对象 */ +const uploadPath = computed(() => { + const list = JSON.parse(JSON.stringify(user_file_type.value)); + for (const item of fileList.value) { + const targetType = item.fileType; + for (let i = 0; i < list.length; i++) { + if (list[i].value == targetType) { + list[i] = { ...list[i], ...item }; // 合并对象 + break; + } + } + } + for (let i = 0; i < list.length; i++) { + if (!list[i].hasOwnProperty('fileType')) { + list[i].fileType = list[i].value; + } + } + console.log(list); + return list; +}); + const { queryParams, form, rules } = toRefs(data); /** 查询施工人员列表 */ @@ -433,13 +593,13 @@ const getList = async () => { }; const selectProject = (e: any) => { - //选中项目筛选出项目下的分包单位 + //选中项目筛选出项目下的分包单位并清空分包单位value contractorList.value = skipOptions.value.filter((item) => item.id == e)[0].contractorList; + skipObject.contractorId = ''; }; const setUnits = async () => { //人员迁移 - console.log('🚀 ~ setUnits ~ skipObject:', skipObject); let res = await transferConstructionUser(skipObject); if (res.code == 200) { ElMessage.success(res.msg); @@ -483,6 +643,28 @@ const getProjectTeamList = async () => { loading.value = false; }; +/** 上传安全协议书按钮操作 */ + +const updateProjectFile = async () => { + buttonLoading.value = true; + let fileList = uploadPath.value.map((item) => { + return { + fileId: item.path, + fileType: item.fileType + }; + }); + const data = { + userId: currentUserId.value, + fileList + }; + console.log('🚀 ~ updateProjectFile ~ data:', data); + await setConstructionUserFile(data); + proxy?.$modal.msgSuccess('上传成功'); + buttonLoading.value = false; + fileStatus.value = false; + await getList(); +}; + const getTeamName = (teamId: string | number) => { const team = projectTeamOpt.value.find((item: any) => item.value === teamId); return team ? team.label : teamId; @@ -544,6 +726,17 @@ const handleShowDrawer = (row?: ConstructionUserVO) => { showDetailDrawer.value = true; }; +//下载模板 +const downloadTemplate = async () => { + const loadingInstance = ElLoadingService({ + lock: true, + text: 'Loading', + background: 'rgba(0, 0, 0, 0.7)' + }); + await dowloadConstructionUserTemplate({ projectId: currentProject.value.id }); + loadingInstance.close(); +}; + /** 人员迁移 */ const handleChange = async (row: ConstructionUserVO) => { const _id = row?.id || ids.value[0]; @@ -554,6 +747,33 @@ const handleChange = async (row: ConstructionUserVO) => { skip.value = true; }; +//切换人脸 +const handleToggle = async (row: ConstructionUserVO) => { + reset(); + skipName.value = row?.userName; + const _id = row?.id || ids.value[0]; + const res = await getConstructionUser(_id); + Object.assign(form.value, res.data); + showFaceDrawer.value = true; +}; + +const handleExit = async (row: ConstructionUserVO) => { + const _id = row?.id || ids.value[0]; + currentUserId.value = _id; + const res = await getConstructionUserExit({ userId: _id }); + exitList.value = res.data; + exitStatus.value = true; +}; + +//上传按钮 +const handleUpload = async (row: ConstructionUserVO) => { + const _id = row?.id || ids.value[0]; + currentUserId.value = _id; + const res = await listConstructionUserFile({ userId: _id }); + fileList.value = res.data; + fileStatus.value = true; +}; + /** 提交按钮 */ const submitForm = () => { constructionUserFormRef.value?.validate(async (valid: boolean) => { @@ -566,6 +786,7 @@ const submitForm = () => { } proxy?.$modal.msgSuccess('操作成功'); dialog.visible = false; + showFaceDrawer.value = false; await getList(); } }); @@ -601,6 +822,69 @@ const handleExport = () => { `constructionUser_${new Date().getTime()}.xlsx` ); }; +/** 用户状态编辑操作 */ +const handleEdit = async () => { + if (!vocationalStatus.value) { + proxy?.$modal.msgError('请选择状态'); + return; + } + const data = { + idList: ids.value, + status: vocationalStatus.value + }; + await updateConstructionUserStatus(data); + proxy?.$modal.msgSuccess('修改成功'); + getList(); + ids.value = []; + statusDialog.value = false; +}; + +//打开修改日薪 +const openSalaryDialog = (row: ConstructionUserVO) => { + const _id = row?.id || ids.value[0]; + currentUserId.value = _id; + if (row.salary) { + setSalary(); + return; + } + console.log(row); + salaryStatus.value = true; +}; + +//变更日薪 +const handleSalary = async () => { + if (!changeSalary.value) { + proxy?.$modal.msgError('请输入薪资'); + return; + } + setSalary(); +}; +const setSalary = async () => { + await updateConstructionUserSalary({ id: currentUserId.value, salary: changeSalary.value }); + proxy?.$modal.msgSuccess('修改成功'); + getList(); + changeSalary.value = ''; + salaryStatus.value = false; +}; + +// 批量切换在职状态 +const handlePlayCardStatus = async (e) => { + playCardLoding.value = true; + const clock = e ? 1 : 0; + await updateConstructionUserPlayCardStatus({ projectId: currentProject.value.id, clock }); + proxy?.$modal.msgSuccess('修改成功'); + getList(); + playCardLoding.value = false; +}; + +// 切换在职状态 +const handleClockStatus = async (row: ConstructionUserVO) => { + playCardLoding.value = true; + await updateConstructionUserPlayCardOneStatus({ id: row.id, clock: row.clock }); + proxy?.$modal.msgSuccess('修改成功'); + getList(); + playCardLoding.value = false; +}; onMounted(() => { getList(); @@ -608,7 +892,7 @@ onMounted(() => { getProjectTeamList(); }); -