This commit is contained in:
BianLzhaoMin 2025-11-10 10:34:19 +08:00
parent e05defd293
commit 19496ab5b8
10 changed files with 762 additions and 97 deletions

View File

@ -1,4 +1,4 @@
# VITE_API_BASE_URL = http://112.29.103.165:1616 # VITE_API_BASE_URL = http://112.29.103.165:1616
# VITE_API_BASE_URL = /api VITE_API_BASE_URL = /api
VITE_API_BASE_URL = http://192.168.0.14:1999/hd-real-name # VITE_API_BASE_URL = http://192.168.0.14:1999/hd-real-name
# VITE_API_BASE_URL = http://192.168.0.234:38080 # VITE_API_BASE_URL = http://192.168.0.234:38080

View File

@ -3,12 +3,13 @@
<view class="notice-bar-content" :style="scrollStyle"> <view class="notice-bar-content" :style="scrollStyle">
<!-- 第一组内容 --> <!-- 第一组内容 -->
<text <text
v-for="(text, index) in textArray" class="notice-text"
:key="`first-${index}`" :key="`first-${index}`"
:style="textStyle[index]" :style="textStyle[index]"
class="notice-text" v-for="(text, index) in textArray"
@tap="onTextClick(text.path)"
> >
{{ text }} {{ text.text }}
</text> </text>
<!-- 第二组内容用于无缝循环 --> <!-- 第二组内容用于无缝循环 -->
<text <text
@ -16,8 +17,9 @@
:key="`second-${index}`" :key="`second-${index}`"
:style="textStyle[index]" :style="textStyle[index]"
class="notice-text" class="notice-text"
@tap="onTextClick(text.path)"
> >
{{ text }} {{ text.text }}
</text> </text>
</view> </view>
</view> </view>
@ -147,6 +149,13 @@ onMounted(() => {
onUnmounted(() => { onUnmounted(() => {
stopScroll() // stopScroll() //
}) })
//
const onTextClick = (path) => {
uni.navigateTo({
url: path,
})
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -238,7 +238,14 @@
{ {
"path": "pages/home/child-pages/personInfo/index", "path": "pages/home/child-pages/personInfo/index",
"style": { "style": {
"navigationBarTitleText": "在场人员" "navigationBarTitleText": "人员列表"
}
},
// ----
{
"path": "pages/home/child-pages/entryUnsettled/index",
"style": {
"navigationBarTitleText": "出场未上传《离场结算确认单》"
} }
} }
], ],

View File

@ -0,0 +1,449 @@
<template>
<!-- 出场未结算 -->
<view class="project-list-container">
<view class="search-content">
<view class="search-wrapper">
<up-input
clearable
ref="inputRef"
class="search-name"
v-model="queryParams.workerName"
placeholder="输入姓名"
>
<template #suffix>
<up-icon name="search" size="24" color="#909399" @tap="onSearchName" />
</template>
</up-input>
</view>
<view class="data-summary">已查询 {{ total }} 条数据</view>
</view>
<scroll-view scroll-y class="project-list-content" @scrolltolower="onHandleScrollToLower">
<view
:key="item.id"
class="project-card"
v-for="(item, index) in personList"
@tap="onOpenPersonDetails(item)"
>
<view class="project-card-header">
<text class="index-circle">{{ index + 1 }}</text>
<text> {{ item.workerName }} - {{ item.idNumber || '?' }} </text>
</view>
<view class="row-new">
<text class="label-text">联系方式</text>
<text class="info-item">{{ item?.phone }}</text>
</view>
<view class="row-new">
<text class="label-text">所属工程</text>
<text class="info-item">{{ item?.proName }}</text>
</view>
<view class="row-new">
<text class="label-text">所属班组</text>
<text class="info-item">{{ item?.teamName }}</text>
</view>
<view class="row-new">
<text class="label-text">出场时间</text>
<text class="info-item">{{ item?.exitTime }}</text>
</view>
<view class="row-new">
<text class="label-text">出场天数</text>
<text class="info-item" style="color: #f56c6c">{{
item.daysSinceExit > 31
? item.daysSinceExit + '(已转入失信人员)'
: item.daysSinceExit
}}</text>
</view>
<view class="row-new">
<text class="label-text">所属分公司</text>
<text class="info-item">{{ item?.subCompanyName }}</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="entryUnsettled">
import { debounce } from 'lodash-es'
import { useCommonStore } from '@/stores'
import { ref, computed, onMounted } from 'vue'
import { getHomeIndexEntryUnsettledMsgAPI } from '@/services/home-index.js'
import { onLoad } from '@dcloudio/uni-app'
import Empty from '@/static/image/Empty.png'
const inputRef = ref(null) //
const personList = ref([]) //
const isLoading = ref(false) //
const total = ref(0) //
//
const queryParams = ref({
pageNum: 1,
pageSize: 10,
workerName: '',
})
//
const onSearchName = () => {
queryParams.value.pageNum = 1
personList.value = []
getPersonListFun()
}
//
const getPersonListFun = async (isRefresh = false) => {
isLoading.value = true
try {
const res = await getHomeIndexEntryUnsettledMsgAPI(queryParams.value)
total.value = res?.total || 0
if (isRefresh) {
personList.value = res?.rows || []
} else {
personList.value = [...personList.value, ...(res?.rows || [])]
}
} catch (error) {
console.error('获取工程列表失败:', error)
} finally {
isLoading.value = false
}
}
//
const onHandleScrollToLower = debounce(() => {
if (hasMore.value) {
queryParams.value.pageNum++
getPersonListFun()
}
}, 1000)
//
const hasMore = computed(() => {
return personList.value.length < total.value
})
onLoad(async (options) => {
getPersonListFun()
})
</script>
<style scoped lang="scss">
.project-list-container {
height: 100%;
display: flex;
flex-direction: column;
background-color: #f5f7fa;
padding: 20rpx;
box-sizing: border-box;
}
.search-content {
background-color: #fff;
margin-bottom: 20rpx;
padding: 20rpx;
border-radius: 10rpx;
border: 1px solid #e5e5e5;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.08);
.search-wrapper {
display: flex;
align-items: center;
gap: 20rpx;
.search-name {
flex: 1;
}
.filter-icon {
padding: 10rpx;
}
}
.data-summary {
margin-top: 20rpx;
font-size: 24rpx;
color: #4ca4fe;
}
}
.project-list-content {
// flex: 1;
overflow-y: auto;
.project-card {
padding: 30rpx;
padding-bottom: 0;
box-sizing: border-box;
background-color: #fff;
border-radius: 10rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.08);
border: 1px solid #e5e5e5;
.project-card-header {
display: flex;
align-items: center;
padding-bottom: 20rpx;
border-bottom: 1px solid #e5e5e5;
// margin-bottom: 20rpx;
.index-circle {
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-circle ::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; /* 三角形宽度 */
}
.project-title {
flex: 1;
font-size: 32rpx;
font-weight: bold;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.favorite-icon {
margin-left: 20rpx;
flex-shrink: 0;
}
}
.common-info {
padding: 20rpx 0;
display: flex;
align-items: center;
border-bottom: 1px solid #e5e5e5;
&:last-child {
border-bottom: none;
}
.label-text-1 {
font-size: 26rpx;
color: #909399;
}
.value-text-2 {
font-size: 26rpx;
margin-left: 30rpx;
}
}
.common-info-1 view {
width: 50%;
display: flex;
align-items: center;
justify-content: space-around;
}
.row-new {
padding: 20rpx 0;
display: flex;
align-items: center;
border-bottom: 1px solid #e5e5e5;
&:last-child {
border-bottom: none;
}
.label-text {
color: #909399;
font-size: 26rpx;
margin-right: 30rpx;
}
.info-item {
// margin-left: 30rpx;
font-size: 26rpx;
}
}
.project-info-row {
display: flex;
align-items: center;
padding: 16rpx 0;
&.row-1 {
.info-item {
flex: 1;
font-size: 26rpx;
color: #666;
text-align: center;
&.status-text {
color: #67c23a;
font-weight: 500;
}
}
}
&.row-2,
&.row-3 {
// justify-content: space-around;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
.info-group {
display: flex;
flex-direction: column;
align-items: center;
flex: 1;
background-color: #f5f7fa;
padding: 10rpx;
border-radius: 10rpx;
border: 1px solid #e5e5e5;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.08);
.info-label {
font-size: 24rpx;
color: #909399;
margin-bottom: 8rpx;
}
.info-value {
font-size: 32rpx;
font-weight: bold;
&.blue {
color: #165dff;
}
&.green {
color: #67c23a;
}
&.orange {
color: #e6a23c;
}
}
}
}
}
}
.loading-text {
text-align: center;
padding: 40rpx 0;
font-size: 24rpx;
color: #909399;
}
}
.empty-content {
display: flex;
align-items: center;
justify-content: center;
height: 60vh;
}
//
.filter-panel {
width: 600rpx;
height: 100vh;
background-color: #fff;
display: flex;
flex-direction: column;
box-sizing: border-box;
.filter-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
padding: 30rpx 30rpx 20rpx;
text-align: center;
flex-shrink: 0;
}
//
.filter-content {
flex: 1;
overflow-y: auto;
padding: 15rpx 30rpx;
box-sizing: border-box;
}
.filter-section {
margin-bottom: 50rpx;
.filter-label {
font-size: 28rpx;
color: #333;
margin-bottom: 20rpx;
font-weight: 500;
}
.filter-buttons {
display: flex;
flex-wrap: wrap;
gap: 20rpx;
.filter-btn {
padding: 16rpx 32rpx;
font-size: 26rpx;
color: #666;
background-color: #f5f7fa;
border-radius: 8rpx;
border: 1px solid #e5e5e5;
transition: all 0.3s;
&.active {
background-color: #165dff;
color: #fff;
border-color: #165dff;
}
}
}
}
//
.filter-footer {
display: flex;
gap: 20rpx;
padding: 20rpx 30rpx;
box-sizing: border-box;
background-color: #fff;
border-top: 1px solid #e5e5e5;
flex-shrink: 0;
.filter-reset-btn {
flex: 1;
}
.filter-confirm-btn {
flex: 1;
}
}
}
</style>

View File

@ -342,21 +342,25 @@ const onSearchName = () => {
// //
const getPersonListFun = async (isRefresh = false) => { const getPersonListFun = async (isRefresh = false) => {
console.log('queryParams.value查询参数', queryParams.value) const queryParamsCopy = JSON.parse(JSON.stringify(queryParams.value))
const params = {} const params = {}
// queryParams.valueparams // queryParams.valueparams
Object.keys(queryParams.value).forEach((key) => { Object.keys(queryParamsCopy).forEach((key) => {
if (queryParams.value[key]) { if (queryParamsCopy[key]) {
params[key] = queryParams.value[key] params[key] = queryParamsCopy[key]
} }
if (key === 'age' && queryParams.value[key] && queryParams.value[key].includes('-')) { if (key === 'age' && queryParamsCopy[key] && queryParamsCopy[key].includes('-')) {
params.startAge = queryParams.value[key].split('-')[0] params.startAge = queryParamsCopy[key].split('-')[0]
params.endAge = queryParams.value[key].split('-')[1] params.endAge = queryParamsCopy[key].split('-')[1]
} }
}) })
if (queryParams.value.lightStatus == 3) {
params.lightStatusSeven = 7
params.lightStatus = 1
}
isLoading.value = true isLoading.value = true
try { try {
console.log('params查询参数', params)
const res = await getHomeIndexPersonListMsgAPI(params) const res = await getHomeIndexPersonListMsgAPI(params)
total.value = res?.total || 0 total.value = res?.total || 0

View File

@ -6,9 +6,18 @@
<view style="width: 74%"> <view style="width: 74%">
<MultiColorNoticeBar <MultiColorNoticeBar
:textArray="[ :textArray="[
`黄灯人数:${noticeListData.yellowNum}`, {
`黄灯超7天人数:${noticeListData.yellowThanSevenDayNum}`, path: '/pages/home/child-pages/personInfo/index?lightStatus=1',
`出场未上传结算单:${noticeListData.exitNoFileNum}`, text: `黄灯人数:${noticeListData.yellowNum}`,
},
{
path: '/pages/home/child-pages/personInfo/index?lightStatus=3',
text: `黄灯超7天人数:${noticeListData.yellowThanSevenDayNum}`,
},
{
path: '/pages/home/child-pages/entryUnsettled/index',
text: `出场未上传结算单:${noticeListData.exitNoFileNum}`,
},
]" ]"
:textStyle="[{ color: '#ffed51' }, { color: '#bc2843' }, { color: '#f81115' }]" :textStyle="[{ color: '#ffed51' }, { color: '#bc2843' }, { color: '#f81115' }]"
:scrollSpeed="0.5" :scrollSpeed="0.5"

View File

@ -35,6 +35,7 @@
class="metric-item" class="metric-item"
:key="item.title" :key="item.title"
v-for="item in swiperList_1" v-for="item in swiperList_1"
@tap="onNavigateTo(item.path)"
> >
<view class="metric-dot"></view> <view class="metric-dot"></view>
<text class="metric-label">{{ item.title }}</text> <text class="metric-label">{{ item.title }}</text>
@ -49,7 +50,10 @@
<!-- 第二页在场人员统计 --> <!-- 第二页在场人员统计 -->
<template v-if="index === 1"> <template v-if="index === 1">
<view class="personnel-stats"> <view class="personnel-stats">
<view class="stat-card glass-card"> <view
class="stat-card glass-card"
@tap="onNavigateTo(commonPath + 'personInfo/index')"
>
<view class="stat-icon"> <view class="stat-icon">
<view class="icon-badge"> <view class="icon-badge">
<up-image width="44" height="44" :src="PersonnelIcon" /> <up-image width="44" height="44" :src="PersonnelIcon" />
@ -63,7 +67,10 @@
<text class="stat-unit"></text> <text class="stat-unit"></text>
</view> </view>
</view> </view>
<view class="stat-card glass-card"> <view
class="stat-card glass-card"
@tap="onNavigateTo(commonPath + 'personInfo/index?isAtt=1')"
>
<view class="stat-icon"> <view class="stat-icon">
<view class="icon-badge"> <view class="icon-badge">
<up-image <up-image
@ -95,7 +102,10 @@
/> />
</view> </view>
</view> </view>
<view class="rate-content"> <view
class="rate-content"
@tap="onNavigateTo(commonPath + 'entryUnsettled/index')"
>
<text class="rate-label">出场未结算</text> <text class="rate-label">出场未结算</text>
<text class="rate-value"> <text class="rate-value">
{{ exitNoFileNum }} {{ exitNoFileNum }}
@ -116,16 +126,32 @@
<view class="rate-content"> <view class="rate-content">
<text class="rate-label">红绿灯人员</text> <text class="rate-label">红绿灯人员</text>
<view class="traffic-lights"> <view class="traffic-lights">
<view class="light-item-wrapper"> <view
class="light-item-wrapper"
@tap="
onNavigateTo(
commonPath +
'personInfo/index?lightStatus=1',
)
"
>
<view class="light-dot yellow-dot"></view> <view class="light-dot yellow-dot"></view>
<text class="light-item"> <text class="light-item">
黄灯人数: {{ yellowNum }} 黄灯人数: {{ yellowNum }}
</text> </text>
</view> </view>
<view class="light-item-wrapper"> <view
class="light-item-wrapper"
@tap="
onNavigateTo(
commonPath +
'personInfo/index?lightStatus=3',
)
"
>
<view class="light-dot red-dot"></view> <view class="light-dot red-dot"></view>
<text class="light-item"> <text class="light-item">
黄灯7天: {{ yellowThanSevenDayNum }} 黄灯7天人数: {{ yellowThanSevenDayNum }}
</text> </text>
</view> </view>
</view> </view>
@ -153,13 +179,14 @@ const attNum = ref(0)
const yellowNum = ref(0) const yellowNum = ref(0)
const exitNoFileNum = ref(0) const exitNoFileNum = ref(0)
const yellowThanSevenDayNum = ref(0) const yellowThanSevenDayNum = ref(0)
const commonPath = '/pages/home/child-pages/'
// 1 // 1
const swiperList_1 = ref([ const swiperList_1 = ref([
{ title: '总工程', key: 'mainProNum' }, { title: '总工程', key: 'mainProNum', path: `${commonPath}all-project/index` },
{ title: '标段工程', key: 'proNum' }, { title: '标段工程', key: 'proNum', path: `${commonPath}lot-project/index` },
{ title: '在用分包单位', key: 'subNum' }, { title: '在用分包单位', key: 'subNum', path: `${commonPath}useSub/index` },
{ title: '在用班组', key: 'teamNum' }, { title: '在用班组', key: 'teamNum', path: `${commonPath}useTeam/index` },
]) ])
const swiperInfo_1 = ref({ const swiperInfo_1 = ref({
@ -231,6 +258,12 @@ const swiperList = ref([
}, },
}, },
]) ])
const onNavigateTo = (path) => {
uni.navigateTo({
url: path,
})
}
</script> </script>
<style scoped> <style scoped>
@ -307,7 +340,7 @@ const swiperList = ref([
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 30rpx; padding: 0 30rpx;
position: relative; position: relative;
z-index: 1; z-index: 1;
} }

View File

@ -2,11 +2,22 @@
<!-- 切换工程弹框 --> <!-- 切换工程弹框 -->
<view class="app-container-1"> <view class="app-container-1">
<view class="switch-project-content"> <view class="switch-project-content">
<view class="my-project-title"> 选择工程 </view> <view class="my-project-title">
<view> <view class="title-icon">
<up-input clearable v-model="searchProjectValue" placeholder="输入搜索关键词"> <!-- <up-icon name="folder" size="28" /> -->
<up-image width="28" height="28" shape="circle" :src="SwitchImg" />
</view>
<text class="title-text">选择工程</text>
</view>
<view class="search-wrapper">
<up-input
clearable
placeholder="输入搜索关键词"
v-model="searchProjectValue"
:custom-style="{ backgroundColor: '#f8f9fa' }"
>
<template #suffix> <template #suffix>
<up-icon name="search" size="24" color="#909399" @tap="onSearchProject" /> <up-icon name="search" size="24" color="#165DFF" @tap="onSearchProject" />
</template> </template>
</up-input> </up-input>
</view> </view>
@ -18,7 +29,15 @@
v-for="item in projectList" v-for="item in projectList"
@tap="onSwitchProjectConfirm(item)" @tap="onSwitchProjectConfirm(item)"
> >
{{ item.name }} <view class="project-item-left">
<view class="project-icon">
<up-icon name="file-text" size="20" color="#165DFF" />
</view>
<text class="project-name">{{ item.name }}</text>
</view>
<view class="project-item-right">
<up-icon name="arrow-right" size="18" color="#c0c4cc" />
</view>
</view> </view>
</view> </view>
@ -34,6 +53,7 @@
import { onMounted, ref } from 'vue' import { onMounted, ref } from 'vue'
import { useCommonStore } from '@/stores' import { useCommonStore } from '@/stores'
import { getProjectSelectListByConditionAPI } from '@/services/common' import { getProjectSelectListByConditionAPI } from '@/services/common'
import SwitchImg from '@/static/image/my/switch.png'
const searchProjectValue = ref('') const searchProjectValue = ref('')
const projectList = ref([]) const projectList = ref([])
const projectListAll = ref([]) const projectListAll = ref([])
@ -76,6 +96,7 @@ const getProjectList = async () => {
// //
const onJumpHome = () => { const onJumpHome = () => {
//
uni.switchTab({ url: '/pages/home/index' }) uni.switchTab({ url: '/pages/home/index' })
} }
@ -91,46 +112,186 @@ onMounted(() => {
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
box-sizing: border-box; box-sizing: border-box;
background-color: #f0f2f5; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
position: relative;
overflow: hidden;
//
&::before {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
animation: rotate 20s linear infinite;
} }
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}
.switch-project-content { .switch-project-content {
width: 86vw; width: 86vw;
max-width: 600rpx;
height: 80vh; height: 80vh;
border-radius: 10rpx; max-height: 900rpx;
box-shadow: 0 0 10rpx 2rpx rgba(0, 0, 0, 0.1); border-radius: 24rpx;
padding: 20rpx; box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
padding: 40rpx 30rpx;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background-color: #fff; background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20rpx);
box-sizing: border-box; box-sizing: border-box;
position: relative;
z-index: 1;
border: 1px solid rgba(255, 255, 255, 0.3);
.my-project-title { .my-project-title {
margin-bottom: 20rpx; margin-bottom: 30rpx;
font-size: 18px; display: flex;
font-weight: bold; align-items: center;
justify-content: center;
gap: 16rpx;
padding-bottom: 24rpx;
border-bottom: 2rpx solid #f0f2f5;
// .title-icon {
// display: flex;
// align-items: center;
// justify-content: center;
// width: 56rpx;
// height: 56rpx;
// background: linear-gradient(135deg, #165dff 0%, #409eff 100%);
// border-radius: 14rpx;
// box-shadow: 0 4rpx 12rpx rgba(22, 93, 255, 0.3);
// :deep(.up-icon) {
// color: #fff !important;
// }
// }
.title-text {
font-size: 36rpx;
font-weight: 600;
color: #333; color: #333;
padding: 14rpx 0; letter-spacing: 2rpx;
// border-bottom: 1px solid #e5e5e5; }
text-align: center; }
.search-wrapper {
margin-bottom: 30rpx;
:deep(.up-input) {
border-radius: 16rpx;
overflow: hidden;
}
:deep(.up-input__content) {
padding: 20rpx 24rpx;
}
} }
.my-project-list { .my-project-list {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
padding-right: 10rpx;
//
&::-webkit-scrollbar {
width: 6rpx;
}
&::-webkit-scrollbar-track {
background: #f5f5f5;
border-radius: 10rpx;
}
&::-webkit-scrollbar-thumb {
background: #165dff;
border-radius: 10rpx;
&:hover {
background: #409eff;
}
}
.project-item { .project-item {
margin-top: 16rpx; margin-bottom: 20rpx;
width: 100%; width: 100%;
padding: 16rpx 24rpx; padding: 28rpx 32rpx;
border: 1px solid #e5e5e5;
box-sizing: border-box; box-sizing: border-box;
border-radius: 14rpx; border-radius: 20rpx;
background-color: #f0f2f5; background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
color: #333; color: #333;
display: flex;
align-items: center;
justify-content: space-between;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
border: 1px solid rgba(22, 93, 255, 0.1);
transition: all 0.3s ease;
cursor: pointer;
&:active {
transform: translateY(2rpx);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
}
.project-item-left {
display: flex;
align-items: center;
gap: 20rpx;
flex: 1;
min-width: 0;
.project-icon {
display: flex;
align-items: center;
justify-content: center;
width: 64rpx;
height: 64rpx;
background: linear-gradient(
135deg,
rgba(22, 93, 255, 0.1) 0%,
rgba(64, 158, 255, 0.1) 100%
);
border-radius: 16rpx;
flex-shrink: 0;
}
.project-name {
font-size: 30rpx;
font-weight: 500;
color: #333;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.project-item-right {
display: flex;
align-items: center;
flex-shrink: 0;
margin-left: 20rpx;
}
//
&:hover {
border-color: rgba(22, 93, 255, 0.3);
box-shadow: 0 6rpx 20rpx rgba(22, 93, 255, 0.15);
}
} }
} }
@ -141,13 +302,17 @@ onMounted(() => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin-top: 20rpx; margin-top: 20rpx;
.up-empty { .up-empty {
margin-bottom: 20rpx; margin-bottom: 30rpx;
} }
.up-button { .up-button {
width: 95%; width: 95%;
margin: 0 auto; margin: 0 auto;
margin-bottom: 30rpx; margin-bottom: 30rpx;
border-radius: 16rpx;
box-shadow: 0 4rpx 12rpx rgba(22, 93, 255, 0.3);
} }
} }
} }

View File

@ -71,3 +71,12 @@ export const getHomeIndexPersonListMsgAPI = (data = {}) => {
data, data,
}) })
} }
// 首页接口 ---- 二级页面 获取出场未结算数据
export const getHomeIndexEntryUnsettledMsgAPI = (data = {}) => {
return http({
method: 'GET',
url: '/bmw/homePageSub/getWorkerNotFileMsg',
data,
})
}

View File

@ -19,15 +19,10 @@ const baseURL = import.meta.env.VITE_API_BASE_URL
// 添加请求拦截 // 添加请求拦截
const httpInterceptor = { const httpInterceptor = {
invoke(options) { invoke(options) {
// console.log(options, 'options')
if (options.isUploadFile) {
if (!options.url.startsWith('http')) { if (!options.url.startsWith('http')) {
options.url = baseURL + options.url options.url = baseURL + options.url
} }
console.log(options.url, '文件上传')
// 2. 设置请求超时时间默认为60s设置为 10s // 2. 设置请求超时时间默认为60s设置为 10s
options.timeout = 60000 options.timeout = 60000
@ -36,33 +31,16 @@ const httpInterceptor = {
// 'source-client': 'mini', // 'source-client': 'mini',
...options.header, ...options.header,
} }
// 4. 增加 token 请求头标识
const memberStore = useMemberStore() const memberStore = useMemberStore()
const token = memberStore.token const token = memberStore.token
// 如果是文件上传请求,则不进行加密处理
if (options.isUploadFile) {
// 4. 增加 token 请求头标识
if (token) { if (token) {
options.header.Authorization = token options.header.Authorization = token
} }
console.log(options, 'options--**----')
} else { } else {
// 1. 先判断请求 url 是否为完整的 http 请求路径 如果不是则拼接 baseURL
if (!options.url.startsWith('http')) {
options.url = baseURL + options.url
}
// 2. 设置请求超时时间默认为60s设置为 10s
options.timeout = 60000
// 3. 增加小程序端请求头标识
options.header = {
// 'source-client': 'mini',
...options.header,
}
// 4. 增加 token 请求头标识 // 4. 增加 token 请求头标识
const memberStore = useMemberStore()
const token = memberStore.token
if (token) { if (token) {
options.header.Authorization = token options.header.Authorization = token
options.header.Token = token options.header.Token = token
@ -70,9 +48,10 @@ const httpInterceptor = {
const commonStore = useCommonStore() // 请求配置 const commonStore = useCommonStore() // 请求配置
const requestConfig = commonStore.requestConfig // 请求配置 const requestConfig = commonStore.requestConfig // 请求配置
const env = import.meta.env.MODE const env = import.meta.env.MODE // 环境变量
// 5. 增加请求配置 // 5. 增加请求配置
// 入参加密 // 入参加密
options.header['encryptRequest'] = options.header['encryptRequest'] =
import.meta.env.MODE === 'development' ? false : requestConfig.encryptRequest import.meta.env.MODE === 'development' ? false : requestConfig.encryptRequest
@ -86,13 +65,15 @@ const httpInterceptor = {
const queryData = const queryData =
options.data instanceof Object ? JSON.stringify(options.data) : options.data options.data instanceof Object ? JSON.stringify(options.data) : options.data
// 如果是POST请求
if (typeof queryData !== 'undefined' && options.method.toUpperCase() === 'POST') { if (typeof queryData !== 'undefined' && options.method.toUpperCase() === 'POST') {
// 加密数据 // 加密数据 只有在非开发环境且加密请求配置为true时才进行加密
if (requestConfig.encryptRequest && env !== 'development') { if (requestConfig.encryptRequest && env !== 'development') {
options.data = encryptWithSM4(queryData + '|' + hashWithSM3AndSalt(queryData)) options.data = encryptWithSM4(queryData + '|' + hashWithSM3AndSalt(queryData))
} }
} }
// 如果是GET请求
if (options.data instanceof Object && options.method.toUpperCase() === 'GET') { if (options.data instanceof Object && options.method.toUpperCase() === 'GET') {
// 加密数据 // 加密数据
if (requestConfig.encryptRequest && env !== 'development') { if (requestConfig.encryptRequest && env !== 'development') {
@ -117,21 +98,20 @@ export const http = (options) => {
...options, ...options,
success(res) { success(res) {
console.log(res, '请求拦截器处解密后的返回值')
const currentEnv = getCurrentEnv() const currentEnv = getCurrentEnv()
// 判断是H5 还是App环境 // 判断是H5 还是App环境
let isEncryptResponse = '' let isEncryptResponse = ''
if (currentEnv === 'windows') { if (currentEnv === 'windows') {
isEncryptResponse = 'encryptresponse' isEncryptResponse = 'encryptresponse' // H5环境和APP环境返回的header字段不同
} else { } else {
isEncryptResponse = 'encryptResponse' isEncryptResponse = 'encryptResponse' // H5环境和APP环境返回的header字段不同
} }
// 如果返回的header字段中包含加密响应则进行解密
if (res.header[isEncryptResponse]) { if (res.header[isEncryptResponse]) {
res.data = JSON.parse(decryptWithSM4(res.data)) res.data = JSON.parse(decryptWithSM4(res.data))
} }
// console.log(res.data, '请求拦截器处解密后的返回值')
// 1. 判断是否请求成功 // 1. 判断是否请求成功
if (res.statusCode >= 200 && res.statusCode < 300) { if (res.statusCode >= 200 && res.statusCode < 300) {
if (res.data) { if (res.data) {