bonus-ui/src/views/home/equipment-supply/index.vue

569 lines
21 KiB
Vue
Raw Normal View History

<template>
<div class="app-container">
2025-03-21 16:38:15 +08:00
<template v-if="!isHome">
<!-- 机具供应展示 -->
<el-form size="small" :model="queryParams" ref="queryFormRef">
<el-row>
<el-col :span="6">
<el-form-item>
<el-date-picker
v-model="queryDate"
2025-03-26 13:55:21 +08:00
type="daterange"
2025-03-21 16:38:15 +08:00
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
2025-03-26 13:55:21 +08:00
value-format="yyyy-MM-dd"
format="yyyy-MM-dd"
2025-03-24 15:13:26 +08:00
style="width: 95%"
2025-03-21 16:38:15 +08:00
/>
</el-form-item>
</el-col>
<el-col :span="6">
2025-03-25 14:31:14 +08:00
<el-form-item prop="unitId">
<treeselect
:options="unitList"
:show-count="true"
2025-03-21 16:38:15 +08:00
style="width: 95%"
2025-03-25 14:31:14 +08:00
:normalizer="normalizer"
noChildrenText="没有数据了"
noOptionsText="没有数据"
placeholder="请选择公司"
2025-03-25 16:52:07 +08:00
noResultsText="没有搜索结果"
v-model="queryParams.unitId"
:disable-branch-nodes="true"
2025-03-25 14:31:14 +08:00
/>
2025-03-21 16:38:15 +08:00
</el-form-item>
</el-col>
<el-col :span="6">
2025-03-25 14:31:14 +08:00
<el-form-item prop="projectId">
<treeselect
2025-03-25 16:52:07 +08:00
style="width: 95%"
:show-count="true"
2025-03-25 14:31:14 +08:00
:options="projectList"
:normalizer="normalizer"
noOptionsText="没有数据"
2025-03-25 16:52:07 +08:00
noChildrenText="没有数据了"
2025-03-25 14:31:14 +08:00
placeholder="请选择领工程"
2025-03-25 16:52:07 +08:00
noResultsText="没有搜索结果"
:disable-branch-nodes="true"
v-model="queryParams.projectId"
2025-03-25 14:31:14 +08:00
/>
2025-03-21 16:38:15 +08:00
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="onHandleSearch">查询</el-button>
<el-button icon="el-icon-refresh" @click="onHandleReset">重置</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
2025-03-21 16:38:15 +08:00
<!-- 卡片区域 -->
<div class="card-box">
2025-03-24 15:13:26 +08:00
<div class="title-card">需求供应</div>
2025-03-21 16:38:15 +08:00
<div class="card-box-content-1">
<div v-for="(card, index) in cardList_1" :key="index">
<CardModel
2025-03-25 18:34:37 +08:00
:ratio="card.ratio"
2025-03-21 16:38:15 +08:00
:theme="card.theme"
:iconType="card.icon"
2025-03-25 18:34:37 +08:00
:cardNum="card.cardNum"
2025-03-25 16:52:07 +08:00
:cardTitle="card.title"
2025-03-21 16:38:15 +08:00
:isReduce="card.isReduce"
@onOpenLevelTwoPages="onOpenLevelTwoPages"
/>
</div>
<div class="card-box-space-last">
<CardModelSpace
:key="index"
:theme="card.theme"
:iconType="card.icon"
2025-03-25 16:52:07 +08:00
:cardTitle="card.title"
2025-03-25 18:34:37 +08:00
:cardNum="card.cardNum"
2025-03-21 16:38:15 +08:00
v-for="(card, index) in cardList_3"
/>
</div>
</div>
</div>
2025-03-21 16:38:15 +08:00
<div class="card-box">
2025-03-24 15:13:26 +08:00
<div class="title-card">仓储状态</div>
2025-03-21 16:38:15 +08:00
<div class="card-box-content">
<div v-for="(card, index) in cardList_2" :key="index">
<CardModel
:theme="card.theme"
:iconType="card.icon"
2025-03-25 16:52:07 +08:00
:cardTitle="card.title"
2025-03-21 16:38:15 +08:00
:isReduce="card.isReduce"
:cardNum="card.cardNum"
:ratio="card.ratio"
2025-03-21 16:38:15 +08:00
@onOpenLevelTwoPages="onOpenLevelTwoPages"
/>
</div>
</div>
</div>
2025-03-21 16:38:15 +08:00
<!-- 图表区域 -->
<div class="chart-box">
<div :key="index" v-for="(chart, index) in chartList">
<ChartModelBox
:chartTitle="chart.title"
:ChartTypeName="chart.type"
:pie_1Data="pie_1Data"
:pie_2Data="pie_2Data"
:barAndLineX="barAndLineX"
:barY1="barY1"
:barY2="barY2"
:lineY1="lineY1"
:lineY2="lineY2"
/>
2025-03-21 16:38:15 +08:00
</div>
</div>
2025-03-21 16:38:15 +08:00
</template>
<template v-else>
<TableModel @onCloseLevelTwoPages="onCloseLevelTwoPages" :levelTwoTitle="levelTwoTitle" />
</template>
</div>
</template>
<script>
2025-03-21 16:38:15 +08:00
import CardModel from './components/card-model' // 卡片组件
import CardModelSpace from './components/card-model-space' // 第一行右侧小卡片组件
import ChartModelBox from './components/chart-model-box' // 图表组件
import TableModel from './components/table-model' // 二级页面列表组件
2025-03-25 14:31:14 +08:00
import Treeselect from '@riophae/vue-treeselect'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import {
getCardListApi,
getPie_1DataApi,
getPie_2DataApi,
getCardList_2Api,
getBarAndLineDataApi
} from '@/api/home/equipment-supply.js'
2025-03-25 14:31:14 +08:00
import { getListProject, getListUnite } from '@/api/lease/apply'
2025-07-04 15:11:51 +08:00
import {
getProjectInfoApi,
getUserInfoByUserNameApi,
getUserInfoByIdCardApi,
updateTeamProjectApi
} from '@/api/materialsStation'
export default {
components: {
CardModel,
CardModelSpace,
2025-03-21 16:38:15 +08:00
ChartModelBox,
2025-03-25 14:31:14 +08:00
TableModel,
Treeselect
},
data() {
return {
2025-03-21 16:38:15 +08:00
// 是否二级页面
isHome: false,
// 二级页面标题
levelTwoTitle: '',
2025-03-25 14:31:14 +08:00
// 公司列表
unitList: [],
// 工程列表
projectList: [],
// 日期查询条件
queryDate: [],
// 表单查询条件
2025-03-21 16:38:15 +08:00
queryParams: {
startTime: '',
endTime: '',
2025-03-25 14:31:14 +08:00
unitId: undefined,
projectId: undefined
2025-03-21 16:38:15 +08:00
},
2025-03-25 14:31:14 +08:00
cardList_1: [
{
title: '需求量',
theme: '#ffa94c',
icon: 'demand_count',
2025-03-25 18:34:37 +08:00
isReduce: false,
cardNum: 0,
ratio: 0
},
{
title: '已供应量',
theme: '#027db4',
icon: 'supply_ready',
2025-03-25 18:34:37 +08:00
isReduce: false,
cardNum: 0,
ratio: 0
},
{
title: '待供应量',
theme: '#fb6260',
icon: 'supply_to_be',
2025-03-25 18:34:37 +08:00
isReduce: true,
cardNum: 0,
ratio: 0
}
],
cardList_2: [
{
title: '在库量',
theme: '#5ad55a',
icon: 'In_the_library',
isReduce: false,
cardNum: 0,
ratio: 0
},
{
title: '在用量',
theme: '#0099ff',
icon: 'In_use',
isReduce: true,
cardNum: 0,
ratio: 0
},
{
title: '在修量',
theme: '#8167f5',
icon: 'In_repair',
isReduce: false,
cardNum: 0,
ratio: 0
},
{
2025-05-08 16:24:57 +08:00
title: '修试待入库量',
theme: '#b8741a',
icon: 'repair_store',
isReduce: true,
cardNum: 0,
ratio: 0
},
{
2025-05-08 16:24:57 +08:00
title: '新购待入库量',
theme: '#bfbf00',
icon: 'penning_store',
isReduce: true,
cardNum: 0,
ratio: 0
2025-05-08 16:24:57 +08:00
},
],
cardList_3: [
{
title: '工程总数量(个)',
theme: '#ffa94c',
2025-03-25 18:34:37 +08:00
icon: 'project_num',
cardNum: 0
},
{
title: '供应总件数(件)',
theme: '#52c1f5',
2025-03-25 18:34:37 +08:00
icon: 'quantity_num',
cardNum: 0
},
{
title: '供应总价值(万元)',
theme: '#73a0fa',
2025-03-25 18:34:37 +08:00
icon: 'total_price',
cardNum: 0
}
],
// 图表区数据
chartList: [
{
title: '需求供应情况统计',
type: 'PieChart1'
},
{
title: '机具状态统计',
type: 'PieChart2'
},
{
title: '机具需求占比',
type: 'BarChart'
},
{
title: '待供应占比统计',
type: 'LineChart'
}
],
pie_1Data: [],
pie_2Data: [],
barAndLineX: [],
barY1: [],
lineY1: [],
barY2: [],
2025-07-04 15:11:51 +08:00
lineY2: [],
idCard: '',
projectIds: []
}
},
methods: {
2025-03-25 14:31:14 +08:00
// 获取卡片列表信息
async getCardListFun() {
const queryParams = {
...this.queryParams,
startTime: this.queryDate && this.queryDate.length > 0 ? this.queryDate[0] : '',
endTime: this.queryDate && this.queryDate.length > 0 ? this.queryDate[1] : ''
}
2025-03-25 18:34:37 +08:00
const { data: res } = await getCardListApi(queryParams)
const {
demandNum,
2025-05-08 16:24:57 +08:00
// demandIncrease,
2025-03-25 18:34:37 +08:00
suppliedQuantityNum,
2025-05-08 16:24:57 +08:00
// suppliedQuantityIncrease,
2025-03-25 18:34:37 +08:00
suppliedToBeQuantityNum,
2025-05-08 16:24:57 +08:00
// suppliedToBeQuantityIncrease,
2025-03-25 18:34:37 +08:00
projectNum,
suppliedQuantityAllNum,
suppliedQuantityPrice
} = res
this.cardList_1[0].cardNum = demandNum
2025-05-08 16:24:57 +08:00
// this.cardList_1[0].ratio = Math.abs(demandIncrease)
// demandIncrease > 0 ? (this.cardList_1[0].isReduce = true) : (this.cardList_1[0].isReduce = false)
2025-03-25 18:34:37 +08:00
this.cardList_1[1].cardNum = suppliedQuantityNum
2025-05-08 16:24:57 +08:00
// this.cardList_1[1].ratio = Math.abs(suppliedQuantityIncrease)
// suppliedQuantityIncrease > 0 ? (this.cardList_1[1].isReduce = true) : (this.cardList_1[1].isReduce = false)
2025-03-25 18:34:37 +08:00
this.cardList_1[2].cardNum = suppliedToBeQuantityNum
2025-05-08 16:24:57 +08:00
// this.cardList_1[2].ratio = Math.abs(suppliedToBeQuantityIncrease)
// suppliedToBeQuantityIncrease > 0
// ? (this.cardList_1[2].isReduce = true)
// : (this.cardList_1[2].isReduce = false)
2025-03-25 18:34:37 +08:00
this.cardList_3[0].cardNum = projectNum
this.cardList_3[1].cardNum = suppliedQuantityAllNum || 0
this.cardList_3[2].cardNum = suppliedQuantityPrice || 0
// 获取第二行卡片数据
const { data: result } = await getCardList_2Api(queryParams)
const {
inStockNum,
2025-05-08 16:24:57 +08:00
// inStockIncrease,
inUseNum,
2025-05-08 16:24:57 +08:00
// inUseIncrease,
inRepairNum,
2025-05-08 16:24:57 +08:00
// inRepairIncrease,
newPurchaseNum,
2025-05-08 16:24:57 +08:00
// newPurchaseIncrease,
newRepairNum,
2025-05-08 16:24:57 +08:00
// newRepairIncrease
} = result
this.cardList_2[0].cardNum = inStockNum
2025-05-08 16:24:57 +08:00
// this.cardList_2[0].ratio = Math.abs(inStockIncrease)
// inStockIncrease > 0 ? (this.cardList_2[0].isReduce = true) : (this.cardList_2[0].isReduce = false)
this.cardList_2[1].cardNum = inUseNum
2025-05-08 16:24:57 +08:00
// this.cardList_2[1].ratio = Math.abs(inUseIncrease)
// inUseIncrease > 0 ? (this.cardList_2[1].isReduce = true) : (this.cardList_2[1].isReduce = false)
this.cardList_2[2].cardNum = inRepairNum
2025-05-08 16:24:57 +08:00
// this.cardList_2[2].ratio = Math.abs(inRepairIncrease)
// inRepairIncrease > 0 ? (this.cardList_2[2].isReduce = true) : (this.cardList_2[2].isReduce = false)
this.cardList_2[3].cardNum = newPurchaseNum
2025-05-08 16:24:57 +08:00
// this.cardList_2[3].ratio = Math.abs(newPurchaseIncrease)
// newPurchaseIncrease > 0 ? (this.cardList_2[3].isReduce = true) : (this.cardList_2[3].isReduce = false)
this.cardList_2[4].cardNum = newRepairNum
2025-05-08 16:24:57 +08:00
// this.cardList_2[4].ratio = Math.abs(newRepairIncrease)
// newRepairIncrease > 0 ? (this.cardList_2[4].isReduce = true) : (this.cardList_2[4].isReduce = false)
this.pie_2Data = [
{ value: inStockNum, name: '在库量', itemStyle: { color: '#26a8ff' } },
{ value: inUseNum, name: '在用量', itemStyle: { color: '#45d8d9' } },
{ value: inRepairNum, name: '在修量', itemStyle: { color: '#ff8e9d' } },
{ value: newPurchaseNum, name: '新购待入库量', itemStyle: { color: '#6ccaf6' } },
{ value: newRepairNum, name: '修试待入库量', itemStyle: { color: '#ffb667' } }
]
// 获取饼图和柱状图
const { data: barAndLine } = await getBarAndLineDataApi(queryParams)
const { typeNameList, demandNumList, suppliedQuantityNumList, suppliedToBeQuantityNumList } = barAndLine
this.barAndLineX = typeNameList
this.barY1 = demandNumList
this.lineY1 = demandNumList
this.barY2 = suppliedQuantityNumList
this.lineY2 = suppliedToBeQuantityNumList
console.log('barAndLine', barAndLine)
},
// 获取图表数据
async getPie_1DataFun() {
const queryParams = {
...this.queryParams,
startTime: this.queryDate && this.queryDate.length > 0 ? this.queryDate[0] : '',
endTime: this.queryDate && this.queryDate.length > 0 ? this.queryDate[1] : ''
}
const { data: pie1 } = await getPie_1DataApi(queryParams)
const { demandNum, suppliedQuantityNum, suppliedToBeQuantityNum } = pie1
this.pie_1Data = [
2025-05-08 16:24:57 +08:00
// { value: demandNum, name: '计划需求量', itemStyle: { color: '#65dfe0' } },
{ value: suppliedQuantityNum, name: '已供应量', itemStyle: { color: '#ff8e9d' } },
{ value: suppliedToBeQuantityNum, name: '待供应量', itemStyle: { color: '#6ccaf6' } }
]
2025-03-25 14:31:14 +08:00
},
2025-03-25 14:31:14 +08:00
// 获取公司和工程
async getCompanyAndProjectFun() {
const comRes = await getListUnite({ projectId: null })
this.unitList = comRes.data
const proRes = await getListProject({ unitId: null })
this.projectList = proRes.data
},
// 查询
2025-03-25 14:31:14 +08:00
onHandleSearch() {
2025-03-25 18:34:37 +08:00
this.getCardListFun()
this.getPie_1DataFun()
2025-03-25 14:31:14 +08:00
},
// 重置
onHandleReset() {
2025-03-26 16:59:45 +08:00
this.queryDate = this.getDefaultDateRange()
2025-03-21 16:38:15 +08:00
this.$refs.queryFormRef.resetFields()
2025-03-26 13:55:21 +08:00
this.getCardListFun()
2025-03-27 17:55:22 +08:00
this.getPie_1DataFun()
2025-03-21 16:38:15 +08:00
},
// 自定义事件 打开二级页面
onOpenLevelTwoPages(title) {
this.levelTwoTitle = title
this.isHome = true
},
// 自定义事件 关闭二级页面
onCloseLevelTwoPages() {
this.isHome = false
2025-03-25 14:31:14 +08:00
},
// 转换菜单数据结构
normalizer(node) {
if (node.children && !node.children.length) {
delete node.children
}
return {
id: node.id,
label: node.name,
children: node.children
}
2025-03-26 16:59:45 +08:00
},
// 默认日期范围
getDefaultDateRange() {
const today = new Date()
2025-03-31 09:53:28 +08:00
// 获取上个月的同一天
const lastMonth = new Date(today)
2025-03-26 16:59:45 +08:00
lastMonth.setMonth(today.getMonth() - 1)
2025-03-31 09:53:28 +08:00
// 处理日期溢出问题
if (lastMonth.getDate() !== today.getDate()) {
lastMonth.setDate(0) // 设置为上个月的最后一天
2025-03-26 16:59:45 +08:00
}
const formatDate = date => {
const y = date.getFullYear()
const m = String(date.getMonth() + 1).padStart(2, '0')
const d = String(date.getDate()).padStart(2, '0')
return `${y}-${m}-${d}`
}
return [formatDate(lastMonth), formatDate(today)]
2025-07-04 15:11:51 +08:00
},
// start
// 获取用户信息
async getUserInfoByUserName() {
try {
const userName = sessionStorage.getItem('userName')
console.log('🚀 ~ getUserInfoByUserName ~ userName:', userName)
const res = await getUserInfoByUserNameApi({ userName })
this.idCard = res?.data?.idCard
sessionStorage.setItem('idCard', res?.data?.idCard)
} catch (error) {
console.log('🚀 ~ getUserInfoByUserName ~ error:', error)
}
},
async projectInfoList() {
try {
const res = await getProjectInfoApi({ unitId: null, isApp: true })
console.log('🚀 ~ projectInfoList ~ res:', res)
if (res.data && res.data.length > 0) {
this.projectIds = res.data.map(item => item.proId)
} else {
this.projectIds = []
}
} catch (error) {
console.log('🚀 ~ projectInfoList ~ error:', error)
}
},
async getUserInfoByIdCard() {
const params = {
idCard: this.idCard,
projectIds: this.projectIds
}
console.log('🚀 ~ getUserInfoByIdCard ~ params:', params)
try {
const res = await getUserInfoByIdCardApi(params)
console.log('🚀 ~ getUserInfoByIdCard ~ res:', res)
if (res.code === 200 && res.data && res.data.length > 0) {
const params = {
teamList: res.data
}
const res2 = await updateTeamProjectApi(params)
console.log('🚀 ~ getUserInfoByIdCard ~ res2:', res2)
}
} catch (error) {
console.log('🚀 ~ getUserInfoByIdCard ~ error:', error)
}
},
// end
2025-03-25 14:31:14 +08:00
},
2025-07-04 15:11:51 +08:00
async created() {
2025-03-26 16:59:45 +08:00
this.queryDate = this.getDefaultDateRange()
2025-03-25 14:31:14 +08:00
this.getCompanyAndProjectFun()
2025-03-25 18:48:55 +08:00
this.getCardListFun()
this.getPie_1DataFun()
2025-07-04 15:11:51 +08:00
await Promise.all([this.getUserInfoByUserName(), this.projectInfoList()])
this.getUserInfoByIdCard()
}
}
</script>
<style scoped lang="scss">
// 卡片区样式
.card-box {
display: flex;
2025-03-24 15:13:26 +08:00
.title-card {
padding: 16px 0;
margin-right: 14px;
writing-mode: vertical-rl;
letter-spacing: 4px;
font-size: 14px;
}
.card-box-content-1 {
flex: 1;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
margin-right: -12px;
.card-box-space-last {
grid-column: span 2;
display: grid;
grid-template-columns: repeat(3, 1fr);
align-items: center;
gap: 6px;
2025-03-25 14:37:36 +08:00
margin-right: -6px;
}
}
.card-box-content {
flex: 1;
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 12px;
2025-03-25 14:37:36 +08:00
margin-right: -18px;
}
}
// 图表区样式
.chart-box {
width: 100%;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 12px;
}
2025-03-25 16:52:07 +08:00
::v-deep .vue-treeselect__control {
height: 30px;
}
</style>