feat: 软件版本归并率统计

master
李小林 7 months ago
parent 6d8aa3d71d
commit 8601505e6e
  1. 6
      src/api/device-type-ver/index.ts
  2. 22
      src/api/report/index.ts
  3. 37
      src/api/report/types.ts
  4. 372
      src/views/family/statement/soft-merge-statistics/index.vue

@ -166,3 +166,9 @@ export function getSoftVerOption(): AxiosPromise<OptionType[]> {
method: "GET",
});
}
export function getMergeSoftVerOption(): AxiosPromise<OptionType[]> {
return request({
url: `/api/device-type-ver/v1/merge-soft-ver-option`,
method: "GET",
});
}

@ -4,7 +4,7 @@ import {
DeviceTypeHardSoftReportQuery,
DeviceTypeHardSoftVerVO,
ReportBasicQuery,
ReportDetailPageResult,
ReportDetailPageResult, SoftMergePageResult, SoftMergeReportQuery,
TerminalCapabilityStatisticsVO
} from "@/api/report/types";
@ -60,7 +60,7 @@ export function reportDevTypeSoftVerStatistics(
}
export function reportExportDeviceTypeHardSoftVer(
queryParams: ReportBasicQuery
queryParams: DeviceTypeHardSoftReportQuery
) {
return request({
url: `/api/report/v1/_export/device-type-soft-ver`,
@ -69,3 +69,21 @@ export function reportExportDeviceTypeHardSoftVer(
responseType: "arraybuffer",
});
}
export function reportSoftVerMergeStatistics(
data: SoftMergeReportQuery
): AxiosPromise<SoftMergePageResult> {
return request({
url: `/api/report/v1/device-type-soft-merge`,
method: "POST",
data,
});
}
export function exportSoftMergeVer(queryParams: SoftMergeReportQuery) {
return request({
url: `/api/report/v1/_export/soft-ver-merge`,
method: "get",
params: queryParams,
responseType: "arraybuffer",
});
}

@ -104,7 +104,7 @@ export interface DeviceTypeHardSoftReportQuery extends PageQuery {
onLineEndTime?: string;
}
export interface DeviceTypeHardSoftVerVO {
area?: String;
area?: string;
subArea?: string;
@ -118,3 +118,38 @@ export interface DeviceTypeHardSoftVerVO {
devCount?: number;
}
export interface SoftMergeReportQuery extends PageQuery {
area?: number;
devName?: string;
devType?: string;
devHardVer?: string;
category?: string;
softVer?: string;
onLineStartTime?: string;
onLineEndTime?: string;
}
export interface SoftVerMergeVO {
category?: string;
devName?: string;
devHard?: string;
hardCount?: number;
softVer?: string;
softCount?: string;
devType?: string;
softAvg?: string;
}
export type SoftMergePageResult = PageResult<SoftVerMergeVO[]>;

@ -0,0 +1,372 @@
<template>
<div class="app-container">
<el-card v-show="active === 0" shadow="never">
<template #header>
<div class="flex justify-between">
<div style="display: flex; align-items: center">
<el-icon size="15"><Grid /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>详细清单统计</span
>
</div>
<div>
<el-button type="primary" @click="getData">运行报表</el-button>
<el-button
type="primary"
v-if="tableData.length != 0"
@click="active = 1"
>查看报表
</el-button>
</div>
</div>
</template>
<div>
<el-form :model="queryForm">
<el-descriptions :column="2" border>
<el-descriptions-item
label="分公司"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="area">
<el-select v-model="queryForm.area">
<el-option
v-for="item in areaOption"
:label="item.label"
:value="item.value"
:key="item.value"
/>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="设备厂商"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="category">
<el-select v-model="queryForm.category" filterable>
<el-option
v-for="item in vendorNameOption"
:label="item.label"
:value="item.value"
:key="item.value"
/>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="设备硬件版本"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="devHardVer">
<el-select v-model="queryForm.devHardVer" filterable>
<el-option
v-for="item in devHardVerOption"
:label="item.label"
:value="item.value"
:key="item.value"
/>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="归并软件版本"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="softVer">
<el-select v-model="queryForm.softVer" filterable>
<el-option
v-for="item in softVerOption"
:label="item.label"
:value="item.value"
:key="item.value"
/>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="终端型号"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="devName">
<el-select v-model="queryForm.devName" filterable>
<el-option
v-for="item in typeNameOption"
:label="item.label"
:value="item.value"
:key="item.value"
/>
</el-select>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="设备类型"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-form-item prop="devType">
<dictionary
v-model="queryForm.devType"
type-code="dev_type_name"
/>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item
label="最近一次上线时间"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div class="flex justify-between" style="width: 160px">
<el-form-item prop="onLineStartTime">
<el-date-picker
style="width: 230px"
v-model="queryForm.onLineStartTime"
type="datetime"
/>
</el-form-item>
<span
style="line-height: 35px; margin-right: 5px; margin-left: 5px"
></span
>
<el-form-item prop="onLineEndTime">
<el-date-picker
style="width: 235px"
v-model="queryForm.onLineEndTime"
type="datetime"
/>
</el-form-item>
</div>
</el-descriptions-item>
</el-descriptions>
</el-form>
</div>
</el-card>
<el-card v-show="active === 1" shadow="never">
<template #header>
<div class="flex justify-between">
<div style="display: flex; align-items: center">
<el-icon size="15"><Grid /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备信息列表</span
>
</div>
<div>
<el-button type="primary" @click="exportDetail">导出报表</el-button>
<el-button type="primary" @click="back">返回</el-button>
</div>
</div>
</template>
<div class="any-table">
<el-table
:data="tableData"
v-loading="loading"
style="width: 100%"
max-height="450"
border
>
<el-table-column
label="设备类型"
prop="devType"
align="center"
/>
<el-table-column
label="厂商"
prop="category"
align="center"
show-overflow-tooltip
/>
<el-table-column
label="设备型号"
prop="devName"
align="center"
/>
<el-table-column
label="硬件版本"
prop="devHard"
align="center"
/>
<el-table-column
label="归并版本"
prop="softVer"
align="center"
/>
<el-table-column
label="终端数量"
prop="hardCount"
align="center"
/>
<el-table-column
label="归并版本数"
prop="softCount"
align="center"
/>
<el-table-column
label="归并率"
prop="softAvg"
align="center"
/>
</el-table>
<pagination
v-if="total > 0"
v-model:total="total"
v-model:page="queryForm.pageNum"
v-model:limit="queryForm.pageSize"
@pagination="getData"
/>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { Grid } from "@element-plus/icons-vue";
import { SoftMergeReportQuery, SoftVerMergeVO } from "@/api/report/types";
import {
exportSoftMergeVer,
reportArea,
reportExportDetail,
reportSoftVerMergeStatistics
} from "@/api/report";
import {
getHardVerOption,
getTypeNameOption,
getVendorNameOption,
} from "@/api/device-type";
import { confirm } from "@/utils/confirm";
import { getMergeSoftVerOption } from "@/api/device-type-ver";
defineOptions({
name: "SoftMergeStatistics",
inheritAttrs: false,
});
const queryForm = ref<SoftMergeReportQuery>({
pageNum: 1,
pageSize: 10,
});
const active = ref<number>(0);
const areaOption = ref<OptionType[]>([{ label: "全省", value: 0 }]);
const vendorNameOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]);
const typeNameOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]);
const devHardVerOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]);
const softVerOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]);
const tableData = ref<SoftVerMergeVO[]>([]);
const loading = ref<boolean>(false);
const total = ref<number>(0);
const getData = () => {
active.value = 1;
loading.value = true;
reportSoftVerMergeStatistics(queryForm.value)
.then(({ data }) => {
tableData.value = data.list;
total.value = data.total;
})
.finally(() => {
loading.value = false;
});
};
const back = () => {
active.value = 0;
};
const loadVendorNameOption = () => {
getVendorNameOption().then(({ data }) => {
vendorNameOption.value.push(...data);
});
};
const loadHardVerOption = async () => {
await getHardVerOption("").then(({ data }) => {
devHardVerOption.value.push(...data);
});
};
const loadSoftVerOption = async () => {
await getMergeSoftVerOption().then(({ data }) => {
softVerOption.value.push(...data);
});
};
const loadTypeNameOption = () => {
getTypeNameOption("").then(({ data }) => {
typeNameOption.value.push(...data);
});
};
const loadArea = (groupId: number) => {
reportArea(groupId).then(({ data }) => {
areaOption.value.push(...data);
});
};
const exportDetail = () => {
confirm("确认导出该数据吗", () => {
loading.value = true;
exportSoftMergeVer(queryForm.value)
.then((response: any) => {
const fileData = response.data;
const fileName = decodeURI(
response.headers["content-disposition"].split(";")[1].split("=")[1]
);
const fileType =
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
const blob = new Blob([fileData], { type: fileType });
const downloadUrl = window.URL.createObjectURL(blob);
const downloadLink = document.createElement("a");
downloadLink.href = downloadUrl;
downloadLink.download = fileName;
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
window.URL.revokeObjectURL(downloadUrl);
})
.finally(() => {
loading.value = false;
});
});
};
onMounted(() => {
loadArea(0);
loadVendorNameOption();
loadTypeNameOption();
loadHardVerOption();
loadSoftVerOption();
});
</script>
<style scoped lang="scss">
:deep(.my-label) {
width: 50px !important;
background: var(--el-color-white) !important;
}
:deep(.el-card__body) {
padding: 10px 5px;
}
:deep(.el-form-item--default) {
margin-bottom: 0;
}
</style>
Loading…
Cancel
Save