diff --git a/package.json b/package.json index 2091a489..3c04f55a 100644 --- a/package.json +++ b/package.json @@ -12,19 +12,19 @@ "preview": "vite preview" }, "dependencies": { - "@ant-design/icons-vue": "^7.0.1", - "@antv/g6": "4.8.24", + "@ant-design/icons-vue": "7.0.1", + "@antv/g6": "4.8.25", "@codemirror/lang-javascript": "6.2.3", "@codemirror/lang-yaml": "6.1.2", "@codemirror/merge": "6.10.0", "@codemirror/theme-one-dark": "6.1.2", "@tato30/vue-pdf": "1.11.3", - "@vueuse/core": "12.8.2", + "@vueuse/core": "13.0.0", "@xterm/addon-fit": "0.10.0", "@xterm/xterm": "5.5.0", "ant-design-vue": "4.2.6", "antdv-pro-layout": "4.2.0", - "antdv-pro-modal": "4.0.6", + "antdv-pro-modal": "4.0.8", "codemirror": "6.0.1", "crypto-js": "4.2.0", "dayjs": "1.11.13", @@ -50,12 +50,12 @@ "@types/js-cookie": "3.0.6", "@types/node": "^18.0.0", "@types/nprogress": "0.2.3", - "@vitejs/plugin-vue": "5.2.1", + "@vitejs/plugin-vue": "5.2.3", "less": "4.2.2", - "typescript": "5.6.3", + "typescript": "5.8.2", "unplugin-vue-components": "0.28.0", - "vite": "6.2.0", - "vite-plugin-compression": "~0.5.1", - "vue-tsc": "2.2.0" + "vite": "6.3.3", + "vite-plugin-compression": "0.5.1", + "vue-tsc": "2.2.8" } } diff --git a/public/neDataImput/pcf_template.txt b/public/neDataImput/pcf_template.txt index d6ee40e8..0c6ffa0e 100644 --- a/public/neDataImput/pcf_template.txt +++ b/public/neDataImput/pcf_template.txt @@ -1,2 +1,2 @@ imsi,msisdn,sess_rules,pcc_rules,hdr_enrich,rfsp,sar,qos_audio,qos_video -001012082101039,1234,internet|ims_sig,internet|ims_sig,321321,255,321312,32131,32131 \ No newline at end of file +001012082101039,1234,internet|ims_sig,internet|ims_sig,321321,255,321312,32131,32131 diff --git a/public/neDataImput/udm_auth_template.txt b/public/neDataImput/udm_auth_template.txt index 79c40d62..cb716591 100644 --- a/public/neDataImput/udm_auth_template.txt +++ b/public/neDataImput/udm_auth_template.txt @@ -1,2 +1,2 @@ 001011100001157,1234567890ABCDEF1234567890ABCDEF,0,8000,11111111111111111111111111111111 -001011100001158,1234567890ABCDEF1234567890ABCDEF,0,8000,11111111111111111111111111111111 \ No newline at end of file +001011100001158,1234567890ABCDEF1234567890ABCDEF,0,8000,11111111111111111111111111111111 diff --git a/public/neDataImput/udm_sub_template.txt b/public/neDataImput/udm_sub_template.txt index 0e42251e..dde832c7 100644 --- a/public/neDataImput/udm_sub_template.txt +++ b/public/neDataImput/udm_sub_template.txt @@ -1,2 +1,2 @@ 001011100001157,62357000583,def_ambr,def_nssai,def_arfb,def_sar,0,3,def_snssai,1-000001&internet&ims,1,64,24,65,def_eps,1,010200000000,- -001011100001158,62357000585,def_ambr,def_nssai,def_arfb,def_sar,0,3,def_snssai,1-000001&internet&ims,1,64,24,65,def_eps,1,010200000000,- \ No newline at end of file +001011100001158,62357000585,def_ambr,def_nssai,def_arfb,def_sar,0,3,def_snssai,1-000001&internet&ims,1,64,24,65,def_eps,1,010200000000,- diff --git a/public/neDataImput/udm_voip_template.txt b/public/neDataImput/udm_voip_template.txt new file mode 100644 index 00000000..21657b00 --- /dev/null +++ b/public/neDataImput/udm_voip_template.txt @@ -0,0 +1,3 @@ +#username,password +62357000580,123456 +62357000581,123456 diff --git a/public/neDataImput/udm_volte_template.txt b/public/neDataImput/udm_volte_template.txt new file mode 100644 index 00000000..c23508f7 --- /dev/null +++ b/public/neDataImput/udm_volte_template.txt @@ -0,0 +1,4 @@ +#vlote=0 MSISDN and IMSI need to be filled in the same way. +#imsi,msisdn,vlote,vni +460996650000580,62357000580,1,ims.mnc000.mcc460.3gppnetwork.org +62357000581,62357000581,0,ims.mnc000.mcc460.3gppnetwork.org diff --git a/src/api/login.ts b/src/api/auth.ts similarity index 61% rename from src/api/login.ts rename to src/api/auth.ts index e66963c6..eab43a76 100644 --- a/src/api/login.ts +++ b/src/api/auth.ts @@ -1,15 +1,28 @@ -import { CACHE_SESSION_CRYPTO_API } from '@/constants/cache-keys-constants'; -import { sessionGet } from '@/utils/cache-session-utils'; import { request } from '@/plugins/http-fetch'; -// 登录方法 +/** + * 登录方法 + * @param data 数据 + * @returns 结果 + */ export function login(data: Record) { return request({ - url: '/login', + url: '/auth/login', method: 'POST', data: data, whithToken: false, - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', + }); +} + +/** + * 退出方法 + * @returns object + */ +export function logout() { + return request({ + url: '/auth/logout', + method: 'POST', + repeatSubmit: false, }); } @@ -20,11 +33,24 @@ export function login(data: Record) { */ export function register(data: Record) { return request({ - url: '/register', + url: '/auth/register', method: 'POST', data: data, whithToken: false, - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', + }); +} + +/** + * 刷新登录令牌 + * @param data 数据 + * @returns 结果 + */ +export function refreshToken(refreshToken: string) { + return request({ + url: '/auth/refresh-token', + method: 'POST', + data: { refreshToken }, + whithToken: false, }); } @@ -40,16 +66,15 @@ export function getInfo() { } /** - * 退出方法 + * 获取路由 * @returns object */ -export function logout() { +export const getRouter = () => { return request({ - url: '/logout', - method: 'POST', - repeatSubmit: false, + url: '/router', + method: 'GET', }); -} +}; /** * 获取验证码 diff --git a/src/api/faultManage/actAlarm.ts b/src/api/faultManage/actAlarm.ts index a53fda48..210d9023 100644 --- a/src/api/faultManage/actAlarm.ts +++ b/src/api/faultManage/actAlarm.ts @@ -116,6 +116,21 @@ export function clearAlarm(ids: number[]) { }); } +/** + * 告警信息导出 + * @param params 查询列表条件 + * @returns object + */ +export function exportAlarm(params: Record) { + return request({ + url: '/neData/alarm/export', + method: 'GET', + params: params, + responseType: 'blob', + timeout: 60_000, + }); +} + /** * 手工同步 * @param data 鉴权对象 diff --git a/src/api/faultManage/historyAlarm.ts b/src/api/faultManage/historyAlarm.ts index f6648b36..231884c7 100644 --- a/src/api/faultManage/historyAlarm.ts +++ b/src/api/faultManage/historyAlarm.ts @@ -4,19 +4,6 @@ import { parseObjLineToHump } from '@/utils/parse-utils'; import { parseDateToStr } from '@/utils/date-utils'; import useUserStore from '@/store/modules/user'; -/** - * 查询列表 - * @param query 查询参数 - * @returns object - */ -export async function listAct(query: Record) { - return await request({ - url: `/neData/alarm/list`, - method: 'GET', - params: query, - }); -} - /** * 确认告警信息 * @param data 鉴权对象 diff --git a/src/api/index.ts b/src/api/index.ts index 4806e43c..f7d04d31 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,65 +1,5 @@ import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { request } from '@/plugins/http-fetch'; -import { parseDateToStr } from '@/utils/date-utils'; -import { NE_TYPE_LIST } from '@/constants/ne-constants'; - -/** - * 查询公告列表 - * @param query 查询参数 - * @returns object - */ -export async function listMain() { - const result = await request({ - url: '/api/rest/systemManagement/v1/elementType/all/objectType/systemState', - method: 'GET', - timeout: 60_000, - }); - // console.log(result); - let realData = result.data.data; - const mergedData = realData.map((obj: any) => { - // console.log(obj); - const [key, value] = Object.entries(obj)[0]; - const ipAddress = (value as any).ipAddress; - const systemState = (value as any).systemState; - const serialNum = (value as any).serialNum; - const version = (value as any).version; - - const errCode = systemState && systemState['errorCode']; - var time = new Date(); - // console.log(key, value); - let mergedObj; - if (errCode === undefined && systemState) { - mergedObj = { - ...systemState, - refresh: parseDateToStr(time), - ipAddress: ipAddress, - name: key.split('/').join('_'), - status: 'Normal', - }; - } else { - mergedObj = { - version, - refresh: parseDateToStr(time), - ipAddress, - serialNum, - name: key.split('/').join('_'), - expiryDate: '-', - status: 'Abnormal', - }; - } - return mergedObj; - }); - //通过sort进行冒泡排序 - mergedData.sort((a: any, b: any) => { - const typeA = NE_TYPE_LIST.indexOf(a.name.split('_')[0]); - const typeB = NE_TYPE_LIST.indexOf(b.name.split('_')[0]); - if (typeA === -1) return 1; // 如果不在特定顺序中,排到后面 - if (typeB === -1) return -1; // 如果不在特定顺序中,排到后面 - return typeA - typeB; - }); - - return mergedData; -} /** * 获取服务器时间 diff --git a/src/api/logManage/exportFile.ts b/src/api/logManage/exportFile.ts index 19f7b068..2ce72877 100644 --- a/src/api/logManage/exportFile.ts +++ b/src/api/logManage/exportFile.ts @@ -53,43 +53,3 @@ export function delFile(query: Record) { params: query, }); } - -/** - * 更新FTP信息 - * @param data 数据 - * @returns object - */ -export function updateFTPInfo(data: Record) { - return request({ - url: `/lm/table/ftp`, - method: 'POST', - data: data, - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', - }); -} - -/** - * 获取FTP信息 - * @param data 数据 - * @returns object - */ -export function getFTPInfo() { - return request({ - url: `/lm/table/ftp`, - method: 'GET', - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', - }); -} - -/** - * 发送FTP文件 - * @param data 数据 - * @returns object - */ -export function putFTPInfo(filePath: string, fileName: string) { - return request({ - url: `/lm/table/ftp`, - method: 'PUT', - data: { filePath, fileName }, - }); -} diff --git a/src/api/ne/neConfigBackup.ts b/src/api/ne/neConfigBackup.ts index e6b8c817..af63fdea 100644 --- a/src/api/ne/neConfigBackup.ts +++ b/src/api/ne/neConfigBackup.ts @@ -83,43 +83,3 @@ export function importNeConfigBackup(data: Record) { data: data, }); } - -/** - * 更新FTP信息 - * @param data 数据 - * @returns object - */ -export function updateFTPInfo(data: Record) { - return request({ - url: `/ne/config/backup/ftp`, - method: 'POST', - data: data, - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', - }); -} - -/** - * 获取FTP信息 - * @param data 数据 - * @returns object - */ -export function getFTPInfo() { - return request({ - url: `/ne/config/backup/ftp`, - method: 'GET', - crypto: sessionGet(CACHE_SESSION_CRYPTO_API) !== 'false', - }); -} - -/** - * 发送FTP文件 - * @param data 数据 - * @returns object - */ -export function putFTPInfo(path: string) { - return request({ - url: `/ne/config/backup/ftp`, - method: 'PUT', - data: { path }, - }); -} diff --git a/src/api/neData/backup.ts b/src/api/neData/backup.ts new file mode 100644 index 00000000..eeb3781c --- /dev/null +++ b/src/api/neData/backup.ts @@ -0,0 +1,38 @@ +import { request } from '@/plugins/http-fetch'; + +/** + * 备份文件-获取FTP配置 + * @returns object + */ +export function getBackupFTP() { + return request({ + url: '/neData/backup/ftp', + method: 'GET', + }); +} + +/** + * 备份文件-文件FTP发送 + * @param data 对象 + * @returns object + */ +export function pushBackupFTP(data: Record) { + return request({ + url: '/neData/backup/ftp', + method: 'POST', + data, + }); +} + +/** + * 备份文件-更新FTP配置 + * @param data 对象 + * @returns object + */ +export function updateBackupFTP(data: Record) { + return request({ + url: '/neData/backup/ftp', + method: 'PUT', + data, + }); +} diff --git a/src/api/neData/udm_voip.ts b/src/api/neData/udm_voip.ts new file mode 100644 index 00000000..0046de39 --- /dev/null +++ b/src/api/neData/udm_voip.ts @@ -0,0 +1,134 @@ +import { request } from '@/plugins/http-fetch'; + +/** + * UDMVOIP用户重载数据 + * @param neId 网元ID + * @returns object + */ +export function resetUDMVOIP(neId: string) { + return request({ + url: `/neData/udm/voip/resetData/${neId}`, + method: 'PUT', + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户列表 + * @param query 查询参数 + * @returns object + */ +export function listUDMVOIP(query: Record) { + return request({ + url: '/neData/udm/voip/list', + method: 'GET', + params: query, + timeout: 30_000, + }); +} + +/** + * UDMVOIP用户信息 + * @param neId 网元ID + * @param username username + * @returns object + */ +export function getUDMVOIP(neId: string, username: string) { + return request({ + url: `/neData/udm/voip/${neId}/${username}`, + method: 'GET', + }); +} + +/** + * UDMVOIP用户新增 + * @param data VOIP对象 + * @returns object + */ +export function addUDMVOIP( + neId: string, + data: { username: string; password: string } +) { + return request({ + url: `/neData/udm/voip/${neId}`, + method: 'POST', + data: data, + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户批量新增 + * @param data VOIP对象 + * @param num 数量 + * @returns object + */ +export function batchAddUDMVOIP( + neId: string, + data: { username: string; password: string }, + num: number +) { + return request({ + url: `/neData/udm/voip/${neId}/${num}`, + method: 'POST', + data: data, + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户删除 + * @param data VOIP对象 + * @returns object + */ +export function delUDMVOIP(neId: string, username: string) { + return request({ + url: `/neData/udm/voip/${neId}/${username}`, + method: 'DELETE', + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户批量删除 + * @param neId 网元ID + * @param username username + * @param num 数量 + * @returns object + */ +export function batchDelUDMVOIP(neId: string, username: string, num: number) { + return request({ + url: `/neData/udm/voip/${neId}/${username}/${num}`, + method: 'DELETE', + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户导出 + * @param data 数据参数 + * @returns bolb + */ +export function exportUDMVOIP(data: Record) { + return request({ + url: '/neData/udm/voip/export', + method: 'GET', + params: data, + responseType: 'blob', + timeout: 180_000, + }); +} + +/** + * UDMVOIP用户导入 + * @param data 表单数据对象 + * @returns object + */ +export function importUDMVOIP(data: Record) { + return request({ + url: `/neData/udm/voip/import`, + method: 'POST', + data, + timeout: 180_000, + }); +} diff --git a/src/api/neData/udm_volte_ims.ts b/src/api/neData/udm_volte_ims.ts new file mode 100644 index 00000000..7a96bd30 --- /dev/null +++ b/src/api/neData/udm_volte_ims.ts @@ -0,0 +1,127 @@ +import { request } from '@/plugins/http-fetch'; + +/** + * UDMVolteIMS用户重载数据 + * @param neId 网元ID + * @returns object + */ +export function resetUDMVolteIMS(neId: string) { + return request({ + url: `/neData/udm/volte-ims/resetData/${neId}`, + method: 'PUT', + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户列表 + * @param query 查询参数 + * @returns object + */ +export function listUDMVolteIMS(query: Record) { + return request({ + url: '/neData/udm/volte-ims/list', + method: 'GET', + params: query, + timeout: 30_000, + }); +} + +/** + * UDMVolteIMS用户信息 + * @param neId 网元ID + * @param imsi IMSI + * @returns object + */ +export function getUDMVolteIMS(neId: string, imsi: string) { + return request({ + url: `/neData/udm/volte-ims/${neId}/${imsi}`, + method: 'GET', + }); +} + +/** + * UDMVolteIMS用户新增 + * @param data 签约对象 + * @returns object + */ +export function addUDMVolteIMS(data: Record) { + return request({ + url: `/neData/udm/volte-ims/${data.neId}`, + method: 'POST', + data: data, + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户批量新增 + * @param data 签约对象 + * @param num 数量 + * @returns object + */ +export function batchAddUDMVolteIMS(data: Record, num: number) { + return request({ + url: `/neData/udm/volte-ims/${data.neId}/${num}`, + method: 'POST', + data: data, + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户删除 + * @param data 签约对象 + * @returns object + */ +export function delUDMVolteIMS(neId: string, imsi: string) { + return request({ + url: `/neData/udm/volte-ims/${neId}/${imsi}`, + method: 'DELETE', + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户批量删除 + * @param neId 网元ID + * @param imsi IMSI + * @param num 数量 + * @returns object + */ +export function batchDelUDMVolteIMS(neId: string, imsi: string, num: number) { + return request({ + url: `/neData/udm/volte-ims/${neId}/${imsi}/${num}`, + method: 'DELETE', + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户导出 + * @param data 数据参数 + * @returns bolb + */ +export function exportUDMVolteIMS(data: Record) { + return request({ + url: '/neData/udm/volte-ims/export', + method: 'GET', + params: data, + responseType: 'blob', + timeout: 180_000, + }); +} + +/** + * UDMVolteIMS用户导入 + * @param data 表单数据对象 + * @returns object + */ +export function importUDMVolteIMS(data: Record) { + return request({ + url: `/neData/udm/volte-ims/import`, + method: 'POST', + data, + timeout: 180_000, + }); +} diff --git a/src/api/perfManage/taskManage.ts b/src/api/perfManage/taskManage.ts index bcd32b47..bd9e99ec 100644 --- a/src/api/perfManage/taskManage.ts +++ b/src/api/perfManage/taskManage.ts @@ -220,6 +220,6 @@ export function taskRun(data: Record) { export function taskStop(data: Record) { return request({ url: `/api/rest/performanceManagement/v1/elementType/${data.neType.toLowerCase()}/objectType/measureTask?id=${data.id}`, - method: 'PATCH', + method: 'PUT', }); } \ No newline at end of file diff --git a/src/api/router.ts b/src/api/router.ts deleted file mode 100644 index 4846be2b..00000000 --- a/src/api/router.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { request } from '@/plugins/http-fetch'; - -/** - * 获取路由 - * @returns object - */ -export const getRouters = () => { - return request({ - url: '/router', - method: 'GET', - }); -}; diff --git a/src/api/system/user.ts b/src/api/system/user.ts index 4563069f..f59758f8 100644 --- a/src/api/system/user.ts +++ b/src/api/system/user.ts @@ -136,3 +136,16 @@ export function changeUserStatus( data: { userId, statusFlag }, }); } + +/** + * 用户强制重置密码 + * @param password 密码 + * @returns object + */ +export function updateUserPasswordForce(password: string) { + return request({ + url: '/system/user/profile/password-force', + method: 'PUT', + data: { password }, + }); +} diff --git a/src/api/tool/file.ts b/src/api/tool/file.ts index 5a29df83..ff31c5ae 100644 --- a/src/api/tool/file.ts +++ b/src/api/tool/file.ts @@ -210,6 +210,50 @@ export function chunkUpload(data: FormData) { }); } +/** + * 本地文件列表 + * @param path 文件路径 + * @param search search prefix + * @returns object + */ +export async function listFile(query: Record) { + return request({ + url: `/file/list`, + method: 'GET', + params: query, + }); +} + +/** + * 本地文件获取下载 + * @param path 文件路径 + * @param fileName 文件名 + * @returns object + */ +export async function getFile(path: string, fileName: string) { + return request({ + url: `/file`, + method: 'GET', + params: { path, fileName }, + responseType: 'blob', + timeout: 60_000, + }); +} + +/** + * 本地文件删除 + * @param path 文件路径 + * @param fileName 文件名 + * @returns object + */ +export async function delFile(path: string, fileName: string) { + return request({ + url: `/file`, + method: 'DELETE', + params: { path, fileName }, + }); +} + /** * 转存上传文件到静态资源 * @returns object diff --git a/src/api/trace/analysis.ts b/src/api/trace/analysis.ts deleted file mode 100644 index 1a4ccf11..00000000 --- a/src/api/trace/analysis.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { request } from '@/plugins/http-fetch'; - -/** - * 跟踪任务数据列表 - * @param query 查询参数 - * @returns object - */ -export async function listTraceData(query: Record) { - return request({ - url: '/trace/task/list', - method: 'GET', - params: query, - }); -} - -/** - * 信令数据解析HTML - * @param id 任务ID - * @returns - */ -export function getTraceRawInfo(id: Record) { - return request({ - url: `/api/rest/traceManagement/v1/decMessage/${id}`, - method: 'GET', - responseType: 'text', - }); -} diff --git a/src/api/trace/packet.ts b/src/api/trace/packet.ts index 2266e510..57f777dd 100644 --- a/src/api/trace/packet.ts +++ b/src/api/trace/packet.ts @@ -62,3 +62,18 @@ export function packetKeep(taskNo: string, duration: number = 120) { data: { taskNo, duration }, }); } + +/** + * 信令跟踪文件 + * @param taskNo 对象 + * @returns object + */ +export function packetPCAPFile(taskNo: string) { + return request({ + url: '/trace/packet/filePull', + method: 'GET', + params: { taskNo }, + responseType: 'blob', + timeout: 180_000, + }); +} diff --git a/src/api/trace/task.ts b/src/api/trace/task.ts index d30473e1..629b71ba 100644 --- a/src/api/trace/task.ts +++ b/src/api/trace/task.ts @@ -76,29 +76,31 @@ export function filePullTask(traceId: string) { method: 'GET', params: { traceId }, responseType: 'blob', - timeout: 60_000, + timeout: 180_000, }); } /** - * 获取网元跟踪接口列表 + * 跟踪任务数据列表 + * @param query 查询参数 * @returns object */ -export async function getNeTraceInterfaceAll() { - // 发起请求 - const result = await request({ - url: `/api/rest/databaseManagement/v1/elementType/omc_db/objectType/ne_info`, +export async function listTraceData(query: Record) { + return request({ + url: '/trace/data/list', + method: 'GET', + params: query, + }); +} + +/** + * 查询跟踪任务数据信息 + * @param id ID + * @returns object + */ +export async function getTraceData(id: string | number) { + return request({ + url: `/trace/data/${id}`, method: 'GET', - params: { - SQL: `SELECT ne_type,interface FROM trace_info GROUP BY ne_type,interface`, - }, }); - // 解析数据 - if (result.code === RESULT_CODE_SUCCESS && Array.isArray(result.data.data)) { - let data = result.data.data[0]; - return Object.assign(result, { - data: parseObjLineToHump(data['trace_info']), - }); - } - return result; } diff --git a/src/components/ForcePasswdChange/index.vue b/src/components/ForcePasswdChange/index.vue new file mode 100644 index 00000000..0229ffd8 --- /dev/null +++ b/src/components/ForcePasswdChange/index.vue @@ -0,0 +1,218 @@ + + + + diff --git a/src/constants/result-constants.ts b/src/constants/result-constants.ts index ae7dfeeb..76332a40 100644 --- a/src/constants/result-constants.ts +++ b/src/constants/result-constants.ts @@ -1,14 +1,14 @@ /**响应-code加密数据 */ -export const RESULT_CODE_ENCRYPT = 2; +export const RESULT_CODE_ENCRYPT = 200999; /**响应-msg加密数据 */ export const RESULT_MSG_ENCRYPT: Record = { zh_CN: '加密!', - en_US: 'encrypt!', + en_US: 'Encrypt!', }; /**响应-code正常成功 */ -export const RESULT_CODE_SUCCESS = 1; +export const RESULT_CODE_SUCCESS = 200001; /**响应-msg正常成功 */ export const RESULT_MSG_SUCCESS: Record = { @@ -17,7 +17,16 @@ export const RESULT_MSG_SUCCESS: Record = { }; /**响应-code错误失败 */ -export const RESULT_CODE_ERROR = 0; +export const RESULT_CODE_ERROR = 400001; + +/**响应-code错误异常 */ +export const RESULT_CODE_EXCEPTION = 500001; + +/**响应-服务器连接出错 */ +export const RESULT_MSG_SERVER_ERROR: Record = { + zh_CN: '服务器连接出错!', + en_US: 'Server Connection Error!', +}; /**响应-msg错误失败 */ export const RESULT_MSG_ERROR: Record = { @@ -37,18 +46,6 @@ export const RESULT_MSG_NOT_TYPE: Record = { en_US: 'Unknown Response Data Type!', }; -/**响应-服务器连接出错 */ -export const RESULT_MSG_SERVER_ERROR: Record = { - zh_CN: '服务器连接出错!', - en_US: 'Server Connection Error!', -}; - -/**响应-请求地址未找到 */ -export const RESULT_MSG_URL_NOTFOUND: Record = { - zh_CN: '请求地址未找到!', - en_US: 'Request Address Not Found!', -}; - /**响应-数据正在处理,请勿重复提交 */ export const RESULT_MSG_URL_RESUBMIT: Record = { zh_CN: '数据正在处理,请勿重复提交!', diff --git a/src/constants/token-constants.ts b/src/constants/token-constants.ts index 03d2cc87..44316013 100644 --- a/src/constants/token-constants.ts +++ b/src/constants/token-constants.ts @@ -2,10 +2,13 @@ export const TOKEN_RESPONSE_FIELD = 'accessToken'; /**令牌-请求头标识前缀 */ -export const TOKEN_KEY_PREFIX = 'Bearer '; +export const TOKEN_KEY_PREFIX = 'Bearer'; /**令牌-请求头标识 */ export const TOKEN_KEY = 'Authorization'; -/**令牌-存放Cookie标识 */ -export const TOKEN_COOKIE = 'AuthOMC'; +/**令牌-访问令牌存放Cookie标识 */ +export const TOKEN_ACCESS_COOKIE = 'omc_access'; + +/**令牌-刷新令牌存放Cookie标识 */ +export const TOKEN_REFRESH_COOKIE = 'omc_refresh'; diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 60f189c4..2662f1f1 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -16,7 +16,6 @@ export default { errorFields: 'Please fill in the required information in {num} correctly!', tablePaginationTotal: 'Total {total} items', noData: "No Data", - zebra:'Tabular zebra pattern', ok: 'Ok', cancel: 'Cancel', close: 'Close', @@ -131,7 +130,7 @@ export default { }, LockScreen: { inputPlacePwd:'Lock Screen Password', - validSucc:'Validation Passed', + enter:'Enter', validError:'Validation Failure', backLogin:'Logout to Relogin', backReload:'Restarting now, please wait...', @@ -139,6 +138,14 @@ export default { systemReset:'Resetting now, please wait...', systemReset2:'Data information is being reset.', }, + ForcePasswdChange: { + title: 'Password Change', + desc: 'Instruction', + passwordPolicy: 'Password policy strength', + passwordPolicyMsg: 'At least {minLength} bits, containing at least {specialChars} special characters and at least {uppercase} uppercase and at least {lowercase} lowercase letters.', + passwdExpire: 'Password expiration date', + passwdExpireMsg: 'Valid for {expDay} days, please change your password {alertDay} days before expiration.', + }, }, // 静态路由 @@ -163,7 +170,7 @@ export default { userNameReg: 'The account cannot start with a number and can contain uppercase and lowercase letters, numbers, and no less than 5 digits.', userNamePlease: 'Please enter the correct login account', userNameHit: 'Login account', - passwordReg: 'The password should contain at least uppercase and lowercase letters, numbers, special symbols, and no less than 6 digits.', + passwordReg: 'Please enter the correct password format', passwordPlease: 'Please enter the correct login password', passwordHit: 'Login password', passwordConfirmHit: 'Confirm login password', @@ -295,7 +302,7 @@ export default { oldPasswordTip: "The old password must not be empty and must be at least 6 digits long", oldPasswordPleace: "Please enter the old password", newPassword: "New Password", - newPasswordTip: "Password contains at least upper and lower case letters, numbers, special symbols, and not less than 6 digits", + newPasswordTip: "Please enter the correct password format", newPassworddPleace: "Please enter a new password", confirmPassword: "Confirm new password", confirmPasswordPleace: "Please confirm the new password", @@ -506,7 +513,7 @@ export default { delTip: 'Confirm deletion of network element information data items?', oam: { title: 'OAM Configuration', - sync: 'Sync to NE', + restart: 'Restart NE', oamEnable: 'Service', oamPort: 'Port', snmpEnable: 'Service', @@ -659,6 +666,19 @@ export default { name: "Name", downTip: 'Confirmed to download the backup file [{txt}]?', title: "Modify Backup {txt}", + backupModal: { + pushFileOper: "Send Current File To Remote Backup", + title: "Setting Remote Backup Service", + enable: "Enable", + toIp: "Service IP", + toIpPleace: "Please input the remote backup server IP address", + toPort: "Service Port", + username: "UserName", + usernamePleace: 'Please enter the service login username', + password: "Password", + dir: "Save Dir", + dirPleace: 'Please enter the service address target file directory', + } }, neQuickSetup: { reloadPara5G: 'Reload', @@ -711,8 +731,45 @@ export default { }, neData: { common: { + startIMSI: 'Starting IMSI', + imsi: 'IMSI', + imsiTip: 'IMSI=MCC+MNC+MSIN', + imsiTip1: 'MCC=Mobile Country Code, consisting of three digits.', + imsiTip2: 'MNC = Mobile Network Number, consisting of two digits', + imsiTip3: 'MSIN = Mobile Subscriber Identification Number, consisting of 10 equal digits.', + imsiPlease: "Please enter IMSI correctly", + msisdn: 'Mobile Customer Identification Number', + msisdnPlease: "Please enter the Mobile Customer Identification Number correctly", + loadDataConfirm: 'Confirmed to reload data?', + loadData: 'Load Data', + loadDataTip: 'Successfully fetched loaded data: {num} items, the system is internally updating the data, it will take about {timer} seconds, please wait!!!!!.', + batchOper: 'Batch Operation', + batchAddText: 'Batch Addition', + batchDelText: 'Batch Deletion', + batchUpdateText: 'Batch Update', + batchNum: 'Number of releases', + checkDel:'Check Delete', importTemplate: 'Download Template', }, + udmVOIP: { + startUsername: 'Starting username', + username: 'username', + usernamePlease: "Please enter your username correctly", + password: "password", + passwordPlease: "Please enter your password correctly", + addTitle: 'Add VOIP subscriber', + delTip: 'Confirm that you want to delete the information of VOIP user as [{num}]?', + exportTip: "Confirm exporting xlsx table files based on search criteria?", + }, + udmVolteIMS: { + startMSISDN: 'Starting MSISDN', + voipTip: 'When VoIP is selected MSISDN will be equal to IMSI', + addTitle: 'Addition of new IMS subscribers', + vniTip: 'Example: ims.mnc000.mcc000.3gppnetwork.org', + vniPlease: 'Please enter VNI correctly', + delTip: 'Are you sure you want to delete the information of IMS signing as [{num}]?', + exportTip: "Confirm exporting xlsx table files based on search criteria?", + }, baseStation: { list: "List", topology: "Topology", @@ -735,6 +792,12 @@ export default { exportTip: "Confirm exporting xlsx table files based on search criteria?", importDataEmpty: "Imported data is empty", }, + backupData: { + auth: "UDM Authentication", + sub: "UDM Subscribers", + voip: "VoIP Authentication", + volte: "IMS Subscribers", + } }, neUser: { auth: { @@ -1004,25 +1067,6 @@ export default { }, }, traceManage: { - analysis: { - imsi: 'IMSI', - imsiPlease: 'Please enter IMSI', - msisdn: 'MSISDN', - msisdnPlease: 'Please enter MSISDN', - trackTaskId: 'Task ID', - srcIp: 'Source IP Address', - dstIp: 'Destination IP Address', - signalType: 'Signaling Type', - msgDirect: 'Message Direction', - msgType: 'Message Type', - rowTime: 'Record Time', - signalData: 'Signaling Data', - signalDetail: 'Signaling Details', - noData: 'No information content', - taskTitle: 'Task {num}', - taskDownText: 'Download HTML', - taskDownTip: 'Confirm downloading the signaling details HTML file?', - }, pcap: { capArgPlease: 'Please enter tcpdump -i any support parameter', cmd: 'Command', @@ -1073,30 +1117,35 @@ export default { imsiTip: 'Mobile communication IMSI number', srcIp: 'Source IP Address', srcIpPlease: 'Please enter the IP address', - srcIpTip: 'Current sender IPv4 address', + srcIpTip: 'sending IPv4 address', dstIp: 'Destination IP Address', dstIpPlease: 'Please enter the IP address', - dstIpTip: 'IPv4 address of the receiving end of the other party', + dstIpTip: 'receiving end IPv4 address', interfaces: 'Signaling Interface', interfacesPlease: 'Please enter the signaling interface', - signalPort: 'Signal Port', - signalPortPlease: 'Please enter the signaling port', - signalPortTip: 'Port of the side corresponding to the destination IP address or source IP address', - rangePicker: 'Start/End Time', + rangePicker: 'Task Time', rangePickerPlease: 'Please select the start and end time of the task', remark: 'Remark', remarkPlease: 'Task description can be entered', addTask: 'Add Task', - editTask: 'Modify Task', viewTask: 'View Task', errorTaskInfo: 'Failed to obtain task information', delTaskTip: 'Are you sure to delete the data item with record ID {id} ?', stopTask: 'Successful cessation of tasks {id}', stopTaskTip: 'Confirm stopping the task with record ID {id} ?', - pcapView: "Tracking Data Analysis", - traceFile: "Tracking File", + pcapView: "Track Data Analysis", + traceFile: "Track File", errMsg: "Error Message", imsiORmsisdn: "imsi or msisdn is null, cannot start task", + dataView: "Track Data", + protocolOrInterface: "Protocol/Interface", + msgNe: 'Network Element', + msgEvent: 'Event', + msgType: 'Type', + msgDirect: 'Direction', + msgLen: 'Length', + rowTime: 'Time', + taskInfo: 'Task information', }, }, faultManage: { @@ -1141,13 +1190,11 @@ export default { delSuss:'Clear successfully', delSure:'Whether to clear this alarm', showSet:'Show filter settings', + exportTip: "Confirm exporting xlsx table files based on search criteria?", exportSure:'Confirm whether to export all active alarm information', viewIdInfo:'View {alarmId} record information', closeModal:'Close', }, - historyAlarm:{ - exportSure:'Confirm whether to export all historical alarm information', - }, faultSetting:{ interfaceType:'Type', email:'Email', @@ -1216,12 +1263,17 @@ export default { tailLines: 'End Lines', }, exportFile:{ - fileName:'File Source', + fileSource:'File Source', + fileSourcePlease:'Please select the source of the document', downTip: "Confirm the download file name is [{fileName}] File?", downTipErr: "Failed to get file", deleteTip: "Confirm the delete file name is [{fileName}] File?", deleteTipErr: "Failed to delete file", - selectTip:"Please select File Name", + operateLog:'Operation Log', + cdrIMS:'Voice CDR', + cdrSMF:'Data CDR', + cdrSMSC:'SMS CDR', + cdrSGWC:'Roaming Data CDR', } }, monitor: { @@ -1599,7 +1651,7 @@ export default { loginTime: 'Login Time', status: 'Status', userNameTip:'The account number can only contain strings of uppercase letters, lowercase letters and numbers with a minimum length of 6 digits', - passwdTip:'The password should contain at least uppercase and lowercase letters, numbers, special symbols, and no less than 6 digits', + passwdTip:'Please enter the correct password format', nickNameTip:'Nicknames no less than 2 digits', emailTip:'Please enter the correct email address', phoneTip:'Please enter the correct phone number', diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index f12de383..7ecd1703 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -16,7 +16,6 @@ export default { errorFields: '请正确填写 {num} 处必填信息!', tablePaginationTotal: '总共 {total} 条', noData: "暂无数据", - zebra:'表格斑马纹', ok: '确定', cancel: '取消', close: '关闭', @@ -131,7 +130,7 @@ export default { }, LockScreen: { inputPlacePwd:'请输入锁屏密码', - validSucc:'校验通过', + enter:'进入', validError:'校验失败', backLogin:'退出并重新登录', backReload:'正在重启,请稍等...', @@ -139,6 +138,14 @@ export default { systemReset:'正在重置,请稍等...', systemReset2:'数据信息正在重置', }, + ForcePasswdChange: { + title: '密码修改', + desc: '说明', + passwordPolicy: '密码策略强度', + passwordPolicyMsg: '至少{minLength}位,至少包含{specialChars}个特殊字符和至少{uppercase}大写字母和至少{lowercase}小写字母', + passwdExpire: '密码有效期', + passwdExpireMsg: '有效期为{expDay}天,请在过期前{alertDay}天进行密码修改', + }, }, // 静态路由 @@ -163,7 +170,7 @@ export default { userNameReg: '账号不能以数字开头,可包含大写小写字母,数字,且不少于5位', userNamePlease: '请输入正确登录账号', userNameHit: '登录账号', - passwordReg: '密码至少包含大小写字母、数字、特殊符号,且不少于6位', + passwordReg: '请输入正确的密码格式', passwordPlease: '请输入正确登录密码', passwordHit: '登录密码', passwordConfirmHit: '确认登录密码', @@ -295,7 +302,7 @@ export default { oldPasswordTip: "旧密码不能为空,且不少于6位", oldPasswordPleace: "请输入旧密码", newPassword: "新密码", - newPasswordTip: "密码至少包含大小写字母、数字、特殊符号,且不少于6位", + newPasswordTip: "请输入正确的密码格式", newPassworddPleace: "请输入新密码", confirmPassword: "确认新密码", confirmPasswordPleace: "请确认新密码", @@ -506,7 +513,7 @@ export default { delTip: '确认删除网元信息数据项吗?', oam: { title: 'OAM配置', - sync: '同步到网元', + restart: '下发后重启网元', oamEnable: '服务', oamPort: '端口', snmpEnable: '服务', @@ -659,6 +666,19 @@ export default { name: "名称", downTip: '确认要下载备份文件【{txt}】吗?', title: "修改备份信息 {txt}", + backupModal: { + pushFileOper: "将当前文件发送到远程备份", + title: "设置远程备份服务", + enable: "启用", + toIp: "服务IP", + toIpPleace: "请输入远程备份服务器 IP 地址", + toPort: "服务端口", + username: "登录用户名", + usernamePleace: '请输入服务登录用户名', + password: "登录密码", + dir: "保存目录", + dirPleace: '请输入服务地址目标文件目录', + } }, neQuickSetup: { reloadPara5G: '刷新', @@ -711,8 +731,45 @@ export default { }, neData: { common: { + startIMSI: '起始IMSI', + imsi: 'IMSI', + imsiTip: 'IMSI=MCC+MNC+MSIN', + imsiTip1: 'MCC=移动国家号码, 由三位数字组成', + imsiTip2: 'MNC=移动网络号,由两位数字组成', + imsiTip3: 'MSIN=移动客户识别码,采用等长10位数字构成', + imsiPlease: "请正确输入IMSI", + msisdn: '移动客户识别码', + msisdnPlease: "请正确输入移动客户识别码", + loadDataConfirm: '确认要重新加载数据吗?', + loadData: '加载数据', + loadDataTip: '成功获取加载数据:{num}条,系统内部正在进行数据更新,大约需要{timer}秒,请稍候!!!', + batchOper: '批量操作', + batchAddText: '批量新增', + batchDelText: '批量删除', + batchUpdateText: '批量更新', + batchNum: '批量个数', + checkDel:'勾选删除', importTemplate: '导入模板', }, + udmVOIP: { + startUsername: '起始用户名', + username: '用户名', + usernamePlease: "请正确输入用户名", + password: "密码", + passwordPlease: "请正确输入密码", + addTitle: '新增VOIP用户', + delTip: '确认要删除VOIP用户为【{num}】的信息吗?', + exportTip: "确认根据搜索条件导出xlsx表格文件吗?", + }, + udmVolteIMS: { + startMSISDN: '起始MSISDN', + voipTip: '当选择VoIP时MSISDN会等于IMSI', + addTitle: '新增IMS签约用户', + vniTip: '示例:ims.mnc000.mcc000.3gppnetwork.org', + vniPlease: '请正确输入VNI', + delTip: '确认要删除IMS签约为【{num}】的信息吗?', + exportTip: "确认根据搜索条件导出xlsx表格文件吗?", + }, baseStation: { list: "列表", topology: "拓扑图", @@ -735,6 +792,12 @@ export default { exportTip: "确认根据搜索条件导出xlsx表格文件吗?", importDataEmpty: "导入数据为空", }, + backupData: { + auth: "UDM鉴权用户", + sub: "UDM签约用户", + voip: "VOIP鉴权用户", + volte: "IMS签约用户", + } }, neUser: { auth: { @@ -1004,25 +1067,6 @@ export default { }, }, traceManage: { - analysis: { - imsi: 'IMSI', - imsiPlease: '请输入IMSI', - msisdn: 'MSISDN', - msisdnPlease: '请输入MSISDN', - trackTaskId: '跟踪任务标记', - srcIp: '源IP地址', - dstIp: '目标IP地址', - signalType: '信令类型', - msgDirect: '消息元', - msgType: '消息类型', - rowTime: '记录时间', - signalData: '信令数据', - signalDetail: '信令详情', - noData: '无信息内容', - taskTitle: '任务 {num}', - taskDownText: '下载HTML', - taskDownTip: '确认下载信令详情HTML文件?', - }, pcap: { capArgPlease: '请输入tcpdump -i any支持参数', cmd: '命令', @@ -1073,21 +1117,17 @@ export default { imsiTip: '移动通信IMSI编号', srcIp: '源IP地址', srcIpPlease: '请输入源IP地址', - srcIpTip: '当前发送端IPv4地址', + srcIpTip: '发送端IPv4地址', dstIp: '目标IP地址', dstIpPlease: '请输入目标IP地址', - dstIpTip: '对方接收端IPv4地址', + dstIpTip: '接收端IPv4地址', interfaces: '信令接口', interfacesPlease: '请输入信令接口', - signalPort: '信令端口', - signalPortPlease: '请输入信令端口', - signalPortTip: '目标IP地址或源IP地址对应一方的端口', - rangePicker: '开始结束时间', + rangePicker: '任务时间', rangePickerPlease: '请选择任务时间开始结束时间', remark: '说明', remarkPlease: '可输入任务说明', addTask: '添加任务', - editTask: '修改任务', viewTask: '查看任务', errorTaskInfo: '获取任务信息失败', delTaskTip: '确认删除记录编号为 {id} 的数据项?', @@ -1097,6 +1137,15 @@ export default { traceFile: "跟踪文件", errMsg: "错误信息", imsiORmsisdn: "imsi 或 msisdn 是空值,不能开始任务", + dataView: "跟踪数据", + protocolOrInterface: "协议/接口", + msgNe: '消息网元', + msgEvent: '消息事件', + msgType: '消息类型', + msgDirect: '消息方向', + msgLen: '消息长度', + rowTime: '消息时间', + taskInfo: '任务信息', }, }, faultManage: { @@ -1141,13 +1190,11 @@ export default { delSuss:'清除成功', delSure:'是否清除该告警', showSet:'显示过滤设置', + exportTip: "确认根据搜索条件导出xlsx表格文件吗?", exportSure:'确认是否导出全部活动告警信息', viewIdInfo:'查看{alarmId} 记录信息', closeModal:'关闭', }, - historyAlarm:{ - exportSure:'确认是否导出全部历史告警信息?', - }, faultSetting:{ interfaceType:'类型', email:'Email', @@ -1179,7 +1226,7 @@ export default { type:'网元类型', neId:'网元唯一标识', MML:'MML', - logTime:'log Time' + logTime:'记录时间' }, forwarding:{ alarmId:'告警唯一标识', @@ -1216,12 +1263,17 @@ export default { tailLines: '末尾行数', }, exportFile:{ - fileName:'文件来源', + fileSource:'文件来源', + fileSourcePlease:'请选择文件来源', downTip: "确认下载文件名为 【{fileName}】 文件?", downTipErr: "文件获取失败", deleteTip: "确认删除文件名为 【{fileName}】 文件?", deleteTipErr: "文件删除失败", - selectTip:"请选择文件名", + operateLog:'操作日志', + cdrIMS:'语音话单', + cdrSMF:'数据话单', + cdrSMSC:'短信话单', + cdrSGWC:'漫游数据话单', } }, monitor: { @@ -1599,7 +1651,7 @@ export default { loginTime: '登录时间', status: '用户状态', userNameTip:'账号只能包含大写字母、小写字母和数字的字符串,长度至少为6位', - passwdTip:'密码至少包含大小写字母、数字、特殊符号,且不少于6位', + passwdTip:'请输入正确的密码格式', nickNameTip:'昵称不少于2位', emailTip:'请输入正确的邮箱地址', phoneTip:'请输入正确的手机号码', diff --git a/src/layouts/BasicLayout.vue b/src/layouts/BasicLayout.vue index 2d5dddcc..f9bd2e0d 100644 --- a/src/layouts/BasicLayout.vue +++ b/src/layouts/BasicLayout.vue @@ -8,6 +8,7 @@ import { import RightContent from './components/RightContent.vue'; import Tabs from './components/Tabs.vue'; import GlobalMask from '@/components/GlobalMask/index.vue'; +import ForcePasswdChange from '@/components/ForcePasswdChange/index.vue'; import { scriptUrl } from '@/assets/js/icon_font_8d5l8fzk5b87iudi'; import { computed, @@ -362,6 +363,8 @@ onUnmounted(() => { + + diff --git a/src/plugins/auth-token.ts b/src/plugins/auth-token.ts index 536d54b1..88361459 100644 --- a/src/plugins/auth-token.ts +++ b/src/plugins/auth-token.ts @@ -1,25 +1,53 @@ import Cookies from 'js-cookie'; -import { TOKEN_COOKIE } from '@/constants/token-constants'; import { localRemove, localSet } from '@/utils/cache-local-utils'; import { CACHE_LOCAL_LOCK_PASSWD, CACHE_LOCAL_MASK, } from '@/constants/cache-keys-constants'; +import { + TOKEN_ACCESS_COOKIE, + TOKEN_REFRESH_COOKIE, +} from '@/constants/token-constants'; -/**获取cookis中Token字符串 */ -export function getToken(): string { - return Cookies.get(TOKEN_COOKIE) || ''; +/**获取访问令牌 */ +export function getAccessToken(): string { + return Cookies.get(TOKEN_ACCESS_COOKIE) || ''; } -/**设置cookis中Token字符串 */ -export function setToken(token: string): void { - Cookies.set(TOKEN_COOKIE, token || ''); +/** + * 设置访问令牌 + * @param token token字符串 + * @param exp 过期时间(秒) + */ +export function setAccessToken(token: string, exp: number): void { + const expires = new Date(new Date().getTime() + exp * 1000); + Cookies.set(TOKEN_ACCESS_COOKIE, token, { expires }); localSet(CACHE_LOCAL_MASK, 'none'); } -/**移除cookis中Token字符串,localStorage中锁屏字符串 */ -export function removeToken(): void { - Cookies.remove(TOKEN_COOKIE); +/**移除访问令牌 */ +export function delAccessToken(): void { + Cookies.remove(TOKEN_ACCESS_COOKIE); localRemove(CACHE_LOCAL_MASK); localRemove(CACHE_LOCAL_LOCK_PASSWD); } + +/**获取刷新令牌 */ +export function getRefreshToken(): string { + return Cookies.get(TOKEN_REFRESH_COOKIE) || ''; +} + +/** + * 设置刷新令牌 + * @param token token字符串 + * @param exp 过期时间(秒) + */ +export function setRefreshToken(token: string, exp: number): void { + const expires = new Date(new Date().getTime() + exp * 1000); + Cookies.set(TOKEN_REFRESH_COOKIE, token, { expires }); +} + +/**移除刷新令牌 */ +export function delRefreshToken(): void { + Cookies.remove(TOKEN_REFRESH_COOKIE); +} diff --git a/src/plugins/http-fetch.ts b/src/plugins/http-fetch.ts index b5f38c97..f3673262 100644 --- a/src/plugins/http-fetch.ts +++ b/src/plugins/http-fetch.ts @@ -1,10 +1,16 @@ -import { getToken, removeToken } from '@/plugins/auth-token'; +import { + getAccessToken, + setAccessToken, + delAccessToken, + getRefreshToken, + setRefreshToken, + delRefreshToken, +} from '@/plugins/auth-token'; import { sessionGet, sessionGetJSON, sessionSetJSON, } from '@/utils/cache-session-utils'; -import { localGet } from '@/utils/cache-local-utils'; import { TOKEN_KEY, TOKEN_KEY_PREFIX } from '@/constants/token-constants'; import { CACHE_LOCAL_I18N, @@ -18,6 +24,7 @@ import { import { RESULT_CODE_ENCRYPT, RESULT_CODE_ERROR, + RESULT_CODE_EXCEPTION, RESULT_CODE_SUCCESS, RESULT_MSG_ENCRYPT, RESULT_MSG_ERROR, @@ -25,10 +32,11 @@ import { RESULT_MSG_SERVER_ERROR, RESULT_MSG_SUCCESS, RESULT_MSG_TIMEOUT, - RESULT_MSG_URL_NOTFOUND, RESULT_MSG_URL_RESUBMIT, } from '@/constants/result-constants'; import { decryptAES, encryptAES } from '@/utils/encrypt-utils'; +import { localGet } from '@/utils/cache-local-utils'; +import { refreshToken } from '@/api/auth'; /**响应结果类型 */ export type ResultType = { @@ -61,7 +69,7 @@ type OptionsType = { /**请求地址 */ url: string; /**请求方法 */ - method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; + method: 'GET' | 'POST' | 'PUT' | 'DELETE'; /**请求头 */ headers?: HeadersInit; /**地址栏参数 */ @@ -133,16 +141,21 @@ function beforeRequest(options: OptionsType): OptionsType | Promise { Reflect.set(options.headers, 'Accept-Language', `${language};q=0.9`); // 是否需要设置 token - const token = getToken(); - if (options.whithToken && token) { - Reflect.set(options.headers, TOKEN_KEY, TOKEN_KEY_PREFIX + token); + const accessToken = getAccessToken(); + if (options.whithToken && accessToken) { + Reflect.set( + options.headers, + TOKEN_KEY, + TOKEN_KEY_PREFIX + ' ' + accessToken + ); } // 是否需要防止数据重复提交 if ( options.repeatSubmit && options.dataType === 'json' && - ['post', 'put'].includes(options.method) + !(options.data instanceof FormData) && + ['POST', 'PUT'].includes(options.method) ) { const requestObj: RepeatSubmitType = { url: options.url, @@ -212,13 +225,31 @@ function beforeRequest(options: OptionsType): OptionsType | Promise { return options; } -/**请求后的拦截 */ -function interceptorResponse(res: ResultType): ResultType | Promise { +/**响应前的拦截 */ +async function beforeResponse( + options: OptionsType, + res: ResultType +): Promise { // console.log('请求后的拦截', res); // 登录失效时,移除授权令牌并重新刷新页面 - if (res.code === 401) { - removeToken(); + // 登录失效时,移除访问令牌并重新请求 + if (res.code === 401001) { + const result = await refreshToken(getRefreshToken()); + // 更新访问令牌和刷新令牌 + if (result.code === RESULT_CODE_SUCCESS) { + setAccessToken(result.data.accessToken, result.data.refreshExpiresIn); + setRefreshToken(result.data.refreshToken, result.data.refreshExpiresIn); + return await request(options); + } else { + delAccessToken(); + delRefreshToken(); + window.location.reload(); + } + } + if ([401002, 401003].includes(res.code)) { + delAccessToken(); + delRefreshToken(); window.location.reload(); } @@ -271,43 +302,45 @@ function interceptorResponse(res: ResultType): ResultType | Promise { * @returns 返回 Promise */ export async function request(options: OptionsType): Promise { - options = Object.assign({}, FATCH_OPTIONS, options); - let timeoutId: any = 0; + let reqOptions = Object.assign({}, FATCH_OPTIONS, options); + // 请求超时控制请求终止 - if (!options.signal) { + let timeoutId: any = null; + if (!reqOptions.signal) { const controller = new AbortController(); - const { signal } = controller; - options.signal = signal; + reqOptions.signal = controller.signal; timeoutId = setTimeout(() => { controller.abort(); // 终止请求 - }, options.timeout); + }, reqOptions.timeout); } // 检查请求拦截 - const beforeReq = beforeRequest(options); + const beforeReq = beforeRequest(reqOptions); if (beforeReq instanceof Promise) { return await beforeReq; } - options = beforeReq; + reqOptions = beforeReq; // 判断用户传递的URL是否http或/开头 - if (!options.url.startsWith('http')) { - const uri = options.url.startsWith('/') ? options.url : `/${options.url}`; - options.url = options.baseUrl + uri; + if (!reqOptions.url.startsWith('http')) { + const uri = reqOptions.url.startsWith('/') + ? reqOptions.url + : `/${reqOptions.url}`; + reqOptions.url = reqOptions.baseUrl + uri; } try { - const res = await fetch(options.url, options); + const res = await fetch(reqOptions.url, reqOptions); // console.log('请求结果:', res); - - // 状态码拦截处理 - const reqNot = stateCode(res); - if (reqNot != false) { - return reqNot; + if (res.status === 500) { + return { + code: RESULT_CODE_EXCEPTION, + msg: RESULT_MSG_SERVER_ERROR[language], + }; } // 根据响应数据类型返回 - switch (options.responseType) { + switch (reqOptions.responseType) { case 'text': // 文本数据 const str = await res.text(); return { @@ -317,11 +350,7 @@ export async function request(options: OptionsType): Promise { case 'json': // json格式数据 const result = await res.json(); // 请求后的拦截 - const beforeRes = interceptorResponse(result); - if (beforeRes instanceof Promise) { - return await beforeRes; - } - return result; + return await beforeResponse(options, result); case 'blob': // 二进制数据则直接返回 case 'arrayBuffer': const contentType = res.headers.get('content-type') || ''; @@ -330,7 +359,7 @@ export async function request(options: OptionsType): Promise { return result as ResultType; } const data = - options.responseType === 'blob' + reqOptions.responseType === 'blob' ? await res.blob() : await res.arrayBuffer(); return { @@ -356,41 +385,7 @@ export async function request(options: OptionsType): Promise { } throw error; } finally { - clearTimeout(timeoutId); // 请求成功,清除超时计时器 + clearTimeout(timeoutId); // 清除超时计时器 + timeoutId = null; } } - -/** - * 判断状态码处理结果信息(不可处理) - * @param res 请求结果 - * @returns - */ -function stateCode(res: Response) { - // 网络异常 - if (res.status === 500) { - return { - code: RESULT_CODE_ERROR, - msg: RESULT_MSG_SERVER_ERROR[language], - }; - } - // 上传文件成功无内容返回 - if (res.status === 204 || res.statusText === 'No Content') { - return { - code: RESULT_CODE_SUCCESS, - msg: RESULT_MSG_SUCCESS[language], - }; - } - // 地址找不到 - if (res.status === 404 || res.status === 405) { - return { - code: RESULT_CODE_ERROR, - msg: RESULT_MSG_URL_NOTFOUND[language], - }; - } - // 身份授权 - if (res.status === 401) { - removeToken(); - window.location.reload(); - } - return false; -} diff --git a/src/plugins/ws-websocket.ts b/src/plugins/ws-websocket.ts index 771efee2..ca2c00a0 100644 --- a/src/plugins/ws-websocket.ts +++ b/src/plugins/ws-websocket.ts @@ -1,5 +1,5 @@ import { sessionGet } from '@/utils/cache-session-utils'; -import { getToken } from './auth-token'; +import { getAccessToken } from './auth-token'; import { localGet } from '@/utils/cache-local-utils'; import { CACHE_LOCAL_I18N } from '@/constants/cache-keys-constants'; import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants'; @@ -92,7 +92,7 @@ export class WS { // 地址栏参数 let params = Object.assign({}, options.params, { // 设置 token - [TOKEN_RESPONSE_FIELD]: getToken(), + [TOKEN_RESPONSE_FIELD]: getAccessToken(), // 多语言 ['language']: localGet(CACHE_LOCAL_I18N) || 'en_US', }); @@ -119,17 +119,15 @@ export class WS { }; // 用于指定当从服务器接受到信息时的回调函数。 ws.onmessage = ev => { + if (ev.type !== 'message') return; // 解析文本消息 - if (ev.type === 'message') { - const data = ev.data; - try { - const jsonData = JSON.parse(data); - if (typeof options.onmessage === 'function') { - options.onmessage(jsonData); - } - } catch (error) { - console.error('websocket message formatting error', error); + try { + const jsonData = JSON.parse(ev.data); + if (typeof options.onmessage === 'function') { + options.onmessage(jsonData); } + } catch (error) { + console.error('websocket message formatting error', error); } }; // 用于指定连接关闭后的回调函数。 @@ -221,7 +219,7 @@ export class WS { this.heartInterval = window.setInterval(() => { this.send({ requestId: `${Date.now()}`, - type: 'ping', + type: 'PING', }); }, heartTimer); } diff --git a/src/router/index.ts b/src/router/index.ts index 35f415c8..821b5f03 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -8,7 +8,7 @@ import NProgress from 'nprogress'; import 'nprogress/nprogress.css'; import BasicLayout from '../layouts/BasicLayout.vue'; import BlankLayout from '../layouts/BlankLayout.vue'; -import { getToken } from '@/plugins/auth-token'; +import { getAccessToken } from '@/plugins/auth-token'; import { validHttp } from '@/utils/regular-utils'; import useUserStore from '@/store/modules/user'; import useAppStore from '@/store/modules/app'; @@ -182,7 +182,7 @@ router.beforeEach(async (to, from, next) => { // next({ name: 'Index' }); // } - let token = getToken(); + let token = getAccessToken(); // 免用户登录认证 if (!appStore.loginAuth) { diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index 7c337335..5c60b8ae 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -1,7 +1,9 @@ import { getSysConf } from '@/api'; -import { CACHE_LOCAL_I18N, CACHE_SESSION_CRYPTO_API } from '@/constants/cache-keys-constants'; +import { + CACHE_LOCAL_I18N, + CACHE_SESSION_CRYPTO_API, +} from '@/constants/cache-keys-constants'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; -// import { removeToken } from '@/plugins/auth-token'; import { parseUrlPath } from '@/plugins/file-static-url'; import { localGet, localSet } from '@/utils/cache-local-utils'; import { sessionSet } from '@/utils/cache-session-utils'; @@ -16,11 +18,12 @@ type AppStore = { /**应用版本 */ appVersion: string; - /**服务版本 */ + /**版本号 */ version: string; - // buildTime: string; /**系统引导使用 */ // bootloader: boolean; + /**服务版本 */ + serverVersion: string; // 用户登录认证 loginAuth: boolean; // 用户接口加密 @@ -54,13 +57,13 @@ const useAppStore = defineStore('app', { appCode: import.meta.env.VITE_APP_CODE, appVersion: import.meta.env.VITE_APP_VERSION, - version: `-`, - // buildTime: `-`, + version: '-', // bootloader: false, + serverVersion: '-', loginAuth: true, cryptoApi: true, - serialNum: `-`, - copyright: `Copyright ©2023 For ${import.meta.env.VITE_APP_NAME}`, + serialNum: '-', + copyright: `Copyright ©2023-2025 For ${import.meta.env.VITE_APP_NAME}`, logoType: 'icon', filePathIcon: '', filePathBrand: '', @@ -86,15 +89,16 @@ const useAppStore = defineStore('app', { const res = await getSysConf(); if (res.code === RESULT_CODE_SUCCESS && res.data) { this.version = res.data.version; - // this.buildTime = res.data.buildTime; + this.serverVersion = res.data.serverVersion; // this.bootloader = res.data.bootloader === 'true'; // // 引导时 // if (this.bootloader) { - // removeToken(); + // delAccessToken(); + // delRefreshToken(); // } this.loginAuth = res.data.loginAuth !== 'false'; this.cryptoApi = res.data.cryptoApi !== 'false'; - sessionSet(CACHE_SESSION_CRYPTO_API, res.data.cryptoApi); + sessionSet(CACHE_SESSION_CRYPTO_API, res.data.cryptoApi); this.serialNum = res.data.serialNum; this.appName = res.data.title; this.copyright = res.data.copyright; diff --git a/src/store/modules/mask.ts b/src/store/modules/mask.ts index dc6a03c7..5e4a6a5f 100644 --- a/src/store/modules/mask.ts +++ b/src/store/modules/mask.ts @@ -20,7 +20,7 @@ type MaskStateType = { const useMaskStore = defineStore('mask', { state: (): MaskStateType => ({ type: (localGet(CACHE_LOCAL_MASK) || 'none') as MaskStateType['type'], - lockPasswd: localGet(CACHE_LOCAL_LOCK_PASSWD) || '', + lockPasswd: atob(localGet(CACHE_LOCAL_LOCK_PASSWD) || ''), lockTimeout: 0, }), getters: {}, @@ -59,7 +59,7 @@ const useMaskStore = defineStore('mask', { }, 5_000); } if (type === 'lock') { - localSet(CACHE_LOCAL_LOCK_PASSWD, this.lockPasswd); + localSet(CACHE_LOCAL_LOCK_PASSWD, btoa(this.lockPasswd)); } else { localRemove(CACHE_LOCAL_LOCK_PASSWD); } diff --git a/src/store/modules/neinfo.ts b/src/store/modules/neinfo.ts index 16a2bcce..ebf4cd9f 100644 --- a/src/store/modules/neinfo.ts +++ b/src/store/modules/neinfo.ts @@ -2,7 +2,6 @@ import { defineStore } from 'pinia'; import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { listAllNeInfo } from '@/api/ne/neInfo'; import { parseDataToOptions } from '@/utils/parse-tree-utils'; -import { getNeTraceInterfaceAll } from '@/api/trace/task'; import { getNePerformanceList } from '@/api/perfManage/taskManage'; /**网元信息类型 */ @@ -13,8 +12,6 @@ type NeInfo = { neCascaderOptions: Record[]; /**选择器单级父类型 */ neSelectOtions: Record[]; - /**跟踪接口列表 */ - traceInterfaceList: Record[]; /**性能测量数据集 */ perMeasurementList: Record[]; }; @@ -24,7 +21,6 @@ const useNeInfoStore = defineStore('neinfo', { neList: [], neCascaderOptions: [], neSelectOtions: [], - traceInterfaceList: [], perMeasurementList: [], }), getters: { @@ -56,7 +52,7 @@ const useNeInfoStore = defineStore('neinfo', { async fnNelist() { // 有数据不请求 if (this.neList.length > 0) { - return { code: 1, data: this.neList, msg: 'success' }; + return { code: RESULT_CODE_SUCCESS, data: this.neList, msg: 'success' }; } const res = await listAllNeInfo({ bandStatus: false, @@ -79,29 +75,11 @@ const useNeInfoStore = defineStore('neinfo', { } return res; }, - // 刷新跟踪接口列表 - async fnRefreshNeTraceInterface() { - this.traceInterfaceList = []; - const res = await this.fnNeTraceInterface(); - return res; - }, - // 获取跟踪接口列表 - async fnNeTraceInterface() { - // 有数据不请求 - if (this.traceInterfaceList.length > 0) { - return { code: 1, data: this.traceInterfaceList, msg: 'success' }; - } - const res = await getNeTraceInterfaceAll(); - if (res.code === RESULT_CODE_SUCCESS) { - this.traceInterfaceList = res.data; - } - return res; - }, // 获取性能测量数据集列表 async fnNeTaskPerformance() { // 有数据不请求 if (this.perMeasurementList.length > 0) { - return { code: 1, data: this.perMeasurementList, msg: 'success' }; + return { code: RESULT_CODE_SUCCESS, data: this.perMeasurementList, msg: 'success' }; } const res = await getNePerformanceList(); if (res.code === RESULT_CODE_SUCCESS) { diff --git a/src/store/modules/router.ts b/src/store/modules/router.ts index a4131a7d..ade7ef3b 100644 --- a/src/store/modules/router.ts +++ b/src/store/modules/router.ts @@ -5,7 +5,7 @@ import type { RouteMeta, RouteRecordRaw, } from 'vue-router'; -import { getRouters } from '@/api/router'; +import { getRouter } from '@/api/auth'; import BasicLayout from '@/layouts/BasicLayout.vue'; import BlankLayout from '@/layouts/BlankLayout.vue'; import LinkLayout from '@/layouts/LinkLayout.vue'; @@ -46,7 +46,7 @@ const useRouterStore = defineStore('router', { * @returns 生成的路由菜单 */ async generateRoutes() { - const res = await getRouters(); + const res = await getRouter(); if (res.code === RESULT_CODE_SUCCESS) { const buildRoutes = buildRouters(res.data.concat()); this.buildRouterData = buildRoutes; diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 14a3011a..025b1729 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -1,14 +1,20 @@ import defaultAvatar from '@/assets/images/default_avatar.png'; import useLayoutStore from './layout'; -import { login, logout, getInfo } from '@/api/login'; -import { setToken, removeToken } from '@/plugins/auth-token'; +import { login, logout, getInfo } from '@/api/auth'; +import { + delAccessToken, + delRefreshToken, + setAccessToken, + setRefreshToken, +} from '@/plugins/auth-token'; import { defineStore } from 'pinia'; -import { TOKEN_RESPONSE_FIELD } from '@/constants/token-constants'; -import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; +import { RESULT_CODE_EXCEPTION, RESULT_CODE_SUCCESS } from '@/constants/result-constants'; import { parseUrlPath } from '@/plugins/file-static-url'; /**用户信息类型 */ type UserInfo = { + /**用户ID */ + forcePasswdChange: boolean; /**用户ID */ userId: string; /**登录账号 */ @@ -33,6 +39,7 @@ type UserInfo = { const useUserStore = defineStore('user', { state: (): UserInfo => ({ + forcePasswdChange: false, userId: '', userName: '', roles: [], @@ -102,8 +109,11 @@ const useUserStore = defineStore('user', { async fnLogin(loginBody: Record) { const res = await login(loginBody); if (res.code === RESULT_CODE_SUCCESS && res.data) { - const token = res.data[TOKEN_RESPONSE_FIELD]; - setToken(token); + setAccessToken(res.data.accessToken, res.data.refreshExpiresIn); + setRefreshToken(res.data.refreshToken, res.data.refreshExpiresIn); + if (res.data?.forcePasswdChange) { + this.forcePasswdChange = true; + } } return res; }, @@ -139,10 +149,15 @@ const useUserStore = defineStore('user', { // } // useLayoutStore().changeWaterMark(waterMarkContent); useLayoutStore().changeWaterMark(''); + // 强制修改密码 + if (res.data?.forcePasswdChange) { + this.forcePasswdChange = true; + } } // 网络错误时退出登录状态 - if (res.code === 0) { - removeToken(); + if (res.code === RESULT_CODE_EXCEPTION) { + delAccessToken(); + delRefreshToken(); window.location.reload(); } return res; @@ -156,7 +171,8 @@ const useUserStore = defineStore('user', { } finally { this.roles = []; this.permissions = []; - removeToken(); + delAccessToken(); + delRefreshToken(); } }, }, diff --git a/src/utils/date-utils.ts b/src/utils/date-utils.ts index 1104d66e..8dd0d24b 100644 --- a/src/utils/date-utils.ts +++ b/src/utils/date-utils.ts @@ -20,8 +20,10 @@ export const YYYYMMDDHHMMSS = 'YYYYMMDDHHmmss'; /**年-月-日 时:分:秒 列如:2022-12-30 01:01:59 */ export const YYYY_MM_DD_HH_MM_SS = 'YYYY-MM-DD HH:mm:ss'; -/**特殊 列如:2025-04-28 08:00:46 GMT+08:00 */ -export const YYYY_MM_DD_HH_MM_SSZ = 'YYYY-MM-DD HH:mm:ss [GMT]Z'; +/**国际时间 列如:2022-12-30T01:01:59+08:00 */ +export const RFC3339 = 'YYYY-MM-DDTHH:mm:ssZ'; +/**国际时间 列如:Thu, Nov 14 2024 10:19 GMT+08:00 */ +export const RFC822Z = 'ddd, MMM DD YYYY HH:mm [GMT]Z'; /** * 格式时间字符串 @@ -39,12 +41,12 @@ export function parseStrToDate( /** * 格式时间 * @param date 可转的Date对象 - * @param formatStr 时间格式 默认YYYY-MM-DD HH:mm:ssZZ + * @param formatStr 时间格式 默认 RFC3339 * @returns 时间格式字符串 */ export function parseDateToStr( date: string | number | Date, - formatStr: string = YYYY_MM_DD_HH_MM_SSZ + formatStr: string = RFC3339 ): string { return dayjs(date).format(formatStr); } diff --git a/src/utils/parse-utils.ts b/src/utils/parse-utils.ts index 8e13fd43..ada8afec 100644 --- a/src/utils/parse-utils.ts +++ b/src/utils/parse-utils.ts @@ -101,7 +101,14 @@ export function parseObjLineToHump(obj: any): any { * @param decimalPlaces 保留小数位,默认2位 * @returns 单位 xB */ -export function parseSizeFromFile(bytes: number, decimalPlaces: number = 2) { +export function parseSizeFromFile( + bytes: number, + decimalPlaces: number = 2 +): string { + if (typeof bytes !== 'number' || isNaN(bytes) || bytes < 0) { + return `${bytes}`; + } + if (bytes === 0) return '0 B'; const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; let i = 0; while (bytes >= 1024 && i < units.length - 1) { diff --git a/src/utils/regular-utils.ts b/src/utils/regular-utils.ts index 157737c8..83f5b3fa 100644 --- a/src/utils/regular-utils.ts +++ b/src/utils/regular-utils.ts @@ -27,14 +27,15 @@ export const regExpUserName = /^[A-Za-z0-9]{6,}$/; * 有效密码格式 * * 密码至少包含大小写字母、数字、特殊符号,且不少于6位 + * /^(?![A-Za-z0-9]+$)(?![a-z0-9\W]+$)(?![A-Za-z\W]+$)(?![A-Z0-9\W]+$)[a-zA-Z0-9\W]{6,}$/ */ -export const regExpPasswd = /^.{5,}$/; - // /^(?![A-Za-z0-9]+$)(?![a-z0-9\W]+$)(?![A-Za-z\W]+$)(?![A-Z0-9\W]+$)[a-zA-Z0-9\W]{6,}$/; +export const regExpPasswd = /^.{6,}$/; /** * 有效手机号格式 + * /^1[3|4|5|6|7|8|9][0-9]\d{8}$/ */ -export const regExpMobile = /^.{3,}$/; // /^1[3|4|5|6|7|8|9][0-9]\d{8}$/; +export const regExpMobile = /^.{3,}$/; /** * 有效邮箱格式 @@ -46,8 +47,9 @@ export const regExpEmail = * 有效用户昵称格式 * * 用户昵称只能包含字母、数字、中文和下划线,且不少于2位 + * /^[\w\u4e00-\u9fa5-]{2,}$/ */ -export const regExpNick = /^.{2,}$/; // /^[\w\u4e00-\u9fa5-]{2,}$/; +export const regExpNick = /^.{2,}$/; /** * 是否为http(s)://开头 diff --git a/src/views/account/components/reset-passwd.vue b/src/views/account/components/reset-passwd.vue index 0daa7d7f..a48b1f8f 100644 --- a/src/views/account/components/reset-passwd.vue +++ b/src/views/account/components/reset-passwd.vue @@ -52,6 +52,7 @@ function fnFinish() { updateUserPassword(state.form.oldPassword, state.form.confirmPassword) .then(res => { if (res.code === RESULT_CODE_SUCCESS) { + fnLogOut(); Modal.success({ title: t('common.tipTitle'), content: t('views.account.settings.submitOkTip', { @@ -59,7 +60,7 @@ function fnFinish() { }), okText: t('views.account.settings.submitOk'), onOk() { - fnLogOut().finally(() => router.push({ name: 'Login' })); + router.push({ name: 'Login' }); }, }); } else { diff --git a/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts b/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts index 4366405d..edc1335b 100644 --- a/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts +++ b/src/views/dashboard/overview/hooks/useUPFTotalFlow.ts @@ -23,7 +23,9 @@ export const upfFlowData = ref({ /**UPF-流量数据 数据解析 */ export function upfFlowParse(data: Record) { - upfFlowData.value.lineXTime.push(parseDateToStr(+data['timeGroup'], 'HH:mm:ss')); + upfFlowData.value.lineXTime.push( + parseDateToStr(+data['timeGroup'], 'HH:mm:ss') + ); const upN3 = parseSizeFromKbs(+data['UPF.03'], 5); upfFlowData.value.lineYUp.push(upN3[0]); const downN6 = parseSizeFromKbs(+data['UPF.06'], 5); diff --git a/src/views/dashboard/overview/index.vue b/src/views/dashboard/overview/index.vue index f7ac67c0..88345d96 100644 --- a/src/views/dashboard/overview/index.vue +++ b/src/views/dashboard/overview/index.vue @@ -385,7 +385,7 @@ onBeforeUnmount(() => { class="item toRouter" :title="t('views.dashboard.overview.toRouter')" > -
+
@@ -399,11 +399,7 @@ onBeforeUnmount(() => {
diff --git a/src/views/faultManage/history-alarm/index.vue b/src/views/faultManage/history-alarm/index.vue index 5bc1f21c..30a83323 100644 --- a/src/views/faultManage/history-alarm/index.vue +++ b/src/views/faultManage/history-alarm/index.vue @@ -7,11 +7,11 @@ import { SizeType } from 'ant-design-vue/es/config-provider'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { ColumnsType } from 'ant-design-vue/es/table'; import { - listAct, updateConfirm, cancelConfirm, exportAll, } from '@/api/faultManage/historyAlarm'; +import { listAct, exportAlarm } from '@/api/faultManage/actAlarm'; import useI18n from '@/hooks/useI18n'; import useDictStore from '@/store/modules/dict'; import useNeInfoStore from '@/store/modules/neinfo'; @@ -59,9 +59,6 @@ let rangePickerPresets = ref([ }, ]); -/**表格字段列排序 */ -let tableColumnsDnd = ref([]); - /**查询参数 */ let queryParams = reactive({ alarmStatus: 0, @@ -144,7 +141,7 @@ let tableState: TabeStateType = reactive({ }); /**表格字段列 */ -let tableColumns: ColumnsType = [ +let tableColumns = ref([ { title: t('views.faultManage.activeAlarm.alarmType'), dataIndex: 'alarmType', @@ -241,7 +238,10 @@ let tableColumns: ColumnsType = [ fixed: 'right', width: 100, }, -]; +]); + +/**表格字段列排序 */ +let tableColumnsDnd = ref([]); /**表格分页器参数 */ let tablePagination = reactive({ @@ -466,7 +466,7 @@ function mapKeysWithReduce(data: any[], titleMapping: Record) { function fnExportAll() { Modal.confirm({ title: 'Tip', - content: t('views.faultManage.historyAlarm.exportSure'), + content: t('views.faultManage.activeAlarm.exportSure'), onOk() { const key = 'exportAlarmHis'; message.loading({ content: t('common.loading'), key }); @@ -543,6 +543,38 @@ function fnModalCancel() { modalState.openByShowSet = false; } +/**列表导出 */ +function fnExportList() { + if (modalState.confirmLoading) return; + Modal.confirm({ + title: t('common.tipTitle'), + content: t('views.faultManage.activeAlarm.exportTip'), + onOk() { + const hide = message.loading(t('common.loading'), 0); + const querys = toRaw(queryParams); + exportAlarm(querys) + .then(res => { + if (res.code === RESULT_CODE_SUCCESS) { + message.success({ + content: t('common.operateOk'), + duration: 3, + }); + saveAs(res.data, `history_alarm_export_${Date.now()}.xlsx`); + } else { + message.error({ + content: `${res.msg}`, + duration: 3, + }); + } + }) + .finally(() => { + hide(); + modalState.confirmLoading = false; + }); + }, + }); +} + /**查询列表, pageNum初始页数 */ function fnGetList(pageNum?: number) { if (tableState.loading) return; @@ -712,11 +744,17 @@ onMounted(() => {