You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

420 lines
11 KiB
Vue

<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="选择巷道" prop="srmNumber">
<el-select
v-model="queryParams.streetId"
placeholder="请选择巷道"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
>
<el-option
v-for="dict in streetList"
:key="dict.id"
:label="dict.name"
:value="dict.id"
/>
</el-select>
</el-form-item>
<el-form-item label="方向" prop="fromDirection">
<el-select
v-model="queryParams.direction"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.DIRECTION)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item ><el-button @click="handleQuery" type="primary">搜索</el-button></el-form-item>
</el-form>
</ContentWrap>
<!-- 按钮墙 -->
<ContentWrap>
<!-- 按钮墙 -->
<el-tabs :tab-position="top" style="height: 100%" class="demo-tabs">
<el-tab-pane v-for="(item, index) in columnMap" :key="index" :label="item">
<el-row v-for="(row, rowIndex) in rows" :key="'row-' + rowIndex">
<el-col :span="1">{{ row + "层" }}</el-col>
<el-col :span="1" v-for="(colum, colIndex) in columnLists[index]" :key="'col-' + colIndex">
<el-button
style="width: 90%;"
:type="getButtonType(row, colum)"
:key="'button-' + colIndex"
:disabled="isDisabled(row, colum)"
@click="getDialogVisible(row, colum)"
>
{{ row + "-" + colum }}
</el-button>
</el-col>
</el-row>
</el-tab-pane>
</el-tabs>
</ContentWrap>
<ContentWrap v-if="f">
<el-row :gutter="20">
<el-col style="height: 30vh;" :span="5">
<el-card style="height: 100%;" shadow="always">
<p>统计信息:</p>
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<Echart style="height:200px;" :options="option" />
</el-card>
</el-col>
<el-col style="height: 30vh;" :span="18">
<el-card style="height: 100%;" shadow="always">
<div style="width: 100%;height: 100%;">
<!-- 为 ECharts 准备一个定义了宽高的 DOM -->
<!-- 遍历 Map 中的每个 key-value 对 -->
<!-- 遍历 Map 中的每个 key-value 对 -->
<div v-for="(title) in buttonByObjectMap.keys()" :key="title">
<!-- 标题 -->
<h4>{{ title }}</h4>
<!-- 遍历每个标题下的按钮数组 -->
<el-space :size="size" :spacer="spacer">
<div
class="mb-15px"
style="width: 5%;" v-for="(button, index) in buttonByObjectMap.get(title)" :key="index">
<el-button
:type="getButtonType(button.row, button.column)"
:key="'button2-' + index"
:disabled="isDisabled(button.row, button.column)"
@click="getDialogVisible(button.row, button.column)"
>
{{ button.row }}-{{ button.column }}
</el-button>
</div>
</el-space>
</div>
</div>
</el-card>
</el-col>
</el-row>
</ContentWrap>
<el-dialog
v-model="dialogVisible"
:title="getStreetName()+getDirectionName()+'侧'+rowName+'层'+columnName+'列'"
width="40%"
@close="handleClose"
>
<stock :stockId="getStockId()" :key="getStockId()"/>
</el-dialog>
</template>
<script setup lang="ts">
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
import { StreetApi,StreetVO } from '@/api/logistics/street'
import { StockApi,StockVO } from '@/api/logistics/stock'
import stock from '@/views/logistics/stock/stock.vue'
import { forEach } from 'lodash-es'
import { EChartsOption } from 'echarts'
import { log } from 'console'
import Cookies from 'js-cookie';
const message = useMessage() //
const { t } = useI18n() // ist
let rows = ref(12);
let columns = ref(48);
//
const rowMax = ref(20);
const columnMax = ref(20);
const columnList = ref<number[]>([]);
const rowName = ref("")
const columnName = ref("")
const currentStockId =ref(0)
let columnMap = ref<String[]>([]);
const buttons = ref<ButtonVo[]>([]);
const dialogVisible = ref(false)
const getDialogVisible = (row,colum) => {
clearTimer()
rowName.value = row
columnName.value = colum
dialogVisible.value = true
}
// 从 Cookie 加载 queryParams
const loadQueryParamsFromCookie = () => {
const savedQueryParams = Cookies.get('queryParams');
if (savedQueryParams) {
const parsedParams = JSON.parse(savedQueryParams);
Object.assign(queryParams, parsedParams); // 更新 reactive 对象
}
};
const columnLists = computed(() => {
return columnMap.value.map((_, index) => {
const minIndex = index * columnMax.value + 1;
const maxIndex = (index + 1) * columnMax.value < columns.value ? (index + 1) * columnMax.value : columns.value;
const columnList = [];
for (let i = minIndex; i <= maxIndex; i++) {
columnList.push(i);
}
return columnList;
});
});
const loading = ref(true) // 列表的加载中
const total = ref(0) // 列表的总页数
const queryParams = reactive({
streetId: 1,
direction: 1
})
interface ButtonVo {
id?: number; // 可选,因为可能是新创建的对象
streetId?: number;
orderNum?: string;
lotnum?: string;
checkNum?: string;
code?: string;
category?: string;
count?: number;
wmsCode?: string;
wmsCategory?: string;
wmsCount?: number;
wmsTrayCode?: string;
trayCode?: string;
direction?: number;
side?: number;
row?: number;
column?: number;
status?: string;
preoperationPic?: string;
overoperationPic?: string;
storageCode?: string;
checkPic?: string;
exportTime?: Date;
subtag?: string;
reply?: string;
taskWmsId?: string;
addre?: string;
checkId?: number;
statusVision?: string;
}
// 将 queryParams 存入 Cookie
const saveQueryParamsToCookie = () => {
Cookies.set('queryParams', JSON.stringify(queryParams), { expires: 7 }); // 设置有效期为 7 天
};
/** 搜索按钮操作 */
const handleQuery = async () => {
columnMap.value = []
const data = await StockApi.getStreetList(queryParams)
saveQueryParamsToCookie()
getStreetStatus()
rows = ref(data.rows)
columns =ref(data.columns)
const page = columns.value/columnMax.value
for(var i = 0; i <= page; i++){
columnMap.value.push(i*columnMax.value+1+"-"+((i+1)*columnMax.value<columns.value?(i+1)*columnMax.value:columns.value))
}
}
const handleClose = () => {
dialogVisible.value = false
startTimer()
}
const isDisabled = (row: number, column: number): boolean => {
return !buttonMap.value.has(`${row}-${column}`);
};
const getStockId = (): string => {
return buttonByIdMap.value.get(`${rowName.value}-${columnName.value}`) ||"";
};
const getButtonType = (row: number, column: number): string => {
return buttonMap.value.get(`${row}-${column}`) ||"";
};
const handleReset = (index) => {
columnList.value = []
const minIndex = (index) *columnMax.value +1
const maxIndex = (index+1) * (columnMax.value)<columns.value?(index+1) * (columnMax.value):columns.value
for(var i = minIndex; i <= maxIndex; i++){
columnList.value.push(i)
}
return columnList
}
// getStreetStatus
const buttonMap = ref(new Map<string, string>());// 存储 row-column 到 status 的映射
// getStreetStatus
const buttonByIdMap = ref(new Map<string, string>());// 存储 row-column 到 stockId 的映射
const buttonByStatusMap = ref(new Map<string, number>());// 存储 row-column 到 statusString 的映射
const buttonByObjectMap = ref(new Map<string, Array<object>>());
const getStreetStatus = async () => {
buttonMap.value = new Map()
buttonByIdMap.value = new Map()
buttonByStatusMap.value = new Map()
buttonByObjectMap.value = new Map()
const data = await StockApi.getStreetStatus(queryParams)
for(var i = 0; i < data.length; i++){
buttonMap.value.set(`${data[i].row}-${data[i].column}`, data[i].colour)
buttonByIdMap.value.set(`${data[i].row}-${data[i].column}`, data[i].id)
if(buttonByStatusMap.value.has(data[i].statusString)){
buttonByStatusMap.value.set(data[i].statusString, buttonByStatusMap.value.get(data[i].statusString)!+1)
buttonByObjectMap.value.get(data[i].statusString)?.push(data[i])
}else{
buttonByStatusMap.value.set(data[i].statusString, 1)
buttonByObjectMap.value.set(data[i].statusString, [data[i]])
}
}
console.log(buttonByObjectMap.value);
}
// 监听 buttonByStatusMap 的变化
watch(buttonByStatusMap, (newMap) => {
const echartData = Array.from(newMap, ([name, value]) => ({ name, value }))
option.series[0].data = echartData
}, { deep: true })
const streetList = ref<StreetVO[]>([]) // 巷道队列
const getStreetName = ()=>{
return streetList.value.find(item => item.id === queryParams.streetId)?.name
}
const getDirectionName = ()=>{
return getIntDictOptions(DICT_TYPE.DIRECTION).find(item => item.value === queryParams.direction)?.label
}
/** 查询巷道列表 */
const getStringList = () => {
try {
const data = StreetApi.getStreetList()
data.then((res)=>{
streetList.value = res
})
} finally {
}
}
// 构造 ECharts 数据,使用 statusString 作为 name
const echartData =(()=>{
return Array.from(buttonByStatusMap.value, ([name, value]) => ({ name, value }));
}
);
// 定时器相关
let timer: NodeJS.Timeout | null = null
const startTimer = () => {
timer = setInterval(() => {
// 在这里添加定时执行的逻辑
// 例如,每秒更新一次数据
getStreetStatus()
}, 15000) // 每秒执行一次
}
const clearTimer = () => {
if (timer) {
clearInterval(timer)
timer = null
}
}
// 构造 ECharts 数据,使用 statusString 作为 name
const option = reactive({
tooltip: {
trigger: 'item'
},
legend: {
top: '5%',
left: 'center'
},
series: [
{
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: 20,
fontWeight: 'bold'
}
},
labelLine: {
show: false
}, // 自定义颜色
normal: {
color: function(params) {
// 可以根据params.name来返回不同的颜色
const colorList = ['#87cefa', '#da70d6', '#32cd32', '#ff6347'];
return colorList[params.dataIndex]; // 根据数据项的index分配颜色
}
},
data: echartData()
}
]
});
/** 初始化 **/
onMounted(() => {
handleQuery()
getStringList()
loadQueryParamsFromCookie()
startTimer() // 启动定时器
handleReset(0)
})
onUnmounted(() => {
clearTimer() // 清除定时器
})
</script>