修改请求数据,修改页面逻辑,添加服务器

This commit is contained in:
junleea 2025-06-02 14:07:33 +08:00
parent be0a4a0a74
commit cfe1eb8f3b
14 changed files with 843 additions and 336 deletions

9
package-lock.json generated
View File

@ -12,6 +12,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
@ -1425,6 +1426,14 @@
"process": "^0.11.10" "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": { "node_modules/immutable": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz", "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",

View File

@ -13,6 +13,7 @@
"cors": "^2.8.5", "cors": "^2.8.5",
"crypto-js": "^4.2.0", "crypto-js": "^4.2.0",
"element-plus": "^2.4.4", "element-plus": "^2.4.4",
"highlight.js": "^11.11.1",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",

View File

@ -1,54 +1,44 @@
import request from '@/utils/request.js' import request from '@/utils/request.js';
import request2 from '@/utils/gs_req.js';
import request_aliyun from '@/utils/aliyun_erver.js'; import request_aliyun from '@/utils/aliyun_erver.js';
import { createRequestInstance } from '@/utils/req_base.js';
export const runCIDService = (data) => { 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(); 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) => { export const updateCIDService = (data) => {
const params = new URLSearchParams(); // const params = new URLSearchParams();
for (let key in data) { // for (let key in data) {
if (key == 'token') continue; // if (key == 'token') continue;
params.append(key, data[key]) // params.append(key, data[key])
} // }
let request1 = getRequest(); 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) => { export const deleteCIDService = (data) => {
const params = new URLSearchParams(); // const params = new URLSearchParams();
for (let key in data) { // for (let key in data) {
params.append(key, data[key]) // params.append(key, data[key])
} // }
let request1 =getRequest(); 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) => { export const addCIDService = (data) => {
const params = new URLSearchParams(); // const params = new URLSearchParams();
for (let key in data) { // for (let key in data) {
params.append(key, data[key]) // params.append(key, data[key])
} // }
let request1 = getRequest() 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) => { export const getCIDListService = (data) => {
const params = new URLSearchParams(); let request1 = getRequest();
for (let d in data) { return request1.post('/cid/list', data, {
params.append(d, data[d]);
}
let request1 = getRequest()
request1.defaults.headers["token"] = data.token.value;
return request1.post('/cid/list', params, {
headers: { headers: {
'token': data.token, // 将 token 替换为您的令牌值 'token': data.token, // 将 token 替换为您的令牌值
} }
@ -59,14 +49,9 @@ export const getCIDListService = (data) => {
} }
export const getCIDLogListService = (data) => { export const getCIDLogListService = (data) => {
const params = new URLSearchParams();
for (let d in data) {
params.append(d, data[d]);
}
let request1 = getRequest(); let request1 = getRequest();
// request.headers["Content-Type"] = "application/json";
request1.defaults.headers["token"] = data.token.value; return request1.post('/cid/log', data, {
return request1.post('/cid/log', params, {
headers: { headers: {
'token': data.token, // 将 token 替换为您的令牌值 'token': data.token, // 将 token 替换为您的令牌值
} }
@ -81,7 +66,8 @@ function getRequest() {
} else if (server === "js.ljsea.top") { } else if (server === "js.ljsea.top") {
request1 = request_aliyun; request1 = request_aliyun;
}else{ }else{
request1 = request2; console.log("Using custom server:", server);
request1 = createRequestInstance("https://"+server)
} }
return request1; return request1;
} }

View File

@ -1,39 +1,38 @@
import request from '@/utils/request.js' 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'; import request_aliyun from '@/utils/aliyun_erver.js';
export const updateConfigFileService = (data) => { export const updateConfigFileService = (data) => {
const params = new URLSearchParams(); let params={};
for (let key in data) { for (let key in data) {
params.append(key, data[key]) if (key === 'token') continue;
params[key] = data[key];
} }
let request1 = getRequest(); let request1 = getRequest();
return request1.post('/file/config_update', params, { "headers": { 'token': data.token } }); return request1.post('/file/config_update', params, { "headers": { 'token': data.token } });
} }
export const deleteConfigFileService = (data) => { export const deleteConfigFileService = (data) => {
const params = new URLSearchParams();
for (let key in data) {
params.append(key, data[key])
}
let request1 = getRequest(); 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) => { export const addConfigFileService = (data) => {
const params = new URLSearchParams(); let params={};
for (let key in data) { for (let key in data) {
params.append(key, data[key]) if (key === 'token') continue;
params[key] = data[key];
} }
let request1 = getRequest(); let request1 = getRequest();
return request1.post('/file/config_add', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' }); return request1.post('/file/config_add', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
} }
export const getConfigFileListService = (data) => { export const getConfigFileListService = (data) => {
const params = new URLSearchParams(); let params={};
for (let d in data) { for (let key in data) {
params.append(d, data[d]); if (key === 'token') continue;
params[key] = data[key];
} }
// request.headers["Content-Type"] = "application/json // request.headers["Content-Type"] = "application/json
let request1 = getRequest(); let request1 = getRequest();
@ -65,7 +64,8 @@ function getRequest() {
} else if (server === "js.ljsea.top") { } else if (server === "js.ljsea.top") {
request1 = request_aliyun; request1 = request_aliyun;
}else{ }else{
request1 = request2; console.log("Using custom server:", server);
request1 = createRequestInstance("https://"+server)
} }
return request1; return request1;
} }

View File

@ -1,4 +1,4 @@
import request from '@/utils/request.js' import request from '@/utils/uc_req.js';
import md5 from 'js-md5'; import md5 from 'js-md5';
export const loginService = (loginData) => { export const loginService = (loginData) => {

62
src/utils/req_base.js Normal file
View File

@ -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/");

View File

@ -6,42 +6,122 @@ const baseURL = "https://tx.ljsea.top/";
//const baseURL= "http://localhost:8083"; //const baseURL= "http://localhost:8083";
//const baseURL="https://pm.ljsea.top"; //const baseURL="https://pm.ljsea.top";
//const baseURL = "https://gep.ljsea.xyz/"; //const baseURL = "https://gep.ljsea.xyz/";
let isRefreshing = false;
let requests = [];
const request = axios.create({ const request = axios.create({
baseURL: baseURL, baseURL: baseURL,
}); });
// 请求拦截器 - 添加token
request.interceptors.request.use();
// 响应拦截器
request.interceptors.response.use( request.interceptors.response.use(
result => { result => {
if(result.status!==200 ){ if(result.status !== 200) {
router.push("/login") 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);
} }
) if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
request.interceptors.request.use( // 检测到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; export default request;

127
src/utils/uc_req.js Normal file
View File

@ -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;

View File

@ -36,6 +36,12 @@ export default {
script: "", script: "",
token: localStorage.getItem("token"), 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: { updateForm: {
id:0, id:0,
cidtoken:"", cidtoken:"",
@ -52,7 +58,7 @@ export default {
// methods // methods
// //
methods: { methods: {
async getDeviceList() { async getCIDList() {
const loading = ElLoading.service({ const loading = ElLoading.service({
lock: true, lock: true,
text: '加载中', text: '加载中',
@ -70,7 +76,7 @@ export default {
} }
}, },
onSubmit() { onSubmit() {
getDeviceList({ token: token }); getCIDList({ token: token });
}, },
handleSizeChange() { handleSizeChange() {
alert("每页记录数变化" + val); alert("每页记录数变化" + val);
@ -133,7 +139,7 @@ export default {
if (d_re.code == 0) { if (d_re.code == 0) {
ElMessage.success("删除成功"); ElMessage.success("删除成功");
// //
this.getDeviceList(); this.getCIDList();
} else { } else {
ElMessage.error("操作失败"); ElMessage.error("操作失败");
} }
@ -165,7 +171,7 @@ export default {
result = await addCIDService(this.addForm); result = await addCIDService(this.addForm);
if (result.code == 0) { if (result.code == 0) {
ElMessage.success("添加成功"); ElMessage.success("添加成功");
this.getDeviceList() this.getCIDList()
} else { } else {
ElMessage.error("添加失败"); ElMessage.error("添加失败");
} }
@ -184,10 +190,11 @@ export default {
}); });
let result = {}; let result = {};
try { try {
this.updateForm.time = parseInt(this.updateForm.time);
result = await updateCIDService(this.updateForm); result = await updateCIDService(this.updateForm);
if (result.code == 0) { if (result.code == 0) {
ElMessage.success("修改成功"); ElMessage.success("修改成功");
this.getDeviceList() this.getCIDList()
} else { } else {
ElMessage.error("修改失败"); ElMessage.error("修改失败");
} }
@ -209,7 +216,7 @@ export default {
}, },
handleServerChange(){ handleServerChange(){
localStorage.setItem("cid_server", this.tokenData.server); localStorage.setItem("cid_server", this.tokenData.server);
this.getDeviceList() this.getCIDList()
}, },
handleMenuSelect(val) { handleMenuSelect(val) {
router.push(val); router.push(val);
@ -238,7 +245,7 @@ export default {
} }
// console.log("mounted"); // console.log("mounted");
this.getIpClient(); this.getIpClient();
this.getDeviceList(); this.getCIDList();
}, },
}; };
</script> </script>
@ -258,7 +265,7 @@ export default {
<el-button <el-button
class="el-button--danger" class="el-button--danger"
type="primary" type="primary"
@click="getDeviceList()" @click="getCIDList()"
>查询</el-button >查询</el-button
> >
</el-form-item> </el-form-item>
@ -268,10 +275,13 @@ export default {
> >
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-select v-model="tokenData.server" @change="handleServerChange"> <el-select allow-create filterable v-model="tokenData.server" @change="handleServerChange">
<el-option label="gep.ljsea.xyz" value="gep.ljsea.xyz">gep.ljsea.xyz</el-option> <el-option
<el-option label="tx.ljsea.top" value="tx.ljsea.top">tx.ljsea.top</el-option> v-for="item in server_list"
<el-option label="js.ljsea.top" value="js.ljsea.top">阿里云新加坡</el-option> :key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>

View File

@ -390,6 +390,7 @@ export default {
<el-form-item> <el-form-item>
<el-select <el-select
v-model="tokenData.server" v-model="tokenData.server"
@change="handleServerChange" @change="handleServerChange"
> >
<el-option label="gep.ljsea.top" value="gep.ljsea.top" <el-option label="gep.ljsea.top" value="gep.ljsea.top"
@ -401,6 +402,8 @@ export default {
<el-option label="js.ljsea.top" value="js.ljsea.top" <el-option label="js.ljsea.top" value="js.ljsea.top"
>js.ljsea.top</el-option >js.ljsea.top</el-option
> >
<el-option label="as.ljsea.top" value="as.ljsea.top"
>as.ljsea.top</el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -1,57 +1,62 @@
<template> <template>
<div class="login-bg"> <div class="login-bg">
<div class="login-container"> <div class="login-container">
<div class="login-header"> <div class="login-header">
<img class="logo mr10" src="../assets/img/logo.svg" alt="" /> <img class="logo mr10" src="../assets/img/logo.svg" alt="" />
<div class="login-title">综合系统</div> <div class="login-title">综合系统</div>
</div> </div>
<el-form :model="param" :rules="rules" ref="login" size="large"> <el-form :model="param" :rules="rules" ref="login" size="large">
<el-form-item prop="username"> <el-form-item prop="username">
<el-input v-model="param.username" placeholder="用户名或邮箱"> <el-input v-model="param.username" placeholder="用户名或邮箱">
<template #prepend> <template #prepend>
<el-icon> <el-icon>
<User /> <User />
</el-icon> </el-icon>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item prop="password"> <el-form-item prop="password">
<el-input <el-input
type="password" type="password"
placeholder="密码" placeholder="密码"
v-model="param.password" v-model="param.password"
@keyup.enter="submitForm(login)" @keyup.enter="submitForm(login)"
> >
<template #prepend> <template #prepend>
<el-icon> <el-icon>
<Lock /> <Lock />
</el-icon> </el-icon>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
<!-- <div class="pwd-tips"> <!-- <div class="pwd-tips">
<el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" /> <el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" />
<el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link> <el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link>
</div> --> </div> -->
<el-button class="login-btn" type="primary" size="large" @click="onLogin">登录</el-button> <el-button
<!-- <p class="login-text"> class="login-btn"
type="primary"
size="large"
@click="onLogin"
>登录</el-button
>
<!-- <p class="login-text">
没有账号<el-link type="primary" @click="$router.push('/register')">立即注册</el-link> 没有账号<el-link type="primary" @click="$router.push('/register')">立即注册</el-link>
</p> --> </p> -->
</el-form> </el-form>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive,inject } from 'vue'; import { ref, reactive, inject } from "vue";
import { useRouter } from 'vue-router'; import { useRouter } from "vue-router";
import { ElMessage } from 'element-plus'; import { ElMessage } from "element-plus";
import {loginService} from "@/api/user.js"; import { loginService } from "@/api/user.js";
import {GetUserInfoService} from "@/api/user.js"; import { GetUserInfoService } from "@/api/user.js";
// //
const lgStr = localStorage.getItem('login-param'); const lgStr = localStorage.getItem("login-param");
const defParam = lgStr ? JSON.parse(lgStr) : null; const defParam = lgStr ? JSON.parse(lgStr) : null;
const globalData = inject("globalData"); const globalData = inject("globalData");
// //
@ -60,87 +65,82 @@ const checked = ref(lgStr ? true : false);
const router = useRouter(); const router = useRouter();
// //
const param = reactive({ const param = reactive({
username: defParam ? defParam.username : '', username: defParam ? defParam.username : "",
password: defParam ? defParam.password : '' password: defParam ? defParam.password : "",
}); });
// //
const rules = { const rules = {
username: [ username: [
{ {
required: true, required: true,
message: '请输入用户名', message: "请输入用户名",
trigger: 'blur' trigger: "blur",
} },
], ],
password: [ password: [
{ {
required: true, required: true,
message: '请输入密码', message: "请输入密码",
trigger: 'blur' trigger: "blur",
} },
] ],
}; };
// //
const login = ref(null); const login = ref(null);
// //
var loginData = ref({ var loginData = ref({
username: "", username: "",
email: "", email: "",
password: "", password: "",
ip: "", ip: "",
}); });
// //
const onLogin = async () => { const onLogin = async () => {
console.log("params:",param) console.log("params:", param);
loginData.value.username = param.username; loginData.value.username = param.username;
loginData.value.password = param.password; loginData.value.password = param.password;
let result = await loginService(loginData); let result = await loginService(loginData);
console.log("login result:", result); console.log("login result:", result);
if (result.code !== 0) { if (result.code !== 0) {
//alert(result.message); //alert(result.message);
ElMessage.error("登录失败!用户名或密码错误"); ElMessage.error("登录失败!用户名或密码错误");
return return;
} }
globalData.token = result.data; globalData.token = result.data;
localStorage.setItem("token", result.data.token); localStorage.setItem("token", result.data.access_token);
localStorage.setItem("userId", result.data.id); localStorage.setItem("userId", result.data.user_id);
localStorage.setItem("username", result.data.username); localStorage.setItem("username", result.data.username);
let now = new Date(); await getMyUserInfo(result.data.user_id);
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); // //token.value= result.data;
await getMyUserInfo(result.data.id); router.push("/user");
//token.value= result.data;
router.push("/user");
}; };
const getMyUserInfo = async (id) => { const getMyUserInfo = async (id) => {
let result = {}; let result = {};
try { try {
let tokenData ={ let tokenData = {
token: localStorage.getItem("token"), token: localStorage.getItem("token"),
id: id, id: id,
};
result = await GetUserInfoService(tokenData);
if (result.code === 0) {
//console.log("token data:",this.tokenData)
localStorage.setItem("video_func", result.data.VideoFunc);
localStorage.setItem("device_func", result.data.DeviceFunc);
localStorage.setItem("cid_func", result.data.CIDFunc);
localStorage.setItem("role", result.data.Role);
//alert("video_func:" + localStorage.getItem("video_func")+" type:" +typeof(localStorage.getItem("video_func")));
}
} catch (e) {
console.log(e);
} }
result = await GetUserInfoService(tokenData);
if (result.code === 0) {
//console.log("token data:",this.tokenData)
localStorage.setItem("video_func", result.data.VideoFunc);
localStorage.setItem("device_func", result.data.DeviceFunc);
localStorage.setItem("cid_func", result.data.CIDFunc);
localStorage.setItem("role", result.data.Role);
//alert("video_func:" + localStorage.getItem("video_func")+" type:" +typeof(localStorage.getItem("video_func")));
}
} catch (e) {
console.log(e);
}
}; };
// //
</script> </script>
<style scoped> <style scoped>

View File

@ -31,6 +31,12 @@ export default {
shel_content: "", shel_content: "",
server:"" server:""
}, },
serverList: [
{ label: "家里服务器", value: "home_server" },
{ label: "腾讯服务器", value: "tx_vp_server" },
{ label: "阿里云服务器", value: "aliyun_vp_server" },
{ label:"azure服务器", value:"azure_vp_server" }
],
role: "", role: "",
tokenData: { tokenData: {
@ -368,9 +374,12 @@ export default {
<el-row> <el-row>
<el-form-item label="服务器" prop="server"> <el-form-item label="服务器" prop="server">
<el-select v-model="addForm.server"> <el-select v-model="addForm.server">
<el-option label="家里服务器" value="home_server">家里服务器</el-option> <el-option
<el-option label="腾讯服务器" value="tx_vp_server">腾讯服务器</el-option> v-for="item in serverList"
<el-option label="腾讯服务器" value="aliyun_vp_server">阿里云服务器</el-option> :key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-row> </el-row>

View File

@ -1,138 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人记录 - 登录</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://unpkg.com/element-plus/dist/index.css">
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script src="https://unpkg.com/element-plus"></script>
<style>
body {
background-image: url('https://picsum.photos/1920/1080');
background-size: cover;
background-repeat: no-repeat;
background-attachment: fixed;
}
.login-container {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.el-card {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
text-align: center;
padding: 10px 0;
background-color: rgba(0, 0, 0, 0.5);
color: white;
}
.third-party-login {
text-align: center;
}
.third-party-login .el-button {
margin: 5px;
}
.qq-btn {
background-image: url(https://wiki.connect.qq.com/wp-content/uploads/2016/12/Connect_logo_4.png);
}
</style>
</head>
<body>
<div id="app">
<div class="login-container">
<el-card>
<template #header>
<h3 class="text-2xl font-bold text-center">个人记录登录页面</h3>
</template>
<el-form ref="loginFormRef" :model="loginForm" label-width="80px">
<el-form-item label="用户名">
<el-input v-model="loginForm.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="loginForm.password" type="password"></el-input>
</el-form-item>
<el-form-item>
<el-button size="medium" @click="handleLogin">登录</el-button>
</el-form-item>
</el-form>
<a href="https://ljsea.top" style="font-size: 12px;color: blue;width: 120px;">跳转主页</a>
<el-divider content-position="center">第三方登录</el-divider>
<img src="https://wiki.connect.qq.com/wp-content/uploads/2016/12/Connect_logo_4.png" @click="thirdLogin('qq')">
<div class="third-party-login">
<!-- <el-button
class="qq-btn"
@click="thirdLogin('qq')"
></el-button> -->
</div>
</el-card>
</div>
<div class="footer">
<a href="https://beian.miit.gov.cn/">备案号蜀ICP备2022027005号-2</a>
</div>
</div>
<script>
const { createApp } = Vue;
const app = createApp({
data() {
return {
loginForm: {
username: '',
password: ''
},
currentLoginRequest: 0,
maxLoginRepeatRequest: 60,
loginFormRef: null
};
},
methods: {
handleLogin() {
console.log('登录信息:', this.loginForm);
if (this.loginForm.username === '' || this.loginForm.password === '') {
ElementPlus.ElMessage({
message: '用户名和密码不能为空',
type: 'error',
});
return;
}
ElementPlus.ElMessage({
message: '用户名或密码错误',
type: 'error',
});
},
handleQQLogin() {
console.log('点击了 QQ 登录');
// 这里应添加实际的 QQ 登录逻辑,比如跳转到 QQ 登录授权页面
},
async thirdLogin(type) {
let loginUrl = 'https://graph.qq.com/oauth2.0/show?which=error&display=pc&error=100010&which=Login&display=pc&client_id=101827468&response_type=code&state=eyJ1dWlkIjoiZTIyMDM5OGEtOTczMy00NjVlLWFkMTMtNWE5ZTE2YWI5ZmFkIiwidHlwZSI6ImxvZ2luIiwicHJvamVjdCI6IlNBVyIsInBsYXRmb3JtIjoicXEiLCJ1c2VyX2lkIjowfQ%3D%3D';
window.open(loginUrl, "_blank");
},
}
});
app.use(ElementPlus);
app.mount('#app');
</script>
</body>
</html>

View File

@ -0,0 +1,358 @@
<template>
<transition name="slide">
<div class="side-panel">
<button @click="handleClose" class="close-btn"></button>
<el-button type="primary" @click="UpdateFileCOntent">保存修改</el-button>
<div class="content">
<h2>{{ fileName }}</h2>
<div class="editor-container">
<textarea
ref="textareaRef"
v-model="localContent"
@input="handleInput"
@scroll="handleScroll"
spellcheck="false"
></textarea>
<pre class="highlight-container" ref="highlightRef"><code v-html="highlightedCode"></code></pre>
</div>
</div>
</div>
</transition>
</template>
<script setup lang="ts">
import { ref, watch, nextTick, onMounted } from "vue";
import { updateConfigFileService } from "@/api/file";
import { ElMessage } from "element-plus";
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css';
const props = defineProps({
content: {
type: String,
default: "",
},
show: {
type: Boolean,
default: false,
},
fileName: {
type: String,
default: "编辑代码",
},
fileID: {
type: Number,
default: 0,
},
});
const emit = defineEmits<{
(e: "close"): void;
}>();
const textareaRef = ref<HTMLTextAreaElement | null>(null);
const highlightRef = ref<HTMLElement | null>(null);
const localContent = ref(props.content);
const highlightedCode = ref('');
//
const detectLanguage = (fileName: string) => {
const extension = fileName.split('.').pop()?.toLowerCase();
const languageMap: Record<string, string> = {
'js': 'javascript',
'jsx': 'javascript',
'ts': 'typescript',
'tsx': 'typescript',
'html': 'html',
'css': 'css',
'scss': 'scss',
'less': 'less',
'py': 'python',
'java': 'java',
'php': 'php',
'go': 'go',
'rb': 'ruby',
'rs': 'rust',
'c': 'c',
'cpp': 'cpp',
'cs': 'csharp',
'json': 'json',
'md': 'markdown',
'xml': 'xml',
'yaml': 'yaml',
'yml': 'yaml',
'sh': 'bash',
'bash': 'bash',
'sql': 'sql',
};
return extension && languageMap[extension] ? languageMap[extension] : 'plaintext';
};
//
const highlightCode = () => {
if (!localContent.value) {
highlightedCode.value = '';
return;
}
const language = detectLanguage(props.fileName);
try {
if (language !== 'plaintext') {
const highlighted = hljs.highlight(localContent.value, { language });
highlightedCode.value = highlighted.value;
} else {
//
const highlighted = hljs.highlightAuto(localContent.value);
highlightedCode.value = highlighted.value;
}
} catch (error) {
console.error('Highlight error:', error);
// HTML
highlightedCode.value = localContent.value
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}
};
//
const handleInput = () => {
highlightCode();
nextTick(() => {
if (textareaRef.value && highlightRef.value) {
//
highlightRef.value.scrollTop = textareaRef.value.scrollTop;
highlightRef.value.scrollLeft = textareaRef.value.scrollLeft;
}
});
};
//
const handleScroll = () => {
if (textareaRef.value && highlightRef.value) {
highlightRef.value.scrollTop = textareaRef.value.scrollTop;
highlightRef.value.scrollLeft = textareaRef.value.scrollLeft;
}
};
// props.content
watch(
() => props.content,
(newVal) => {
localContent.value = newVal;
highlightCode();
}
);
// textarea
watch(
() => props.show,
async (newVal) => {
if (newVal) {
await nextTick();
textareaRef.value?.focus();
highlightCode();
}
}
);
//
onMounted(() => {
highlightCode();
});
const handleClose = () => {
emit("close");
};
const UpdateFileCOntent = async () => {
let req = {
token: localStorage.getItem("token"),
id: props.fileID,
content: localContent.value,
};
try {
let result = await updateConfigFileService(req);
if (result["code"] === 0) {
ElMessage.success("修改成功");
} else {
ElMessage.error("修改失败");
}
} catch (e) {
console.log(e);
}
};
</script>
<style scoped lang="css">
.side-panel {
position: fixed;
top: 0;
right: 0;
width: 70%;
height: 100%;
background-color: #282c34;
z-index: 1001;
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);
padding: 20px;
display: flex;
flex-direction: column;
color: #abb2bf;
}
.close-btn {
position: absolute;
top: 10px;
right: 10px;
width: 30px;
height: 30px;
background: none;
border: none;
cursor: pointer;
z-index: 1;
}
.close-btn::before,
.close-btn::after {
content: '';
position: absolute;
width: 20px;
height: 2px;
background-color: #abb2bf;
top: 50%;
left: 50%;
transition: background-color 0.2s;
}
.close-btn::before {
transform: translate(-50%, -50%) rotate(45deg);
}
.close-btn::after {
transform: translate(-50%, -50%) rotate(-45deg);
}
.close-btn:hover::before,
.close-btn:hover::after {
background-color: #61afef;
}
.content {
flex: 1;
display: flex;
flex-direction: column;
margin-top: 20px;
}
.content h2 {
color: #e5e5e5;
margin-bottom: 15px;
}
.editor-container {
position: relative;
flex: 1;
border-radius: 4px;
background-color: #282c34;
overflow: hidden;
}
.editor-container textarea {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 12px;
border: 1px solid #3e4451;
border-radius: 4px;
resize: none;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
color: transparent;
background-color: transparent;
caret-color: #61afef;
z-index: 2;
white-space: pre;
overflow: auto;
tab-size: 2;
}
.editor-container textarea:focus {
outline: none;
border-color: #61afef;
}
.highlight-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
padding: 12px;
margin: 0;
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
pointer-events: none;
overflow: auto;
z-index: 1;
white-space: pre;
tab-size: 2;
background-color: #282c34;
}
.highlight-container code {
font-family: inherit;
}
/* 滚动条样式 */
.editor-container textarea::-webkit-scrollbar,
.highlight-container::-webkit-scrollbar {
width: 8px;
height: 8px;
}
.editor-container textarea::-webkit-scrollbar-track,
.highlight-container::-webkit-scrollbar-track {
background: #21252b;
}
.editor-container textarea::-webkit-scrollbar-thumb,
.highlight-container::-webkit-scrollbar-thumb {
background: #3e4451;
border-radius: 4px;
}
.editor-container textarea::-webkit-scrollbar-thumb:hover,
.highlight-container::-webkit-scrollbar-thumb:hover {
background: #4b5363;
}
/* 保存按钮样式 */
:deep(.el-button--primary) {
background-color: #61afef;
border-color: #61afef;
}
:deep(.el-button--primary:hover) {
background-color: #528bbc;
border-color: #528bbc;
}
.slide-enter-active,
.slide-leave-active {
transition: transform 0.3s ease;
}
.slide-enter-from,
.slide-leave-to {
transform: translateX(100%);
}
</style>