bonus-material-app/src/pages/toolsLedger/toolsLedger.vue

340 lines
9.2 KiB
Vue

<template>
<uni-nav-bar dark :fixed="true" shadow background-color="#4AA4EA" status-bar title="设备库存">
<template v-slot:left>
<view style="font-size: 18px; display: flex; align-items: center" @click="back">
<uni-icons type="left" size="20" color="#fff"></uni-icons>
<text>返回</text>
</view>
</template>
</uni-nav-bar>
<div class="content">
<div class="search-box">
<uni-data-select
v-if="isTeam"
v-model="queryParams.teamId"
:localdata="teamList"
filterable
:clear="false"
@change="getList"
style="margin-right: 10px;"
></uni-data-select>
<uni-easyinput
v-model="queryParams.keyWord"
placeholder="搜索物资名称、规格型号"
prefixIcon="search"
clearable
/>
<button size="mini" style="background-color: #f0a037; color: #fff; margin-left: 10px;" @click="getList">
查询
</button>
</div>
<scroll-view scroll-y class="scroll-container">
<div class="equipment-list">
<div
v-for="(category, categoryIndex) in filteredEquipmentCategories"
:key="categoryIndex"
class="equipment-category-section"
>
<!-- 设备类别标题 -->
<div
class="equipment-category"
@click="toggleCategory(categoryIndex)"
>
<span>{{ category.name }}</span>
<uni-icons
:type="category.expanded ? 'top' : 'bottom'"
size="16"
color="#999"
class="expand-icon"
></uni-icons>
</div>
<!-- 设备规格列表 -->
<div v-if="category.expanded" class="equipment-specs">
<div
v-for="(spec, specIndex) in category.specs"
:key="specIndex"
class="equipment-item"
@click="showDetail(category.name , spec)"
>
<div class="equipment-info">
<div class="equipment-name">{{ category.name }}</div>
<div class="equipment-spec">{{ spec.model }}</div>
<div class="equipment-spec" v-if="isTeam">{{ spec.maCode }}</div>
</div>
<div class="equipment-quantity"><span>{{ isTeam ? '在用数量:' : '在库数量:' }}</span>{{ isTeam ? spec.usNum : spec.quantity }}</div>
</div>
</div>
</div>
</div>
<div style="display: flex; justify-content: center; align-items: center; height: 50px; margin: 10px 0;">
{{ '没有更多数据了~' }}
</div>
</scroll-view>
</div>
</template>
<script setup>
import { onLoad } from '@dcloudio/uni-app';
import { onMounted, ref, reactive, computed } from 'vue'
import { getToolsLedgerList, getTeamUseNumList } from "../../services/ledger";
import { getBmTeamList } from '@/services/back.js'
import { useMemberStore } from '@/stores'
const memberStore = useMemberStore()
const userInfo = ref(memberStore.userInfo || {})
const searchText = ref('')
const isTeam = ref(false)
const teamList = ref([])
const queryParams = reactive({
teamId: '',
keyWord: '',
})
const back = () => {
uni.navigateBack({
delta: 1,
})
}
// 设备类别数据
const equipmentCategories = ref([])
onLoad((opt) => {
console.log('🚀 ~ onLoad ~ opt:', opt)
isTeam.value = opt.params ? JSON.parse(opt.params).isTeam : false
if (isTeam.value) {
getTeamList()
} else {
getList()
}
})
onMounted(() => {
// getList()
})
// 获取班组
const getTeamList = async () => {
try {
const idCard = uni.getStorageSync('idCard') || ''
const res = await getBmTeamList({ isAll: 0, idCard })
if (res.data.length > 0) {
teamList.value = res.data.map((item) => {
return {
...item,
value: item.id,
text: item.teamName,
}
})
if (res.data.some((item) => item.teamLeaderIdCard == userInfo.value.userName)) {
const team = res.data.find((item) => item.teamLeaderIdCard == userInfo.value.userName)
queryParams.teamId = team.id
} else {
queryParams.teamId = res.data[0].id
}
}
getList()
} catch (error) {
console.log('🚀 ~ getTeamList ~ error:', error)
}
}
const filteredEquipmentCategories = computed(() => {
if (!searchText.value) return equipmentCategories.value;
return equipmentCategories.value
.filter(category => {
const hasMatchingSpecs = category.specs.some(spec =>
category.name.toLowerCase().includes(searchText.value.toLowerCase()) ||
spec.model.toLowerCase().includes(searchText.value.toLowerCase())
);
return hasMatchingSpecs;
})
.map(category => ({
...category,
specs: category.specs.filter(spec =>
category.name.toLowerCase().includes(searchText.value.toLowerCase()) ||
spec.model.toLowerCase().includes(searchText.value.toLowerCase())
)
}));
});
const toggleCategory = (categoryIndex) => {
// 获取过滤后的类别名称
const filteredCategoryName = filteredEquipmentCategories.value[categoryIndex].name;
// 在原始数组中查找对应类别的索引
const originalIndex = equipmentCategories.value.findIndex(
category => category.name === filteredCategoryName
);
// 如果找到,则切换展开状态
if (originalIndex !== -1) {
equipmentCategories.value[originalIndex].expanded =
!equipmentCategories.value[originalIndex].expanded;
}
};
// 获取设备列表数据
const getList = async () => {
const params = {
keyWord: queryParams.keyWord,
teamId: queryParams.teamId,
teamName: queryParams.teamName,
}
console.log('🚀 ~ getList ~ params:', params)
try {
let res = null
if (isTeam.value) {
res = await getTeamUseNumList(params)
} else {
res = await getToolsLedgerList(params)
}
console.log('获取设备列表数据:', res)
if (res.code === 200 && res.data) {
// 转换API返回的数据结构为组件需要的格式
const formattedData = res.data.map(item => {
return {
name: item.typeName,
expanded: false, // 默认收起
thirdTypeId: item.thirdTypeId,
specs: item.modelList ? item.modelList.map(model => {
return {
...model,
model: model.typeModelName,
quantity: model.storeNum || 0,
manageType: model.manageType,
buyPrice: model.buyPrice,
typeId: model.typeId,
}
}) : [],
}
})
equipmentCategories.value = formattedData
// 如果只有一个类别,默认展开
if (equipmentCategories.value.length === 1) {
equipmentCategories.value[0].expanded = true
}
}
} catch (error) {
console.error('获取设备列表失败:', error)
equipmentCategories.value = []
}
}
const showDetail = (categoryName, spec) => {
if (isTeam.value) return
console.log('查看详情:', spec.typeId, spec.manageType);
const qty = parseFloat(spec.quantity);
if (spec.manageType === '编码' && !isNaN(qty) && qty > 0) {
uni.navigateTo({
url: '/pages/toolsLedger/toolsLedgerDetails?typeId=' + spec.typeId,
});
} else {
uni.showModal({
title: `${categoryName}\n${spec.model}`,
content: `当前库存数量: ${!isNaN(qty) && qty >= 0 ? qty : 0}`,
showCancel: false
});
}
}
</script>
<style lang="scss" scoped>
.content {
padding: 10px;
height: calc(100vh - 100px);
.search-box {
padding: 10px;
background: #fff;
margin-bottom: 10px;
border-radius: 8px;
display: flex;
align-items: center;
}
.equipment-list {
background: #fff;
border-radius: 8px;
overflow: hidden;
.equipment-category-section {
border-bottom: 1px solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.equipment-category {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 16px;
font-weight: bold;
padding: 15px;
background: #fafafa;
cursor: pointer;
transition: background-color 0.2s;
&:active {
background: #f0f0f0;
}
.expand-icon {
transition: transform 0.2s;
}
}
.equipment-specs {
.equipment-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px 15px;
border-bottom: 1px solid #f5f5f5;
cursor: pointer;
transition: background-color 0.2s;
&:last-child {
border-bottom: none;
}
&:active {
background: #f8f8f8;
}
.equipment-info {
.equipment-name {
color: #333;
font-size: 14px;
}
.equipment-spec {
color: #666;
font-size: 12px;
margin-top: 2px;
}
}
.equipment-quantity {
color: #4AA4EA;
font-size: 14px;
font-weight: 500;
}
}
}
}
}
}
.scroll-container {
height: calc(100vh - 150px);
}
</style>