库存盘点和项目的初版
This commit is contained in:
385
pages/workbench/wms/wms.vue
Normal file
385
pages/workbench/wms/wms.vue
Normal file
@@ -0,0 +1,385 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<!-- 筛选表单 一行展示 -->
|
||||
<view class="filter-form-row">
|
||||
<!-- 型号筛选 -->
|
||||
<view :class="['filter-item', activeFilter === 'model' ? 'filter-item-expand' : 'filter-item-collapse']">
|
||||
<template v-if="activeFilter === 'model'">
|
||||
<view class="input-clear-wrap">
|
||||
<input
|
||||
class="filter-input"
|
||||
v-model="queryParams.model"
|
||||
placeholder="型号"
|
||||
@blur="onFilterBlur('model')"
|
||||
:style="{ color: queryParams.model ? '#2979ff' : '#999' }"
|
||||
/>
|
||||
<view v-if="queryParams.model" class="clear-icon" @click="clearFilter('model')">
|
||||
<uni-icons type="closeempty" color="#bbb" size="18" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="filter-icon" @click="toggleFilter('model')">
|
||||
<uni-icons type="cart" :color="queryParams.model ? '#2979ff' : '#bbb'" size="24" />
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 物料名称筛选 -->
|
||||
<view :class="['filter-item', activeFilter === 'name' ? 'filter-item-expand' : 'filter-item-collapse']">
|
||||
<template v-if="activeFilter === 'name'">
|
||||
<view class="input-clear-wrap">
|
||||
<input
|
||||
class="filter-input"
|
||||
v-model="queryParams.name"
|
||||
placeholder="物料名称"
|
||||
@blur="onFilterBlur('name')"
|
||||
:style="{ color: queryParams.name ? '#2979ff' : '#999' }"
|
||||
/>
|
||||
<view v-if="queryParams.name" class="clear-icon" @click="clearFilter('name')">
|
||||
<uni-icons type="closeempty" color="#bbb" size="18" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="filter-icon" @click="toggleFilter('name')">
|
||||
<uni-icons type="search" :color="queryParams.name ? '#2979ff' : '#bbb'" size="24" />
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<!-- 品牌筛选 -->
|
||||
<view :class="['filter-item', activeFilter === 'brand' ? 'filter-item-expand' : 'filter-item-collapse']">
|
||||
<template v-if="activeFilter === 'brand'">
|
||||
<view class="input-clear-wrap">
|
||||
<input
|
||||
class="filter-input"
|
||||
v-model="queryParams.brand"
|
||||
placeholder="品牌"
|
||||
@blur="onFilterBlur('brand')"
|
||||
:style="{ color: queryParams.brand ? '#2979ff' : '#999' }"
|
||||
/>
|
||||
<view v-if="queryParams.brand" class="clear-icon" @click="clearFilter('brand')">
|
||||
<uni-icons type="closeempty" color="#bbb" size="18" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="filter-icon" @click="toggleFilter('brand')">
|
||||
<uni-icons type="circle" :color="queryParams.brand ? '#2979ff' : '#bbb'" size="24" />
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
<button class="filter-btn" @click="resetQuery">重置</button>
|
||||
</view>
|
||||
|
||||
<!-- 列表展示,下拉加载更多 -->
|
||||
<scroll-view class="list" scroll-y @scrolltolower="loadMore">
|
||||
<view v-for="(item, index) in oaWarehouseList" :key="item.id" class="list-item">
|
||||
<view class="row">
|
||||
<text class="index">{{ index + 1 }}</text>
|
||||
<text class="name">{{ item.name }}</text>
|
||||
<text class="model">{{ item.model }}</text>
|
||||
<text class="brand">{{ item.brand }}</text>
|
||||
</view>
|
||||
<view class="row">
|
||||
<text class="price">单价:{{ item.price }}</text>
|
||||
<text :class="['inventory', item.inventory < item.threshold ? 'low' : '']">
|
||||
库存:{{ item.inventory }}
|
||||
<text v-if="item.taskInventory !== null">({{ item.taskInventory }})</text>
|
||||
</text>
|
||||
<text class="unit">{{ item.unit }}</text>
|
||||
<text class="specifications">{{ item.specifications }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="oaWarehouseList.length === 0" class="empty">暂无数据</view>
|
||||
<view v-if="loadingMore" class="loading-more">加载中...</view>
|
||||
<view v-if="!hasMore && oaWarehouseList.length > 0" class="no-more">没有更多了</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listStock } from '@/api/oa/wms/stock.js'
|
||||
import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue'
|
||||
import uniEasyinput from '@/uni_modules/uni-easyinput/components/uni-easyinput/uni-easyinput.vue'
|
||||
export default {
|
||||
components: {
|
||||
uniIcons
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
oaWarehouseList: [],
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
model: '',
|
||||
name: '',
|
||||
brand: ''
|
||||
},
|
||||
total: 0,
|
||||
loadingMore: false,
|
||||
hasMore: true,
|
||||
activeFilter: 'model' // 当前展开的筛选项
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.getList()
|
||||
},
|
||||
methods: {
|
||||
getList(isLoadMore = false) {
|
||||
if (!isLoadMore) {
|
||||
this.queryParams.pageNum = 1
|
||||
this.oaWarehouseList = []
|
||||
this.hasMore = true
|
||||
}
|
||||
listStock(this.queryParams).then(res => {
|
||||
const rows = res.rows || []
|
||||
this.total = res.total || 0
|
||||
if (isLoadMore) {
|
||||
this.oaWarehouseList = this.oaWarehouseList.concat(rows)
|
||||
} else {
|
||||
this.oaWarehouseList = rows
|
||||
}
|
||||
// 判断是否还有更多
|
||||
this.hasMore = this.oaWarehouseList.length < this.total
|
||||
this.loadingMore = false
|
||||
})
|
||||
},
|
||||
handleQuery() {
|
||||
this.getList(false)
|
||||
},
|
||||
toggleFilter(type) {
|
||||
this.activeFilter = type
|
||||
},
|
||||
onFilterBlur(type) {
|
||||
// 输入框失焦后自动筛选
|
||||
this.handleQuery()
|
||||
},
|
||||
clearFilter(type) {
|
||||
this.queryParams[type] = ''
|
||||
this.handleQuery()
|
||||
},
|
||||
resetQuery() {
|
||||
this.queryParams = {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
model: '',
|
||||
name: '',
|
||||
brand: ''
|
||||
}
|
||||
this.getList(false)
|
||||
},
|
||||
loadMore() {
|
||||
if (!this.hasMore || this.loadingMore) return
|
||||
this.loadingMore = true
|
||||
this.queryParams.pageNum++
|
||||
this.getList(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.input-clear-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.clear-icon {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
z-index: 2;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
padding: 4rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.container {
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.filter-form-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
background: #fff;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 2rpx 8rpx #eee;
|
||||
padding: 8rpx 16rpx;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.filter-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 56rpx;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.filter-item-expand {
|
||||
flex: 1 1 0%;
|
||||
margin-right: 16rpx;
|
||||
min-width: 120rpx;
|
||||
}
|
||||
|
||||
.filter-item-collapse {
|
||||
flex: 0 0 48rpx;
|
||||
margin-right: 8rpx;
|
||||
min-width: 48rpx;
|
||||
max-width: 48rpx;
|
||||
}
|
||||
|
||||
.filter-input {
|
||||
width: 100%;
|
||||
padding: 8rpx 12rpx;
|
||||
border: 1rpx solid #eee;
|
||||
border-radius: 6rpx;
|
||||
background: #f8f8f8;
|
||||
font-size: 28rpx;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.filter-input {
|
||||
width: 100%;
|
||||
padding: 8rpx 12rpx;
|
||||
border: 1rpx solid #eee;
|
||||
border-radius: 6rpx;
|
||||
background: #f8f8f8;
|
||||
font-size: 28rpx;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
margin-right: 12rpx;
|
||||
padding: 8rpx 24rpx;
|
||||
background: #2979ff;
|
||||
color: #fff;
|
||||
border-radius: 6rpx;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.list {
|
||||
background: #fff;
|
||||
border-radius: 8rpx;
|
||||
box-shadow: 0 2rpx 8rpx #eee;
|
||||
height: 90vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
margin: 16rpx 16rpx 0 16rpx;
|
||||
padding: 24rpx 20rpx 16rpx 20rpx;
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 2rpx 12rpx #e5e5e5;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.index {
|
||||
width: 48rpx;
|
||||
color: #bbb;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #2979ff;
|
||||
margin-right: 24rpx;
|
||||
max-width: 220rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.model {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
margin-right: 20rpx;
|
||||
max-width: 160rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.brand {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-right: 20rpx;
|
||||
max-width: 120rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-size: 28rpx;
|
||||
color: #faad14;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.inventory {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
margin-right: 20rpx;
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
.inventory.low {
|
||||
color: #ff4d4f !important;
|
||||
background: #fff2f0;
|
||||
border-radius: 6rpx;
|
||||
padding: 0 8rpx;
|
||||
}
|
||||
|
||||
.unit {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.specifications {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 16rpx;
|
||||
max-width: 120rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
padding: 40rpx 0;
|
||||
}
|
||||
|
||||
.loading-more {
|
||||
text-align: center;
|
||||
color: #2979ff;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.no-more {
|
||||
text-align: center;
|
||||
color: #bbb;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user