This commit is contained in:
fleyx 2025-03-12 19:48:49 +08:00
parent 4b8a7829d9
commit ef92c13a4f
18 changed files with 470 additions and 202 deletions

View File

@ -0,0 +1,10 @@
export default interface QbCommonDto {
method: string;
url: string;
query: any;
body: any;
/**
* 1:application/json 2:formdata 3:application/x-www-form-urlencoded
*/
contentType: number;
}

View File

@ -0,0 +1,7 @@
key-error:
en: Secret error
zh: 秘钥错误
qb:
version-error:
en: qBittorrent version must be V4.xx
zh: qBittorrent 版本必须为V4.xx

View File

@ -0,0 +1,34 @@
import YAML from 'yaml';
import fs from 'fs-extra';
import path from 'path'
import config from '../config'
import logger from '../util/LogUtil';
const map = {};
export function init() {
let i18nFolder = path.join(config.rootPath, 'i18n');
let files = fs.readdirSync(i18nFolder).filter(item => item.endsWith(".yaml"));
files.forEach(file => {
let res = YAML.parse(fs.readFileSync(path.join(i18nFolder, file), 'utf-8'));
dealYaml("", res);
})
logger.info("i18n加载完毕");
}
export function getMessage(lang: string, key: string): string {
let val = map[key + "." + (lang ? lang : 'en')];
return val ? val : key;
}
function dealYaml(pre: string, res: any) {
Object.keys(res).forEach(key => {
let val = res[key];
let mapKey = pre == '' ? key : (pre + "." + key);
if (typeof val != "object") {
map[mapKey] = val;
} else {
dealYaml(mapKey, val);
}
})
}

View File

@ -9,8 +9,8 @@ import handleError from "./middleware/handleError";
import init from "./middleware/init";
import SqliteUtil from './util/SqliteHelper';
import log from './util/LogUtil';
import QbService from './service/QbService';
import qbService from "./service/QbService";
import * as i18n from './i18n';
console.log(config);
@ -33,6 +33,7 @@ app.use(RouterMW(router, path.join(config.rootPath, "dist/api")));
(async () => {
await SqliteUtil.createPool();
await qbService.init();
await i18n.init();
app.listen(config.port);
log.info(`server listened `, config.port);
})();

View File

@ -1,35 +1,37 @@
import log from '../util/LogUtil';
import config from "../config";
import {getMessage} from "../i18n";
let f = async (ctx, next) => {
try {
//检查是否有密码
if (checkToken(ctx)) {
await next();
} else {
ctx.status = 401;
ctx.body = "密钥验证错误";
}
} catch (error: any) {
if (error.status != undefined) {
ctx.status = error.status;
} else {
ctx.status = 500;
}
ctx.body = error.message;
log.error(error);
}
let lang = ctx.request.headers['lang'];
try {
//检查是否有密码
if (checkToken(ctx)) {
await next();
} else {
ctx.status = 401;
ctx.body = getMessage(lang, "key-error");
}
} catch (error: any) {
if (error.status != undefined) {
ctx.status = error.status;
} else {
ctx.status = 500;
}
ctx.body = getMessage(lang, error.message);
log.error(error);
}
}
function checkToken(ctx) {
if (!config.token) {
return true;
}
let requestPath = ctx.method + ctx.path.replace(config.urlPrefix, "");
if (config.publicPath.has(requestPath)) {
return true;
}
return config.token == ctx.headers.token;
if (!config.token) {
return true;
}
let requestPath = ctx.method + ctx.path.replace(config.urlPrefix, "");
if (config.publicPath.has(requestPath)) {
return true;
}
return config.token == ctx.headers.token;
}

View File

@ -31,7 +31,7 @@ export default async (ctx, next) => {
ctx.set("X-Powered-By", ' 3.2.1');
ctx.set("Content-Type", "application/json;charset=utf-8");
//合并请求参数到allParams
let objs = new Array();
let objs = [];
if (ctx.method == "POST" || ctx.method == "PUT") {
if (ctx.request.body) {
if (ctx.request.body.fields != undefined && ctx.request.body.files != undefined) {

View File

@ -1,31 +1,32 @@
{
"name": "nas_backup",
"version": "1.0.0",
"description": "文件备份用",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxb",
"license": "ISC",
"dependencies": {
"@types/fs-extra": "^5.0.4",
"@types/koa": "^2.0.47",
"@types/node": "^11.13.4",
"axios": "^0.21.4",
"fs-extra": "^7.0.0",
"koa": "^2.5.3",
"koa-body": "^4.0.4",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"koa2-cors": "^2.0.6",
"log4js": "^6.3.0",
"moment": "^2.22.2",
"mysql2": "^2.2.5",
"querystring": "^0.2.1",
"sqlite": "^4.0.23",
"sqlite3": "^5.0.2",
"uuid": "^3.3.2",
"winston": "^3.1.0"
}
}
{
"name": "nas_backup",
"version": "1.0.0",
"description": "文件备份用",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxb",
"license": "ISC",
"dependencies": {
"@types/fs-extra": "^5.0.4",
"@types/koa": "^2.0.47",
"@types/node": "^11.13.4",
"axios": "^0.21.4",
"fs-extra": "^7.0.0",
"koa": "^2.5.3",
"koa-body": "^4.0.4",
"koa-router": "^7.4.0",
"koa-static": "^5.0.0",
"koa2-cors": "^2.0.6",
"log4js": "^6.3.0",
"moment": "^2.22.2",
"mysql2": "^2.2.5",
"querystring": "^0.2.1",
"sqlite": "^4.0.23",
"sqlite3": "^5.0.2",
"uuid": "^3.3.2",
"winston": "^3.1.0",
"yaml": "^2.3.3"
}
}

View File

@ -44,6 +44,9 @@ dependencies:
mysql2:
specifier: ^2.2.5
version: 2.3.3
querystring:
specifier: ^0.2.1
version: 0.2.1
sqlite:
specifier: ^4.0.23
version: 4.1.2
@ -56,6 +59,9 @@ dependencies:
winston:
specifier: ^3.1.0
version: 3.8.2
yaml:
specifier: ^2.3.3
version: 2.3.3
packages:
@ -1404,6 +1410,12 @@ packages:
side-channel: 1.0.4
dev: false
/querystring@0.2.1:
resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==}
engines: {node: '>=0.4.x'}
deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
dev: false
/raw-body@2.5.2:
resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==}
engines: {node: '>= 0.8'}
@ -1771,6 +1783,11 @@ packages:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: false
/yaml@2.3.3:
resolution: {integrity: sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ==}
engines: {node: '>= 14'}
dev: false
/ylru@1.3.2:
resolution: {integrity: sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==}
engines: {node: '>= 4.0.0'}

View File

@ -3,6 +3,8 @@ import {tryLogin, get, post, updateQbInfo, getQbInfo} from '../util/QbApiUtil';
import GlobalConfigService from "./GlobalConfigService";
import GlobalConfig from "../entity/po/GlobalConfig";
import BtListItemDto from "../entity/dto/BtListItemDto";
import QbCommonDto from "../entity/dto/QbCommonDto";
import {boolTag} from "yaml/dist/schema/core/bool";
class QbService {
@ -14,13 +16,18 @@ class QbService {
if (body.address.endsWith("/")) {
body.address = body.address.substring(0, body.address.length - 1);
}
await GlobalConfigService.insertOrReplace(new GlobalConfig("qbConfig", JSON.stringify(body), "qb config"));
updateQbInfo(body);
body.valid = await tryLogin();
body.version = body ? (await get("/app/version", null)) : null;
if (parseFloat(body.version.replace("v", "")) < 4.1) {
body.valid = false;
body.version = null;
throw new Error("qb.version-error");
}
await GlobalConfigService.insertOrReplace(new GlobalConfig("qbConfig", JSON.stringify(body), "qb config"));
return body;
}
a
/**
*
*/
@ -36,6 +43,16 @@ a
return res;
}
static async commonGet(body: QbCommonDto): Promise<any> {
return await get(body.url, body.body);
}
static async commonPost(body: QbCommonDto): Promise<any> {
return await post(body.url, body.query, body.body, body.contentType);
}
/**
*
*/

View File

@ -16,24 +16,40 @@ export function getQbInfo() {
}
export async function get(url: string, data: object) {
return await request("get", url, data, null, false);
return await request("get", url, data, null, 1);
}
export async function post(url: string, data: object, isForm = false) {
return await request("post", url, null, data, isForm);
/**
*
* @param url
* @param data
* @param formType 1:application/json 2:formdata 3:application/x-www-form-urlencoded
*/
export async function post(url: string, query: any, data: object, formType = 1) {
return await request("post", url, query, data, formType);
}
async function request(method: Method, url: string, query: any, body: any, isForm = false) {
/**
*
* @param url
* @param data
* @param formType 1:application/json 2:formdata 3:application/x-www-form-urlencoded
*/
async function request(method: Method, url: string, query: any, body: any, formType = 1) {
if (!qbInfo.valid) {
throw new Error("qbittorrent无法连接请检查配置");
}
let isTryLogin = false;
while (true) {
let headers = {"Cookie": cookie};
if (isForm) {
headers['content-type'] = "multipart/form-data";
} else if (method == "post") {
headers['content-type'] = "application/json";
if (method == 'post') {
if (formType == 1) {
headers['content-type'] = "application/json";
} else if (formType == 2) {
headers['content-type'] = "multipart/form-data";
} else {
headers['content-type'] = "application/x-www-form-urlencoded";
}
}
let res = await axios.request({
baseURL: qbInfo.address,

View File

@ -1,28 +1,29 @@
{
"name": "open-renamer",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"dayjs": "^1.10.7",
"element-plus": "^2.2.25",
"vue": "^3.2.45",
"vue-router": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"@vue/compiler-sfc": "^3.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^2.2.1"
}
}
{
"name": "open-renamer",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"axios": "^0.21.1",
"core-js": "^3.6.5",
"dayjs": "^1.10.7",
"element-plus": "^2.2.25",
"vue": "^3.2.45",
"vue-i18n": "^9.5.0",
"vue-router": "^4.0.0-0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"@vue/compiler-sfc": "^3.0.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^2.2.1"
}
}

View File

@ -23,6 +23,9 @@ dependencies:
vue:
specifier: ^3.2.45
version: 3.2.47
vue-i18n:
specifier: ^9.5.0
version: 9.5.0(vue@3.2.47)
vue-router:
specifier: ^4.0.0-0
version: 4.1.6(vue@3.2.47)
@ -1302,6 +1305,27 @@ packages:
'@hapi/hoek': 9.3.0
dev: true
/@intlify/core-base@9.5.0:
resolution: {integrity: sha512-y3ufM1RJbI/DSmJf3lYs9ACq3S/iRvaSsE3rPIk0MGH7fp+JxU6rdryv/EYcwfcr3Y1aHFlCBir6S391hRZ57w==}
engines: {node: '>= 16'}
dependencies:
'@intlify/message-compiler': 9.5.0
'@intlify/shared': 9.5.0
dev: false
/@intlify/message-compiler@9.5.0:
resolution: {integrity: sha512-CAhVNfEZcOVFg0/5MNyt+OFjvs4J/ARjCj2b+54/FvFP0EDJI5lIqMTSDBE7k0atMROSP0SvWCkwu/AZ5xkK1g==}
engines: {node: '>= 16'}
dependencies:
'@intlify/shared': 9.5.0
source-map-js: 1.0.2
dev: false
/@intlify/shared@9.5.0:
resolution: {integrity: sha512-tAxV14LMXZDZbu32XzLMTsowNlgJNmLwWHYzvMUl6L8gvQeoYiZONjY7AUsqZW8TOZDX9lfvF6adPkk9FSRdDA==}
engines: {node: '>= 16'}
dev: false
/@jridgewell/gen-mapping@0.1.1:
resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==}
engines: {node: '>=6.0.0'}
@ -7869,6 +7893,18 @@ packages:
resolution: {integrity: sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==}
dev: true
/vue-i18n@9.5.0(vue@3.2.47):
resolution: {integrity: sha512-NiI3Ph1qMstNf7uhYh8trQBOBFLxeJgcOxBq51pCcZ28Vs18Y7BDS58r8HGDKCYgXdLUYqPDXdKatIF4bvBVZg==}
engines: {node: '>= 16'}
peerDependencies:
vue: ^3.0.0
dependencies:
'@intlify/core-base': 9.5.0
'@intlify/shared': 9.5.0
'@vue/devtools-api': 6.5.0
vue: 3.2.47
dev: false
/vue-loader@15.10.1(@vue/compiler-sfc@3.2.47)(css-loader@6.7.3)(lodash@4.17.21)(webpack@5.75.0):
resolution: {integrity: sha512-SaPHK1A01VrNthlix6h1hq4uJu7S/z0kdLUb6klubo738NeQoLbS6V9/d8Pv19tU0XdQKju3D1HSKuI8wJ5wMA==}
peerDependencies:

View File

@ -1,69 +1,87 @@
<template>
<div class="app">
<el-menu :default-active="activeIndex" mode="horizontal" background-color="#545c64" text-color="#fff" active-text-color="#ffd04b" router>
<el-menu-item index="/">重命名</el-menu-item>
<!-- <el-menu-item index="/auto">自动化</el-menu-item>-->
<el-sub-menu index="/download">
<template #title>bt下载</template>
<el-menu-item index="/download/center">下载中心</el-menu-item>
<el-menu-item index="/download/config">配置</el-menu-item>
</el-sub-menu>
</el-menu>
<div class="header">
<el-menu :default-active="data.activeIndex" mode="horizontal" background-color="#545c64" text-color="#fff"
active-text-color="#ffd04b" router>
<el-menu-item index="/">{{ $t("menu.rename") }}</el-menu-item>
<!-- <el-menu-item index="/auto">自动化</el-menu-item>-->
<el-sub-menu index="/download">
<template #title>{{ $t("menu.download") }}</template>
<el-menu-item index="/download/center">{{ $t("menu.downloadHome") }}</el-menu-item>
<el-menu-item index="/download/config">{{ $t("menu.downloadConfig") }}</el-menu-item>
</el-sub-menu>
</el-menu>
<el-dropdown style="position: absolute;right:1em;top:1em;color: white;cursor: pointer" @command="langChange">
{{ $t("langChange") }} : {{ data.curLangLabel }}
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item v-for="item in data.langList" :key="item.code" :command="item.code">
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div class="content">
<router-view />
</div>
<div class="footer">
版本
<div class="footer">{{ $t("version") }}
<el-tooltip effect="dark" content="点击查看更新记录" placement="top">
<a href="https://blog.fleyx.com/blog/detail/20221130/#%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95" target="_blank">
{{ version }}</a
>
<a href="https://blog.fleyx.com/blog/detail/20221130/#%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95"
target="_blank">
{{ data.version }}</a>
</el-tooltip>
&nbsp;&nbsp;
<template v-if="latestVersion && showNewVersion">
最新版本:
<template v-if="data.latestVersion && data.showNewVersion">
{{ $t("newestVersion") }}:
<el-tooltip effect="dark" content="点击查看更新文档" placement="top">
<a href="https://blog.fleyx.com/blog/detail/20221130/#%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95" target="_blank">
{{ latestVersion }}</a
>
<a href="https://blog.fleyx.com/blog/detail/20221130/#%E7%89%88%E6%9C%AC%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95"
target="_blank">
{{ data.latestVersion }}</a>
</el-tooltip>
&nbsp;&nbsp;
</template>
开源地址:<a href="https://github.com/FleyX/open-renamer">open-renamer</a> &nbsp;&nbsp;<a href="https://github.com/FleyX/open-renamer/issues"
>反馈</a
>
{{ $t("openSourceLocation") }}:<a href="https://github.com/FleyX/open-renamer">github open-renamer</a>
&nbsp;&nbsp;<a href="https://github.com/FleyX/open-renamer/issues">{{ $t("feedback") }}</a>
</div>
</div>
</template>
<script>
<script setup>
import { onBeforeMount, reactive } from "vue";
import { useI18n } from "vue-i18n";
const { locale, t } = useI18n();
import httpUtil from "./utils/HttpUtil";
export default {
name: "Home",
data() {
return {
version: "1.6.2",
latestVersion: null,
activeIndex: location.pathname,
showNewVersion: false,
};
},
async beforeCreate() {
window.token = localStorage.getItem("token");
const data = reactive({
version: "1.6.2",
latestVersion: null,
activeIndex: location.pathname,
showNewVersion: false,
curLangLabel: "",
langList: [{ code: "en", label: "English" },
{ code: "zh", label: "中文" }]
});
onBeforeMount(async () => {
window.token = localStorage.getItem("token");
window.isWindows = await httpUtil.get("/file/isWindows");
window.isWindows = await httpUtil.get("/file/isWindows");
},
async created() {
//
let config = await httpUtil.get("https://s3.fleyx.com/picbed/openRenamer/config.json");
this.latestVersion = config.version;
this.showNewVersion = checkVersion(this.version, this.latestVersion);
},
async mounted() {
console.log(this.$route);
console.log(location);
},
};
//
let config = await httpUtil.get("https://s3.fleyx.com/picbed/openRenamer/config.json");
data.latestVersion = config.version;
data.showNewVersion = checkVersion(data.version, data.latestVersion);
data.curLangLabel = data.langList.filter(item => item.code === locale.value)[0].label;
console.log(data.curLangLabel);
});
function langChange(command) {
data.curLangLabel = data.langList.filter(item => command === item.code)[0].label;
locale.value = command;
localStorage.setItem("lang", command);
console.log(command);
}
function checkVersion(version, latestVersion) {
if (version === latestVersion) {
@ -112,6 +130,10 @@ body {
margin: 0 auto;
background-color: white;
.header {
position: relative;
}
.content {
flex: 1;
padding: 0 10px 0 10px;

View File

@ -0,0 +1,35 @@
export default {
langChange: "change language",
version: "version",
newestVersion: "latest version",
openSourceLocation: "Open source address",
feedback: "Feedback",
menu: {
rename: "Rename",
download: "QBittorrent Download",
downloadConfig: "Config",
downloadHome: "Download center"
},
action: {
success: "action success",
fail: "action fail",
edit: "edit",
cancel: "cancel",
submit: "submit",
confirm: "confirm"
},
qbConfig: {
address: "Deploy address",
addressAlt: "Example: http://localhost:8080 (only v4.1 and above)",
error: "Error",
version: "Version",
username: "Username",
usernameAlt: "QBittorrent username",
password: "Password",
passwordAlt: "QBittorrent password",
downloadPath: "QB download path",
downloadPathAlt: "qBittorrent download path (this will need to be configured if qbittorrent and open-renamer are deployed in different docker containers)",
localPath: "Local path",
localPathAlt: "Corresponding to the path of the system (if qbittorrent and open-renamer are deployed in different docker containers, this parameter needs to be configured)"
}
};

View File

@ -0,0 +1,35 @@
export default {
langChange: "选择语言",
version: "版本",
newestVersion: "最新版本",
openSourceLocation: "开源地址",
feedback: "反馈",
menu: {
rename: "重命名",
download: "qBittorrent下载",
downloadConfig: "配置",
downloadHome: "下载中心"
},
action: {
success: "操作成功",
fail: "操作失败",
edit: "编辑",
cancel: "取消",
submit: "提交",
confirm: "确认"
},
qbConfig: {
address: "部署地址",
addressAlt: "例如:http://localhost:8080(仅支持v4.1及以上)",
error: "配置错误",
version: "版本",
username: "用户名",
usernameAlt: "qBittorrent 用户名",
password: "密码",
passwordAlt: "qBittorrent 密码",
downloadPath: "qb下载路径",
downloadPathAlt: "qb下载路径如果qbittorrent和open-renamer部署在不同的docker容器中需要配置此项",
localPath: "对应本系统路径",
localPathAlt: "对应本系统路径如果qbittorrent和open-renamer部署在不同的docker容器中需要配置此项"
}
};

View File

@ -2,9 +2,29 @@ import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import ElementPlus, { ElMessage } from "element-plus";
import { createI18n } from "vue-i18n";
import "element-plus/dist/index.css";
import en from "./i18n/en";
import zh from "./i18n/zh";
const messages = {
en,
zh
};
const lang = (navigator.language || "en").toLocaleLowerCase();
const locale = localStorage.getItem("lang") || lang.split("-")[0] || "en";
console.log(messages, locale);
const i18n = createI18n({
legacy: false,
locale,
fallbackLocale: "en",
messages
});
const vueInstance = createApp(App);
vueInstance.use(router).use(ElementPlus).mount("#app");
vueInstance.use(router).use(ElementPlus).use(i18n).mount("#app");
vueInstance.config.globalProperties.$message = ElMessage;
window.vueInstance = vueInstance;

View File

@ -1,5 +1,5 @@
import * as http from 'axios';
import router from '../router/index';
import * as http from "axios";
import router from "../router/index";
/**
* 请求
@ -12,36 +12,36 @@ import router from '../router/index';
* @returns 数据
*/
async function request(url, method, params, body, isForm) {
let options = {
url,
baseURL: '/openRenamer/api',
method,
params,
headers: {token: window.token}
};
if (isForm) {
options.headers['Content-Type'] = 'multipart/form-data';
let options = {
url,
baseURL: "/openRenamer/api",
method,
params,
headers: { token: window.token, lang: localStorage.getItem("lang") }
};
if (isForm) {
options.headers["Content-Type"] = "multipart/form-data";
}
if (body) {
options.data = body;
}
let res;
try {
res = await http.default.request(options);
} catch (err) {
console.log(Object.keys(err));
console.log(err.response);
if (err.response.status === 401) {
window.vueInstance.config.globalProperties.$message.error("密钥验证错误");
router.push("/public/login");
} else if (err.response.status === 400) {
window.vueInstance.config.globalProperties.$message.error(err.response.data);
} else {
window.vueInstance.config.globalProperties.$message.error("发生了某些异常问题");
}
if (body) {
options.data = body;
}
let res;
try {
res = await http.default.request(options);
} catch (err) {
console.log(Object.keys(err));
console.log(err.response);
if (err.response.status === 401) {
window.vueInstance.config.globalProperties.$message.error('密钥验证错误');
router.push("/public/login");
} else if (err.response.status === 400) {
window.vueInstance.config.globalProperties.$message.error(err.response.data);
} else {
window.vueInstance.config.globalProperties.$message.error('发生了某些异常问题');
}
throw err;
}
return res.data;
throw err;
}
return res.data;
}
/**
@ -51,7 +51,7 @@ async function request(url, method, params, body, isForm) {
* @param {*} redirect 未登陆是否跳转到登陆页
*/
async function get(url, params = null) {
return request(url, 'get', params, null, false);
return request(url, "get", params, null, false);
}
/**
@ -63,7 +63,7 @@ async function get(url, params = null) {
* @param {*} redirect 是否重定向
*/
async function post(url, params, body, isForm = false) {
return request(url, 'post', params, body, isForm);
return request(url, "post", params, body, isForm);
}
/**
@ -75,7 +75,7 @@ async function post(url, params, body, isForm = false) {
* @param {*} redirect 是否重定向
*/
async function put(url, params, body, isForm = false) {
return request(url, 'put', params, body, isForm);
return request(url, "put", params, body, isForm);
}
/**
@ -85,12 +85,12 @@ async function put(url, params, body, isForm = false) {
* @param {*} redirect 是否重定向
*/
async function deletes(url, params = null) {
return request(url, 'delete', params, null);
return request(url, "delete", params, null);
}
export default {
get,
post,
put,
delete: deletes,
get,
post,
put,
delete: deletes
};

View File

@ -1,40 +1,52 @@
<template>
<div>配置qb</div>
<el-form :model="data.qbConfig" label-width="8em">
<el-form-item label="qb版本">
{{ data.qbConfig.version ? data.qbConfig.version : "配置错误,无法访问" }}
<el-form :model="data.qbConfig" label-width="10em">
<el-form-item :label="t('qbConfig.version')">
{{ data.qbConfig.version ? data.qbConfig.version : $t("qbConfig.error") }}
</el-form-item>
<el-form-item label="访问地址">
<el-input type="text" v-model="data.qbConfig.address" placeholder="例如:http://localhost:8080(仅支持v4.1及以上)"/>
<el-form-item :label="t('qbConfig.address')">
<el-input :disabled="data.disabled" type="text" v-model="data.qbConfig.address"
:placeholder="t('qbConfig.addressAlt')" />
</el-form-item>
<el-form-item label="用户名">
<el-input type="text" v-model="data.qbConfig.username" placeholder="qb访问用户名"/>
<el-form-item :label="t('qbConfig.username')">
<el-input :disabled="data.disabled" type="text" v-model="data.qbConfig.username"
:placeholder="t('qbConfig.usernameAlt')" />
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="data.qbConfig.password" placeholder="qb访问密码"/>
<el-form-item :label="t('qbConfig.password')">
<el-input :disabled="data.disabled" type="password" v-model="data.qbConfig.password"
:placeholder="t('qbConfig.passwordAlt')" />
</el-form-item>
<el-form-item label="qb下载路径">
<el-input type="text" v-model="data.qbConfig.qbDownloadPath" placeholder="qb下载路径(qb中选择的下载路径)"/>
<el-form-item :label="t('qbConfig.downloadPath')">
<el-input :disabled="data.disabled" type="text" v-model="data.qbConfig.qbDownloadPath"
:placeholder="t('qbConfig.downloadPathAlt')" />
</el-form-item>
<el-form-item label="对应本系统路径">
<el-input type="text" v-model="data.qbConfig.renameQbDownloadPath" placeholder="qb下载路径对应到本软件中的路径"/>
<el-form-item :label="t('qbConfig.localPath')">
<el-input :disabled="data.disabled" type="text" v-model="data.qbConfig.renameQbDownloadPath"
:placeholder="t('qbConfig.localPathAlt')" />
</el-form-item>
<div style="text-align: center">
<el-button type="" @click="editInfo = false">取消</el-button>
<el-button type="primary" @click="submitQb">提交</el-button>
<template v-if="!data.disabled">
<el-button type="warning" @click="data.disabled= true">{{ $t("action.cancel") }}</el-button>
<el-button type="primary" @click="submitQb">{{ $t("action.submit") }}</el-button>
</template>
<el-button type="primary" @click="data.disabled= false" v-else>{{ $t("action.edit") }}</el-button>
</div>
</el-form>
</template>
<script setup>
import {ref, reactive, onMounted, computed} from "vue";
import { ref, reactive, onMounted, computed } from "vue";
import { ElMessage } from "element-plus";
import http from "@/utils/HttpUtil";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
//
const data = reactive({
qbConfig: {},
disabled: true
});
//qb访
let editInfo = ref(false);
onMounted(async () => {
data.qbConfig = await http.get("/qb/config");
@ -42,6 +54,8 @@ onMounted(async () => {
async function submitQb() {
data.qbConfig = await http.post("/qb/saveQbInfo", null, data.qbConfig);
ElMessage({ message: t("action.success"), type: "success" });
}
</script>