parent
31b5532801
commit
189d56b9d1
@ -0,0 +1,28 @@ |
||||
import { AxiosPromise } from "axios"; |
||||
import request from "@/utils/request"; |
||||
import { ReportBasicQuery, ReportDetailPageResult } from "@/api/report/types"; |
||||
|
||||
export function reportArea(groupId?: number): AxiosPromise<OptionType[]> { |
||||
return request({ |
||||
url: `/api/domain/v1/report-area/options/${groupId}`, |
||||
method: "GET", |
||||
}); |
||||
} |
||||
|
||||
export function reportDetailPage( |
||||
data: ReportBasicQuery |
||||
): AxiosPromise<ReportDetailPageResult> { |
||||
return request({ |
||||
url: `/api/report/v1/detail-inventory-statistics`, |
||||
method: "POST", |
||||
data, |
||||
}); |
||||
} |
||||
export function reportExportDetail(queryParams: ReportBasicQuery) { |
||||
return request({ |
||||
url: `/api/report/v1/_export`, |
||||
method: "get", |
||||
params: queryParams, |
||||
responseType: "arraybuffer", |
||||
}); |
||||
} |
@ -0,0 +1,61 @@ |
||||
export interface ReportBasicQuery extends PageQuery { |
||||
area?: number; |
||||
|
||||
subarea?: number; |
||||
|
||||
category?: string; |
||||
|
||||
devName?: string; |
||||
|
||||
accessType?: string; |
||||
|
||||
devType?: string; |
||||
|
||||
gateWayType?: string; |
||||
|
||||
firstStartTime?: string; |
||||
|
||||
firstEndTime?: string; |
||||
|
||||
lastStartTime?: string; |
||||
|
||||
lastEndTime?: string; |
||||
|
||||
onLineStartTime?: string; |
||||
|
||||
onLineEndTime?: string; |
||||
} |
||||
export interface DetailInventoryStatisticsVO { |
||||
area?: String; |
||||
|
||||
subArea?: string; |
||||
|
||||
devId?: string; |
||||
|
||||
category?: string; |
||||
|
||||
devName?: string; |
||||
|
||||
oui?: string; |
||||
|
||||
devSno?: string; |
||||
|
||||
devHard?: string; |
||||
|
||||
devSoft?: string; |
||||
|
||||
gateWayType?: string; |
||||
|
||||
sno?: string; |
||||
|
||||
pppoe?: string; |
||||
|
||||
createTime?: string; |
||||
|
||||
modifyTime?: string; |
||||
|
||||
onLineTime?: string; |
||||
|
||||
rgMode?: string; |
||||
} |
||||
export type ReportDetailPageResult = PageResult<DetailInventoryStatisticsVO[]>; |
@ -1,27 +1,472 @@ |
||||
<template> |
||||
<div class="app-container"></div> |
||||
<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> <span |
||||
style="font-weight: 700; font-size: 14px; line-height: 16px" |
||||
>详细清单统计</span |
||||
> |
||||
</div> |
||||
<el-button type="primary" @click="getData">运行报表</el-button> |
||||
</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="subarea"> |
||||
<el-select v-model="queryForm.subarea"> |
||||
<el-option |
||||
v-for="item in subareaOption" |
||||
: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="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="accessType"> |
||||
<dictionary |
||||
v-model="queryForm.accessType" |
||||
type-code="dev_access_type" |
||||
/> |
||||
</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" |
||||
> |
||||
<el-form-item prop="gateWayType"> |
||||
<dictionary |
||||
v-model="queryForm.gateWayType" |
||||
type-code="dev_type_name_new" |
||||
/> |
||||
</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="firstStartTime"> |
||||
<el-date-picker |
||||
style="width: 230px" |
||||
v-model="queryForm.firstStartTime" |
||||
type="datetime" |
||||
value-format="YYYY-MM-DD hh:mm:ss" |
||||
/> |
||||
</el-form-item> |
||||
<span |
||||
style="line-height: 35px; margin-right: 5px; margin-left: 5px" |
||||
>至</span |
||||
> |
||||
<el-form-item prop="firstEndTime"> |
||||
<el-date-picker |
||||
style="width: 235px" |
||||
v-model="queryForm.firstEndTime" |
||||
type="datetime" |
||||
value-format="YYYY-MM-DD hh:mm:ss" |
||||
/> |
||||
</el-form-item> |
||||
</div> |
||||
</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="lastStartTime"> |
||||
<el-date-picker |
||||
style="width: 230px" |
||||
v-model="queryForm.lastStartTime" |
||||
type="datetime" |
||||
/> |
||||
</el-form-item> |
||||
<span |
||||
style="line-height: 35px; margin-right: 5px; margin-left: 5px" |
||||
>至</span |
||||
> |
||||
<el-form-item prop="lastEndTime"> |
||||
<el-date-picker |
||||
style="width: 235px" |
||||
v-model="queryForm.lastEndTime" |
||||
type="datetime" |
||||
/> |
||||
</el-form-item> |
||||
</div> |
||||
</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> <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="area" |
||||
align="center" |
||||
fixed |
||||
width="100" |
||||
/> |
||||
<el-table-column |
||||
label="区局" |
||||
prop="subArea" |
||||
align="center" |
||||
width="150" |
||||
/> |
||||
<el-table-column |
||||
label="厂商" |
||||
prop="category" |
||||
align="center" |
||||
width="150" |
||||
show-overflow-tooltip |
||||
/> |
||||
<el-table-column |
||||
label="设备型号" |
||||
prop="oui" |
||||
align="center" |
||||
width="100" |
||||
/> |
||||
<el-table-column |
||||
label="设备序列号" |
||||
prop="devSno" |
||||
align="center" |
||||
width="200" |
||||
/> |
||||
<el-table-column |
||||
label="硬件版本" |
||||
prop="devHard" |
||||
align="center" |
||||
width="150" |
||||
/> |
||||
<el-table-column |
||||
label="软件版本" |
||||
prop="devSoft" |
||||
align="center" |
||||
width="200" |
||||
/> |
||||
<el-table-column |
||||
label="网关类型" |
||||
prop="gateWayType" |
||||
align="center" |
||||
width="100" |
||||
/> |
||||
<el-table-column |
||||
label="接入类型" |
||||
prop="rgMode" |
||||
align="center" |
||||
width="100" |
||||
/> |
||||
<el-table-column |
||||
label="逻辑ID" |
||||
prop="sno" |
||||
align="center" |
||||
width="150" |
||||
/> |
||||
<el-table-column |
||||
label="宽带账号" |
||||
prop="pppoe" |
||||
align="center" |
||||
width="150" |
||||
/> |
||||
<el-table-column |
||||
label="首次装机时间" |
||||
prop="createTime" |
||||
width="200" |
||||
align="center" |
||||
/> |
||||
<el-table-column |
||||
label="最近一次装机时间" |
||||
prop="modifyTime" |
||||
width="200" |
||||
align="center" |
||||
/> |
||||
<el-table-column |
||||
label="最近一次上线时间" |
||||
prop="onLineTime" |
||||
width="200" |
||||
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 { |
||||
DetailInventoryStatisticsVO, |
||||
ReportBasicQuery, |
||||
} from "@/api/report/types"; |
||||
import { reportArea, reportDetailPage, reportExportDetail } from "@/api/report"; |
||||
import { getTypeNameOption, getVendorNameOption } from "@/api/device-type"; |
||||
import { confirm } from "@/utils/confirm"; |
||||
|
||||
defineOptions({ |
||||
name: "DetailInventoryStatistics", |
||||
inheritAttrs: false, |
||||
}); |
||||
const queryForm = ref<SelectForm>({ |
||||
const queryForm = ref<ReportBasicQuery>({ |
||||
pageNum: 1, |
||||
pageSize: 10, |
||||
}); |
||||
const options = ref<OptionType[]>([ |
||||
{ label: "客户名称", value: "customName" }, |
||||
{ label: "系统管理域", value: "regionAreaId" }, |
||||
]); |
||||
const buttonColSpan = computed(() => { |
||||
return queryForm.value.selectName === undefined ? 18 : 12; |
||||
}); |
||||
const resetSelect = () => { |
||||
queryForm.value.selectValue = undefined; |
||||
const active = ref<number>(0); |
||||
const areaOption = ref<OptionType[]>([{ label: "全省", value: 0 }]); |
||||
const subareaOption = ref<OptionType[]>([]); |
||||
const vendorNameOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]); |
||||
const typeNameOption = ref<OptionType[]>([{ label: "全选", value: "-1" }]); |
||||
const tableData = ref<DetailInventoryStatisticsVO[]>([]); |
||||
const loading = ref<boolean>(false); |
||||
const total = ref<number>(0); |
||||
watch( |
||||
() => queryForm.value.area, |
||||
() => { |
||||
if (queryForm.value.area === undefined) { |
||||
return; |
||||
} |
||||
loadSubarea(queryForm.value.area); |
||||
} |
||||
); |
||||
const getData = () => { |
||||
active.value = 1; |
||||
loading.value = true; |
||||
reportDetailPage(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 loadSubarea = (groupId: number) => { |
||||
reportArea(groupId).then(({ data }) => { |
||||
subareaOption.value = 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; |
||||
reportExportDetail(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(); |
||||
}); |
||||
</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> |
||||
|
@ -1,6 +1,23 @@ |
||||
<template> |
||||
<div> |
||||
<router-view /> |
||||
</div> |
||||
<router-view> |
||||
<template #default="{ Component, route }"> |
||||
<transition |
||||
enter-active-class="animate__animated animate__fadeIn" |
||||
mode="out-in" |
||||
> |
||||
<keep-alive :include="cachedViews"> |
||||
<component :is="Component" :key="route.path" /> |
||||
</keep-alive> |
||||
</transition> |
||||
</template> |
||||
</router-view> |
||||
</template> |
||||
<script setup lang="ts"></script> |
||||
|
||||
<script setup lang="ts"> |
||||
import { useTagsViewStore } from "@/store"; |
||||
defineOptions({ |
||||
name: "Statement", |
||||
inheritAttrs: false, |
||||
}); |
||||
const cachedViews = computed(() => useTagsViewStore().cachedViews); // 缓存页面集; |
||||
</script> |
||||
|
Loading…
Reference in new issue