sh_real_name_system_app/src/pages/person-exit/index.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>