This commit is contained in:
parent
e05defd293
commit
19496ab5b8
|
|
@ -1,4 +1,4 @@
|
|||
# VITE_API_BASE_URL = http://112.29.103.165:1616
|
||||
# VITE_API_BASE_URL = /api
|
||||
VITE_API_BASE_URL = http://192.168.0.14:1999/hd-real-name
|
||||
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.234:38080
|
||||
|
|
|
|||
|
|
@ -3,12 +3,13 @@
|
|||
<view class="notice-bar-content" :style="scrollStyle">
|
||||
<!-- 第一组内容 -->
|
||||
<text
|
||||
v-for="(text, index) in textArray"
|
||||
class="notice-text"
|
||||
:key="`first-${index}`"
|
||||
:style="textStyle[index]"
|
||||
class="notice-text"
|
||||
v-for="(text, index) in textArray"
|
||||
@tap="onTextClick(text.path)"
|
||||
>
|
||||
{{ text }}
|
||||
{{ text.text }}
|
||||
</text>
|
||||
<!-- 第二组内容(用于无缝循环) -->
|
||||
<text
|
||||
|
|
@ -16,8 +17,9 @@
|
|||
:key="`second-${index}`"
|
||||
:style="textStyle[index]"
|
||||
class="notice-text"
|
||||
@tap="onTextClick(text.path)"
|
||||
>
|
||||
{{ text }}
|
||||
{{ text.text }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -147,6 +149,13 @@ onMounted(() => {
|
|||
onUnmounted(() => {
|
||||
stopScroll() // 清理定时器
|
||||
})
|
||||
|
||||
// 点击文本
|
||||
const onTextClick = (path) => {
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
|
|
|||
|
|
@ -238,7 +238,14 @@
|
|||
{
|
||||
"path": "pages/home/child-pages/personInfo/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "在场人员"
|
||||
"navigationBarTitleText": "人员列表"
|
||||
}
|
||||
},
|
||||
// 首页二级页面 ---- 出场未结算
|
||||
{
|
||||
"path": "pages/home/child-pages/entryUnsettled/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "出场未上传《离场结算确认单》"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -342,21 +342,25 @@ const onSearchName = () => {
|
|||
|
||||
// 获人员列表数据
|
||||
const getPersonListFun = async (isRefresh = false) => {
|
||||
console.log('queryParams.value查询参数', queryParams.value)
|
||||
const queryParamsCopy = JSON.parse(JSON.stringify(queryParams.value))
|
||||
const params = {}
|
||||
// 循环queryParams.value,如果值不为空,则添加到params中
|
||||
Object.keys(queryParams.value).forEach((key) => {
|
||||
if (queryParams.value[key]) {
|
||||
params[key] = queryParams.value[key]
|
||||
Object.keys(queryParamsCopy).forEach((key) => {
|
||||
if (queryParamsCopy[key]) {
|
||||
params[key] = queryParamsCopy[key]
|
||||
}
|
||||
if (key === 'age' && queryParams.value[key] && queryParams.value[key].includes('-')) {
|
||||
params.startAge = queryParams.value[key].split('-')[0]
|
||||
params.endAge = queryParams.value[key].split('-')[1]
|
||||
if (key === 'age' && queryParamsCopy[key] && queryParamsCopy[key].includes('-')) {
|
||||
params.startAge = queryParamsCopy[key].split('-')[0]
|
||||
params.endAge = queryParamsCopy[key].split('-')[1]
|
||||
}
|
||||
})
|
||||
|
||||
if (queryParams.value.lightStatus == 3) {
|
||||
params.lightStatusSeven = 7
|
||||
params.lightStatus = 1
|
||||
}
|
||||
isLoading.value = true
|
||||
try {
|
||||
console.log('params查询参数', params)
|
||||
const res = await getHomeIndexPersonListMsgAPI(params)
|
||||
total.value = res?.total || 0
|
||||
|
||||
|
|
|
|||
|
|
@ -6,9 +6,18 @@
|
|||
<view style="width: 74%">
|
||||
<MultiColorNoticeBar
|
||||
:textArray="[
|
||||
`黄灯人数:${noticeListData.yellowNum}`,
|
||||
`黄灯超7天人数:${noticeListData.yellowThanSevenDayNum}`,
|
||||
`出场未上传结算单:${noticeListData.exitNoFileNum}`,
|
||||
{
|
||||
path: '/pages/home/child-pages/personInfo/index?lightStatus=1',
|
||||
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' }]"
|
||||
:scrollSpeed="0.5"
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
class="metric-item"
|
||||
:key="item.title"
|
||||
v-for="item in swiperList_1"
|
||||
@tap="onNavigateTo(item.path)"
|
||||
>
|
||||
<view class="metric-dot"></view>
|
||||
<text class="metric-label">{{ item.title }}:</text>
|
||||
|
|
@ -49,7 +50,10 @@
|
|||
<!-- 第二页:在场人员统计 -->
|
||||
<template v-if="index === 1">
|
||||
<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="icon-badge">
|
||||
<up-image width="44" height="44" :src="PersonnelIcon" />
|
||||
|
|
@ -63,7 +67,10 @@
|
|||
<text class="stat-unit">人</text>
|
||||
</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="icon-badge">
|
||||
<up-image
|
||||
|
|
@ -95,7 +102,10 @@
|
|||
/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="rate-content">
|
||||
<view
|
||||
class="rate-content"
|
||||
@tap="onNavigateTo(commonPath + 'entryUnsettled/index')"
|
||||
>
|
||||
<text class="rate-label">出场未结算</text>
|
||||
<text class="rate-value">
|
||||
{{ exitNoFileNum }}
|
||||
|
|
@ -116,16 +126,32 @@
|
|||
<view class="rate-content">
|
||||
<text class="rate-label">红绿灯人员</text>
|
||||
<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>
|
||||
<text class="light-item">
|
||||
黄灯人数: {{ yellowNum }}
|
||||
</text>
|
||||
</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>
|
||||
<text class="light-item">
|
||||
黄灯7天: {{ yellowThanSevenDayNum }}
|
||||
黄灯超7天人数: {{ yellowThanSevenDayNum }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -153,13 +179,14 @@ const attNum = ref(0)
|
|||
const yellowNum = ref(0)
|
||||
const exitNoFileNum = ref(0)
|
||||
const yellowThanSevenDayNum = ref(0)
|
||||
const commonPath = '/pages/home/child-pages/'
|
||||
|
||||
// 轮播图1数据
|
||||
const swiperList_1 = ref([
|
||||
{ title: '总工程', key: 'mainProNum' },
|
||||
{ title: '标段工程', key: 'proNum' },
|
||||
{ title: '在用分包单位', key: 'subNum' },
|
||||
{ title: '在用班组', key: 'teamNum' },
|
||||
{ title: '总工程', key: 'mainProNum', path: `${commonPath}all-project/index` },
|
||||
{ title: '标段工程', key: 'proNum', path: `${commonPath}lot-project/index` },
|
||||
{ title: '在用分包单位', key: 'subNum', path: `${commonPath}useSub/index` },
|
||||
{ title: '在用班组', key: 'teamNum', path: `${commonPath}useTeam/index` },
|
||||
])
|
||||
|
||||
const swiperInfo_1 = ref({
|
||||
|
|
@ -231,6 +258,12 @@ const swiperList = ref([
|
|||
},
|
||||
},
|
||||
])
|
||||
|
||||
const onNavigateTo = (path) => {
|
||||
uni.navigateTo({
|
||||
url: path,
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
@ -307,7 +340,7 @@ const swiperList = ref([
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 30rpx;
|
||||
padding: 0 30rpx;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,11 +2,22 @@
|
|||
<!-- 切换工程弹框 -->
|
||||
<view class="app-container-1">
|
||||
<view class="switch-project-content">
|
||||
<view class="my-project-title"> 选择工程 </view>
|
||||
<view>
|
||||
<up-input clearable v-model="searchProjectValue" placeholder="输入搜索关键词">
|
||||
<view class="my-project-title">
|
||||
<view class="title-icon">
|
||||
<!-- <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>
|
||||
<up-icon name="search" size="24" color="#909399" @tap="onSearchProject" />
|
||||
<up-icon name="search" size="24" color="#165DFF" @tap="onSearchProject" />
|
||||
</template>
|
||||
</up-input>
|
||||
</view>
|
||||
|
|
@ -18,7 +29,15 @@
|
|||
v-for="item in projectList"
|
||||
@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>
|
||||
|
||||
|
|
@ -34,6 +53,7 @@
|
|||
import { onMounted, ref } from 'vue'
|
||||
import { useCommonStore } from '@/stores'
|
||||
import { getProjectSelectListByConditionAPI } from '@/services/common'
|
||||
import SwitchImg from '@/static/image/my/switch.png'
|
||||
const searchProjectValue = ref('')
|
||||
const projectList = ref([])
|
||||
const projectListAll = ref([])
|
||||
|
|
@ -76,6 +96,7 @@ const getProjectList = async () => {
|
|||
|
||||
// 跳转首页
|
||||
const onJumpHome = () => {
|
||||
// 跳转首页
|
||||
uni.switchTab({ url: '/pages/home/index' })
|
||||
}
|
||||
|
||||
|
|
@ -91,46 +112,186 @@ onMounted(() => {
|
|||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
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 {
|
||||
width: 86vw;
|
||||
max-width: 600rpx;
|
||||
height: 80vh;
|
||||
border-radius: 10rpx;
|
||||
box-shadow: 0 0 10rpx 2rpx rgba(0, 0, 0, 0.1);
|
||||
padding: 20rpx;
|
||||
|
||||
max-height: 900rpx;
|
||||
border-radius: 24rpx;
|
||||
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
|
||||
padding: 40rpx 30rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(20rpx);
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
|
||||
.my-project-title {
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30rpx;
|
||||
display: flex;
|
||||
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;
|
||||
padding: 14rpx 0;
|
||||
// border-bottom: 1px solid #e5e5e5;
|
||||
text-align: center;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
:deep(.up-input) {
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
:deep(.up-input__content) {
|
||||
padding: 20rpx 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.my-project-list {
|
||||
flex: 1;
|
||||
|
||||
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 {
|
||||
margin-top: 16rpx;
|
||||
margin-bottom: 20rpx;
|
||||
width: 100%;
|
||||
padding: 16rpx 24rpx;
|
||||
border: 1px solid #e5e5e5;
|
||||
padding: 28rpx 32rpx;
|
||||
box-sizing: border-box;
|
||||
border-radius: 14rpx;
|
||||
background-color: #f0f2f5;
|
||||
border-radius: 20rpx;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
|
||||
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;
|
||||
justify-content: center;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.up-empty {
|
||||
margin-bottom: 20rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.up-button {
|
||||
width: 95%;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(22, 93, 255, 0.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,3 +71,12 @@ export const getHomeIndexPersonListMsgAPI = (data = {}) => {
|
|||
data,
|
||||
})
|
||||
}
|
||||
|
||||
// 首页接口 ---- 二级页面 获取出场未结算数据
|
||||
export const getHomeIndexEntryUnsettledMsgAPI = (data = {}) => {
|
||||
return http({
|
||||
method: 'GET',
|
||||
url: '/bmw/homePageSub/getWorkerNotFileMsg',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,15 +19,10 @@ const baseURL = import.meta.env.VITE_API_BASE_URL
|
|||
// 添加请求拦截
|
||||
const httpInterceptor = {
|
||||
invoke(options) {
|
||||
// console.log(options, 'options')
|
||||
|
||||
if (options.isUploadFile) {
|
||||
if (!options.url.startsWith('http')) {
|
||||
options.url = baseURL + options.url
|
||||
}
|
||||
|
||||
console.log(options.url, '文件上传')
|
||||
|
||||
// 2. 设置请求超时时间,默认为60s,设置为 10s
|
||||
options.timeout = 60000
|
||||
|
||||
|
|
@ -36,33 +31,16 @@ const httpInterceptor = {
|
|||
// 'source-client': 'mini',
|
||||
...options.header,
|
||||
}
|
||||
|
||||
// 4. 增加 token 请求头标识
|
||||
const memberStore = useMemberStore()
|
||||
const token = memberStore.token
|
||||
// 如果是文件上传请求,则不进行加密处理
|
||||
if (options.isUploadFile) {
|
||||
// 4. 增加 token 请求头标识
|
||||
if (token) {
|
||||
options.header.Authorization = token
|
||||
}
|
||||
|
||||
console.log(options, 'options--**----')
|
||||
} 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 请求头标识
|
||||
const memberStore = useMemberStore()
|
||||
const token = memberStore.token
|
||||
if (token) {
|
||||
options.header.Authorization = token
|
||||
options.header.Token = token
|
||||
|
|
@ -70,9 +48,10 @@ const httpInterceptor = {
|
|||
|
||||
const commonStore = useCommonStore() // 请求配置
|
||||
const requestConfig = commonStore.requestConfig // 请求配置
|
||||
const env = import.meta.env.MODE
|
||||
const env = import.meta.env.MODE // 环境变量
|
||||
|
||||
// 5. 增加请求配置
|
||||
|
||||
// 入参加密
|
||||
options.header['encryptRequest'] =
|
||||
import.meta.env.MODE === 'development' ? false : requestConfig.encryptRequest
|
||||
|
|
@ -86,13 +65,15 @@ const httpInterceptor = {
|
|||
const queryData =
|
||||
options.data instanceof Object ? JSON.stringify(options.data) : options.data
|
||||
|
||||
// 如果是POST请求
|
||||
if (typeof queryData !== 'undefined' && options.method.toUpperCase() === 'POST') {
|
||||
// 加密数据
|
||||
// 加密数据 只有在非开发环境且加密请求配置为true时才进行加密
|
||||
if (requestConfig.encryptRequest && env !== 'development') {
|
||||
options.data = encryptWithSM4(queryData + '|' + hashWithSM3AndSalt(queryData))
|
||||
}
|
||||
}
|
||||
|
||||
// 如果是GET请求
|
||||
if (options.data instanceof Object && options.method.toUpperCase() === 'GET') {
|
||||
// 加密数据
|
||||
if (requestConfig.encryptRequest && env !== 'development') {
|
||||
|
|
@ -117,21 +98,20 @@ export const http = (options) => {
|
|||
...options,
|
||||
|
||||
success(res) {
|
||||
console.log(res, '请求拦截器处解密后的返回值')
|
||||
const currentEnv = getCurrentEnv()
|
||||
// 判断是H5 还是App环境
|
||||
let isEncryptResponse = ''
|
||||
if (currentEnv === 'windows') {
|
||||
isEncryptResponse = 'encryptresponse'
|
||||
isEncryptResponse = 'encryptresponse' // H5环境和APP环境返回的header字段不同
|
||||
} else {
|
||||
isEncryptResponse = 'encryptResponse'
|
||||
isEncryptResponse = 'encryptResponse' // H5环境和APP环境返回的header字段不同
|
||||
}
|
||||
|
||||
// 如果返回的header字段中包含加密响应,则进行解密
|
||||
if (res.header[isEncryptResponse]) {
|
||||
res.data = JSON.parse(decryptWithSM4(res.data))
|
||||
}
|
||||
|
||||
// console.log(res.data, '请求拦截器处解密后的返回值')
|
||||
// 1. 判断是否请求成功
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
if (res.data) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue