feat: 远程操作、任务列表、样式更换

master
李小林 8 months ago
parent 8da55c377e
commit 832bf3bf66
  1. 14
      src/api/device-type-ver/index.ts
  2. 9
      src/api/device-type-ver/types.ts
  3. 9
      src/api/operate-task2/index.ts
  4. 80
      src/api/remote/index.ts
  5. 22
      src/api/remote/types.ts
  6. BIN
      src/assets/logo.png
  7. 2
      src/layout/components/NavBar/index.vue
  8. 10
      src/layout/components/TagsView/index.vue
  9. 50
      src/router/index.ts
  10. 2
      src/settings.ts
  11. 5
      src/styles/index.scss
  12. 6
      src/styles/variables.scss
  13. 3
      src/utils/index.ts
  14. 41
      src/views/dashboard/index.vue
  15. 18
      src/views/family/operate/remote-operation/components/DeviceAbility.vue
  16. 118
      src/views/family/operate/remote-operation/components/DeviceMonitoring.vue
  17. 8
      src/views/family/operate/remote-operation/components/DeviceOperateLog.vue
  18. 8
      src/views/family/operate/remote-operation/components/DeviceOrder.vue
  19. 183
      src/views/family/operate/remote-operation/components/DeviceSpeed.vue
  20. 11
      src/views/family/operate/remote-operation/components/DeviceStatus.vue
  21. 8
      src/views/family/operate/remote-operation/components/DeviceTypeVersionLog.vue
  22. 142
      src/views/family/operate/remote-operation/components/Ping.vue
  23. 9
      src/views/family/operate/remote-operation/components/Profiles.vue
  24. 14
      src/views/family/operate/remote-operation/components/RemoteOperateInfo.vue
  25. 162
      src/views/family/operate/remote-operation/components/RemoteOperateList.vue
  26. 8
      src/views/family/operate/remote-operation/components/SoapPackageLog.vue
  27. 8
      src/views/family/operate/remote-operation/components/TerminalLogFiles.vue
  28. 109
      src/views/family/operate/remote-operation/components/UpgradeSoftVer.vue
  29. 76
      src/views/family/operate/task/index.vue
  30. 2
      src/views/system/user/index.vue

@ -2,8 +2,10 @@ import {
BindingTr069Form,
DeviceTypeToVerPageResult,
DeviceTypeToVerQuery,
DeviceTypeVerForm, DevVerServicePageResult,
GroupNamePageResult
DeviceTypeVerForm,
DevVerServicePageResult,
GroupNamePageResult,
SoftVersionUpgradeVO,
} from "@/api/device-type-ver/types";
import request from "@/utils/request";
import { AxiosPromise } from "axios";
@ -150,3 +152,11 @@ export function tr069BindingDevType(data: BindingTr069Form) {
data,
});
}
export function upgradeSoftVerTable(
devId: number
): AxiosPromise<SoftVersionUpgradeVO[]> {
return request({
url: `/api/device-type-ver/v1/upgrade-soft-ver/${devId}`,
method: "GET",
});
}

@ -47,3 +47,12 @@ export interface BindingTr069Form {
tr069VerId?: number;
}
export interface SoftVersionUpgradeVO {
typeAndVerId?: number;
fileId?: number;
softVer?: string;
devTypeVerDesc?: string;
}

@ -15,3 +15,12 @@ export function operateTask2Page(
data,
});
}
export function taskTablePage(
data?: PageQuery
): AxiosPromise<OperateTask2PageResult> {
return request({
url: `/api/operate-task2/v1/task-page`,
method: "POST",
data,
});
}

@ -1,9 +1,11 @@
import request from "@/utils/request";
import { AxiosPromise } from "axios";
import {
DeviceMonitorForm,
PingForm,
RemoteDevInfoVO,
RemoteOperateResult,
UnBindingForm,
RemoteOperateResult, SpeedInfo,
UnBindingForm
} from "@/api/remote/types";
import { DeviceLinkVO } from "@/api/operate-log/types";
import { FTTRInfoVO, ServiceCompareVO } from "@/api/operate-result-args/types";
@ -76,3 +78,77 @@ export function remoteFTTRSubGateway(devId: number) {
method: "GET",
});
}
export function remoteIpPing(data: PingForm) {
return request({
url: `/api/equipment/v1/remote/ip-ping`,
method: "POST",
data,
});
}
export function remoteUploadConfig(devId: number) {
return request({
url: `/api/equipment/v1/remote/upload-config/${devId}`,
method: "GET",
});
}
export function remoteUploadLog(devId: number) {
return request({
url: `/api/equipment/v1/remote/upload-log/${devId}`,
method: "GET",
});
}
export function remoteReboot(devId: number) {
return request({
url: `/api/equipment/v1/remote/reboot/${devId}`,
method: "GET",
});
}
export function remoteFactoryReset(devId: number) {
return request({
url: `/api/equipment/v1/remote/factory-reset/${devId}`,
method: "GET",
});
}
export function remoteDeviceMonitor(data: DeviceMonitorForm) {
return request({
url: `/api/equipment/v1/remote/device-monitor`,
method: "POST",
data,
});
}
export function getSpeedInfo(devId: number): AxiosPromise<SpeedInfo> {
return request({
url: `/api/speed/v1/speed-info/${devId}`,
method: "get",
});
}
export function remoteCheckConnType(devId: number): AxiosPromise<string> {
return request({
url: `/api/equipment/v1/remote/check-conn-type/${devId}`,
method: "GET",
});
}
export function tr143Speed(
devId: number,
downloadUrl: string
): AxiosPromise<RemoteOperateResult> {
return request({
url: `/api/equipment/v1/remote/tr143-speed/${devId}`,
method: "GET",
params: { downloadUrl },
});
}
export function remoteSoftVerUpgrade(devId: number, fileId?: number) {
return request({
url: `/api/equipment/v1/remote/soft-version-upgrade/${devId}/${fileId}`,
method: "GET",
});
}
export function remoteOpenRegister(devId: number, fileId?: number) {
return request({
url: `/api/equipment/v1/remote/register/${devId}`,
method: "GET",
});
}

@ -64,6 +64,24 @@ export interface DeviceInfo {
devTypeNameDetail?: string;
}
export interface RemoteOperateResult {
resultState?: string;
resultCode?: string;
resultState: string;
resultCode: string;
}
export interface PingForm {
deviceId?: number;
host?: string;
pingNumber?: string;
packSize?: string;
pingInterface?: string;
}
export interface DeviceMonitorForm {
devId?: number;
monitorPeriod?: string;
monitorInterval?: string;
}
export interface SpeedInfo {
downloadUrls: string[];
speedMaxRate: string;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -13,6 +13,6 @@
@apply flex-x-between;
height: $navbar-height;
//background: var(--el-bg-color);
background: var(--el-bg-color);
}
</style>

@ -377,14 +377,14 @@ onMounted(() => {
width: 100%;
height: 50px;
color: #68758e;
//background-color: var(--el-bg-color);
//border: 1px solid var(--el-border-color-light);
//box-shadow: 0 1px 1px var(--el-box-shadow-light);
background-color: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
box-shadow: 0 1px 1px var(--el-box-shadow-light);
.tags-item {
display: inline-block;
padding: 3px 8px;
margin: 6px 0 0 5px;
margin: 8px 0 0 5px;
font-size: 13.5px;
//height: 32px;
line-height: 25px;
@ -397,7 +397,7 @@ onMounted(() => {
}
&:first-of-type {
margin-left: 10px;
margin-left: 5px;
}
&:last-of-type {

@ -321,6 +321,56 @@ export const constantRoutes: RouteRecordRaw[] = [
title: "软件版本对外接口调用信息",
},
},
{
path: "/resources/remote/ping/:devId",
name: "Ping",
component: () =>
import("@/views/family/operate/remote-operation/components/Ping.vue"),
meta: {
hidden: true,
keepAlive: true,
title: "测试Ping",
},
},
{
path: "/resources/remote/device-monitor/:devId",
name: "DeviceMonitoring",
component: () =>
import(
"@/views/family/operate/remote-operation/components/DeviceMonitoring.vue"
),
meta: {
hidden: true,
keepAlive: true,
title: "设备监控",
},
},
{
path: "/resources/remote/device-speed/:devId/:pppoe",
name: "DeviceSpeed",
component: () =>
import(
"@/views/family/operate/remote-operation/components/DeviceSpeed.vue"
),
meta: {
hidden: true,
keepAlive: true,
title: "测速操作",
},
},
{
path: "/resources/remote/upgrade-soft-ver/:devId",
name: "UpgradeSoftVer",
component: () =>
import(
"@/views/family/operate/remote-operation/components/UpgradeSoftVer.vue"
),
meta: {
hidden: true,
keepAlive: true,
title: "软件版本升级",
},
},
],
},
];

@ -12,7 +12,7 @@ const defaultSettings: AppSettings = {
size: "default",
language: "zh-cn",
themeColor: "#00C3EE",
watermarkEnabled: true,
watermarkEnabled: false,
watermarkContent: pkg.name,
};

@ -1,13 +1,14 @@
@use "./reset";
.app-container {
padding: 10px;
margin-top: 20px;
//padding: 10px;
border-radius: 8px;
}
.search-container {
padding: 18px 0 0 10px;
margin-bottom: 10px;
margin-bottom: 4px;
background-color: var(--el-bg-color-overlay);
border: 1px solid var(--el-border-color-light);
border-radius: 8px;

@ -1,11 +1,11 @@
/** 全局SCSS变量 */
:root {
--menu-background: var(--el-bg-color-page);
--menu-background: #fff;
--menu-text: #68758e;
--menu-active-text: var(--el-menu-active-color);
--menu-hover: #263445;
--sidebar-logo-background: #fff;
--sidebar-logo-background: #000;
}
/** 暗黑主题 */
@ -21,7 +21,7 @@ $menu-background: var(--menu-background); // 菜单背景色
$menu-text: var(--menu-text); // 菜单文字颜色
$menu-active-text: var(--menu-active-text); // 菜单激活文字颜色
$menu-hover: var(--menu-hover); // 菜单悬停背景色
$sidebar-logo-background: var(--el-bg-color-page); // 侧边栏 Logo 背景色
$sidebar-logo-background: #fff; // 侧边栏 Logo 背景色
$sidebar-width: 210px; // 侧边栏宽度
$sidebar-width-collapsed: 54px; // 侧边栏收缩宽度

@ -1,4 +1,6 @@
import { AxiosResponse } from "axios";
import { RouteLocationNormalizedLoaded } from "vue-router";
import { useTagsViewStore } from "@/store";
/**
* Check if an element has a class
@ -61,7 +63,6 @@ export function downloadHook(res: AxiosResponse) {
let fileName = "";
if (result) {
fileName = decodeURI(result[1]);
console.log(fileName);
}
const downloadElement = document.createElement("a");
// 创建下载的链接

@ -1,29 +1,27 @@
<template>
<div class="dashboard-container">
<el-card shadow="never">
<el-row justify="space-between">
<el-col :span="18" :xs="24">
<div class="flex h-full items-center">
<img
class="w-20 h-20 mr-5 rounded-full"
:src="userStore.user.avatar + '?imageView2/1/w/80/h/80'"
/>
<div>
<p>{{ greetings }}</p>
<p class="text-sm text-gray">
今日天气晴朗气温在15至25之间东南风
</p>
</div>
</div>
</el-col>
</el-row>
</el-card>
<div class="app-container">
<el-card shadow="never">
<el-row justify="space-between">
<el-col :span="18" :xs="24">
<div class="flex h-full items-center">
<img
class="w-20 h-20 mr-5 rounded-full"
:src="userStore.user.avatar + '?imageView2/1/w/80/h/80'"
/>
<div>
<p>{{ greetings }}</p>
<p class="text-sm text-gray">
今日天气晴朗气温在15至25之间东南风
</p>
</div>
</div>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script setup lang="ts">
defineOptions({
name: "Dashboard",
inheritAttrs: false,
@ -35,6 +33,7 @@ import AnyTable from "@/components/Table/AnyTable.vue";
const userStore = useUserStore();
const date: Date = new Date();
// eslint-disable-next-line vue/return-in-computed-property
const greetings = computed(() => {
const hours = date.getHours();
if (hours >= 6 && hours < 8) {

@ -1,11 +1,14 @@
<template>
<div style="margin-top: 10px">
<el-descriptions
title="设备能力信息"
v-loading="loadingCapability"
:column="3"
border
>
<el-descriptions v-loading="loadingCapability" :column="3" border>
<template #title>
<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>
</template>
<el-descriptions-item
label="LAN口数量"
label-align="left"
@ -133,7 +136,7 @@
label-class-name="my-label"
class-name="my-content"
width="180px"
v-if="ability.reboot == null"
v-if="ability.reboot"
>
{{ ability.reboot }}
</el-descriptions-item>
@ -144,6 +147,7 @@
<script setup lang="ts">
import { CapabilityForm } from "@/api/type-ver-ext/types";
import { getCapabilityVO } from "@/api/type-ver-ext";
import { Grid } from "@element-plus/icons-vue";
const prop = defineProps<{
typeAndVerId: number;

@ -0,0 +1,118 @@
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<div style="display: flex; align-items: center">
<el-icon><Loading /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备监控</span
>
</div>
</template>
<el-form
ref="monitorFormRef"
:model="formData"
:rules="rules"
v-loading="loading"
>
<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 style="margin-bottom: 0" prop="monitorPeriod">
<el-input
v-model="formData.monitorPeriod"
placeholder="请输入监控时长"
/>
</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 style="margin-bottom: 0" prop="monitorInterval">
<el-input
v-model="formData.monitorInterval"
placeholder="请输入采样周期"
/>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<template #footer>
<div class="flex justify-end">
<el-button type="primary" @click="submitForm(monitorFormRef)"
>确定</el-button
>
<el-button @click="resetForm(monitorFormRef)">重置</el-button>
</div>
</template>
</el-card>
</div>
</template>
<script setup lang="ts">
import { DeviceMonitorForm } from "@/api/remote/types";
import { FormInstance, FormRules } from "element-plus";
import { remoteDeviceMonitor } from "@/api/remote";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
const formData = ref<DeviceMonitorForm>({
devId: devId,
});
const loading = ref<boolean>(false);
const monitorFormRef = ref<FormInstance>();
const rules = reactive<FormRules<DeviceMonitorForm>>({
monitorInterval: [
{ required: true, message: "请输入采样周期", trigger: "blur" },
],
monitorPeriod: [
{ required: true, message: "请输入监控时长", trigger: "blur" },
],
});
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
loading.value = true;
remoteDeviceMonitor(formData.value)
.then(() => {
ElMessage({
message: "操作成功",
type: "success",
duration: 1000,
});
})
.finally(() => {
loading.value = false;
});
} else {
console.log("error submit!", fields);
}
});
};
</script>
<style scoped>
:deep(.my-label) {
width: 40px !important;
text-align: center !important;
background: var(--el-color-white) !important;
}
:deep(.el-card__body) {
padding: 10px 0 10px 0;
}
</style>

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
设备日志信息列表
<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>
</template>
@ -78,6 +81,7 @@
<script setup lang="ts">
import { DeviceLogVO } from "@/api/operate-log/types";
import { operateLogPage } from "@/api/operate-log";
import { Grid } from "@element-plus/icons-vue";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
设备工单
<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>
<table-bar :columns="columns" @change-columns="changeColumns" />
</div>
@ -144,6 +147,7 @@
<script setup lang="ts">
import { DeviceOrderQuery, OrderTableVO } from "@/api/order/types";
import { deviceOderTablePage } from "@/api/order";
import { Grid } from "@element-plus/icons-vue";
const route = useRoute();
const router = useRouter();

@ -0,0 +1,183 @@
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<div style="display: flex; align-items: center">
<el-icon><Loading /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备测速</span
>
</div>
</template>
<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"
>
{{ speedMaxRate }}
</el-descriptions-item>
<el-descriptions-item
label="上网方式"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<div v-loading="connTypeLoading">
{{ connType }}
</div>
</el-descriptions-item>
<el-descriptions-item
label="宽带账号"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
{{ pppoe }}
</el-descriptions-item>
<el-descriptions-item
label="测速服务器"
label-align="left"
align="center"
label-class-name="my-label"
class-name="my-content"
width="150px"
>
<el-select
v-model="downloadUrl"
placeholder="请选择测速服务器"
style="width: 100%"
>
<el-option
v-for="(item, index) in options"
:key="index"
:label="item"
:value="item"
/>
</el-select>
</el-descriptions-item>
</el-descriptions>
</el-card>
<el-card shadow="never">
<template #header>
<div class="flex justify-between">
<div style="display: flex; align-items: center">
<el-icon><Loading /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>设备测速进度及结果</span
>
</div>
<div>
<el-button
:disabled="loading"
@click="loadTr143Speed"
type="primary"
>开始测速</el-button
>
</div>
</div>
</template>
<div v-loading="loading">
<el-empty
v-if="result?.resultState != '2'"
:description="result?.resultCode"
/>
<div class="flex justify-center">
<el-progress
type="dashboard"
:width="200"
v-if="result?.resultState === '2'"
color="#00C3EE"
:percentage="parseFloat(result?.resultCode)"
>
<template #default="{ percentage }">
<span class="percentage-value">{{ percentage }}</span>
<span class="percentage-label">Mbit/s</span>
</template>
</el-progress>
</div>
</div>
</el-card>
</div>
</template>
<script setup lang="ts">
import { Loading } from "@element-plus/icons-vue";
import { getSpeedInfo, remoteCheckConnType, tr143Speed } from "@/api/remote";
import { RemoteOperateResult } from "@/api/remote/types";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
let pppoe: string = <string>route.params?.pppoe;
const options = ref<string[]>([]);
const downloadUrl = ref<string>("");
const speedMaxRate = ref<string>("");
const connType = ref<string>("");
const connTypeLoading = ref<boolean>(false);
const result = ref<RemoteOperateResult>({
resultState: "10",
resultCode: "暂无结果",
});
const loading = ref<boolean>(false);
const loadSpeedInfo = () => {
getSpeedInfo(devId).then(({ data }) => {
options.value = data.downloadUrls;
speedMaxRate.value = data.speedMaxRate;
if (data.downloadUrls.length != 0) {
downloadUrl.value = data.downloadUrls[0];
}
});
};
const loadConnType = () => {
connTypeLoading.value = true;
remoteCheckConnType(devId)
.then(({ data }) => {
connType.value = data;
})
.finally(() => {
connTypeLoading.value = false;
});
};
const loadTr143Speed = () => {
loading.value = true;
tr143Speed(devId, downloadUrl.value)
.then(({ data }) => {
result.value = data;
})
.finally(() => {
loading.value = false;
});
};
onMounted(() => {
loadSpeedInfo();
loadConnType();
});
</script>
<style scoped>
:deep(.my-label) {
width: 50px !important;
text-align: center !important;
background: var(--el-color-white) !important;
}
:deep(.el-card__body) {
padding: 10px 0 0 0;
}
.percentage-value {
display: block;
margin-top: 10px;
font-size: 28px;
}
.percentage-label {
display: block;
margin-top: 10px;
font-size: 20px;
}
</style>

@ -1,5 +1,13 @@
<template>
<el-descriptions title="设备状态" :column="3" border>
<el-descriptions title="" :column="3" border>
<template #title>
<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>
</template>
<el-descriptions-item
label="设备在线状态"
label-align="left"
@ -51,6 +59,7 @@ import DeviceAbility from "@/views/family/operate/remote-operation/components/De
import { DeviceInfo } from "@/api/remote/types";
import { checkDevOnline } from "@/api/remote";
import DeviceLinkInfo from "@/views/family/operate/remote-operation/components/DeviceLinkInfo.vue";
import { Grid } from "@element-plus/icons-vue";
const prop = defineProps<{
devId: number;
typeAndVerId: number;

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
设备软件版本对外接口能力调用信息
<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>
</template>
@ -32,6 +35,7 @@
<script setup lang="ts">
import { DeviceTypeVerLogVO } from "@/api/device-type-ver-log/types";
import { deviceTypeVerLogPage } from "@/api/device-type-ver-log";
import { Grid } from "@element-plus/icons-vue";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
const tableData = ref<DeviceTypeVerLogVO[]>([]);

@ -0,0 +1,142 @@
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<div style="display: flex; align-items: center">
<el-icon><Loading /></el-icon>&nbsp;<span
style="font-weight: 700; font-size: 14px; line-height: 16px"
>PING测试</span
>
</div>
</template>
<el-form
ref="pingFormRef"
:model="formData"
v-loading="loading"
:rules="rules"
>
<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="host" style="margin-bottom: 0">
<el-input v-model="formData.host" placeholder="请输入主机" />
</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="pingNumber" style="margin-bottom: 0">
<el-input
v-model="formData.pingNumber"
placeholder="请输入重复次数"
/>
</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="packSize" style="margin-bottom: 0">
<el-input
v-model="formData.packSize"
placeholder="请输入包大小"
/>
</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="pingInterface" style="margin-bottom: 0">
<dictionary
type-code="ping_interface"
placeholder="请选择接口类型"
v-model="formData.pingInterface"
/>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-form>
<template #footer>
<div class="flex justify-end">
<el-button type="primary" @click="submitForm(pingFormRef)"
>确认</el-button
>
<el-button @click="resetForm(pingFormRef)">重置</el-button>
</div>
</template>
</el-card>
</div>
</template>
<script setup lang="ts">
import { PingForm } from "@/api/remote/types";
import { FormInstance, FormRules } from "element-plus";
import { remoteIpPing } from "@/api/remote";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
const pingFormRef = ref<FormInstance>();
const loading = ref<boolean>(false);
const formData = ref<PingForm>({ deviceId: devId });
const rules = reactive<FormRules<PingForm>>({
host: [{ required: true, message: "请输入主机", trigger: "blur" }],
pingNumber: [{ required: true, message: "请输入重复次数", trigger: "blur" }],
packSize: [{ required: true, message: "请输入包大小", trigger: "blur" }],
pingInterface: [{ required: true, message: "请选择接口", trigger: "blur" }],
});
const resetForm = (formEl: FormInstance | undefined) => {
if (!formEl) return;
formEl.resetFields();
};
const submitForm = async (formEl: FormInstance | undefined) => {
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
loading.value = true;
remoteIpPing(formData.value)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
} else {
console.log("error submit!", fields);
}
});
};
</script>
<style scoped>
:deep(.my-label) {
width: 40px !important;
text-align: center !important;
background: var(--el-color-white) !important;
}
:deep(.el-card__body) {
padding: 10px 0 10px 0;
}
</style>

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
设备对应的私有厂商配置文件列表
<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="openAddProfile">
@ -65,7 +68,7 @@
</template>
<script setup lang="ts">
import { InfoFilled } from "@element-plus/icons-vue";
import { Grid, InfoFilled } from "@element-plus/icons-vue";
import { FileListVO } from "@/api/file-list/types";
import { getProfilePageData } from "@/api/file-list";
import AddProfile from "@/views/family/operate/remote-operation/components/AddProfile.vue";

@ -2,7 +2,15 @@
<div class="app-container">
<el-scrollbar height="600">
<el-card shadow="never" v-loading="loading">
<el-descriptions title="设备信息" :column="2" border>
<el-descriptions :column="2" border>
<template #title>
<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>
</template>
<template
#extra
v-if="
@ -198,7 +206,7 @@
width="150px"
>
<div class="flex justify-center">
<remote-operate-list />
<remote-operate-list :pppoe="remote.devPppoe" :dev-id="devId" />
<el-divider direction="vertical" />
<el-button type="primary" link @click="skipDevOrder"
>设备工单</el-button
@ -245,7 +253,7 @@
<script setup lang="ts">
import { DeviceInfo, RemoteDevInfoVO, UnBindingForm } from "@/api/remote/types";
import { remoteDevInfo, remoteUnbindingLogicId } from "@/api/remote";
import { InfoFilled } from "@element-plus/icons-vue";
import { Grid, InfoFilled } from "@element-plus/icons-vue";
import OperateTabs from "@/views/family/operate/remote-operation/components/OperateTabs.vue";
import RemoteOperateList from "@/views/family/operate/remote-operation/components/RemoteOperateList.vue";

@ -1,5 +1,5 @@
<template>
<el-dropdown split-button placement="right">
<el-dropdown split-button placement="right" v-loading="loading">
远程操作列表
<template #dropdown>
<el-dropdown-menu>
@ -8,19 +8,32 @@
<el-dropdown-item>设备参数树浏览</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:ping:test']">
<el-dropdown-item divided>设备Ping测试 </el-dropdown-item>
<el-dropdown-item @click="openPing" divided
>设备Ping测试
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:profiles:upload']">
<el-dropdown-item divided>设备配置文件上传 </el-dropdown-item>
<el-dropdown-item @click="uploadConfig" divided
>设备配置文件上传
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:terminal:log_file']">
<el-dropdown-item divided>获取设备终端日志文件 </el-dropdown-item>
<el-dropdown-item @click="uploadLog" divided
>获取设备终端日志文件
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:change']">
<el-dropdown-item divided>设备更换</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:reload']">
<el-dropdown-item divided>设备远程重启 </el-dropdown-item>
<el-dropdown-item @click="reboot" divided
>设备远程重启
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:factory-reset']">
<el-dropdown-item @click="factoryReset" divided
>恢复设备出厂设置
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:profiles:issued']">
<el-dropdown-item divided>设备厂商配置文件下发 </el-dropdown-item>
@ -29,7 +42,9 @@
<el-dropdown-item divided>设备全业务配置下发 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:soft_ver:upgrade']">
<el-dropdown-item divided>设备软件版本升级 </el-dropdown-item>
<el-dropdown-item @click="upgradeSoftVer" divided
>设备软件版本升级
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:loop_back:diagnosis']">
<el-dropdown-item divided>ATMF5Loopback诊断 </el-dropdown-item>
@ -38,7 +53,9 @@
<el-dropdown-item divided>DslLoop诊断</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:dev:monitor']">
<el-dropdown-item divided>设备监控</el-dropdown-item>
<el-dropdown-item @click="deviceMonitor" divided
>设备监控</el-dropdown-item
>
</div>
<div v-hasPerm="['family:remote:ida:diagnosis']">
<el-dropdown-item divided>IAD诊断</el-dropdown-item>
@ -47,10 +64,14 @@
<el-dropdown-item divided>修改业务端口绑定 </el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:terminal:registration']">
<el-dropdown-item divided>开启终端注册页面 </el-dropdown-item>
<el-dropdown-item @click="registration" divided
>开启终端注册页面
</el-dropdown-item>
</div>
<div v-hasPerm="['family:remote:speed:operation']">
<el-dropdown-item divided>测速操作</el-dropdown-item>
<el-dropdown-item @click="speedOperate" divided
>测速操作</el-dropdown-item
>
</div>
<div v-hasPerm="['family:remote:reset:graphs']">
<el-dropdown-item divided>终端重置数图 </el-dropdown-item>
@ -90,7 +111,124 @@
</el-dropdown>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { confirm } from "@/utils/confirm";
import {
remoteFactoryReset,
remoteOpenRegister,
remoteReboot,
remoteUploadConfig,
remoteUploadLog,
} from "@/api/remote";
const route = useRoute();
const router = useRouter();
const prop = defineProps<{
devId: number;
pppoe?: string;
}>();
const loading = ref<boolean>(false);
const openPing = () => {
router.push({
path: `/resources/remote/ping/${prop.devId}`,
});
};
const uploadConfig = () => {
confirm("确认上传配置文件吗", () => {
loading.value = true;
remoteUploadConfig(prop.devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const uploadLog = () => {
confirm("确认上传日志文件吗", () => {
loading.value = true;
remoteUploadLog(prop.devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const reboot = () => {
confirm("确认重启设备吗", () => {
loading.value = true;
remoteReboot(prop.devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const factoryReset = () => {
confirm("确认恢复出厂设置吗", () => {
loading.value = true;
remoteFactoryReset(prop.devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
const speedOperate = () => {
router.push({
path: `/resources/remote/device-speed/${prop.devId}/${prop.pppoe}`,
});
};
const deviceMonitor = () => {
router.push({
path: `/resources/remote/device-monitor/${prop.devId}`,
});
};
const upgradeSoftVer = () => {
router.push({
path: `/resources/remote/upgrade-soft-ver/${prop.devId}`,
});
};
const registration = () => {
confirm("确认开启终端注册页面吗", () => {
loading.value = true;
remoteOpenRegister(prop.devId)
.then(() => {
ElMessage({
message: "操作成功",
duration: 1000,
type: "success",
});
})
.finally(() => {
loading.value = false;
});
});
};
</script>
<style scoped>
</style>
<style scoped></style>

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
SOAP任务列表
<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"
>SOAP任务列表</span
>
</div>
<div>
<el-dropdown split-button placement="bottom-start">
@ -95,6 +98,7 @@ import {
Close,
Delete,
Download,
Grid,
Position,
Refresh,
} from "@element-plus/icons-vue";

@ -3,8 +3,11 @@
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-between">
<div style="font-weight: 700; line-height: 32px; font-size: 14px">
设备日志文件列表
<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>
</template>
@ -41,6 +44,7 @@
<script setup lang="ts">
import { FileListVO } from "@/api/file-list/types";
import { getProfilePageData } from "@/api/file-list";
import { Grid } from "@element-plus/icons-vue";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);

@ -0,0 +1,109 @@
<template>
<div class="app-container">
<el-card shadow="never">
<template #header>
<div style="display: flex; justify-content: space-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>
</template>
<div class="any-table">
<el-table
:data="tableData"
v-loading="loading"
max-height="450"
highlight-current-row
@row-click="handleCurrentChange"
>
<el-table-column width="55">
<template #default="scope">
<el-radio :label="scope.row.fileId" v-model="fileId">
{{ "" }}
</el-radio>
</template>
</el-table-column>
<el-table-column
width="200"
label="版本名称"
align="center"
prop="softVer"
/>
<el-table-column
label="版本描述"
align="center"
prop="devTypeVerDesc"
/>
</el-table>
</div>
<template #footer>
<div class="flex justify-end">
<el-button type="primary" :disabled="loading" @click="submit"
>确定</el-button
>
</div>
</template>
</el-card>
</div>
</template>
<script setup lang="ts">
import { Grid } from "@element-plus/icons-vue";
import { SoftVersionUpgradeVO } from "@/api/device-type-ver/types";
import { ElTable } from "element-plus";
import { upgradeSoftVerTable } from "@/api/device-type-ver";
import { remoteSoftVerUpgrade } from "@/api/remote";
const route = useRoute();
let devId: number = parseInt(<string>route.params.devId);
const fileId = ref<number>();
const tableData = ref<SoftVersionUpgradeVO[]>([]);
const loading = ref<boolean>(false);
const handleCurrentChange = (val: SoftVersionUpgradeVO) => {
fileId.value = val.fileId;
};
const loadData = () => {
loading.value = true;
upgradeSoftVerTable(devId)
.then(({ data }) => {
tableData.value = data;
})
.finally(() => {
loading.value = false;
});
};
const submit = () => {
if (fileId.value === undefined) {
ElMessage({
message: "请选择一个软件版本",
duration: 1000,
type: "success",
});
return;
}
loading.value = true;
remoteSoftVerUpgrade(devId, fileId.value)
.then(() => {
ElMessage({
message: "操作成功",
type: "success",
duration: 1000,
});
})
.finally(() => {
loading.value = false;
});
};
onMounted(() => {
loadData();
});
</script>
<style scoped>
:deep(.el-card__body) {
padding: 10px 0 0 0;
}
</style>

@ -0,0 +1,76 @@
<template>
<div class="app-container">
<el-card>
<template #header>
<div class="head-parent-right">
<el-button :icon="Refresh" type="primary" @click="getData">刷新</el-button>
</div>
</template>
<div class="any-table">
<el-table :data="tableData" v-loading="loading" max-height="500">
<el-table-column label="任务编号" prop="operTaskId" align="center">
<template #default="scope">
<el-button type="primary" link
>{{ scope.row.operTaskId }}
</el-button>
</template>
</el-table-column>
<el-table-column label="AD编号" prop="devAdNo" align="center" />
<el-table-column
label="任务描述"
prop="operTaskDesc"
align="center"
/>
<el-table-column label="操作者" prop="userName" align="center" />
<el-table-column
label="创建时间"
prop="operTaskCreateTime"
align="center"
/>
<el-table-column label="结果" prop="resultState" align="center" />
</el-table>
</div>
<pagination
v-if="total > 0"
v-model:total="total"
v-model:page="queryForm.pageNum"
v-model:limit="queryForm.pageSize"
@pagination="getData"
/>
</el-card>
</div>
</template>
<script setup lang="ts">
import { OperateTask2TableVO } from "@/api/operate-task2/types";
import { operateTask2Page, taskTablePage } from "@/api/operate-task2";
import { Refresh } from "@element-plus/icons-vue";
defineOptions({
name: "Task",
inheritAttrs: false,
});
const tableData = ref<OperateTask2TableVO[]>([]);
const total = ref<number>(0);
const queryForm = ref<PageQuery>({ pageNum: 1, pageSize: 10 });
const loading = ref<boolean>(false);
const getData = () => {
loading.value = true;
taskTablePage(queryForm.value)
.then(({ data }) => {
tableData.value = data.list;
total.value = data.total;
})
.finally(() => {
loading.value = false;
});
};
onMounted(() => {
getData();
});
</script>
<style scoped>
:deep(.el-card__body) {
padding: 10px 0 0 0;
}
</style>

@ -5,7 +5,7 @@
<!-- 部门树 -->
<el-col :lg="4" :xs="24" class="mb-[12px]">
<dept-tree
style="border-radius: 8px"
style="border-radius: 8px; margin-left: 5px"
v-model="queryParams.deptId"
@node-click="handleQuery"
/>

Loading…
Cancel
Save