bonus-material-app/src/pages/expectations/index.vue

505 lines
10 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="page-container">
<!-- Tab 切换 -->
<view class="complete-btn">
<view class="btn" :class="{ active: active === 1 }" @click="changeTab(1)">
<span>在库</span>
<view v-if="active === 1" class="bt-line"></view>
</view>
<view class="btn" style="margin-left: 120rpx" :class="{ active: active === 2 }" @click="changeTab(2)">
<span>在用</span>
<view v-if="active === 2" class="bt-line"></view>
</view>
</view>
<!-- 日期范围 -->
<uni-row class="complete-btn" style="margin: 40rpx;">
<view class="btn">
<span style="color: red;">超期:{{expired}}</span>
</view>
<view class="btn" style="margin-left: 120rpx">
<span style="color: #f3a73f;">临期:{{aboutToExpire}}</span>
</view>
</uni-row>
<!-- 搜索框 -->
<uni-row :gutter="24" class="search-form">
<uni-col :span="20">
<uni-easyinput v-model="queryParams.keyWord" placeholder="请输入内容" />
</uni-col>
<uni-col :span="4">
<view class="search" @click="onSearchBtn">搜索</view>
</uni-col>
</uni-row>
<!-- 列表区域 -->
<scroll-view scroll-y class="scroll-container" @scrolltolower="onScrollTolower">
<view v-for="(item, index) in tableList" :key="index" class="table-list-item" @click="handleItem(item)">
<div class="title">
<div class="status-tag">
<uni-tag v-if="item.status === 'expired'" text="超期" type="error" custom-style="warningStyle" />
<uni-tag v-if="item.status === 'about_to_expire'" text="临期" type="warning"
custom-style="warningStyle" />
</div>
</div>
<view class="line"></view>
<template v-for="field in fieldMap" :key="field.label">
<uni-row :gutter="24" v-show="field.isShow.includes(active)">
<uni-col :span="field.labelSpan">{{ field.label }}</uni-col>
<uni-col :span="field.valueSpan">
<view class="cont">{{ item[field.key] }}</view>
</uni-col>
</uni-row>
</template>
</view>
<view class="loading-text">{{ finish ? '没有更多数据了~' : '正在加载...' }}</view>
</scroll-view>
</view>
</template>
<script setup>
import {
ref,
computed
} from 'vue'
import {
getList,
getCountExpectations
} from '@/services/expectations/expectations.js'
import {
onShow
} from '@dcloudio/uni-app'
import {
debounce
} from 'lodash-es'
const expired = ref(0)
const aboutToExpire = ref(0)
const total = ref(0)
const active = ref(1)
const tableList = ref([])
const dateArray = ref([])
const queryParams = ref({
keyWord: '',
useStatus: 1,
pageNum: 1,
pageSize: 5
})
const fieldMap = [{
label: '单位名称',
key: 'unit',
labelSpan: 6,
valueSpan: 18,
isShow: '2'
},
{
label: '工程名称',
key: 'project',
labelSpan: 6,
valueSpan: 18,
isShow: '2'
}, {
label: '机具名称',
key: 'typeName',
labelSpan: 6,
valueSpan: 18,
isShow: '1,2'
},
{
label: '机具规格',
key: 'specCode',
labelSpan: 6,
valueSpan: 18,
isShow: '1,2'
},
{
label: '数量',
key: 'count',
labelSpan: 6,
valueSpan: 18,
isShow: '1,2'
},
]
const onSearchBtn = () => {
queryParams.value.pageNum = 1
tableList.value = []
getTableList(true)
}
const getTableList = async (isTap = false) => {
const res = await getList(queryParams.value)
total.value = res.data.total
if (isTap) {
tableList.value = res.data.rows
} else {
tableList.value.push(...res.data.rows)
}
}
const getCount = () => {
expired.value = 0;
aboutToExpire.value = 0;
getCountExpectations(queryParams.value).then(res => {
if (res.code === 200) {
expired.value = res.data.expired.count
aboutToExpire.value = res.data.aboutToExpire.count
}
})
}
onShow(() => {
tableList.value = []
total.value = 0
getTableList(true)
getCount();
})
const onScrollTolower = debounce(() => {
if (total.value > tableList.value.length) {
queryParams.value.pageSize += 5
getTableList()
}
}, 500)
const changeTab = index => {
active.value = index
queryParams.value.useStatus = index === 1 ? 1 : 2
queryParams.value.pageNum = 1
getTableList(true)
getCount();
}
const handleItem = item => {
uni.navigateTo({
url: `/pages/expectations/detail?item=${JSON.stringify(item)}&useStatus= ${active.value}`
})
}
const finish = computed(() => total.value === tableList.value.length)
</script>
<style lang="scss" scoped>
.title-left {
display: flex;
flex-direction: column;
.code {
font-size: 32rpx;
font-weight: 600;
color: #3784fb;
letter-spacing: 1rpx;
}
.sub-code {
font-size: 28rpx;
/* 比主code小一点 */
color: #8c8c8c;
/* 灰色更柔和 */
margin-top: 4rpx;
/* 与主code有一点间距 */
}
}
.status-tag {
display: flex;
align-items: center;
}
.page-container {
display: flex;
height: 100vh;
padding: 24rpx;
flex-direction: column;
background-color: #f7f8fa;
.complete-btn {
display: flex;
justify-content: center;
/* padding: 20rpx 24rpx;
background: #fff;
border-radius: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05); */
.btn {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 60rpx;
position: relative;
transition: all 0.3s ease;
span {
font-size: 32rpx;
color: #8c8c8c;
font-weight: 500;
&.active {
color: #3784fb;
font-weight: 600;
.second-active & {
color: #fa8c16;
}
}
}
.bt-line {
width: 32rpx;
height: 6rpx;
background: #3784fb;
margin-top: 12rpx;
border-radius: 6rpx;
transition: all 0.3s ease;
.second-active & {
background: #fa8c16;
}
}
}
}
.search-form {
display: flex;
align-items: center;
padding: 20rpx;
/* background: #fff;
border-radius: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05); */
:deep(.uni-easyinput__content),
:deep(.uni-date-editor) {
background-color: #f7f8fa;
border: 2rpx solid #e8e8e8;
border-radius: 12rpx;
height: 75rpx;
transition: all 0.3s ease;
&:focus-within {
border-color: #3784fb;
box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1);
}
}
:deep(.uni-date) {
width: 100%;
.uni-date-x {
width: 100%;
}
.uni-date-editor--x {
width: 100%;
}
.uni-date-range--x {
width: 100%;
.uni-date-range--x-input {
width: 100%;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24rpx;
.uni-date-range--x-text {
font-size: 28rpx;
color: #262626;
}
}
}
.uni-date-x--border {
width: 100%;
border: 2rpx solid #e8e8e8;
border-radius: 12rpx;
background-color: #f7f8fa;
height: 80rpx;
transition: all 0.3s ease;
&:focus-within {
border-color: #3784fb;
box-shadow: 0 0 0 2rpx rgba(55, 132, 251, 0.1);
}
}
}
:deep(.uni-date-editor) {
.uni-date-range {
display: flex;
align-items: center;
width: 100%;
.uni-date-range--text {
width: 50%;
text-align: center;
color: #333;
}
}
}
}
.search {
height: 60rpx;
background: linear-gradient(135deg, #4b8eff 0%, #3784fb 100%);
text-align: center;
line-height: 60rpx;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: translateY(2rpx);
opacity: 0.9;
}
}
.add {
height: 60rpx;
background: linear-gradient(135deg, #00aa00 0%, #00aa7f 100%);
text-align: center;
line-height: 60rpx;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: 600;
box-shadow: 0 6rpx 20rpx rgba(55, 132, 251, 0.2);
transition: all 0.3s ease;
&:active {
transform: translateY(2rpx);
opacity: 0.9;
}
}
.scroll-container {
padding: 0 2rpx;
.table-list-item {
margin: 24rpx 0;
padding: 32rpx;
background-color: #fff;
min-height: 300rpx;
border-radius: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.06);
transition: all 0.3s ease;
&:active {
transform: scale(0.985);
background-color: #fafbfc;
}
.title {
display: flex;
justify-content: flex-end;
align-items: center;
margin-bottom: 20rpx;
.title-left {
.code {
font-size: 32rpx;
font-weight: 600;
color: #3784fb;
letter-spacing: 1rpx;
}
}
span.status {
padding: 8rpx 28rpx;
border-radius: 8rpx;
font-size: 26rpx;
font-weight: 600;
&.completed {
background-color: rgba(82, 196, 26, 0.1);
color: #52c41a;
}
&.pending {
background-color: rgba(250, 140, 22, 0.1);
color: #fa8c16;
}
}
}
.line {
margin: 24rpx 0;
height: 2rpx;
background: linear-gradient(90deg,
rgba(232, 232, 232, 0) 0%,
rgba(232, 232, 232, 1) 50%,
rgba(232, 232, 232, 0) 100%);
}
:deep(.uni-row) {
/* margin-bottom: 20rpx; */
.uni-col-6 {
color: #8c8c8c;
font-size: 28rpx;
font-weight: 500;
}
}
.cont {
display: flex;
justify-content: flex-end;
line-height: 1.8;
color: #262626;
font-size: 28rpx;
font-weight: 500;
}
}
}
.loading-text {
text-align: center;
font-size: 26rpx;
color: #8c8c8c;
padding: 32rpx 0;
letter-spacing: 1rpx;
}
}
// 优化滑动区域样式
:deep(.uni-swipe_action) {
border-radius: 20rpx;
overflow: hidden;
.uni-swipe_content {
margin: 0 !important;
padding: 0;
background-color: #fff;
}
.uni-swipe_button-group {
height: 100%;
.uni-swipe_button {
writing-mode: vertical-rl;
padding: 0 24rpx;
font-size: 28rpx !important;
font-weight: 600;
// 查看按钮
&:nth-child(1) {
background: linear-gradient(to bottom, #3ad980, #34C759) !important;
}
// 出库按钮
&:nth-child(2) {
background: linear-gradient(to bottom, #3b95ff, #007AFF) !important;
}
&:active {
opacity: 0.85;
}
}
}
}
</style>