368 lines
10 KiB
Vue
368 lines
10 KiB
Vue
<template>
|
|
<!-- 人员出场 -->
|
|
<view class="person-exit">
|
|
<view class="search-content">
|
|
<view style="width: 28%; margin-right: 12rpx">
|
|
<up-select
|
|
:label="initLabel"
|
|
:options="statusList"
|
|
@select="selectItem"
|
|
class="status-select"
|
|
v-model:current="searchType"
|
|
:style="{ height: selectHeight + 'px' }"
|
|
/>
|
|
</view>
|
|
<view>
|
|
<up-input
|
|
clearable
|
|
ref="inputRef"
|
|
class="search-name"
|
|
v-model="searchValue"
|
|
:placeholder="searchPlaceholder"
|
|
>
|
|
<template #suffix>
|
|
<up-icon name="search" size="24" color="#909399" @tap="onSearchName" />
|
|
</template>
|
|
</up-input>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="red-text" style="margin: 20rpx 0">
|
|
出场后一个月未上传《离场工资结算确认单》,人员将自动进入失信人员
|
|
</view>
|
|
|
|
<scroll-view
|
|
scroll-y
|
|
@scrolltolower="onHandleScrollToLower"
|
|
class="person-exit-content"
|
|
v-if="total > 0"
|
|
>
|
|
<view
|
|
:key="item.id"
|
|
class="person-exit-item"
|
|
@tap="onPersonExitItem(item)"
|
|
v-for="(item, index) in personExitList"
|
|
>
|
|
<view class="person-exit-item-header">
|
|
<text class="index-text"> {{ index + 1 }} </text>
|
|
<text> {{ item.name }} - {{ item.sex }} - {{ item.age }} </text>
|
|
</view>
|
|
|
|
<view class="common-info common-info-1">
|
|
<view>
|
|
<text class="label-text">工种</text>
|
|
<text>{{ item.postName }}</text>
|
|
</view>
|
|
<view>
|
|
<text class="label-text">联系方式</text>
|
|
<text>{{ item.phone }}</text>
|
|
</view>
|
|
</view>
|
|
<view class="common-info">
|
|
<text class="label-text">出入场状态</text>
|
|
<!-- <text class="value-text">{{ item.lightStatus }}</text> -->
|
|
|
|
<up-tag
|
|
text="在场"
|
|
size="small"
|
|
type="success"
|
|
class="value-text"
|
|
v-if="item.einStatus === 1"
|
|
/>
|
|
<up-tag
|
|
text="出场"
|
|
size="small"
|
|
type="error"
|
|
class="value-text"
|
|
v-if="item.einStatus === 2"
|
|
/>
|
|
</view>
|
|
<view class="common-info">
|
|
<text class="label-text">所属分包</text>
|
|
<text class="value-text">{{ item.subName }}</text>
|
|
</view>
|
|
<view class="common-info">
|
|
<text class="label-text">所在工程</text>
|
|
<text class="value-text">{{ item.proName }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="loading-text">
|
|
{{ !hasMore ? '没有更多数据了~' : '正在加载...' }}
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<view v-if="total === 0" class="empty-content">
|
|
<up-empty :icon="Empty" />
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup name="PersonExit">
|
|
import { debounce } from 'lodash-es'
|
|
import { ref, computed, onMounted, nextTick } from 'vue'
|
|
import { getPersonExitListAPI } from '@/services/person-exit.js'
|
|
import { useCommonStore } from '@/stores'
|
|
|
|
import Empty from '@/static/image/Empty.png'
|
|
|
|
const inputRef = ref(null)
|
|
const selectHeight = ref(0) // 选择框高度
|
|
const personExitList = ref([]) // 出场人员列表
|
|
const total = ref(0) // 总条数
|
|
const searchType = ref(1) // 搜索类型 1:姓名 2:分包 3:工程
|
|
const searchValue = ref('') // 搜索值
|
|
const searchPlaceholder = ref('输入姓名') // 搜索placeholder
|
|
const commonStore = useCommonStore() // 工程信息
|
|
const queryParams = ref({
|
|
pageNum: 1,
|
|
pageSize: 10,
|
|
name: '',
|
|
subName: '',
|
|
proName: '',
|
|
})
|
|
|
|
const statusList = ref([
|
|
{
|
|
name: '姓名',
|
|
id: 1,
|
|
},
|
|
{
|
|
name: '分包',
|
|
id: 2,
|
|
},
|
|
{
|
|
name: '工程',
|
|
id: 3,
|
|
},
|
|
])
|
|
|
|
// 搜索姓名
|
|
const onSearchName = () => {
|
|
queryParams.value.pageNum = 1
|
|
personExitList.value = []
|
|
switch (searchType.value) {
|
|
case 1:
|
|
queryParams.value.name = searchValue.value
|
|
queryParams.value.subName = ''
|
|
queryParams.value.proName = ''
|
|
break
|
|
case 2:
|
|
queryParams.value.subName = searchValue.value
|
|
queryParams.value.name = ''
|
|
queryParams.value.proName = ''
|
|
break
|
|
case 3:
|
|
queryParams.value.proName = searchValue.value
|
|
queryParams.value.name = ''
|
|
queryParams.value.subName = ''
|
|
break
|
|
}
|
|
getPersonExitListFun()
|
|
}
|
|
|
|
const selectItem = (e) => {
|
|
searchType.value = e.id
|
|
searchValue.value = ''
|
|
searchPlaceholder.value = '输入' + statusList.value.find((item) => item.id === e.id)?.name
|
|
}
|
|
|
|
const initLabel = computed(() => {
|
|
return statusList.value.find((item) => item.id === searchType.value)?.name
|
|
})
|
|
|
|
// 输入框加载完成后获取高度
|
|
const onInputLoaded = async () => {
|
|
// 等待DOM更新
|
|
await nextTick()
|
|
|
|
// 获取输入框高度
|
|
if (inputRef.value) {
|
|
const query = uni.createSelectorQuery().in(this)
|
|
query
|
|
.select('.search-name')
|
|
.boundingClientRect((data) => {
|
|
if (data) {
|
|
selectHeight.value = data.height
|
|
}
|
|
})
|
|
.exec()
|
|
}
|
|
}
|
|
|
|
// 点击打开资料上传页面
|
|
const onPersonExitItem = (item) => {
|
|
if (item.einStatus == 2) {
|
|
uni.$u.toast('人员已出场')
|
|
return
|
|
}
|
|
const {
|
|
name,
|
|
id,
|
|
proId,
|
|
proName,
|
|
subName,
|
|
idNumber,
|
|
workerId,
|
|
teamName,
|
|
subId,
|
|
teamId,
|
|
isShanghai,
|
|
} = item
|
|
const params = {
|
|
name,
|
|
id,
|
|
proId,
|
|
proName,
|
|
subName,
|
|
idNumber,
|
|
workerId,
|
|
teamName,
|
|
subId,
|
|
teamId,
|
|
isShanghai,
|
|
}
|
|
uni.navigateTo({
|
|
url: `/pages/person-exit/data-upload/index?params=${JSON.stringify(params)}`,
|
|
})
|
|
}
|
|
|
|
// 获取人员出场列表数据
|
|
const getPersonExitListFun = async () => {
|
|
const res = await getPersonExitListAPI(queryParams.value)
|
|
total.value = res?.total
|
|
personExitList.value = [...personExitList.value, ...res?.rows]
|
|
}
|
|
|
|
// 滚动到底部
|
|
const onHandleScrollToLower = debounce(() => {
|
|
if (hasMore.value) {
|
|
queryParams.value.pageNum++
|
|
getPersonExitListFun()
|
|
}
|
|
}, 1000)
|
|
|
|
// 计算一下是否还有更多数据
|
|
const hasMore = computed(() => {
|
|
return personExitList.value.length < total.value
|
|
})
|
|
|
|
onMounted(() => {
|
|
queryParams.value.proName = commonStore?.activeProjectName
|
|
onInputLoaded()
|
|
getPersonExitListFun()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.person-exit {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
background-color: #fff;
|
|
padding: 20rpx;
|
|
box-sizing: border-box;
|
|
|
|
.search-content {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
background-color: #fff;
|
|
|
|
.status-select {
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
border: 1px solid #e5e5e5;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
color: #909399;
|
|
}
|
|
}
|
|
}
|
|
|
|
::v-deep .u-select__content .u-select__options__wrap {
|
|
top: 30px !important;
|
|
right: -30px !important;
|
|
}
|
|
|
|
.person-exit-content {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
|
|
.person-exit-item {
|
|
padding: 20rpx;
|
|
box-sizing: border-box;
|
|
background-color: #fff;
|
|
border-radius: 10rpx;
|
|
margin-bottom: 20rpx;
|
|
border: 1px solid #e5e5e5;
|
|
box-shadow: 0 0 10rpx 2rpx rgba(0, 0, 0, 0.1);
|
|
font-size: 14px;
|
|
|
|
.person-exit-item-header {
|
|
padding: 16rpx 0;
|
|
border-bottom: 1px solid #e5e5e5;
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
.index-text {
|
|
position: relative;
|
|
display: inline-block;
|
|
height: 60rpx;
|
|
width: 50rpx;
|
|
margin-right: 60rpx;
|
|
background-color: #409eff;
|
|
color: #fff;
|
|
text-align: center;
|
|
line-height: 60rpx;
|
|
border-top-left-radius: 10rpx;
|
|
border-bottom-left-radius: 10rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
|
|
.index-text::after {
|
|
content: '';
|
|
position: absolute;
|
|
right: -24rpx; /* 三角形宽度的一半 */
|
|
top: 0;
|
|
width: 0;
|
|
height: 0;
|
|
border-top: 30rpx solid transparent; /* 高度的一半 */
|
|
border-bottom: 30rpx solid transparent; /* 高度的一半 */
|
|
border-left: 30rpx solid #409eff; /* 三角形宽度 */
|
|
}
|
|
|
|
& text:last-child {
|
|
font-weight: bold;
|
|
}
|
|
}
|
|
|
|
.common-info {
|
|
padding: 20rpx 0;
|
|
display: flex;
|
|
align-items: center;
|
|
border-bottom: 1px solid #e5e5e5;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
}
|
|
|
|
.common-info-1 view {
|
|
width: 50%;
|
|
display: flex;
|
|
justify-content: space-around;
|
|
}
|
|
|
|
.label-text {
|
|
color: #909399;
|
|
}
|
|
|
|
.value-text {
|
|
margin-left: 30rpx;
|
|
}
|
|
}
|
|
}
|
|
</style>
|