下载资料模板,导入员工资料,详情修正,入退场记录

This commit is contained in:
Teo
2025-04-03 18:06:21 +08:00
parent c8a8d64127
commit 33165ac3e5
11 changed files with 398 additions and 94 deletions

View File

@ -1,4 +1,4 @@
import request from '@/utils/request';
import request, { download } from '@/utils/request';
import { AxiosPromise } from 'axios';
import {
ConstructionUserForm,
@ -9,7 +9,8 @@ import {
ConstructionUserPlayCardForm,
ConstructionUserSalaryForm,
ConstructionUserExitForm,
ConstructionUserTemplateForm
ConstructionUserTemplateForm,
ConstructionUserMembeForm
} from '@/api/project/constructionUser/types';
/**
@ -159,9 +160,31 @@ export const getConstructionUserExit = (query: ConstructionUserExitForm) => {
* @param query
*/
export const dowloadConstructionUserTemplate = (query: ConstructionUserTemplateForm) => {
let { projectId } = query;
const fileName = projectId + '_project.zip';
return download('/project/constructionUserFile/exportFileTemplate', query, fileName);
};
/**
* 施工人员退场
* @param data
*/
export const delConstructionUserMember = (data: ConstructionUserMembeForm) => {
return request({
url: '/project/constructionUserFile/exportFileTemplate',
method: 'get',
params: query
url: '/project/projectTeamMember/',
method: 'delete',
data
});
};
/**
* 上传施工人员文件压缩包,批量导入存储施工人员文件
* @param data
*/
export const importConstructionUserInfo = (file: string) => {
return request({
url: '/project/constructionUserFile/upload/zip',
method: 'post',
data: { file }
});
};

View File

@ -197,6 +197,25 @@ export interface skipType {
id: string | number;
}
export interface ConstructionUserMembeForm {
/**
* 用户id
*/
id: string | number;
/**
* 用户姓名
*/
userName: string | number;
/**
* 文件路径
*/
filePath: string;
/**
* 备注
*/
remark: string | number;
}
export interface ConstructionUserTemplateForm {
/**
* 项目id
@ -300,6 +319,10 @@ export interface ConstructionUserForm extends BaseEntity {
* 分包公司id
*/
contractorId?: string | number;
/**
* 结算方式
*/
wageMeasureUnit?: string | number;
/**
* 班组id

View File

@ -40,6 +40,10 @@ export interface ConstructionUserExitVO {
* 用户id
*/
userId: string | number;
/**
* 文件路径地址
*/
pathUrl: Array<string>;
/**
* 身份证号码

View File

@ -24,6 +24,11 @@ export interface ProjectTeamMemberVO {
*/
postId: string | number;
/**
* 施工人员姓名
*/
memberName: string;
/**
* 备注
*/

View File

@ -16,8 +16,9 @@
:list-type="isConstruction ? 'picture-card' : 'text'"
>
<!-- 上传按钮 -->
<el-button v-if="!isConstruction" type="primary">选取文件</el-button>
<el-icon v-else><Plus /></el-icon>
<el-button v-if="!isConstruction && !isImportInfo" type="primary">选取文件</el-button>
<el-button v-if="isImportInfo" type="warning" plain icon="Edit">导入员工资料 </el-button>
<el-icon v-if="isConstruction"><Plus /></el-icon>
<template #file="{ file }">
<div class="pdf" v-if="isConstruction">
<img src="@/assets/icons/svg/pdf.png" alt="" />
@ -47,7 +48,12 @@
的文件
</div>
<!-- 文件列表 -->
<transition-group v-if="!isConstruction" class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
<transition-group
v-if="!isConstruction && !isImportInfo"
class="upload-file-list el-upload-list el-upload-list--text"
name="el-fade-in-linear"
tag="ul"
>
<li v-for="(file, index) in fileList" :key="file.uid" class="el-upload-list__item ele-upload-list__item-content">
<el-link :href="`${file.url}`" :underline="false" target="_blank">
<span class="el-icon-document"> {{ getFileName(file.name) }} </span>
@ -75,11 +81,15 @@ const props = defineProps({
// 大小限制(MB)
fileSize: propTypes.number.def(5),
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf']),
fileType: propTypes.array.def(['doc', 'xls', 'ppt', 'txt', 'pdf', 'png', 'jpg', 'jpeg', 'zip']),
// 是否显示提示
isShowTip: propTypes.bool.def(true),
//是否为施工人员上传
isConstruction: propTypes.bool.def(false)
isConstruction: propTypes.bool.def(false),
//是否为导入资料
isImportInfo: propTypes.bool.def(false),
//ip地址
uploadUrl: propTypes.string.def('/resource/oss/upload')
});
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@ -88,7 +98,7 @@ const number = ref(0);
const uploadList = ref<any[]>([]);
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadFileUrl = ref(baseUrl + '/resource/oss/upload'); // 上传文件服务器地址
const uploadFileUrl = ref(baseUrl + props.uploadUrl); // 上传文件服务器地址
const headers = ref(globalHeaders());
const fileList = ref<any[]>([]);
@ -99,6 +109,7 @@ const fileUploadRef = ref<ElUploadInstance>();
watch(
() => props.modelValue,
async (val) => {
if (props.isImportInfo) return;
if (val) {
let temp = 1;
// 首先将值转为数组
@ -203,6 +214,13 @@ const handleDelete = (index: string | number, type?: string) => {
// 上传结束处理
const uploadedSuccessfully = () => {
if (props.isImportInfo) {
emit('update:modelValue', 'ok');
fileUploadRef.value?.clearFiles();
proxy?.$modal.closeLoading();
proxy?.$modal.msgSuccess('导入成功');
return;
}
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);
@ -259,15 +277,14 @@ const listToString = (list: any[], separator?: string) => {
}
}
.upload-file-uploader {
margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 10px;
position: relative;
.upload-file-list {
margin: 0;
.el-upload-list__item {
border: 1px solid #e4e7ed;
line-height: 2;
margin-bottom: 0;
position: relative;
}
}
.upload-file-list .ele-upload-list__item-content {

View File

@ -81,6 +81,7 @@ declare global {
form: T;
queryParams: D;
rules: ElFormRules;
memberRules?: ElFormRules;
}
/**

View File

@ -180,6 +180,7 @@ export function download(url: string, params: any, fileName: string) {
return service.post(url, params, {
transformRequest: [
(params: any) => {
return tansParams(params);
}
],
@ -188,6 +189,7 @@ export function download(url: string, params: any, fileName: string) {
}).then(async (resp: any) => {
const isLogin = blobValidate(resp);
if (isLogin) {
console.log("🚀 ~ download ~ resp:", resp)
const blob = new Blob([resp]);
FileSaver.saveAs(blob, fileName);
} else {

View File

@ -1,50 +1,138 @@
<template>
<div>
<el-descriptions v-loading="loading" title="用户信息" direction="vertical" border>
<el-descriptions-item :rowspan="3" :width="200" label="人脸照">
<el-image :src="userDetail?.facePicUrl" style="width: 150px; height: 150px" />
</el-descriptions-item>
<el-descriptions-item label="姓名">{{ userDetail?.userName }}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ userDetail?.phone }}</el-descriptions-item>
<el-descriptions-item label="性别">
<dict-tag :options="user_sex_type" :value="userDetail?.sex" />
</el-descriptions-item>
<el-descriptions-item label="年龄">{{ dayjs().diff(dayjs(userDetail?.sfzBirth), 'year') }}</el-descriptions-item>
<el-descriptions-item label="民族">{{ userDetail?.nation }}</el-descriptions-item>
<el-descriptions-item label="籍贯">{{ userDetail?.nativePlace }}</el-descriptions-item>
<el-descriptions-item label="身份证号码">{{ userDetail?.sfzNumber }}</el-descriptions-item>
<el-descriptions-item label="身份证有效期">
{{ dayjs(userDetail?.sfzStart).format('YYYY 年 MM 月 DD 日') }}
{{ dayjs(userDetail?.sfzEnd).format('YYYY 年 MM 月 DD 日') }}
</el-descriptions-item>
<el-descriptions-item label="身份证地址">{{ userDetail?.sfzSite }}</el-descriptions-item>
</el-descriptions>
<br />
<el-descriptions v-loading="loading" title="银行卡" direction="vertical" border>
<el-descriptions-item label="银行卡号">{{ userDetail?.yhkNumber }}</el-descriptions-item>
<el-descriptions-item label="银行开户行">{{ userDetail?.yhkOpeningBank }}</el-descriptions-item>
<el-descriptions-item label="持卡人">{{ userDetail?.yhkCardholder }}</el-descriptions-item>
</el-descriptions>
<br />
<el-descriptions v-loading="loading" title="单位信息" direction="vertical" border>
<el-descriptions-item label="施工单位">{{ userDetail?.contractorVo?.name }}</el-descriptions-item>
<el-descriptions-item label="工种">
<dict-tag :options="type_of_work" :value="userDetail?.typeOfWork" />
</el-descriptions-item>
</el-descriptions>
<br />
<el-descriptions :column="2" v-loading="loading" title="其他信息" direction="vertical" border>
<el-descriptions-item label="班组">{{ userDetail?.teamVo?.teamName }}</el-descriptions-item>
<el-descriptions-item label="打卡状态">
<dict-tag :options="user_clock_type" :value="userDetail?.clock" />
</el-descriptions-item>
<el-descriptions-item label="入场时间">
{{ userDetail?.entryDate ? dayjs(userDetail?.entryDate).format('YYYY 年 MM 月 DD 日 HH:mm:ss') : '' }}
</el-descriptions-item>
<el-descriptions-item label="离场时间">
{{ userDetail?.leaveDate ? dayjs(userDetail?.leaveDate).format('YYYY 年 MM 月 DD 日 HH:mm:ss') : '' }}
</el-descriptions-item>
</el-descriptions>
<div class="block_box">
<span>用户信息</span>
<el-form label-width="130px">
<el-row :gutter="20" justify="space-around">
<el-col :span="12">
<el-form-item label="人脸照">
<el-image :src="userDetail?.facePicUrl" style="width: 150px; height: 150px" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="姓名">
{{ userDetail?.userName }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="联系电话">
{{ userDetail?.phone }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="性别">
<dict-tag :options="user_sex_type" :value="userDetail?.sex" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年龄">
{{ dayjs().diff(dayjs(userDetail?.sfzBirth), 'year') }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="民族">
{{ userDetail?.nation }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="籍贯">
{{ userDetail?.nativePlace }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证号码">
{{ userDetail?.sfzNumber }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证号码">
{{ userDetail?.sfzNumber }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证有效开始期">
{{ dayjs(userDetail?.sfzStart).format('YYYY 年 MM 月 DD 日') }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证有效结束期">
{{ dayjs(userDetail?.sfzEnd).format('YYYY 年 MM 月 DD 日') }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="身份证地址">
{{ userDetail?.sfzSite }}
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div class="block_box">
<span>银行卡</span>
<el-form label-width="130px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="银行卡号">
{{ userDetail?.yhkNumber }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="银行开户行">
{{ userDetail?.yhkOpeningBank }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="持卡人">
{{ userDetail?.yhkCardholder }}
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div class="block_box">
<span>单位信息</span>
<el-form label-width="130px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="施工单位">
{{ userDetail?.contractorVo?.name }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="工种">
<dict-tag :options="type_of_work" :value="userDetail?.typeOfWork" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
<div class="block_box">
<span>其他信息</span>
<el-form label-width="130px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="班组">
{{ userDetail?.teamVo?.teamName }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="打卡状态">
<dict-tag :options="user_clock_type" :value="userDetail?.clock" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="入场时间">
{{ userDetail?.entryDate ? dayjs(userDetail?.entryDate).format('YYYY 年 MM 月 DD 日 HH:mm:ss') : '' }}
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="离场时间">
{{ userDetail?.leaveDate ? dayjs(userDetail?.leaveDate).format('YYYY 年 MM 月 DD 日 HH:mm:ss') : '' }}
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</div>
</template>
@ -85,3 +173,16 @@ watch(
}
);
</script>
<style lang="scss" scoped>
.block_box {
border: 1px solid #9eccfa;
border-radius: 6px;
padding: 10px 20px 20px 10px;
margin: 15px;
> span {
color: #409eff;
font-weight: 700;
font-size: 14px;
}
}
</style>

View File

@ -79,13 +79,21 @@
</el-col>
<el-row @mouseover="informationStatus = true" :gutter="10" @mouseout="informationStatus = false">
<el-col :span="1.5">
<el-button type="success" plain @click="statusDialog = true">员工资料 </el-button>
<el-button type="success" plain>员工资料 </el-button>
</el-col>
<el-col :span="1.5" v-show="informationStatus">
<el-button type="primary" plain icon="Edit" @click="downloadTemplate">下载资料模板 </el-button>
</el-col>
<el-col :span="1.5" v-show="informationStatus">
<el-button type="warning" plain icon="Edit" @click="statusDialog = true">导入员工资料 </el-button>
<!-- <el-button type="warning" plain icon="Edit" @click="importInformation">导入员工资料 </el-button> -->
<file-upload
v-model="filePath"
isImportInfo
:isShowTip="false"
uploadUrl="/project/constructionUserFile/upload/zip"
:limit="1"
:file-size="50"
/>
</el-col>
</el-row>
@ -132,15 +140,17 @@
/>
</template>
</el-table-column>
<el-table-column label="日薪(元)" align="center" min-width="180">
<el-table-column label="薪水" align="center" min-width="180">
<template #default="scope">
<span>{{ scope.row.salary ? scope.row.salary : scope.row.standardSalary }}</span>
<span class="flex justify-center">
{{ scope.row.salary ? scope.row.salary : scope.row.standardSalary }}
(<dict-tag :options="wage_measure_unit_type" :value="scope.row.wageMeasureUnit"></dict-tag>)
</span>
<div class="text-blue text-sm cursor-pointer" @click="openSalaryDialog(scope.row)">{{ scope.row.salary ? '取消变更' : '变更' }}</div>
</template>
</el-table-column>
<el-table-column label="入场时间" align="center" prop="entryDate" min-width="180" />
<el-table-column label="离场时间" align="center" prop="leaveDate" min-width="180" />
<el-table-column label="薪水" align="center" prop="salary" />
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
{{ scope.row.status == 0 ? '在职' : '离职' }}
@ -166,7 +176,7 @@
删除
</el-button>
<el-tooltip content="红点:部分上传,绿点:已上传,无点:未上传" placement="right" effect="dark">
<el-badge is-dot type="primary">
<el-badge :is-dot="scope.row.fileUploadStatus != '1'" :type="uploadStatusColor(scope.row.fileUploadStatus)">
<el-button link type="primary" icon="FolderAdd" @click="handleUpload(scope.row)">文件上传 </el-button>
</el-badge>
</el-tooltip>
@ -184,7 +194,7 @@
<div class="msg">用户信息</div>
<div class="el-row">
<div class="el-col el-col-24">
<el-form-item label="人脸照" prop="pacePhoto">
<el-form-item label="人脸照" prop="facePic">
<image-upload v-model="form.facePic" :limit="1" :is-show-tip="false" />
</el-form-item>
</div>
@ -299,6 +309,13 @@
</el-select>
</el-form-item>
</div>
<div class="el-col el-col-12">
<el-form-item label="结算方式" prop="wageMeasureUnit">
<el-select v-model="form.wageMeasureUnit" clearable placeholder="请选择结算方式">
<el-option v-for="item in wage_measure_unit_type" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="el-col el-col-12">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" style="width: 240px" />
@ -351,7 +368,11 @@
</el-dialog>
<el-dialog :title="skipName + '-切换人脸'" v-model="showFaceDrawer" width="770px">
<div class="flex items-center justify-center">
<image-upload v-model="form.facePic" :limit="1" :is-show-tip="false" />
<el-form :model="form" ref="constructionUserFormRef" :rules="rules">
<el-form-item>
<image-upload v-model="form.facePic" :limit="1" :is-show-tip="false" />
</el-form-item>
</el-form>
</div>
<template #footer>
<span
@ -374,8 +395,8 @@
</template>
</el-dialog>
<el-dialog title="温馨提示" v-model="salaryStatus" width="30%">
<span>请输入薪资(/)</span>
<el-input class="mt-xl" v-model="changeSalary" placeholder="" size="normal" clearable @change=""></el-input>
<span>请输入薪资</span>
<el-input class="mt-xl" v-model="changeSalary" placeholder="" clearable @change=""></el-input>
<template #footer>
<span>
<el-button type="primary" @click="handleSalary">确认</el-button>
@ -386,8 +407,18 @@
<el-dialog title="入场退场记录" v-model="exitStatus" width="600px">
<div v-for="(item, index) in exitList">
<el-timeline>
<el-timeline-item v-for="(itm, idx) in 2" :key="idx" :timestamp="item.entryDate" :color="green">
{{ item.entryDate }}
<el-timeline-item color="#0bbd87" class="mb">
{{ '入场时间:' + item.entryDate }}
</el-timeline-item>
<el-timeline-item color="rgb(255, 73, 73)">
<div class="mb">{{ '退场时间:' + item.entryDate }}</div>
<div class="pl-xl">
<span class="text-coolgray font-bold">退场文件<image-preview v-for="itm in item.pathUrl" :src="itm" width="100px" class="mr" /></span
><br />
<p class="mt text-coolgray">
备注<span class="text-blue">{{ item.remark }}</span>
</p>
</div>
</el-timeline-item>
</el-timeline>
</div>
@ -415,7 +446,8 @@ import {
updateConstructionUserPlayCardOneStatus,
updateConstructionUserSalary,
getConstructionUserExit,
dowloadConstructionUserTemplate
dowloadConstructionUserTemplate,
importConstructionUserInfo
} from '@/api/project/constructionUser';
import {
ConstructionUserForm,
@ -440,10 +472,10 @@ import {
ConstructionUserFileQuery
} from '@/api/project/constructionUserFile/types';
import { ElLoadingService } from 'element-plus';
const imgurl = 'http://zmkg.cqet.top:8899/wxfile/upload_file/2024-12-03/1.jpg';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type } = toRefs<any>(
proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type')
const { type_of_work, user_sex_type, user_clock_type, user_file_type, user_status_type, wage_measure_unit_type } = toRefs<any>(
proxy?.useDict('type_of_work', 'user_sex_type', 'user_clock_type', 'user_file_type', 'user_status_type', 'wage_measure_unit_type')
);
// 获取用户 store
const userStore = useUserStoreHook();
@ -466,6 +498,7 @@ const playCardLoding = ref(false);
const salaryStatus = ref(false);
const exitStatus = ref(false);
const informationStatus = ref(false);
const filePath = ref<string>('');
const exitList = ref<ConstructionUserExitVO[]>([]);
const changeSalary = ref<string>('');
const vocationalStatus = ref<number>(null);
@ -477,7 +510,7 @@ const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const baseUrl = import.meta.env.VITE_APP_BASE_API;
//人员迁移条件
const skipObject: skipType = reactive({
id: '',
@ -507,6 +540,7 @@ const initFormData: ConstructionUserForm = {
sfzNumber: undefined,
sfzStart: undefined,
sfzEnd: undefined,
wageMeasureUnit: undefined,
sfzSite: undefined,
sfzBirth: undefined,
nativePlace: undefined,
@ -555,8 +589,28 @@ const data = reactive<PageData<ConstructionUserForm, ConstructionUserQuery>>({
params: {}
},
rules: {
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }],
clock: [{ required: true, message: '打卡不能为空', trigger: 'blur' }]
clock: [{ required: true, message: '打卡不能为空', trigger: 'blur' }],
facePic: [{ required: true, message: '人脸照不能为空', trigger: 'blur' }],
userName: [{ required: true, message: '人员姓名不能为空', trigger: 'blur' }],
projectId: [{ required: true, message: '项目id不能为空', trigger: 'blur' }],
contractorId: [{ required: true, message: '分包公司id不能为空', trigger: 'blur' }],
teamId: [{ required: true, message: '班组id不能为空', trigger: 'blur' }],
phone: [{ required: true, message: '联系电话不能为空', trigger: 'blur' }],
nation: [{ required: true, message: '民族不能为空', trigger: 'blur' }],
sfzFrontPic: [{ required: true, message: '身份证正面图片不能为空', trigger: 'blur' }],
sfzBackPic: [{ required: true, message: '身份证背面图片不能为空', trigger: 'blur' }],
sfzNumber: [{ required: true, message: '身份证号码不能为空', trigger: 'blur' }],
sfzStart: [{ required: true, message: '身份证有效开始期不能为空', trigger: 'blur' }],
sfzEnd: [{ required: true, message: '身份证有效结束期不能为空', trigger: 'blur' }],
sfzSite: [{ required: true, message: '身份证地址不能为空', trigger: 'blur' }],
sfzBirth: [{ required: true, message: '身份证出生日期不能为空', trigger: 'blur' }],
nativePlace: [{ required: true, message: '籍贯不能为空', trigger: 'blur' }],
yhkPic: [{ required: true, message: '银行卡图片不能为空', trigger: 'blur' }],
yhkNumber: [{ required: true, message: '银行卡号不能为空', trigger: 'blur' }],
yhkOpeningBank: [{ required: true, message: '开户行不能为空', trigger: 'blur' }],
typeOfWork: [{ required: true, message: '工种(字典type_of_work)不能为空', trigger: 'blur' }],
wageMeasureUnit: [{ required: true, message: '工资计量单位不能为空', trigger: 'blur' }],
userRole: [{ required: true, message: '用户角色(1=普通用户,2=管理员)不能为空', trigger: 'blur' }]
}
});
@ -581,6 +635,18 @@ const uploadPath = computed(() => {
return list;
});
/** 返回文件上传状态 */
const uploadStatusColor = computed(() => (str: string) => {
switch (str) {
case '3':
return 'success';
case '2':
return 'danger';
default:
return 'info';
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询施工人员列表 */
@ -733,10 +799,13 @@ const downloadTemplate = async () => {
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)'
});
await dowloadConstructionUserTemplate({ projectId: currentProject.value.id });
const res = await dowloadConstructionUserTemplate({ projectId: currentProject.value.id });
loadingInstance.close();
};
//导入资料
const importInformation = async () => {};
/** 人员迁移 */
const handleChange = async (row: ConstructionUserVO) => {
const _id = row?.id || ids.value[0];
@ -761,7 +830,7 @@ 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;
exitList.value = res.rows;
exitStatus.value = true;
};
@ -777,6 +846,7 @@ const handleUpload = async (row: ConstructionUserVO) => {
/** 提交按钮 */
const submitForm = () => {
constructionUserFormRef.value?.validate(async (valid: boolean) => {
console.log(valid);
if (valid) {
buttonLoading.value = true;
if (form.value.id) {
@ -788,6 +858,8 @@ const submitForm = () => {
dialog.visible = false;
showFaceDrawer.value = false;
await getList();
} else {
console.log(12);
}
});
};

View File

@ -66,8 +66,8 @@
<el-button link type="success" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['project:projectTeamMember:edit']">
修改
</el-button>
<el-button link type="danger" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['project:projectTeamMember:remove']">
删除
<el-button link type="danger" icon="Position" @click="handleExit(scope.row)" v-hasPermi="['project:projectTeamMember:remove']">
退场
</el-button>
</el-space>
</template>
@ -85,7 +85,7 @@
<!-- 添加或修改项目班组下的成员对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="projectTeamMemberFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="施工人员" prop="memberId">
<el-form-item label="施工人员" prop="memberId" v-if="!form.id">
<el-select v-model="form.memberId" clearable placeholder="请选择人员" filterable>
<el-option v-for="item in userNotInTeamOpt" :key="item.value" :label="item.label" :value="item.value" />
<pagination
@ -114,6 +114,27 @@
</div>
</template>
</el-dialog>
<!-- 上传退场记录 -->
<el-dialog title="员工离场" v-model="memberStatus" width="30%">
<el-form :model="memberForm" ref="memberFormRef" :rules="memberRules" label-width="100px" :inline="false">
<el-form-item label="用户名">
<el-input v-model="memberForm.userName" disabled></el-input>
</el-form-item>
<el-form-item label="退场文件">
<file-upload v-model="memberForm.filePath" :limit="10" :is-show-tip="false" :file-size="50" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="memberForm.remark" placeholder="请输入备注" type="textarea"></el-input>
</el-form-item>
</el-form>
<template #footer>
<span>
<el-button type="primary" @click="submitMemberForm" :loading="buttonLoading">确定</el-button>
<el-button @click="memberStatus = false">取消</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
@ -129,8 +150,8 @@ import {
} from '@/api/project/projectTeamMember';
import { computed, reactive, ref } from 'vue';
import { useUserStoreHook } from '@/store/modules/user';
import { listConstructionUser } from '@/api/project/constructionUser';
import { ConstructionUserQuery, ConstructionUserVO } from '@/api/project/constructionUser/types';
import { listConstructionUser, delConstructionUserMember } from '@/api/project/constructionUser';
import { ConstructionUserQuery, ConstructionUserVO, ConstructionUserMembeForm } from '@/api/project/constructionUser/types';
// 获取用户 store
const userStore = useUserStoreHook();
@ -138,10 +159,16 @@ const userStore = useUserStoreHook();
const currentProject = computed(() => userStore.selectedProject);
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { user_post_type } = toRefs<any>(proxy?.useDict('user_post_type'));
const memberStatus = ref(false);
interface Props {
projectTeamVo: ProjectTeamVO;
}
const memberForm = reactive<ConstructionUserMembeForm>({
id: undefined,
filePath: undefined,
remark: undefined,
userName: undefined
});
const props = defineProps<Props>();
// 是否可见
@ -160,6 +187,9 @@ const data = reactive<PageData<ProjectTeamMemberForm, ProjectTeamMemberQuery>>({
},
rules: {
id: [{ required: true, message: '主键id不能为空', trigger: 'blur' }]
},
memberRules: {
filePath: [{ required: true, message: '请上传退场文件', trigger: 'blur' }]
}
});
const buttonLoading = ref(false);
@ -170,12 +200,13 @@ const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const projectTeamMemberFormRef = ref<ElFormInstance>();
const memberFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
const { queryParams, form, rules } = toRefs(data);
const { queryParams, form, rules, memberRules } = toRefs(data);
const projectTeamMemberList = ref<ProjectTeamMemberVO[]>([]);
/** 查询项目班组下的成员列表 */
const getList = async () => {
@ -277,6 +308,31 @@ const submitForm = () => {
});
};
/** 确定退场按钮 */
const submitMemberForm = async () => {
memberFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
await delConstructionUserMember(memberForm).finally(() => (buttonLoading.value = false));
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
memberForm.filePath = undefined;
memberForm.remark = undefined;
}
});
memberStatus.value = false;
};
/** 退场按钮操作 */
const handleExit = async (row?: ProjectTeamMemberVO) => {
const _ids = row?.id || ids.value;
memberForm.userName = row?.memberName;
console.log('🚀 ~ handleDelete ~ row:', row);
memberForm.id = row?.id;
memberStatus.value = true;
};
/** 删除按钮操作 */
const handleDelete = async (row?: ProjectTeamMemberVO) => {
const _ids = row?.id || ids.value;

View File

@ -86,7 +86,7 @@
</div>
</template>
</el-dialog>
<el-dialog :title="currentRow.teamName" v-model="visible">
<el-dialog :title="currentRow.teamName" v-model="visible" width="1000px">
<user-list-dialog :projectTeamVo="currentRow" />
</el-dialog>
</div>