Compare commits
No commits in common. '78fb8d2a7889d1c582f4aaf1018a1df11efc105c' and '577e524c6da7b73c546cbe75ea2188ecdc8e0390' have entirely different histories.
78fb8d2a78
...
577e524c6d
@ -1,21 +0,0 @@ |
|||||||
import request from "@/utils/request"; |
|
||||||
import { AxiosPromise } from "axios"; |
|
||||||
|
|
||||||
export function updateIpv6Config(param1: string, param2: string) { |
|
||||||
return request({ |
|
||||||
url: `/api/ipv6-collection-config/v1/${param1}/${param2}`, |
|
||||||
method: "PUT", |
|
||||||
}); |
|
||||||
} |
|
||||||
export function uploadDevSnoApi(file: any): AxiosPromise<string> { |
|
||||||
const formData = new FormData(); |
|
||||||
formData.append("file", file); |
|
||||||
return request({ |
|
||||||
url: `/api/ipv6-collection-config/v1/upload`, |
|
||||||
method: "POST", |
|
||||||
data: formData, |
|
||||||
headers: { |
|
||||||
"Content-Type": "multipart/form-data", |
|
||||||
}, |
|
||||||
}); |
|
||||||
} |
|
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 571 KiB |
@ -1,289 +0,0 @@ |
|||||||
/** |
|
||||||
* 数字 |
|
||||||
*/ |
|
||||||
const REG_NUMBER: string = ".*\\d+.*"; |
|
||||||
/** |
|
||||||
* 小写字母 |
|
||||||
*/ |
|
||||||
const REG_UPPERCASE: string = ".*[A-Z]+.*"; |
|
||||||
/** |
|
||||||
* 大写字母 |
|
||||||
*/ |
|
||||||
const REG_LOWERCASE: string = ".*[a-z]+.*"; |
|
||||||
/** |
|
||||||
* 特殊符号(~!@#$%^&*()_+|<>,.?/:;'[]{}\) |
|
||||||
*/ |
|
||||||
const REG_SYMBOL: string = ".*[~!@#$%^&*()_+|<>,.?/:;'\\[\\]{}\"]+.*"; |
|
||||||
/** |
|
||||||
* 键盘字符表(小写) |
|
||||||
* 非shift键盘字符表 |
|
||||||
*/ |
|
||||||
const CHAR_TABLE1: string[][] = [ |
|
||||||
["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "=", "\0"], |
|
||||||
["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "[", "]", "\\"], |
|
||||||
["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\0", "\0"], |
|
||||||
["z", "x", "c", "v", "b", "n", "m", ",", ".", "/", "\0", "\0", "\0"], |
|
||||||
]; |
|
||||||
/** |
|
||||||
* shift键盘的字符表 |
|
||||||
*/ |
|
||||||
const CHAR_TABLE2: string[][] = [ |
|
||||||
["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "\0"], |
|
||||||
["q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "{", "}", "|"], |
|
||||||
["a", "s", "d", "f", "g", "h", "j", "k", "l", ":", '"', "\0", "\0"], |
|
||||||
["z", "x", "c", "v", "b", "n", "m", "<", ">", "?", "\0", "\0", "\0"], |
|
||||||
]; |
|
||||||
|
|
||||||
/** |
|
||||||
* 校验密码是否符合条件 |
|
||||||
* @param password 密码 |
|
||||||
* @param username 用户名 |
|
||||||
*/ |
|
||||||
export const checkPasswordRule = (password: string, username: string) => { |
|
||||||
if (password === "" || password.length < 8 || password.length > 32) { |
|
||||||
// console.log("长度小于8,或大于32");
|
|
||||||
return "密码长度应大于8小于32"; |
|
||||||
} |
|
||||||
if (password.indexOf(username) !== -1) { |
|
||||||
// console.log("包含用户名");
|
|
||||||
return "请勿包含用户名"; |
|
||||||
} |
|
||||||
if (isContinuousChar(password)) { |
|
||||||
// console.log("包含3个及以上相同或字典连续字符");
|
|
||||||
return "请勿包含3个及以上相同或连续的字符"; |
|
||||||
} |
|
||||||
if (isKeyBoardContinuousChar(password)) { |
|
||||||
// console.log("包含3个及以上键盘连续字符");
|
|
||||||
return "请勿包含3个及以上键盘连续字符"; |
|
||||||
} |
|
||||||
let i: number = 0; |
|
||||||
if (password.match(REG_NUMBER)) i++; |
|
||||||
if (password.match(REG_LOWERCASE)) i++; |
|
||||||
if (password.match(REG_UPPERCASE)) i++; |
|
||||||
if (password.match(REG_SYMBOL)) i++; |
|
||||||
if (i < 2) { |
|
||||||
// console.log(("数字、小写字母、大写字母、特殊字符,至少包含两种"));
|
|
||||||
return "数字、小写字母、大写字母、特殊字符,至少包含两种"; |
|
||||||
} |
|
||||||
// console.log(i);
|
|
||||||
return "校验通过"; |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* 是否包含3个及以上相同或字典连续字符 |
|
||||||
*/ |
|
||||||
const isContinuousChar = (password: string) => { |
|
||||||
const chars: string[] = password.split(""); |
|
||||||
const charCode: number[] = []; |
|
||||||
for (let i = 0; i < chars.length - 2; i++) { |
|
||||||
charCode[i] = chars[i].charCodeAt(0); |
|
||||||
} |
|
||||||
for (let i = 0; i < charCode.length - 2; i++) { |
|
||||||
const n1 = charCode[i]; |
|
||||||
const n2 = charCode[i + 1]; |
|
||||||
const n3 = charCode[i + 2]; |
|
||||||
// 判断重复字符
|
|
||||||
if (n1 == n2 && n1 == n3) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
// 判断连续字符: 正序 + 倒序
|
|
||||||
if ((n1 + 1 == n2 && n1 + 2 == n3) || (n1 - 1 == n2 && n1 - 2 == n3)) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
return false; |
|
||||||
}; |
|
||||||
/** |
|
||||||
* 是否包含3个及以上键盘连续字符 |
|
||||||
* @param password 待匹配的字符串 |
|
||||||
*/ |
|
||||||
const isKeyBoardContinuousChar = (password: string) => { |
|
||||||
if (password === "") { |
|
||||||
return false; |
|
||||||
} |
|
||||||
//考虑大小写,都转换成小写字母
|
|
||||||
const lpStrChars: string[] = password.toLowerCase().split(""); |
|
||||||
// 获取字符串长度
|
|
||||||
const nStrLen: number = lpStrChars.length; |
|
||||||
// 定义位置数组:row - 行,col - column 列
|
|
||||||
const pRowCharPos: number[] = new Array(nStrLen).fill(""); |
|
||||||
const pColCharPos: number[] = new Array(nStrLen).fill(""); |
|
||||||
for (let i = 0; i < nStrLen; i++) { |
|
||||||
const chLower: string = lpStrChars[i]; |
|
||||||
pColCharPos[i] = -1; |
|
||||||
// 检索在表1中的位置,构建位置数组
|
|
||||||
for (let nRowTable1Idx = 0; nRowTable1Idx < 4; nRowTable1Idx++) { |
|
||||||
for (let nColTable1Idx = 0; nColTable1Idx < 13; nColTable1Idx++) { |
|
||||||
if (chLower == CHAR_TABLE1[nRowTable1Idx][nColTable1Idx]) { |
|
||||||
pRowCharPos[i] = nRowTable1Idx; |
|
||||||
pColCharPos[i] = nColTable1Idx; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// 在表1中没找到,到表二中去找,找到则continue
|
|
||||||
if (pColCharPos[i] >= 0) { |
|
||||||
continue; |
|
||||||
} |
|
||||||
// 检索在表2中的位置,构建位置数组
|
|
||||||
for (let nRowTable2Idx = 0; nRowTable2Idx < 4; nRowTable2Idx++) { |
|
||||||
for (let nColTable2Idx = 0; nColTable2Idx < 13; nColTable2Idx++) { |
|
||||||
if (chLower == CHAR_TABLE2[nRowTable2Idx][nColTable2Idx]) { |
|
||||||
pRowCharPos[i] = nRowTable2Idx; |
|
||||||
pColCharPos[i] = nColTable2Idx; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
// 匹配坐标连线
|
|
||||||
for (let j = 1; j <= nStrLen - 2; j++) { |
|
||||||
//同一行
|
|
||||||
if ( |
|
||||||
pRowCharPos[j - 1] == pRowCharPos[j] && |
|
||||||
pRowCharPos[j] == pRowCharPos[j + 1] |
|
||||||
) { |
|
||||||
// 键盘行正向连续(asd)或者键盘行反向连续(dsa)
|
|
||||||
if ( |
|
||||||
(pColCharPos[j - 1] + 1 == pColCharPos[j] && |
|
||||||
pColCharPos[j] + 1 == pColCharPos[j + 1]) || |
|
||||||
(pColCharPos[j + 1] + 1 == pColCharPos[j] && |
|
||||||
pColCharPos[j] + 1 == pColCharPos[j - 1]) |
|
||||||
) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
//同一列
|
|
||||||
if ( |
|
||||||
pColCharPos[j - 1] == pColCharPos[j] && |
|
||||||
pColCharPos[j] == pColCharPos[j + 1] |
|
||||||
) { |
|
||||||
//键盘列连续(qaz)或者键盘列反向连续(zaq)
|
|
||||||
if ( |
|
||||||
(pRowCharPos[j - 1] + 1 == pRowCharPos[j] && |
|
||||||
pRowCharPos[j] + 1 == pRowCharPos[j + 1]) || |
|
||||||
(pRowCharPos[j - 1] - 1 == pRowCharPos[j] && |
|
||||||
pRowCharPos[j] - 1 == pRowCharPos[j + 1]) |
|
||||||
) { |
|
||||||
return true; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
return false; |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* 密码强度校验 |
|
||||||
*/ |
|
||||||
/** |
|
||||||
* 长度 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
const length = (str: string) => { |
|
||||||
if (str.length < 5) { |
|
||||||
return 5; |
|
||||||
} else if (str.length < 8) { |
|
||||||
return 10; |
|
||||||
} else { |
|
||||||
return 25; |
|
||||||
} |
|
||||||
}; |
|
||||||
/** |
|
||||||
* 字母 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
const letters = (str: string) => { |
|
||||||
let count1 = 0, |
|
||||||
count2 = 0; |
|
||||||
for (let i = 0; i < str.length; i++) { |
|
||||||
if (str.charAt(i) >= "a" && str.charAt(i) <= "z") { |
|
||||||
count1++; |
|
||||||
} |
|
||||||
if (str.charAt(i) >= "A" && str.charAt(i) <= "Z") { |
|
||||||
count2++; |
|
||||||
} |
|
||||||
} |
|
||||||
if (count1 == 0 && count2 == 0) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
if (count1 != 0 && count2 != 0) { |
|
||||||
return 20; |
|
||||||
} |
|
||||||
return 10; |
|
||||||
}; |
|
||||||
|
|
||||||
/** |
|
||||||
* 数字 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
const numbers = (str: string) => { |
|
||||||
let count = 0; |
|
||||||
for (let i = 0; i < str.length; i++) { |
|
||||||
if (str.charAt(i) >= "0" && str.charAt(i) <= "9") { |
|
||||||
count++; |
|
||||||
} |
|
||||||
} |
|
||||||
if (count == 0) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
if (count == 1) { |
|
||||||
return 10; |
|
||||||
} |
|
||||||
return 20; |
|
||||||
}; |
|
||||||
/** |
|
||||||
* 符号 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
const symbols = (str: string) => { |
|
||||||
let count = 0; |
|
||||||
for (let i = 0; i < str.length; i++) { |
|
||||||
if ( |
|
||||||
(str.charCodeAt(i) >= 0x21 && str.charCodeAt(i) <= 0x2f) || |
|
||||||
(str.charCodeAt(i) >= 0x3a && str.charCodeAt(i) <= 0x40) || |
|
||||||
(str.charCodeAt(i) >= 0x5b && str.charCodeAt(i) <= 0x60) || |
|
||||||
(str.charCodeAt(i) >= 0x7b && str.charCodeAt(i) <= 0x7e) |
|
||||||
) { |
|
||||||
count++; |
|
||||||
} |
|
||||||
} |
|
||||||
if (count == 0) { |
|
||||||
return 0; |
|
||||||
} |
|
||||||
if (count == 1) { |
|
||||||
return 10; |
|
||||||
} |
|
||||||
return 25; |
|
||||||
}; |
|
||||||
/** |
|
||||||
* 得分机制 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
const rewards = (str: string) => { |
|
||||||
const letter = letters(str); //字母
|
|
||||||
const number = numbers(str); //数字
|
|
||||||
const symbol = symbols(str); //符号
|
|
||||||
if (letter > 0 && number > 0 && symbol == 0) { |
|
||||||
//字母和数字
|
|
||||||
return 2; |
|
||||||
} |
|
||||||
if (letter == 10 && number > 0 && symbol > 0) { |
|
||||||
//字母、数字和符号
|
|
||||||
return 3; |
|
||||||
} |
|
||||||
if (letter == 20 && number > 0 && symbol > 0) { |
|
||||||
//大小写字母、数字和符号
|
|
||||||
return 5; |
|
||||||
} |
|
||||||
return 0; |
|
||||||
}; |
|
||||||
/** |
|
||||||
* 最终评分 |
|
||||||
* @param str |
|
||||||
*/ |
|
||||||
export const level = (str: string) => { |
|
||||||
const lengths = length(str); //长度
|
|
||||||
const letter = letters(str); //字母
|
|
||||||
const number = numbers(str); //数字
|
|
||||||
const symbol = symbols(str); //符号
|
|
||||||
const reward = rewards(str); //奖励
|
|
||||||
return lengths + letter + number + symbol + reward; |
|
||||||
}; |
|
@ -1,382 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="app-container"> |
|
||||||
<el-card shadow="never"> |
|
||||||
<template #header> |
|
||||||
<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" |
|
||||||
>IPV6采集配置信息</span |
|
||||||
> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
<el-descriptions :column="1" border v-loading="loading"> |
|
||||||
<el-descriptions-item |
|
||||||
label="分公司" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select v-model="area" clearable placeholder="请选择分公司"> |
|
||||||
<el-option |
|
||||||
v-for="item in areaOption" |
|
||||||
:label="item.label" |
|
||||||
:value="item.value" |
|
||||||
:key="item.value" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button type="primary" @click="updateIpv6ConfigParam('areaId')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="区局" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select v-model="subarea" placeholder="请选择区局" clearable> |
|
||||||
<el-option |
|
||||||
v-for="item in subareaOption" |
|
||||||
:label="item.label" |
|
||||||
:value="item.value" |
|
||||||
:key="item.value" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button |
|
||||||
type="primary" |
|
||||||
@click="updateIpv6ConfigParam('subAreaId')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="路由/桥接" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select |
|
||||||
v-model="rgMode" |
|
||||||
placeholder="请选择连接方式" |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option label="桥接" value="1,IP_Routed" /> |
|
||||||
<el-option label="路由" value="2,PPPoE_Bridged" /> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button |
|
||||||
type="primary" |
|
||||||
@click="updateIpv6ConfigParam('routeId')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="设备供应商" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select |
|
||||||
v-model="category" |
|
||||||
placeholder="请选择设备供应商" |
|
||||||
filterable |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option |
|
||||||
v-for="item in vendorNameOption" |
|
||||||
:label="item.label" |
|
||||||
:value="item.value" |
|
||||||
:key="item.value" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button |
|
||||||
type="primary" |
|
||||||
disabled |
|
||||||
@click="updateIpv6ConfigParam('devVendorName')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="设备型号" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select |
|
||||||
v-model="typeName" |
|
||||||
placeholder="请选择设备型号" |
|
||||||
filterable |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option |
|
||||||
v-for="item in typeNameOption" |
|
||||||
:label="item.label" |
|
||||||
:value="item.value" |
|
||||||
:key="item.value" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button |
|
||||||
type="primary" |
|
||||||
@click="updateIpv6ConfigParam('deviceTypeId')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="采集组件" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-select |
|
||||||
v-model="acquisitionComponents" |
|
||||||
placeholder="请选择采集组件" |
|
||||||
clearable |
|
||||||
> |
|
||||||
<el-option label="queryIpv6Info" value="queryIpv6Info" /> |
|
||||||
</el-select> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8"> |
|
||||||
<el-button |
|
||||||
type="primary" |
|
||||||
disabled |
|
||||||
@click="updateIpv6ConfigParam('collectStrId')" |
|
||||||
>修改 |
|
||||||
</el-button> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="导入设备序列号" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
<el-row :gutter="20"> |
|
||||||
<el-col :span="16"> |
|
||||||
<el-upload |
|
||||||
drag |
|
||||||
action="#" |
|
||||||
:limit="1" |
|
||||||
:auto-upload="false" |
|
||||||
accept="text/plain" |
|
||||||
v-model:file-list="fileList" |
|
||||||
> |
|
||||||
<el-icon class="el-icon--upload"> |
|
||||||
<upload-filled /> |
|
||||||
</el-icon> |
|
||||||
<div class="el-upload__text">拖拽上传 或 <em>点击上传</em></div> |
|
||||||
<template #tip> |
|
||||||
<div |
|
||||||
style=" |
|
||||||
margin-top: 7px; |
|
||||||
color: var(--el-text-color-regular); |
|
||||||
font-size: 12px; |
|
||||||
" |
|
||||||
> |
|
||||||
(仅支持txt文件按列排序) |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
</el-upload> |
|
||||||
</el-col> |
|
||||||
<el-col :span="8" style="display: flex; margin: auto 0"> |
|
||||||
<div> |
|
||||||
<el-button type="primary" @click="handUpload" |
|
||||||
>提交文件</el-button |
|
||||||
> |
|
||||||
</div> |
|
||||||
</el-col> |
|
||||||
</el-row> |
|
||||||
</el-descriptions-item> |
|
||||||
</el-descriptions> |
|
||||||
</el-card> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { Grid, UploadFilled } from "@element-plus/icons-vue"; |
|
||||||
import { reportArea } from "@/api/report"; |
|
||||||
import { getTypeNameOption, getVendorNameOption } from "@/api/device-type"; |
|
||||||
import { UploadUserFile } from "element-plus"; |
|
||||||
import { confirm } from "@/utils/confirm"; |
|
||||||
import { updateIpv6Config, uploadDevSnoApi } from "@/api/ipv6Config"; |
|
||||||
|
|
||||||
defineOptions({ |
|
||||||
name: "Ipv6CollectingConfig", |
|
||||||
inheritAttrs: false, |
|
||||||
}); |
|
||||||
const fileList = ref<UploadUserFile[]>([]); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const area = ref<number>(); |
|
||||||
const subarea = ref<number>(); |
|
||||||
const rgMode = ref<string>(); |
|
||||||
const category = ref<string>(); |
|
||||||
const typeName = ref<string>(); |
|
||||||
const acquisitionComponents = ref<string>(); |
|
||||||
const areaOption = ref<OptionType[]>([]); |
|
||||||
const subareaOption = ref<OptionType[]>([]); |
|
||||||
const vendorNameOption = ref<OptionType[]>([]); |
|
||||||
const typeNameOption = ref<OptionType[]>([]); |
|
||||||
watch( |
|
||||||
() => area.value, |
|
||||||
() => { |
|
||||||
if (area.value === undefined) { |
|
||||||
return; |
|
||||||
} |
|
||||||
loadSubarea(area.value); |
|
||||||
} |
|
||||||
); |
|
||||||
const loadSubarea = (groupId: number) => { |
|
||||||
reportArea(groupId).then(({ data }) => { |
|
||||||
subareaOption.value = data; |
|
||||||
}); |
|
||||||
}; |
|
||||||
const loadArea = (groupId: number) => { |
|
||||||
reportArea(groupId).then(({ data }) => { |
|
||||||
areaOption.value.push(...data); |
|
||||||
}); |
|
||||||
}; |
|
||||||
const loadVendorNameOption = () => { |
|
||||||
getVendorNameOption().then(({ data }) => { |
|
||||||
vendorNameOption.value.push(...data); |
|
||||||
}); |
|
||||||
}; |
|
||||||
const loadTypeNameOption = () => { |
|
||||||
getTypeNameOption("").then(({ data }) => { |
|
||||||
typeNameOption.value.push(...data); |
|
||||||
}); |
|
||||||
}; |
|
||||||
const updateIpv6ConfigParam = (param: string) => { |
|
||||||
let param2 = ""; |
|
||||||
switch (param) { |
|
||||||
case "areaId": |
|
||||||
param2 = area.value; |
|
||||||
break; |
|
||||||
case "subAreaId": |
|
||||||
param2 = subarea.value; |
|
||||||
break; |
|
||||||
case "routeId": |
|
||||||
param2 = rgMode.value; |
|
||||||
break; |
|
||||||
case "devVendorName": |
|
||||||
param2 = category.value; |
|
||||||
break; |
|
||||||
case "deviceTypeId": |
|
||||||
param2 = typeName.value; |
|
||||||
break; |
|
||||||
case "collectStrId": |
|
||||||
param2 = acquisitionComponents.value; |
|
||||||
break; |
|
||||||
} |
|
||||||
if (param2 === "" || param2 == undefined) { |
|
||||||
param2 = "-1"; |
|
||||||
} |
|
||||||
confirm("确定修改吗", () => { |
|
||||||
loading.value = true; |
|
||||||
updateIpv6Config(param, param2) |
|
||||||
.then(() => { |
|
||||||
ElMessage({ |
|
||||||
message: "修改成功", |
|
||||||
type: "success", |
|
||||||
duration: 1000, |
|
||||||
}); |
|
||||||
}) |
|
||||||
.finally(() => { |
|
||||||
loading.value = false; |
|
||||||
}); |
|
||||||
}); |
|
||||||
}; |
|
||||||
const handUpload = () => { |
|
||||||
if (fileList.value.length === 0) { |
|
||||||
ElMessage({ |
|
||||||
message: "请选择需要上传的文件", |
|
||||||
type: "error", |
|
||||||
duration: 1000, |
|
||||||
}); |
|
||||||
return; |
|
||||||
} |
|
||||||
const file = fileList.value[0].raw; |
|
||||||
let fileType = file?.type; |
|
||||||
if (fileType != "text/plain") { |
|
||||||
ElMessage({ |
|
||||||
message: "文件类型错误", |
|
||||||
type: "error", |
|
||||||
duration: 1000, |
|
||||||
}); |
|
||||||
return; |
|
||||||
} |
|
||||||
confirm("确定提交文件吗", () => { |
|
||||||
loading.value = true; |
|
||||||
uploadDevSnoApi(file) |
|
||||||
.then(() => { |
|
||||||
ElMessage({ |
|
||||||
message: "操作成功", |
|
||||||
duration: 1000, |
|
||||||
type: "success", |
|
||||||
}); |
|
||||||
}) |
|
||||||
.finally(() => { |
|
||||||
loading.value = false; |
|
||||||
}); |
|
||||||
}); |
|
||||||
}; |
|
||||||
onMounted(() => { |
|
||||||
loadArea(0); |
|
||||||
loadVendorNameOption(); |
|
||||||
loadTypeNameOption(); |
|
||||||
}); |
|
||||||
</script> |
|
||||||
|
|
||||||
<style scoped> |
|
||||||
:deep(.el-card__body) { |
|
||||||
padding: 10px 0 0 0; |
|
||||||
} |
|
||||||
|
|
||||||
:deep(.my-label) { |
|
||||||
width: 10px !important; |
|
||||||
background: var(--el-color-white) !important; |
|
||||||
} |
|
||||||
</style> |
|
@ -1,110 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="app-container"> |
|
||||||
<el-card shadow="never"> |
|
||||||
<template #header> |
|
||||||
<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> |
|
||||||
</template> |
|
||||||
<el-descriptions v-loading="loading" :column="1" border> |
|
||||||
<el-descriptions-item |
|
||||||
label="创建人" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.userName }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="创建时间" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.operTaskCreateTime }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="开始时间" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.operStartTime }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="结束时间" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.operEndTime }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="结果" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.resultState }} |
|
||||||
</el-descriptions-item> |
|
||||||
<el-descriptions-item |
|
||||||
label="原因" |
|
||||||
label-align="left" |
|
||||||
align="left" |
|
||||||
label-class-name="my-label" |
|
||||||
class-name="my-content" |
|
||||||
width="150px" |
|
||||||
> |
|
||||||
{{ result.errorDesc }} |
|
||||||
</el-descriptions-item> |
|
||||||
</el-descriptions> |
|
||||||
</el-card> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { Grid } from "@element-plus/icons-vue"; |
|
||||||
import { OperateTask2ResultVO } from "@/api/operate-task2/types"; |
|
||||||
import { taskResult } from "@/api/operate-task2"; |
|
||||||
const route = useRoute(); |
|
||||||
let taskId: number = parseInt(<string>route.params.taskId); |
|
||||||
const result = ref<OperateTask2ResultVO>({}); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
|
|
||||||
const getData = () => { |
|
||||||
loading.value = false; |
|
||||||
taskResult(taskId) |
|
||||||
.then(({ data }) => { |
|
||||||
result.value = data; |
|
||||||
}) |
|
||||||
.finally(() => { |
|
||||||
loading.value = false; |
|
||||||
}); |
|
||||||
}; |
|
||||||
onMounted(() => { |
|
||||||
getData(); |
|
||||||
}); |
|
||||||
</script> |
|
||||||
|
|
||||||
<style scoped> |
|
||||||
:deep(.my-label) { |
|
||||||
width: 80px !important; |
|
||||||
background: var(--el-color-white) !important; |
|
||||||
} |
|
||||||
:deep(.el-card__body) { |
|
||||||
padding: 10px 0 0 0; |
|
||||||
} |
|
||||||
</style> |
|
@ -1,254 +0,0 @@ |
|||||||
<template> |
|
||||||
<div class="app-container"> |
|
||||||
<div class="flex justify-between"> |
|
||||||
<div class="card mr-1 ml-3"> |
|
||||||
<div> |
|
||||||
<el-image |
|
||||||
class="parent-img" |
|
||||||
style="border-radius: 10px 10px 0 0" |
|
||||||
:src="personUrl" |
|
||||||
/> |
|
||||||
<el-avatar |
|
||||||
:size="100" |
|
||||||
shape="circle" |
|
||||||
fit="cover" |
|
||||||
class="child-avatar" |
|
||||||
:src="avatarUrl" |
|
||||||
/> |
|
||||||
<div class="user-info"> |
|
||||||
<div class="username">{{ userStore.user.username }}</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div class="wh-full"> |
|
||||||
<el-card shadow="never"> |
|
||||||
<template #header> |
|
||||||
<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> |
|
||||||
</template> |
|
||||||
<el-form |
|
||||||
:model="formData" |
|
||||||
ref="ruleFormRef" |
|
||||||
:rules="rules" |
|
||||||
size="large" |
|
||||||
v-loading="loading" |
|
||||||
label-position="top" |
|
||||||
> |
|
||||||
<el-form-item label="当前密码" prop="oldPwd"> |
|
||||||
<el-input |
|
||||||
placeholder="请输入当前密码" |
|
||||||
v-model="formData.oldPwd" |
|
||||||
type="password" |
|
||||||
show-password |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item label="新密码" prop="newPwd"> |
|
||||||
<el-input |
|
||||||
placeholder="请输入新密码密码" |
|
||||||
v-model="formData.newPwd" |
|
||||||
type="password" |
|
||||||
show-password |
|
||||||
/> |
|
||||||
<div class="flex justify-end w-full mt-2"> |
|
||||||
<div class="bar w-20" :style="{ backgroundColor: weakColor }"> |
|
||||||
弱 |
|
||||||
</div> |
|
||||||
<div class="bar w-20" :style="{ backgroundColor: middleColor }"> |
|
||||||
中 |
|
||||||
</div> |
|
||||||
<div class="bar w-20" :style="{ backgroundColor: strongColor }"> |
|
||||||
强 |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</el-form-item> |
|
||||||
<el-form-item label="确认新密码密码" prop="lastPwd"> |
|
||||||
<el-input |
|
||||||
placeholder="请输入新密码密码" |
|
||||||
v-model="formData.lastPwd" |
|
||||||
type="password" |
|
||||||
show-password |
|
||||||
/> |
|
||||||
</el-form-item> |
|
||||||
</el-form> |
|
||||||
<template #footer> |
|
||||||
<div class="flex justify-end"> |
|
||||||
<el-button type="primary" @click="submitForm(ruleFormRef)" |
|
||||||
>保 存</el-button |
|
||||||
> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
</el-card> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup lang="ts"> |
|
||||||
import { Grid } from "@element-plus/icons-vue"; |
|
||||||
import { useUserStore } from "@/store"; |
|
||||||
import { FormInstance, FormRules } from "element-plus"; |
|
||||||
import { checkPasswordRule, level } from "@/utils/checkPwd"; |
|
||||||
import { PasswordForm } from "@/api/user/types"; |
|
||||||
import { confirm } from "@/utils/confirm"; |
|
||||||
import { updateUserPwd } from "@/api/user"; |
|
||||||
const userStore = useUserStore(); |
|
||||||
const ruleFormRef = ref<FormInstance>(); |
|
||||||
const loading = ref<boolean>(false); |
|
||||||
const route = useRoute(); |
|
||||||
const router = useRouter(); |
|
||||||
const formData = ref<PasswordForm>({ |
|
||||||
oldPwd: "", |
|
||||||
newPwd: "", |
|
||||||
lastPwd: "", |
|
||||||
}); |
|
||||||
const personUrl = ref( |
|
||||||
new URL(`../../assets/images/person_bg.jpg`, import.meta.url).href |
|
||||||
); |
|
||||||
const avatarUrl = ref( |
|
||||||
new URL(`../../assets/images/avatar.png`, import.meta.url).href |
|
||||||
); |
|
||||||
// 强度条颜色 |
|
||||||
const weakColor = ref<string>(""); |
|
||||||
const middleColor = ref<string>(""); |
|
||||||
const strongColor = ref<string>(""); |
|
||||||
watch( |
|
||||||
() => formData.value.newPwd, |
|
||||||
(newVal) => { |
|
||||||
if (formData.value.newPwd?.length === 0) { |
|
||||||
weakColor.value = ""; |
|
||||||
return; |
|
||||||
} |
|
||||||
let scores = level(<string>newVal); |
|
||||||
if (scores > 80) { |
|
||||||
strongColor.value = "#00c6ee"; |
|
||||||
} else { |
|
||||||
strongColor.value = ""; |
|
||||||
} |
|
||||||
if (scores > 70) { |
|
||||||
middleColor.value = "#00c6ee"; |
|
||||||
} else { |
|
||||||
middleColor.value = ""; |
|
||||||
} |
|
||||||
if (scores > 0) { |
|
||||||
weakColor.value = "#00c6ee"; |
|
||||||
} else { |
|
||||||
weakColor.value = ""; |
|
||||||
} |
|
||||||
} |
|
||||||
); |
|
||||||
const rules = reactive<FormRules<PasswordForm>>({ |
|
||||||
oldPwd: [{ required: true, message: "请输入当前密码", trigger: "blur" }], |
|
||||||
newPwd: [ |
|
||||||
{ |
|
||||||
validator: (rule: any, value: any, callback: any) => { |
|
||||||
if (value === undefined) { |
|
||||||
callback(new Error("请输入密码")); |
|
||||||
} else if (value.length < 12) { |
|
||||||
callback(new Error("密码必须大于12位")); |
|
||||||
} else { |
|
||||||
const result: string = checkPasswordRule( |
|
||||||
value, |
|
||||||
<string>userStore.user.username |
|
||||||
); |
|
||||||
if (result === "校验通过") { |
|
||||||
callback(); |
|
||||||
} else { |
|
||||||
callback(new Error(result)); |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
required: true, |
|
||||||
trigger: "blur", |
|
||||||
}, |
|
||||||
], |
|
||||||
lastPwd: [ |
|
||||||
{ |
|
||||||
required: true, |
|
||||||
validator: (rule: any, value: any, callback: any) => { |
|
||||||
if (formData.value.newPwd === undefined) { |
|
||||||
callback(new Error("请先输入新密码")); |
|
||||||
} else if (value === undefined) { |
|
||||||
callback(new Error("请输入确认密码")); |
|
||||||
} else if (formData.value.newPwd != formData.value.lastPwd) { |
|
||||||
callback(new Error("两次密码不一致")); |
|
||||||
} else { |
|
||||||
callback(); |
|
||||||
} |
|
||||||
}, |
|
||||||
trigger: "blur", |
|
||||||
}, |
|
||||||
], |
|
||||||
}); |
|
||||||
const submitForm = async (formEl: FormInstance | undefined) => { |
|
||||||
if (!formEl) return; |
|
||||||
await formEl.validate((valid, fields) => { |
|
||||||
if (valid) { |
|
||||||
confirm("确认修改密码吗", () => { |
|
||||||
loading.value = true; |
|
||||||
updateUserPwd(formData.value) |
|
||||||
.then(() => { |
|
||||||
router.push(`/login?redirect=${route.fullPath}`); |
|
||||||
}) |
|
||||||
.finally(() => { |
|
||||||
loading.value = false; |
|
||||||
}); |
|
||||||
}); |
|
||||||
} else { |
|
||||||
console.log("error submit!", fields); |
|
||||||
} |
|
||||||
}); |
|
||||||
}; |
|
||||||
</script> |
|
||||||
|
|
||||||
<style scoped> |
|
||||||
.card { |
|
||||||
/* 设置卡片的宽度 */ |
|
||||||
width: 600px; |
|
||||||
/* 设置卡片的高度(可选,根据需要设置) */ |
|
||||||
/* height: 200px; */ |
|
||||||
/* 设置卡片的背景颜色 */ |
|
||||||
background-color: #fff; |
|
||||||
/* 设置卡片的边框(可选) */ |
|
||||||
border: 1px solid #ddd; |
|
||||||
/* 设置卡片的圆角 */ |
|
||||||
border-radius: 10px; /* 你可以根据需要调整这个值 */ |
|
||||||
/* 设置卡片的盒子模型为border-box,这样padding和border就不会增加元素的宽度和高度 */ |
|
||||||
box-sizing: border-box; |
|
||||||
} |
|
||||||
.parent-img { |
|
||||||
position: relative; |
|
||||||
} |
|
||||||
.child-avatar { |
|
||||||
position: relative; |
|
||||||
top: -50px; |
|
||||||
left: 38%; |
|
||||||
} |
|
||||||
.user-info { |
|
||||||
position: relative; |
|
||||||
top: -50px; |
|
||||||
.username { |
|
||||||
text-align: center; |
|
||||||
font-size: 22px; |
|
||||||
font-weight: 400; |
|
||||||
color: #344767; |
|
||||||
} |
|
||||||
.other-info { |
|
||||||
margin-left: 50px; |
|
||||||
margin-right: 50px; |
|
||||||
color: #677481; |
|
||||||
} |
|
||||||
} |
|
||||||
.bar { |
|
||||||
height: 8px; |
|
||||||
background-color: #dcdfe6; |
|
||||||
margin-right: 3px; |
|
||||||
border-radius: 4px; |
|
||||||
transition: 0.5s all ease; |
|
||||||
text-align: center; |
|
||||||
color: #606266; |
|
||||||
} |
|
||||||
</style> |
|
Loading…
Reference in new issue