lanan-app/pages/internal/addStaff.vue
2025-08-06 18:00:28 +08:00

789 lines
20 KiB
Vue
Raw 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> -->
<view class="page-top" :style='{ justifyContent: "center" }'>
<!-- 返回上一级页面信息 -->
<view class='go-back-page' @click='pageBack'>返回</view>
<!-- 人员/车辆/我的组件显示的表头信息 -->
<view class="other-title-class">
{{ titles }}
</view>
</view>
<view class="container">
<view class="box_">
<view class="d_s" style="margin-bottom: 10px;" v-if="userId">
<view class="touxiang_" v-if="staff.avatar">
<image :src=" imgUrl + staff.avatar" mode="" @click="previewImage(imgUrl + staff.avatar)">
</image>
</view>
<view class="touxiang_" v-else>
<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>
<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.age" style="text-align: right;" />
</view>
<view class="d_b" v-if="!ifAdd">
<view class="">岗位</view>
<view class="" @click="showRole = true">
{{ roleName || '暂无数据' }}
</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>
<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="driverLicenseTypeArr = $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>
<!-- <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'
export default {
components: {
QianziyuSelect
},
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.baseImageUrlNew,
ifAdd: null,
}
},
onLoad(data) {
console.log('data', data)
if (data.id) {
this.titles = '编辑员工'
this.userId = data.id
this.getInfoByUserId()
this.buttonTile = '修改'
}
if (data.ifAdd) {
this.ifAdd = data.ifAdd
}
this.getEducation()
this.getDriveType()
this.getRoles()
},
methods: {
cancelShow() {
this.show = !this.cancelShow
},
// 根据服务套餐查询角色
async getRoles() {
let res = await request({
url: '/system/role/pageByQuery',
method: 'get',
params: {
servicePackageId: 'jiuyuan'
}
})
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: '/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() {
console.log()
// 验证表单信息
const flag = this.validData()
if (!flag) {
return
}
this.staff.userId = this.userId
const data = {
...this.staff,
id: this.staff.driverId,
fileList: this.fileList1
.map(item => {
item.url = item.url.replace(/^https?:\/\/[^/]+\/minio\//, '');
return item;
}), // 去除域名和 minio/
driverLicenseType: this.driverLicenseTypeArrStr,
driverLicenseTypeArr: this.driverLicenseTypeArr.map(item => item.id)
}
console.log('data1111', data)
request({
url: '/system/rescueInfo/updateDriver',
method: 'post',
data: data
}).then(res => {
// 赋予用户角色
/* let resp = request({
url: '/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 = {
realName: this.staff.nickName,
phonenumber: 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 */
}
console.log('data123', data)
let res = await request({
// url: '/base/dl-drive-school-coach/saveNew',
url: '/system/rescueInfo/addDriverApp',
method: 'post',
data: data
})
if (res.code == 200) {
/* console.log('角色', res)
let resp = await request({
url: '/system/permission/assign-user-role',
method: 'post',
data: {
userId: res.data,
roleIds: this.staff.roleIds
}
}) */
uni.showToast({
title: "添加成功"
})
this.show = false
// this.getindex()
setTimeout(() => {
uni.navigateBack({
delta: 1
});
}, 600);
console.log('返回')
}
},
validData() {
if (!this.staff.nickName || !this.staff.mobile) {
uni.showToast({
title: '姓名和电话不能有空',
icon: 'none'
})
return false
}
if (!this.staff.roleIds && !this.userId) {
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)
},
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 ''
},
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: '/system/rescueInfo/addFolder',
method: 'post',
data: this.userId
}).then(res => {
this.staff.folderId = res.data
uni.navigateTo({
url: '/pages/internal/rescueManage?type=staff&folderId=' +
this.staff.folderId
})
})
} else {
uni.navigateTo({
url: '/pages/internal/rescueManage?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) => {
upload({
url: '/common/upload',
filePath: url,
}).then((res) => {
resolve(res.data.url);
console.log(this.fileList1)
this.forceRefreshFiles(); // 强制刷新文件列表
})
});
},
pageBack() {
console.log("执行 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: '/system/rescueInfo/getOnInternal',
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;
}
.page-top {
flex-shrink: 0;
width: 100%;
height: 160rpx;
display: flex;
align-items: center;
color: white;
background: linear-gradient(180deg, #054DF3 0%, #55A3FF 100%);
position: sticky;
/* 粘性定位 */
top: 0;
/* 固定在顶部 */
z-index: 100;
/* 确保在最上层 */
.go-back-page {
position: absolute;
left: 20rpx;
}
}
.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>