detection-business/pages/index/Staffmanagement.vue
2024-12-20 19:32:47 +08:00

875 lines
21 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">
<view style="width: 100%; height: 44px;"></view>
<view class="top-heder" style="margin-top: 1rem">
<view class="t-left" @click="getfan()">
<uni-icons type="left" size="18"></uni-icons>
</view>
<view class="t-input">
<uni-icons type="search" color="#BCBCBC" size="22"></uni-icons>
<input type="text" v-model="workName" placeholder="搜索员工.....">
</view>
<view class="sou" @click="getindex()">搜索</view>
</view>
<!-- <view class="top-tap">
<view class="tap-box" v-for="(item,index) in taplist" :key="index" @click="gettapindex(index,item.id)">
<text :class="{'lan':isListing == item.id}">{{item.Text}}</text>
<view class="gang" v-if="isListing == item.id"></view>
</view>
</view> -->
<scroll-view scroll-x="true" class="box-bottom">
<view class="tap-box" v-for="(item,index) in tabList" :key="index" @click="gettap(index,item.id)">
<view :class="{'lan' : tapindex == index}">{{ item.name }}</view>
<view class="gang" v-if="tapindex == index"></view>
</view>
</scroll-view>
<view class="mub">
<view class="top-ail">
<view class="jsy" v-if="!goodsList||goodsList.length == 0">
<image src="http://www.nuoyunr.com/lananRsc/detection/qs.png" mode=""></image>
</view>
<checkbox-group @change="checkboxChange">
<view class="a-box" v-for="(item,index) in goodsList" :key="index">
<view class="t-box">
<label>
<checkbox :value="item.id+''" color="#FFCC33" style="transform:scale(0.7)"/>
</label>
<view style="display: flex;align-items: center;width: 85%">
<view class="s-img">
<image :src="item.avatar" mode="aspectFill"></image>
</view>
<view class="s-right">
<view class="s-title">{{ item.nickname || item.username }}</view>
<view class="s-hui">岗位{{ item.roleName }}</view>
<view class="s-hui" style="white-space: nowrap; ">电话{{ item.mobile || item.username }}</view>
</view>
</view>
<view>
<view class="bottom-box" @click="gettel(item)">
<uni-icons type="phone-filled" color="#0D2E8D" size="18"></uni-icons>
<text>电话</text>
<!-- @click="getdelete(item.id)" -->
<!-- <text>删除</text> -->
</view>
<view class="bottom-box" style="margin-top: 1rem" @click="toInfo(item)">
<text>查看</text>
</view>
</view>
</view>
</view>
</checkbox-group>
</view>
</view>
<!-- 底部 -->
<view class="d-bottom" @click="showpopup()">
<text>+ 添加员工</text>
</view>
<view class="s-bottom" @click="getdelete()">
<text>- 删除员工</text>
</view>
<u-popup :round="10" :show="show" @close="close" :mask-click="false" @open="open">
<view class="pop-box scrollable-content">
<view class="s-title">添加员工</view>
<view class="on-input">
<view class="s-huix">姓名</view>
<view class=""><input v-model="realName" type="text" placeholder="请输入姓名"></view>
</view>
<view class="on-input">
<view class="s-huix">电话:</view>
<view class=""><input v-model="phoneNum" type="text" placeholder="请输入手机号"></view>
</view>
<view class="on-input">
<view class="s-huix">学历:</view>
<view class="" @click="showEducation = true"><input disabled v-model="educationText" type="text"
placeholder="请选择学历"></view>
</view>
<view class="on-input">
<view class="s-huix">身份证号:</view>
<view class=""><input v-model="idNumber" type="text" placeholder="请输入身份证号"></view>
</view>
<view class="on-input">
<view class="s-huix">入职时间:</view>
<view class="" @click="showJoinedDate = true"><input disabled :value="formattedJoinedDate" type="text"
placeholder="请选择入职时间"></view>
</view>
<view class="on-input">
<view class="s-huix">转正时间:</view>
<view class="" @click="showFormalDate = true"><input disabled :value="formattedFormalDate" type="text"
placeholder="请选择转正时间"></view>
</view>
<view class="on-input">
<view class="s-huix">购买保险时间:</view>
<view class="" @click="showSafeDate = true"><input disabled :value="formattedSafeDate" type="text"
placeholder="请选择购买保险时间"></view>
</view>
<view class="on-input">
<view class="s-huix">附件:</view>
<view class="" @click="addFile"><input disabled type="text" placeholder="添加附件"></view>
</view>
<view v-for="(item, index) in files">
<view class="on-input">
<view class="s-huix">名称:</view>
<view class=""><input v-model="item.name" type="text" placeholder="请输入附件名称"></view>
</view>
<u-upload v-if="!item.fileUrl"
@afterRead="uploadFilePromise($event, index)"
name="6"
multiple
:maxCount="1"
width="100%"
height="140px"
>
</u-upload>
<view v-else class="image-container">
<image :src="item.fileUrl" style="width: 100%;height: 140px;"></image>
<view @click="deletedUrl(index)" class="close-button">
<text>x</text>
</view>
</view>
</view>
<view class="">
<view class="s-huix" style="text-align: left">岗位:</view>
<view class="warp-flax">
<view class="flasxbox" :class="{ 'gwcss' : gwindex == index }" v-for="(item,index) in renList"
:key="index" @click="xgang(index,item.id)">
<text>{{ item.name }}</text>
</view>
</view>
</view>
<view class="tjiao" @click="getyadd">
<text>提交</text>
</view>
</view>
</u-popup>
<u-picker :show="showEducation" ref="uPicker" :columns="educations"
@confirm="chooseEducation" @cancel="showEducation = false"
keyName="label"></u-picker>
<u-datetime-picker
:show="showJoinedDate"
v-model="joinedDate"
@cancel="showJoinedDate = false"
@confirm="chooseJoinDate"
mode="date"
return-type='string'
></u-datetime-picker>
<u-datetime-picker
:show="showFormalDate"
v-model="formalDate"
@cancel="showFormalDate = false"
@confirm="chooseFormalDate"
mode="date"
return-type='string'
></u-datetime-picker>
<u-datetime-picker
:show="showSafeDate"
v-model="safeDate"
@cancel="showSafeDate = false"
@confirm="chooseSafeDate"
mode="date"
return-type='string'
></u-datetime-picker>
</view>
</template>
<script>
import config from '@/config'
import request from '../../utils/request';
import {getDictDataByType, formatDate} from "../../utils/utils";
import upload from '@/utils/upload.js'
export default {
data() {
return {
msg: '3',
goodsList: [],
tabList: [],
renList: [],
baseUrl: "http://192.168.1.4:8080/lanan",
partnerId: '',
isListing: 1,
tapindex: 0,
goodsTitle: "",
taplist: [{
Text: '已发布',
id: 1
},
{
Text: '待上架',
id: 0
},
],
pageNum: 1, //第几页
pageSize: 10, //一页多少张
totalPages: 0, //总数
show: false,
realName: "",
phoneNum: "",
idCard: "",
workName: "",
workids: [],
postid: '',
gwindex: 0,
gwid: 0,
roleId: undefined,
addRoleId: undefined,
education: null,
educationText: null,
idNumber: null,
joinedDate: null,
formalDate: null,
safeDate: null,
educations: [],
showEducation: false,
showJoinedDate: false,
showFormalDate: false,
showSafeDate: false,
files: []
}
},
onLoad() {
},
onPullDownRefresh() {
uni.showLoading()
setTimeout(() => {
uni.hideLoading()
uni.stopPullDownRefresh()
}, 500)
},
onReachBottom() {
if (this.pageNum >= this.totalPages) {
uni.showToast({
title: '没有下一页数据',
icon: 'none'
})
} else {
this.pageNum++
this.getindex()
}
},
onShow() {
this.gettab()
// this.baseUrl = this.$baseUrl
this.partnerId = uni.getStorageSync('partnerId')
// this.getindex()
},
computed: {
formattedJoinedDate() {
if (!this.joinedDate) return '';
return formatDate(this.joinedDate); // 确保formatDate返回'yyyy-MM-dd'格式
},
formattedFormalDate() {
if (!this.formalDate) return '';
return formatDate(this.formalDate); // 确保formatDate返回'yyyy-MM-dd'格式
},
formattedSafeDate() {
if (!this.safeDate) return '';
return formatDate(this.safeDate); // 确保formatDate返回'yyyy-MM-dd'格式
},
},
methods: {
uploadFilePromise(event, index) {
upload({
url: '/common/upload',
filePath: event.file[0].url,
}).then((res) => {
this.files[index].name = event.file[0].name
this.files[index].fileUrl = config.baseImageUrl + "/" + res.data.url
})
},
deletedUrl(index) {
this.files.splice(index, 1)
},
addFile() {
if (this.files.length === 0 || this.files[0].fileUrl !== null) {
this.files.unshift({
name: "未命名",
fileUrl: null
})
}
},
chooseJoinDate(e) {
this.joinedDate = formatDate(e.value)
this.showJoinedDate = false
},
chooseFormalDate(e) {
this.formalDate = formatDate(e.value)
this.showFormalDate = false
},
chooseSafeDate(e) {
this.safeDate = formatDate(e.value)
this.showSafeDate = false
},
chooseEducation(e) {
this.educationText = e.value[0].label
this.education = e.value[0].value
this.showEducation = false
},
toInfo(item) {
uni.navigateTo({
url: '/pages/staff/StaffInfo?id=' + item.id
})
},
gettel(num) {
const value = num.mobile || num.username
uni.makePhoneCall({
phoneNumber: value //仅为示例
});
},
xgang(index, id) {
this.gwindex = index
this.gwid = id
},
async gettab() {
let res = await request({
url: '/system/role/pageByQuery',
method: 'get',
params: {
servicePackageId: 'jiance'
}
})
this.tabList = [{
name: '全部',
id: undefined
}]
this.tabList.push(...res.data)
this.roleId = this.tabList[0].id
this.renList = res.data
this.getindex()
},
gettap(index, id) {
this.tapindex = index
this.roleId = id
this.goodsList = []
this.pageNum = 1
this.getindex()
},
checkboxChange(e) {
this.workids = e.detail.value
},
async showpopup() {
this.show = true
this.educations = [await getDictDataByType("company_staff_edu")]
},
async getindex() {
if (this.workName != '') {
this.pageNum = 1
this.goodsList = []
}
let data = {
nickname: this.workName,
roleId: this.roleId,
pageNo: this.pageNum, //第几页
pageSize: this.pageSize, //一页多少张
}
let res = await request({
url: '/system/role/selectListByRoleId',
method: 'get',
params: data
})
if (res.code == 200) {
if (this.pageNum != 1) {
this.goodsList = this.goodsList.concat(res.rows)
} else {
this.goodsList = res.rows
}
this.goodsList.forEach(item => {
if (item.avatar && !item.avatar.includes(config.baseImageUrl)){
item.avatar = config.baseImageUrl + (item.avatar[0] === '/' ? item.avatar : '/' + item.avatar)
}
})
let total = res.total
this.totalPages = Math.ceil(total / this.pageSize);
}
const newUsers = this.goodsList.filter(item => !item.roleName)
if (newUsers && newUsers.length > 0) {
const ids = newUsers.map(item => item.id)
request({
url: '/inspection/util/getRoleNameByIds?ids=' + ids,
method: 'get'
}).then(res => {
this.goodsList.filter(item => !item.roleName).map(item => {
this.$set(item, "roleName", res.data[item.id])
})
})
}
},
// 去编辑
getedit(id) {
uni.navigateTo({
url: '/pages/order/editorder?id=' + id
})
},
// 下架
async getxia(id) {
let data = {
goodsId: id
}
let res = await request({
url: '/partnerOwn/partner/changeListing',
method: 'post',
params: data
})
if (res.code == 200) {
uni.showToast({
title: "操作成功",
})
this.getindex()
}
},
// 删除
async getdelete() {
if (this.workids == '') {
uni.showToast({
title: '请至少选择一名要删除的员工!',
icon: 'none'
})
return
} else {
// this.workids = this.workids.join(",")
}
let res = await request({
url: '/system/user/deleteUserByIds',
method: 'delete',
data: this.workids
})
if (res.code == 200) {
uni.showToast({
title: "操作成功",
})
this.getindex()
}
},
gettapindex(index, id) {
this.isListing = id
this.getindex()
},
async getyadd() {
if (!this.realName || !this.phoneNum) {
uni.showToast({
title: '不能有空',
icon: 'none'
})
return
}
let data = {
nickname: this.realName,
mobile: this.phoneNum,
username: this.phoneNum,
status: 0,
userType: '01',
roleId: this.gwid,
password: '123456'
}
let res = await request({
url: '/system/user/create',
method: 'post',
data: data
})
//
if (res.code == 200) {
let roleIds = []
roleIds.push(this.gwid)
let resp = await request({
url: '/system/permission/assign-user-role',
method: 'post',
data: {
userId: res.data,
roleIds: roleIds
}
})
const staffData = {
userId: res.data,
name: this.realName,
tel: this.phoneNum,
joinedDate: this.joinedDate,
idNumber: this.idNumber,
education: this.education,
formalDate: this.formalDate,
safeDate: this.safeDate,
fileNames: this.files.length > 0 ? this.files.map(item => item.name).join(",") : "",
fileUrls: this.files.length > 0 ? this.files.map(item => {
return item.fileUrl.replace(config.baseImageUrl + "/", "")
}).join(",") : ""
}
const staffRes = await request({
url: '/company/staff/updateByExistUser',
method: 'post',
data: staffData
})
uni.showToast({
title: "添加成功"
})
this.show = false
this.getindex()
}
},
open() {
},
close() {
this.show = false
},
getfan() {
uni.navigateBack()
}
}
}
</script>
<style scoped lang="scss">
.content {
box-sizing: border-box;
width: 100%;
height: calc(100vh);
background: white;
}
.warp-flax {
width: 100%;
display: flex;
flex-wrap: wrap;
}
.flasxbox {
border-radius: 6px;
box-sizing: border-box;
padding: 5px 10px;
border: 1px solid #999999;
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
margin-top: 5px;
}
.gwcss {
border-radius: 6px;
box-sizing: border-box;
padding: 5px 10px;
border: 1px solid #0D2E8D;
display: flex;
align-items: center;
justify-content: center;
margin-right: 5px;
margin-top: 5px;
color: #0D2E8D;
}
.top-heder {
width: 100%;
height: 46px;
background: white;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: 5px 15px;
}
.t-left {
width: 10%;
}
.t-input {
width: 75%;
height: 36px;
background: #F0F0F0;
border-radius: 50px;
box-sizing: border-box;
padding: 0 15px;
display: flex;
align-items: center;
}
.top-ail {
width: 100%;
box-sizing: border-box;
padding: 15px;
background-color: #F4F4F4;
padding-bottom: 45px;
}
.sou {
width: 10%;
margin-left: 5px;
}
.mub {
background-color: #F4F4F4;
height: calc(100vh);
}
.dix {
display: flex;
align-items: center;
}
.top-tap {
width: 100%;
height: 44px;
display: flex;
justify-content: space-between;
align-items: center;
}
.tap-box {
//width: 20%;
margin-left: 1rem;
height: 100%;
text-align: center;
font-size: 16px;
font-weight: 400;
color: #606266;
box-sizing: border-box;
}
.gang {
width: 30px;
height: 4px;
background: #0D2E8D;
border-radius: 4px;
margin: 4px auto;
}
.a-box {
width: 100%;
border-radius: 8px;
background-color: white;
box-sizing: border-box;
padding: 15px;
margin-bottom: 10px;
}
.t-box {
width: 100%;
box-sizing: border-box;
// padding-bottom: 15px;
display: flex;
// border-bottom: 1px solid #EEEEEE;
}
.s-huix {
width: 30%;
text-align: right;
}
.s-img {
width: 40px;
height: 40px;
border-radius: 50%;
margin-right: 15px;
overflow: hidden;
flex-shrink: 0;
image {
width: 100%;
height: 100%;
}
}
.s-right {
width: 65%;
}
.s-title {
font-size: 18px;
font-weight: bold;
color: #333333;
}
.s-hui {
font-size: 15px;
font-weight: 400;
color: #999999;
margin: 2px auto;
}
.s-ju {
font-size: 18px;
font-weight: bold;
color: #FF571A;
}
.d-bottom {
position: fixed;
bottom: 0px;
width: 50%;
height: 45px;
box-sizing: border-box;
// padding-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
background: #0D2E8D;
color: white;
}
.s-bottom {
position: fixed;
bottom: 0px;
right: 0px;
width: 50%;
height: 45px;
box-sizing: border-box;
// padding-bottom: 20px;
display: flex;
align-items: center;
justify-content: center;
background: crimson;
color: white;
}
.bottom-box {
width: 66px;
height: 31px;
background: #DAE1F8;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50px;
font-size: 15px;
font-weight: 400;
color: #0D2E8D;
margin-left: 5px;
}
.lan {
color: #0D2E8D !important;
}
.jsy {
width: 100%;
margin-top: 20px;
text-align: center;
color: #0D2E8D !important;
}
.pop-box {
width: 100%;
box-sizing: border-box;
padding: 15px;
}
.on-input {
width: 100%;
display: flex;
align-items: center;
border-bottom: 1px solid #DAE1F8;;
box-sizing: border-box;
padding-bottom: 5px;
margin: 10px;
justify-content: space-between;
}
.tjiao {
width: 40%;
height: 30px;
margin: 5px auto;
display: flex;
align-items: center;
justify-content: center;
background: #0D2E8D;
color: white;
border-radius: 50px;
}
.c-tap {
width: 100%;
height: 40px;
box-sizing: border-box;
padding: 15px;
display: flex;
background-color: white;
align-items: center;
}
.tap-box {
//width: 20%;
display: inline-block;
text-align: center;
}
.gang {
height: 4px;
background: #0D2E8D;
width: 80%;
margin: 0px auto;
}
.lan {
color: #0D2E8D;
}
.box-bottom {
width: 100%;
height: 30px;
box-sizing: border-box;
white-space: nowrap;
}
.on-input input {
text-align: right;
padding-right: 1rem
}
.image-container {
position: relative; /* 使子元素可以相对于此容器进行绝对定位 */
width: 100%;
height: 140px;
}
.close-button {
position: absolute;
top: 5px; /* 调整距离顶部的距离 */
right: 5px; /* 调整距离右侧的距离 */
width: 24px; /* 圆的直径 */
height: 24px;
background-color: #ff0000;
color: white;
border-radius: 50%; /* 使按钮呈现圆形 */
display: flex;
//align-items: center;
justify-content: center;
font-size: 16px; /* 调整X的字体大小 */
cursor: pointer; /* 鼠标悬停时显示为指针 */
}
.scrollable-content {
max-height: calc(80vh - 40px); /* 设置最大高度为视口高度的80%减去弹出框的圆角和边距 */
overflow-y: auto; /* 启用垂直滚动 */
padding: 15px; /* 保持与现有padding一致 */
}
</style>