diff --git a/package-lock.json b/package-lock.json index a8daeb7..60da3cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "cors": "^2.8.5", "crypto-js": "^4.2.0", "element-plus": "^2.4.4", + "highlight.js": "^11.11.1", "js-cookie": "^3.0.5", "js-md5": "^0.8.3", "markdown-it": "^14.1.0", @@ -1425,6 +1426,14 @@ "process": "^0.11.10" } }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/immutable": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", diff --git a/package.json b/package.json index 09d4bd5..877e862 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "cors": "^2.8.5", "crypto-js": "^4.2.0", "element-plus": "^2.4.4", + "highlight.js": "^11.11.1", "js-cookie": "^3.0.5", "js-md5": "^0.8.3", "markdown-it": "^14.1.0", diff --git a/src/api/cid.js b/src/api/cid.js index 20b130a..d477f3a 100644 --- a/src/api/cid.js +++ b/src/api/cid.js @@ -1,54 +1,44 @@ -import request from '@/utils/request.js' -import request2 from '@/utils/gs_req.js'; +import request from '@/utils/request.js'; import request_aliyun from '@/utils/aliyun_erver.js'; +import { createRequestInstance } from '@/utils/req_base.js'; export const runCIDService = (data) => { - const params = new URLSearchParams(); - for (let key in data) { - if (key == 'token') continue; - params.append(key, data[key]) - } let request1 = getRequest(); - return request1.post('/cid/run', params, { "headers": { 'token': data.token } }); + return request1.post('/cid/run', data, { "headers": { 'token': data.token } }); } export const updateCIDService = (data) => { - const params = new URLSearchParams(); - for (let key in data) { - if (key == 'token') continue; - params.append(key, data[key]) - } + // const params = new URLSearchParams(); + // for (let key in data) { + // if (key == 'token') continue; + // params.append(key, data[key]) + // } let request1 = getRequest(); - return request1.post('/cid/update', params, { "headers": { 'token': data.token } }); + return request1.post('/cid/update', data, { "headers": { 'token': data.token } }); } export const deleteCIDService = (data) => { - const params = new URLSearchParams(); - for (let key in data) { - params.append(key, data[key]) - } + // const params = new URLSearchParams(); + // for (let key in data) { + // params.append(key, data[key]) + // } let request1 =getRequest(); - return request1.post('/cid/delete', params, { "headers": { 'token': data.token } }); + return request1.post('/cid/delete', data, { "headers": { 'token': data.token } }); } export const addCIDService = (data) => { - const params = new URLSearchParams(); - for (let key in data) { - params.append(key, data[key]) - } + // const params = new URLSearchParams(); + // for (let key in data) { + // params.append(key, data[key]) + // } let request1 = getRequest() - return request1.post('/cid/create', params, { "headers": { 'token': data.token }, 'Content-Type': 'application/json' }); + return request1.post('/cid/create', data, { "headers": { 'token': data.token }, 'Content-Type': 'application/json' }); } export const getCIDListService = (data) => { - const params = new URLSearchParams(); - for (let d in data) { - params.append(d, data[d]); - } - let request1 = getRequest() - request1.defaults.headers["token"] = data.token.value; - return request1.post('/cid/list', params, { + let request1 = getRequest(); + return request1.post('/cid/list', data, { headers: { 'token': data.token, // 将 token 替换为您的令牌值 } @@ -59,14 +49,9 @@ export const getCIDListService = (data) => { } export const getCIDLogListService = (data) => { - const params = new URLSearchParams(); - for (let d in data) { - params.append(d, data[d]); - } let request1 = getRequest(); - // request.headers["Content-Type"] = "application/json"; - request1.defaults.headers["token"] = data.token.value; - return request1.post('/cid/log', params, { + + return request1.post('/cid/log', data, { headers: { 'token': data.token, // 将 token 替换为您的令牌值 } @@ -81,7 +66,8 @@ function getRequest() { } else if (server === "js.ljsea.top") { request1 = request_aliyun; }else{ - request1 = request2; + console.log("Using custom server:", server); + request1 = createRequestInstance("https://"+server) } return request1; } \ No newline at end of file diff --git a/src/api/file.js b/src/api/file.js index 50ea96c..935b12a 100644 --- a/src/api/file.js +++ b/src/api/file.js @@ -1,39 +1,38 @@ import request from '@/utils/request.js' -import request2 from '@/utils/gs_req.js'; +import { createRequestInstance } from '@/utils/req_base.js'; import request_aliyun from '@/utils/aliyun_erver.js'; export const updateConfigFileService = (data) => { - const params = new URLSearchParams(); + let params={}; for (let key in data) { - params.append(key, data[key]) + if (key === 'token') continue; + params[key] = data[key]; } let request1 = getRequest(); return request1.post('/file/config_update', params, { "headers": { 'token': data.token } }); } export const deleteConfigFileService = (data) => { - const params = new URLSearchParams(); - for (let key in data) { - params.append(key, data[key]) - } let request1 = getRequest(); - return request1.post('/file/config_delete', params, { "headers": { 'token': data.token } }); + return request1.post('/file/config_delete', data, { "headers": { 'token': data.token } }); } export const addConfigFileService = (data) => { - const params = new URLSearchParams(); + let params={}; for (let key in data) { - params.append(key, data[key]) + if (key === 'token') continue; + params[key] = data[key]; } let request1 = getRequest(); return request1.post('/file/config_add', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' }); } export const getConfigFileListService = (data) => { - const params = new URLSearchParams(); - for (let d in data) { - params.append(d, data[d]); + let params={}; + for (let key in data) { + if (key === 'token') continue; + params[key] = data[key]; } // request.headers["Content-Type"] = "application/json let request1 = getRequest(); @@ -65,7 +64,8 @@ function getRequest() { } else if (server === "js.ljsea.top") { request1 = request_aliyun; }else{ - request1 = request2; + console.log("Using custom server:", server); + request1 = createRequestInstance("https://"+server) } return request1; } \ No newline at end of file diff --git a/src/api/user.js b/src/api/user.js index 284a117..5b70e00 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -1,4 +1,4 @@ -import request from '@/utils/request.js' +import request from '@/utils/uc_req.js'; import md5 from 'js-md5'; export const loginService = (loginData) => { diff --git a/src/utils/req_base.js b/src/utils/req_base.js new file mode 100644 index 0000000..e2a8602 --- /dev/null +++ b/src/utils/req_base.js @@ -0,0 +1,62 @@ +import axios from "axios"; +import router from "@/router/index.js"; +import { ElMessage } from 'element-plus'; + +// 错误处理函数 +const handleResponseError = (result) => { + if (result.status !== 200) { + router.push("/login"); + } + if (result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) { + ElMessage.error('登录失效,请重新登录!'); + localStorage.removeItem("token"); + router.push("/login"); + return null; + } + if (result.data.code === 7) { + ElMessage.error('该用户已存在,请重新输入!'); + return null; + } + if (result.data.code === 1) { + ElMessage.error('请求失败,请稍后重试!'); + } + return result.data; +}; + +// 请求实例缓存 +const instances = new Map(); + +// 请求工厂函数(单例模式) +export const createRequestInstance = (baseURL, config = {}) => { + // 检查是否已存在该域名的实例 + if (instances.has(baseURL)) { + return instances.get(baseURL); + } + + // 创建新实例 + const instance = axios.create({ + baseURL, + timeout: 10000, // 默认超时时间 + headers: { + 'Content-Type': 'application/json' + }, + ...config + }); + + // 添加响应拦截器 + instance.interceptors.response.use( + result => handleResponseError(result), + error => { + ElMessage.error('请求失败,请稍后重试!'); + return Promise.reject(error); + } + ); + + // 缓存实例 + instances.set(baseURL, instance); + + return instance; +}; + +// 默认导出原有的阿里云请求实例 +export default createRequestInstance("https://tx.ljsea.top/"); \ No newline at end of file diff --git a/src/utils/request.js b/src/utils/request.js index c0913ee..85e2f1a 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -6,42 +6,122 @@ const baseURL = "https://tx.ljsea.top/"; //const baseURL= "http://localhost:8083"; //const baseURL="https://pm.ljsea.top"; //const baseURL = "https://gep.ljsea.xyz/"; + +let isRefreshing = false; +let requests = []; + const request = axios.create({ baseURL: baseURL, }); +// 请求拦截器 - 添加token +request.interceptors.request.use(); + +// 响应拦截器 request.interceptors.response.use( - result => { - if(result.status!==200 ){ - router.push("/login") - } - if(result.data.message==="NOT_LOGIN"|| [2, 3, 4].includes(result.data.code)){ - //alert("登录失效,请重新登录!") - ElMessage.error('登录失效,请重新登录!'); - localStorage.removeItem("token"); - router.push("/login") - return - } - if(result.data.code == 7){ - //alert("该用户已存在,请重新输入!"); - ElMessage.error('该用户已存在,请重新输入!'); - return null - } - - if(result.data.code == 1){ - //alert("请求失败,请稍后重试!"); - ElMessage.error('请求失败,请稍后重试!'); - }else{ - return result.data - } - }, - error => { - //alert("请求失败,请稍后重试!"); - ElMessage.error('请求失败,请稍后重试!'); - return Promise.reject(error); + result => { + if(result.status !== 200) { + router.push("/login"); + } + if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) { + // 检测到token过期 + if (isRefreshing) { + isRefreshing = true; + + // 这里需要替换为实际的refresh token请求 + return axios.post('/user/refresh', { + token: localStorage.getItem("refresh_token") + }).then(res => { + const token = res.data["data"]["token"]; + const refreshToken = res.data["data"]["refresh_token"]; + localStorage.setItem("token", token); + localStorage.setItem("refresh_token", refreshToken); + + // 重试所有挂起的请求 + requests.forEach(cb => cb(token)); + requests = []; + isRefreshing = false; + + // 重试当前请求 + const config = result.config; + config.headers.Authorization = `Bearer ${token}`; + return request(config); + }).catch(err => { + // 刷新token失败,跳转登录 + ElMessage.error('登录已过期,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return Promise.reject(err); + }); + } else if (isRefreshing) { + // 正在刷新token,将请求放入队列 + return new Promise(resolve => { + requests.push(token => { + result.config.headers.Authorization = `Bearer ${token}`; + resolve(request(result.config)); + }); + }); + } else { + // 其他登录失效情况 + ElMessage.error('登录失效,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return; + } } -) -request.interceptors.request.use( -) + if(result.data.code == 7) { + ElMessage.error('该用户已存在,请重新输入!'); + return null; + } + + if(result.data.code == 1) { + ElMessage.error('请求失败,请稍后重试!'); + } else { + return result.data; + } + }, + error => { + if (error.response && error.response.status === 401 && !isRefreshing) { + // 处理401未授权错误 + const originalRequest = error.config; + if (!isRefreshing) { + isRefreshing = true; + + return axios.post('/user/refresh', { + refresh_token: localStorage.getItem("refresh_token") + }).then(res => { + const { token, refresh_token } = res.data; + localStorage.setItem("token", token); + localStorage.setItem("refresh_token", refresh_token); + + requests.forEach(cb => cb(token)); + requests = []; + isRefreshing = false; + + originalRequest.headers.Authorization = `Bearer ${token}`; + return request(originalRequest); + }).catch(err => { + ElMessage.error('登录已过期,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return Promise.reject(err); + }); + } else { + return new Promise(resolve => { + requests.push(token => { + originalRequest.headers.Authorization = `Bearer ${token}`; + resolve(request(originalRequest)); + }); + }); + } + } + ElMessage.error('请求失败,请稍后重试!'); + return Promise.reject(error); + } +); + export default request; \ No newline at end of file diff --git a/src/utils/uc_req.js b/src/utils/uc_req.js new file mode 100644 index 0000000..1ddb07c --- /dev/null +++ b/src/utils/uc_req.js @@ -0,0 +1,127 @@ +import axios from "axios"; +import router from "@/router/index.js"; +import { ElMessage } from 'element-plus'; +//const baseURL = "https://gep.ljsea.top/"; +const baseURL = "https://uc.ljsea.top/"; +//const baseURL= "http://localhost:8083"; +//const baseURL="https://pm.ljsea.top"; +//const baseURL = "https://gep.ljsea.xyz/"; + +let isRefreshing = false; +let requests = []; + +const request = axios.create({ + baseURL: baseURL, +}); + +// 请求拦截器 - 添加token +request.interceptors.request.use(); + +// 响应拦截器 +request.interceptors.response.use( + result => { + if(result.status !== 200) { + router.push("/login"); + } + if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) { + // 检测到token过期 + if (isRefreshing) { + isRefreshing = true; + + // 这里需要替换为实际的refresh token请求 + return axios.post('/user/refresh', { + token: localStorage.getItem("refresh_token") + }).then(res => { + const token = res.data["data"]["token"]; + const refreshToken = res.data["data"]["refresh_token"]; + localStorage.setItem("token", token); + localStorage.setItem("refresh_token", refreshToken); + + // 重试所有挂起的请求 + requests.forEach(cb => cb(token)); + requests = []; + isRefreshing = false; + + // 重试当前请求 + const config = result.config; + config.headers.Authorization = `Bearer ${token}`; + return request(config); + }).catch(err => { + // 刷新token失败,跳转登录 + ElMessage.error('登录已过期,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return Promise.reject(err); + }); + } else if (isRefreshing) { + // 正在刷新token,将请求放入队列 + return new Promise(resolve => { + requests.push(token => { + result.config.headers.Authorization = `Bearer ${token}`; + resolve(request(result.config)); + }); + }); + } else { + // 其他登录失效情况 + ElMessage.error('登录失效,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return; + } + } + + if(result.data.code == 7) { + ElMessage.error('该用户已存在,请重新输入!'); + return null; + } + + if(result.data.code == 1) { + ElMessage.error('请求失败,请稍后重试!'); + } else { + return result.data; + } + }, + error => { + if (error.response && error.response.status === 401 && !isRefreshing) { + // 处理401未授权错误 + const originalRequest = error.config; + if (!isRefreshing) { + isRefreshing = true; + + return axios.post('/user/refresh', { + refresh_token: localStorage.getItem("refresh_token") + }).then(res => { + const { token, refresh_token } = res.data; + localStorage.setItem("token", token); + localStorage.setItem("refresh_token", refresh_token); + + requests.forEach(cb => cb(token)); + requests = []; + isRefreshing = false; + + originalRequest.headers.Authorization = `Bearer ${token}`; + return request(originalRequest); + }).catch(err => { + ElMessage.error('登录已过期,请重新登录!'); + localStorage.removeItem("token"); + localStorage.removeItem("refresh_token"); + router.push("/login"); + return Promise.reject(err); + }); + } else { + return new Promise(resolve => { + requests.push(token => { + originalRequest.headers.Authorization = `Bearer ${token}`; + resolve(request(originalRequest)); + }); + }); + } + } + ElMessage.error('请求失败,请稍后重试!'); + return Promise.reject(error); + } +); + +export default request; \ No newline at end of file diff --git a/src/views/CIDList.vue b/src/views/CIDList.vue index bbc3c42..85caea2 100644 --- a/src/views/CIDList.vue +++ b/src/views/CIDList.vue @@ -36,6 +36,12 @@ export default { script: "", token: localStorage.getItem("token"), }, + server_list: [ + { label: "gep.ljsea.xyz", value: "gep.ljsea.xyz" }, + { label: "tx.ljsea.top", value: "tx.ljsea.top" }, + { label: "js.ljsea.top", value: "js.ljsea.top" }, + {label: "as.ljsea.top", value: "as.ljsea.top"}, + ], updateForm: { id:0, cidtoken:"", @@ -52,7 +58,7 @@ export default { // methods 是一些用来更改状态与触发更新的函数 // 它们可以在模板中作为事件处理器绑定 methods: { - async getDeviceList() { + async getCIDList() { const loading = ElLoading.service({ lock: true, text: '加载中', @@ -70,7 +76,7 @@ export default { } }, onSubmit() { - getDeviceList({ token: token }); + getCIDList({ token: token }); }, handleSizeChange() { alert("每页记录数变化" + val); @@ -133,7 +139,7 @@ export default { if (d_re.code == 0) { ElMessage.success("删除成功"); //刷新页面 - this.getDeviceList(); + this.getCIDList(); } else { ElMessage.error("操作失败"); } @@ -165,7 +171,7 @@ export default { result = await addCIDService(this.addForm); if (result.code == 0) { ElMessage.success("添加成功"); - this.getDeviceList() + this.getCIDList() } else { ElMessage.error("添加失败"); } @@ -184,10 +190,11 @@ export default { }); let result = {}; try { + this.updateForm.time = parseInt(this.updateForm.time); result = await updateCIDService(this.updateForm); if (result.code == 0) { ElMessage.success("修改成功"); - this.getDeviceList() + this.getCIDList() } else { ElMessage.error("修改失败"); } @@ -209,7 +216,7 @@ export default { }, handleServerChange(){ localStorage.setItem("cid_server", this.tokenData.server); - this.getDeviceList() + this.getCIDList() }, handleMenuSelect(val) { router.push(val); @@ -238,7 +245,7 @@ export default { } // console.log("mounted"); this.getIpClient(); - this.getDeviceList(); + this.getCIDList(); }, }; @@ -258,7 +265,7 @@ export default { 查询 @@ -268,10 +275,13 @@ export default { > - - gep.ljsea.xyz - tx.ljsea.top - 阿里云新加坡 + + diff --git a/src/views/FileList.vue b/src/views/FileList.vue index f3f5ad3..ba14531 100644 --- a/src/views/FileList.vue +++ b/src/views/FileList.vue @@ -390,6 +390,7 @@ export default { js.ljsea.top + as.ljsea.top diff --git a/src/views/Login.vue b/src/views/Login.vue index 5acbd43..d7b9287 100644 --- a/src/views/Login.vue +++ b/src/views/Login.vue @@ -1,57 +1,62 @@ \ No newline at end of file + diff --git a/src/views/ShellList.vue b/src/views/ShellList.vue index f37d2c6..605f6f9 100644 --- a/src/views/ShellList.vue +++ b/src/views/ShellList.vue @@ -31,6 +31,12 @@ export default { shel_content: "", server:"" }, + serverList: [ + { label: "家里服务器", value: "home_server" }, + { label: "腾讯服务器", value: "tx_vp_server" }, + { label: "阿里云服务器", value: "aliyun_vp_server" }, + { label:"azure服务器", value:"azure_vp_server" } + ], role: "", tokenData: { @@ -368,9 +374,12 @@ export default { - 家里服务器 - 腾讯服务器 - 阿里云服务器 + diff --git a/src/views/login.html b/src/views/login.html deleted file mode 100644 index d68a9ab..0000000 --- a/src/views/login.html +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - 个人记录 - 登录 - - - - - - - - - -
-
- - - - - - - - - - - 登录 - - - 跳转主页 - 第三方登录 - - - -
- -
- - - - - \ No newline at end of file diff --git a/src/views/slide-code-edit.vue b/src/views/slide-code-edit.vue new file mode 100644 index 0000000..496b3ec --- /dev/null +++ b/src/views/slide-code-edit.vue @@ -0,0 +1,358 @@ + + + + + \ No newline at end of file