lanan-repair-app/pages-internal/staffManagement/addStaff.vue
2025-08-11 17:42:50 +08:00

872 lines
24 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<!-- <headersVue :titles="titles">
<u-icon name="arrow-left" color="#fff" size="18"></u-icon>
</headersVue> -->
<VNavigationBar style="position: relative;z-index: 99;" homeHeaderPaddingTop="0" backgroundColor="#fff"
title-color="#000" :title="titles"></VNavigationBar>
<view class="container">
<view class="box_">
<view class="d_s" style="margin-bottom: 10px;" v-if="userId">
<!-- <view class="touxiang_">
<image src="/static/imgs/yh.png" mode=""></image>
</view> -->
<view class="touxiang_" v-if="staff.avatar">
<!-- <image src="/static/imgs/yh.png" mode=""></image> -->
<image :src=" imgUrl + staff.avatar" mode="" @click="previewImage(imgUrl + staff.avatar)">
</image>
</view>
<view class="touxiang_" v-else>
<!-- <image src="/static/imgs/yh.png" mode=""></image> -->
<image src="/static/imgs/yh.png"></image>
</view>
<view class="">
<view class="name_">{{ staff.nickname }}</view>
<view class="d_s">
<view class="tel_">
<image src="/static/imgs/tel.png" mode=""></image>
</view>
<view class="telnum">手机号:{{ staff.mobile }}</view>
</view>
</view>
</view>
<view class="d_b" v-if="!userId">
<view class="">姓名</view>
<input type="text" placeholder="请输入姓名" v-model="staff.nickname" style="text-align: right;" />
</view>
<view class="d_b" v-if="!userId">
<view class="">手机号</view>
<input type="text" placeholder="请输入手机号" v-model="staff.mobile" style="text-align: right;" />
</view>
<!-- <view class="d_b">
<view class="">学历</view>
<view class="" @click="showEducation = true">
{{ staff.educational != null ? this.staff.educational : '请选择学历' }} >
</view>
</view> -->
<!-- <view class="d_b">
<view class="">身份证号</view>
<input type="text" placeholder="请输入身份证号" v-model="staff.idNumber" style="text-align: right;" />
</view>
<view class="d_b">
<view class="">年龄</view>
<input type="text" placeholder="请输入年龄" v-model="staff.age" style="text-align: right;" />
</view> -->
<view class="d_b">
<view class="">性别</view>
<picker :range="genderOptions" @change="onGenderChange" :value="genderIndex">
<view class="picker">
{{ genderOptions[genderIndex] }}
</view>
</picker>
</view>
<!-- <view class="d_b">
<view class="">户籍地址</view>
<input type="text" placeholder="请输入户籍地址" v-model="staff.regAddress" style="text-align: right;" />
</view>
<view class="d_b">
<view class="">家庭住址</view>
<input type="text" placeholder="请输入家庭住址" v-model="staff.address" style="text-align: right;" />
</view>
<view class="d_b">
<view class="">个人简介</view>
<input type="text" placeholder="请输入个人简介" v-model="staff.instructorDesc"
style="text-align: right;" />
</view> -->
<!-- <view class="d_b">
<view class="">转正时间</view>
<view class="" @click="showFormalDate = true">
{{ staff.probationPeriod != null ? this.staff.probationPeriod : '请选择转正时间' }} >
</view>
</view>
<view class="d_b">
<view class="">购买保险时间</view>
<view class="" @click="showSafeDate = true">
{{ staff.socialSecurityBuyDate != null ? this.staff.socialSecurityBuyDate : '请选择购买保险时间' }} >
</view>
</view> -->
<!-- <view class="d_b">
<view class="">驾照类型</view>
<view class="" @click="showDriveType = true">
{{ driverLicenseTypeArrStr != null ? this.driverLicenseTypeArrStr : '请选择驾照类型' }} >
</view>
</view> -->
<view class="d_b">
<view class="">岗位</view>
<view class="">
{{ staff.roleNames || '请选择岗位' }} >
</view>
</view>
<view class="d_b" @click="goFile" v-if="userId">
<view class="">附件</view>
<view class="lan_">查看附件
<image src="/static/imgs/add.png" mode=""></image>
</view>
</view>
<!-- <u-upload-->
<!-- ref="uploadRef"-->
<!-- :fileList="fileList1"-->
<!-- @afterRead="afterRead"-->
<!-- @delete="deletePic"-->
<!-- name="1"-->
<!-- multiple-->
<!-- :maxCount="10"-->
<!-- v-show="fileList1.length > 0"-->
<!-- >-->
<!-- </u-upload>-->
<!-- <view class="hui_box" v-if="fileList1.length == 0">-->
<!-- <image src="/static/imgs/wod.png" mode=""></image>-->
<!-- <view class="">-->
<!-- <view class="big_">附件格式 jpg/png</view>-->
<!-- <view class="sm_">100KB</view>-->
<!-- </view>-->
<!-- </view>-->
<view class="anniu" @click="submit">
{{ buttonTile }}
</view>
</view>
</view>
<u-picker :show="showEducation" ref="uPicker" :columns="[educations]" @confirm="chooseEducation"
@cancel="showEducation = false" keyName="label"></u-picker>
<qianziyu-select :show="showDriveType" type="checkbox" name="id" :dataLists="driverLicenseType"
:showSearch=false @cancel="showDriveType = false" :checkboxData="driverLicenseTypeArr" @submit="onsubmit"
@update:checkboxData="staff.roleIds = $event">
</qianziyu-select>
<u-datetime-picker :show="showJoinedDate" v-model="selectJoinDate" @cancel="showJoinedDate = false"
@confirm="chooseJoinDate" mode="date" return-type='string'></u-datetime-picker>
<u-datetime-picker :show="showFormalDate" v-model="selectProbationPeriod" @cancel="showFormalDate = false"
@confirm="chooseFormalDate" mode="date" return-type='string'></u-datetime-picker>
<u-datetime-picker :show="showSafeDate" v-model="selectSocialSecurityBuyDate" @cancel="showSafeDate = false"
@confirm="chooseSafeDate" mode="date" return-type='string'></u-datetime-picker>
<!-- <u-picker :show="showRole" ref="uPicker" :columns="[roles]"-->
<!-- @confirm="chooseRole" @cancel="showRole = false"-->
<!-- keyName="name"></u-picker>-->
<!-- <qianziyu-select :show="showRole" type="checkbox" name="name" :dataLists="roles" :showSearch=false
@cancel="showRole = false" :checkboxData="staff.roleIds" @submit="chooseRole()" popupTitle='汇报对象选择'
@update:checkboxData="staff.roleIds = $event">
</qianziyu-select> -->
<!-- <qianziyu-select :show="showRole" type="checkbox" name="name" :dataLists="roles" :showSearch="false"
@cancel="showRole = false" :checkboxData="getInitialRoleSelection()" @submit="handleRoleSubmit"
popupTitle="选择岗位" @update:checkboxData="updateRoleSelection"></qianziyu-select> -->
<qianziyu-select :show="showRole" type="radio" name="name" :dataLists="roles" :showSearch="false"
@cancel="showRole = false" @submit="handleRoleSubmit" popupTitle="选择岗位"></qianziyu-select>
<qianziyu-select :show="showGenderPicker" type="radio" name="label" :dataLists="genderOptions"
:showSearch="false" popupTitle="选择性别" @submit="handleGenderSubmit" @cancel="closeGenderPicker">
</qianziyu-select>
</view>
</template>
<script>
import request from "@/utils/request";
import {
formatDate
} from "@/utils/utils";
import upload from "@/utils/upload";
import config from "@/config";
import QianziyuSelect from '@/components/qianziyu-select/qianziyu-select.vue'
import VNavigationBar from "@/components/VNavigationBar.vue";
export default {
components: {
QianziyuSelect,
VNavigationBar
},
data() {
return {
titles: "新增员工",
staff: {
joinDate: null,
probationPeriod: null,
socialSecurityBuyDate: null,
roleIds: []
},
fileList1: [],
selectJoinDate: new Date().toString(),
selectProbationPeriod: new Date().toString(),
selectSocialSecurityBuyDate: new Date().toString(),
buttonTile: '保存',
show: false,
showRole: false,
status: 'loading',
userId: undefined,
showEducation: false,
showJoinedDate: false,
showFormalDate: false,
showSafeDate: false,
showDriveType: false,
educations: [],
roles: [],
driverLicenseType: [],
driverLicenseTypeArr: [],
driverLicenseTypeArrStr: null,
roleName: null,
genderOptions: ['男', '女'], // 用于显示
genderIndex: 0,
scrollHeight: 'auto',
showGenderPicker: false,
imgUrl: config.imagesUrl,
ifAdd: null,
}
},
onLoad(data) {
if (data.id) {
this.titles = '编辑员工'
this.userId = data.id
this.getInfoByUserId()
this.buttonTile = '修改'
}
this.getEducation()
this.getDriveType()
this.getRoles()
},
methods: {
cancelShow() {
this.show = !this.cancelShow
},
// 根据服务套餐查询角色
async getRoles() {
let res = await request({
url: '/admin-api/system/role/pageByQuery',
method: 'get',
params: {
servicePackageId: 'weixiu'
}
})
this.roles = res.data
},
onsubmit(selectedData) {
selectedData.map(item => item.id);
this.driverLicenseTypeArr = selectedData;
this.driverLicenseTypeArrStr = selectedData.map(item => item.id).join(',');
this.showDriveType = false; // 提交后关闭弹窗
},
// 驾驶证类型下拉框
getDriveType() {
return request({
url: '/admin-api/common/down/getDriverLicenseType',
method: 'get'
}).then(res => {
//提取出数组中的id属性
this.driverLicenseType = res.data
})
},
onGenderChange(e) {
this.genderIndex = e.detail.value;
this.staff.sex = e.detail.value.toString(); // '0' 或 '1'
},
submit() {
const roleIds = Array.isArray(this.staff.roleIds) ?
this.staff.roleIds.map(id => typeof id === 'object' ? id.id : id) : [];
// this.staff.roleIds = this.staff.roleIds.map(item => item.id)
//判断是否是修改
if (this.userId) {
this.update()
} else {
this.add()
}
},
update() {
// 验证表单信息
const flag = this.validData()
if (!flag) {
return
}
this.staff.userId = this.userId
const data = {
...this.staff
}
request({
url: '/admin-api/system/user/update',
method: 'put',
data: data
}).then(res => {
// 赋予用户角色
let resp = request({
url: '/admin-api/system/permission/assign-user-role',
method: 'post',
data: {
userId: this.userId,
roleIds: this.staff.roleIds
}
})
uni.showToast({
title: "编辑成功"
})
// uni.navigateBack()
this.pageBack()
})
},
async add() {
// 验证表单信息
const flag = this.validData()
if (!flag) {
return
}
let data = {
nickname: this.staff.nickname,
mobile: this.staff.mobile,
username: this.staff.mobile,
status: 0,
userType: '01',
roleId: this.staff.roleId,
name: this.nickname,
joinDate: this.staff.joinDate,
idCard: this.staff.idNumber,
age: this.staff.age,
sex: this.staff.sex,
educational: this.staff.educational,
probationPeriod: this.staff.probationPeriod,
socialSecurityBuyDate: this.staff.socialSecurityBuyDate,
driverLicenseTypeArr: this.driverLicenseTypeArr.map(item => item.id),
password: '123456',
regAddress: this.staff.regAddress,
address: this.staff.address,
seniority: this.staff.seniority,
instructorDesc: this.staff.instructorDesc
}
let res = await request({
url: '/admin-api/system/user/create',
method: 'post',
data: data
})
if (res.code == 200) {
console.log('角色', res)
let resp = await request({
url: '/admin-api/system/permission/assign-user-role',
method: 'post',
data: {
userId: res.data,
roleIds: this.staff.roleIds
}
})
uni.showToast({
title: "添加成功"
})
this.show = false
this.getindex()
uni.navigateBack()
}
},
validData() {
if (!this.staff.nickname || !this.staff.mobile) {
uni.showToast({
title: '姓名和电话不能有空',
icon: 'none'
})
return false
}
if (!this.staff || !Array.isArray(this.staff.roleIds) || this.staff.roleIds.length === 0) {
uni.showToast({
title: '请选择岗位',
icon: 'none'
})
return false
}
return true
},
// 打开性别选择器
openGenderPicker() {
this.showGenderPicker = true
},
// 关闭性别选择器
closeGenderPicker() {
this.showGenderPicker = false
},
// 处理性别选择提交
handleGenderSubmit(selectedData) {
this.genderIndex = selectedData[0].index
this.staff.sex = this.genderIndex.toString()
this.closeGenderPicker()
},
chooseJoinDate(e) {
this.$nextTick(() => {
this.staff.joinDate = formatDate(e.value)
this.selectJoinDate = this.staff.joinDate
})
this.showJoinedDate = false
console.log(this.staff)
},
chooseFormalDate(e) {
this.$nextTick(() => {
this.staff.probationPeriod = formatDate(e.value);
this.selectProbationPeriod = this.staff.probationPeriod
})
this.showFormalDate = false;
console.log(this.staff)
},
chooseSafeDate(e) {
this.$nextTick(() => {
this.staff.socialSecurityBuyDate = formatDate(e.value)
this.selectSocialSecurityBuyDate = this.staff.socialSecurityBuyDate
})
this.showSafeDate = false
console.log(this.staff)
},
/* async getInfoByUserId() {
const res = await request({
url: '/admin-api/base/dl-drive-school-coach/getOnInternal',
params: {
id: this.userId
},
method: 'get'
})
this.staff = res.data
console.log('staff', this.staff)
this.genderIndex = parseInt(this.staff.sex || '0');
this.topName = this.staff?.nickname
if (res.data.driverLicenseType) {
this.driverLicenseTypeArrStr = res.data.driverLicenseType
res.data.driverLicenseTypeArr.forEach(item => {
let temp = {
id: item,
name: item
}
this.driverLicenseTypeArr.push(temp)
})
}
if (this?.staff?.roleIds) {
console.log('this.staff.roleIds', this.staff.roleIds)
this.staff.roleIds = this.staff.roleIds.map(roleId => {
return this.roles.find(role => role.id === roleId);
});
this.roleName = this.staff.roleIds.map(item => item.name).join(',')
console.log(this.staff.roleIds)
// this.fileList1 = []
// this.staff.fileList.forEach((item) => {
// const temp = {
// name: item.name,
// url: item.url.startsWith("http") ? item.url : baseImageUrl + '/' + item.url
// }
// this.fileList1.push(temp)
// })
}
}, */
getEducation() {
if (!this.educations || this.educations.length === 0) {
// this.getEducations()
}
const index = this.educations.findIndex(item => item.value === this.staff.education)
if (index !== -1) {
return this.educations[index].label
}
return ''
},
// 学历
/* async getEducations() {
this.educations = await getDictDataByType("company_staff_edu")
}, */
chooseEducation(e) {
this.$set(this.staff, 'education', e.value[0].label)
this.staff.educational = e.value[0].label
this.showEducation = false
},
chooseRole() {
console.log('roleName', this.roleName)
console.log('roleIds', this.staff.roleIds)
this.roleName = this.staff.roleIds.map(item => item.name).join(',')
this.showRole = false
console.log('roleName', this.roleName)
console.log('roleIds', this.staff.roleIds)
},
goFile() {
if (!this.userId) {
uni.showToast({
title: '请先新建员工',
icon: 'none'
})
return
}
if (!this.staff.folderId) {
console.log('当前员工没有文件夹')
//给当前员工创建一个文件夹
request({
// url: '/admin-api/inspectionStaff/addFolder',
url: '/admin-api/base/repair-staff/addFolder',
method: 'post',
data: this.userId
}).then(res => {
this.staff.folderId = res.data
uni.navigateTo({
url: '/pages-internal/dataManagement/deviceManage?type=staff&folderId=' +
this.staff.folderId
})
})
} else {
uni.navigateTo({
url: '/pages-internal/dataManagement/deviceManage?type=staff&folderId=' + this
.staff.folderId
})
}
},
// 上传相关方法
handleUpload() {
// 通过 ref 获取 u-upload 组件实例,并调用其上传方法
this.$refs.uploadRef.chooseFile();
},
// 删除图片
deletePic(event) {
this[`fileList${event.name}`].splice(event.index, 1);
},
// 新增图片
async afterRead(event) {
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file);
let fileListLen = this[`fileList${event.name}`].length;
lists.map((item) => {
this[`fileList${event.name}`].push({
...item,
status: "uploading",
message: "上传中",
});
});
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url);
let item = this[`fileList${event.name}`][fileListLen];
this[`fileList${event.name}`].splice(
fileListLen,
1,
Object.assign(item, {
status: "success",
message: "",
url: result,
})
);
fileListLen++;
}
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
// let a = uni.uploadFile({
// url: "http://192.168.2.21:7001/upload", // 仅为示例,非真实的接口地址
// filePath: url,
// name: "file",
// formData: {
// user: "test",
// },
// success: (res) => {
// setTimeout(() => {
// resolve(res.data.data);
// }, 1000);
// },
// });
upload({
url: '/admin-api/common/upload',
filePath: url,
}).then((res) => {
resolve(res.data.url);
console.log(this.fileList1)
this.forceRefreshFiles(); // 强制刷新文件列表
})
});
},
pageBack() {
uni.navigateBack({
delta: 1 // delta值为1时表示返回的页面层数
});
},
// 获取初始选中的角色(适配您提供的数据结构)
getInitialRoleSelection() {
if (!this.staff.roleIds || !this.roles.length) return [];
// 处理两种情况roleIds可能是数字数组或对象数组
return this.roles.filter(role => {
return Array.isArray(this.staff.roleIds) ?
this.staff.roleIds.some(id =>
typeof id === 'number' ? id === role.id : id.id === role.id) :
false;
});
},
// 处理角色选择提交
handleRoleSubmit(selectedRole) {
// 根据选择的岗位设置员工类型
if (selectedRole.name === '教练') {
this.staff.type = 'jl';
} else if (selectedRole.name === '驾校业务经理') {
this.staff.type = 'ywjl';
} else {
this.staff.type = 'yg'; // 其他情况设为普通员工
}
// 更新显示和存储选中的角色
this.roleName = selectedRole.name;
this.staff.roleIds = [selectedRole.id]; // 保持为数组格式,但只有一个元素
this.showRole = false;
console.log('当前员工类型:', this.staff.type);
console.log('选中角色ID:', this.staff.roleIds);
},
previewImage(currentUrl) {
if (!currentUrl) {
uni.showToast({
title: '图片无效',
icon: 'none'
});
return;
}
uni.previewImage({
current: currentUrl, // 当前图片 URL
urls: [currentUrl], // 所有图片的 URL 数组(如果是单张图片,直接传数组)
success: () => console.log('预览成功'),
fail: (err) => console.error('预览失败:', err)
});
},
// 实时更新选中状态
updateRoleSelection(selectedRoles) {
this.staff.roleIds = selectedRoles.map(role => role.id);
this.updateRoleNameDisplay();
},
// 更新角色名称显示
updateRoleNameDisplay() {
this.roleName = this.roles
.filter(role => this.staff.roleIds.includes(role.id))
.map(role => role.name)
.join(',');
},
// 获取角色信息的方法
async getInfoByUserId() {
const res = await request({
url: '/admin-api/base/repair-staff/get',
params: {
id: this.userId
},
method: 'get'
});
this.staff = res.data;
this.genderIndex = parseInt(this.staff.sex || '0');
// 编辑时回显岗位和类型
if (this.staff.roleIds && this.staff.roleIds.length && this.roles.length) {
const selectedRole = this.roles.find(role => role.id === this.staff.roleIds[0]);
if (selectedRole) {
this.roleName = selectedRole.name;
// 根据已有type设置如果没有则自动设置
if (!this.staff.type) {
this.handleRoleSubmit(selectedRole);
}
}
}
}
},
}
</script>
<style scoped lang="scss">
.content {
/* background: #f4f5f6;
height: 100vh; */
background: #f4f5f6;
height: 100vh;
/* 全屏高度 */
display: flex;
flex-direction: column;
/* 垂直排列 */
overflow: hidden;
}
.container {
/* width: 100%;
background: #f4f5f6;
box-sizing: border-box;
padding: 30rpx;
// padding-top: 200rpx;
padding-bottom: 28px; */
/* 占据剩余空间 */
width: 100%;
background: #f4f5f6;
box-sizing: border-box;
padding: 30rpx;
overflow-y: auto;
/* 启用垂直滚动 */
display: flex;
flex-direction: column;
}
.box_ {
background: #FFFFFF;
width: 100%;
box-sizing: border-box;
padding: 30rpx;
border-radius: 8rpx;
flex: 1;
min-height: min-content;
}
.d_s {
display: flex;
align-items: center;
}
.d_b {
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 30rpx 0rpx;
border-top: 2rpx solid #F5F6F9;
font-size: 28rpx;
color: #8D90A6;
}
.textarea {
flex: 1;
text-align: right;
font-size: 28rpx;
color: #333;
padding: 10rpx;
border: none;
background-color: transparent;
resize: none;
overflow: hidden;
/* 防止滚动条 */
min-height: 60rpx;
}
.touxiang_ {
width: 90rpx;
height: 90rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.tel_ {
width: 30rpx;
height: 30rpx;
margin-right: 20rpx;
image {
width: 100%;
height: 100%;
}
}
.name_ {
font-size: 32rpx;
color: #101A3E;
margin-bottom: 5px;
}
.telnum {
font-size: 24rpx;
color: #366FFF;
}
.lan_ {
font-size: 28rpx;
color: #327DFB;
display: flex;
align-items: center;
image {
width: 36rpx;
height: 36rpx;
margin-left: 15rpx;
}
}
.hui_box {
width: 100%;
background: #F5F6F9;
border-radius: 16rpx;
box-sizing: border-box;
padding: 30rpx;
display: flex;
align-items: center;
image {
width: 90rpx;
height: 90rpx;
margin-right: 15rpx;
}
}
.big_ {
font-size: 28rpx;
color: #101A3E;
}
.sm_ {
font-size: 22rpx;
color: #8D90A6;
}
.anniu {
width: 622rpx;
height: 78rpx;
background: #427FFE;
border-radius: 50rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
margin-top: 80rpx;
}
.d_b_1 {
display: flex;
align-items: flex-start;
/* 改为顶部对齐 */
justify-content: space-between;
box-sizing: border-box;
padding: 30rpx 0;
border-top: 2rpx solid #F5F6F9;
font-size: 28rpx;
color: #8D8D8D;
}
.label {
width: 150rpx;
/* 给标签固定宽度 */
flex-shrink: 0;
/* 防止标签被压缩 */
}
.multiline-input {
text-align: right;
width: 400rpx;
max-height: 110rpx;
min-height: 100rpx;
border: none;
resize: none;
line-height: 1.5;
font-size: 28rpx;
padding: 0;
}
.multiline-textarea {
text-align: right;
width: 400rpx;
max-height: 200rpx;
min-height: 120rpx;
border: none;
resize: none;
line-height: 1.5;
font-size: 28rpx;
padding: 0;
}
</style>