Compare commits

...

5 Commits

Author SHA1 Message Date
20513d14da deploy:pkg打包优化 2025-03-29 14:30:07 +08:00
698087c8bf deploy:报错日志优化 2025-03-16 20:54:55 +08:00
c43f406a29 deploy:增加pkg打包 2025-03-13 13:42:51 +08:00
5b33be94ba Merge branch 'qb' into dev
# Conflicts:
#	openRenamerBackend/package.json
#	openRenamerBackend/pnpm-lock.yaml
#	openRenamerFront/package.json
#	openRenamerFront/pnpm-lock.yaml
#	openRenamerFront/src/App.vue
2025-03-12 20:04:16 +08:00
ef92c13a4f temp 2025-03-12 19:52:19 +08:00
22 changed files with 1144 additions and 1113 deletions

View File

@ -14,4 +14,9 @@ sqls/history.json
static/*
!static/.gitkeep
database.db
.idea
.idea
ndist/index.js
app
app.exe
/ndist/lib/binding/napi-v6-darwin-unknown-arm64/node_sqlite3.node.bak

View File

@ -5,6 +5,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/dist" />
<excludeFolder url="file://$MODULE_DIR$/.vscode" />
<excludeFolder url="file://$MODULE_DIR$/ndist" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />

View File

@ -0,0 +1,7 @@
# shellcheck disable=SC2164
cd ../openRenamerFront
npm run build
cp -r dist/* ../openRenamerBackend/static
cd ../openRenamerBackend
npm run ncc
npm run pkg

View File

@ -3,15 +3,26 @@ import * as process from "process";
//后台所在绝对路径
const rootPath = path.resolve(__dirname, '..');
let map = {};
console.log(process.argv);
//argv 传递 portdataPath,env,token
for (let i = 2; i < process.argv.length; i++) {
if (process.argv[i] != null && process.argv[i] != '') {
let strings = process.argv[i].split(":");
map[strings[0]] = strings[1];
}
}
let config = {
rootPath,
dataPath: process.env.DATA_PATH ? process.env.DATA_PATH : path.join(rootPath, 'data'),
port: process.env.PORT ? parseInt(process.env.PORT) : 8089,
token: process.env.TOKEN ? process.env.TOKEN : null,
dataPath: map['dataPath'] ? map['dataPath'] : process.env.DATA_PATH ? process.env.DATA_PATH : path.join(rootPath, 'data'),
port: map['port'] ? parseInt(map['port']) : process.env.PORT ? parseInt(process.env.PORT) : 8089,
token: map['token'] ? map['token'] : process.env.TOKEN ? process.env.TOKEN : null,
env: map['env'] ? map['env'] : process.env.ENV ? process.env.ENV : "dev",
urlPrefix: '/openRenamer/api',
//是否为windows平台
isWindows: process.platform.toLocaleLowerCase().includes("win"),
isWindows: process.platform.toLocaleLowerCase().includes("win32"),
isMac: process.platform.toLocaleLowerCase().includes("darwin"),
bodyLimit: {
formLimit: '200mb',
jsonLimit: '200mb',

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,9 +9,10 @@ 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';
let start = Date.now();
console.log(config);
const app = new koa();
@ -32,9 +33,10 @@ app.use(handleError);
app.use(RouterMW(router, path.join(config.rootPath, "dist/api")));
(async () => {
await SqliteUtil.createPool();
await qbService.init();
qbService.init();
i18n.init();
app.listen(config.port);
log.info(`server listened `, config.port);
log.info(`server listened ${config.port},cost:${Date.now() - start}ms`);
})();
app.on("error", (error) => {

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,28 +1,38 @@
{
"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.13.12",
"@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",
"sqlite": "4.0.23",
"sqlite3": "5.0.2",
"uuid": "3.3.2"
}
}
{
"name": "nas_backup",
"version": "1.0.0",
"description": "文件备份用",
"main": "index.js",
"scripts": {
"pkg": "tsc && pkg . -t macos -o app"
},
"bin": "dist/index.js",
"pkg": {
"assets": [
"dist/**/*",
"static/**/**",
"sqls/*",
"i18n/*"
]
},
"author": "fxb",
"license": "ISC",
"dependencies": {
"@types/fs-extra": "5.0.4",
"@types/koa": "2.13.12",
"@types/node": "11.13.4",
"axios": "0.29.0",
"fs-extra": "7.0.0",
"koa": "3.0.0-alpha.3",
"koa-body": "4.0.4",
"koa-router": "7.4.0",
"koa-static": "5.0.0",
"koa2-cors": "2.0.6",
"log4js": "6.4.0",
"moment": "2.29.4",
"sqlite": "5.1.1",
"sqlite3": "5.1.5",
"uuid": "3.3.2",
"yaml": "2.7.0"
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,10 @@
import QbConfigDto from "../entity/dto/QbConfigDto";
import {tryLogin, get, post, updateQbInfo, getQbInfo} from '../util/QbApiUtil';
import {get, getQbInfo, post, tryLogin, updateQbInfo} 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 logger from "../util/LogUtil";
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);
}
/**
*
*/
@ -45,7 +62,6 @@ a
updateQbInfo(qbInfo);
qbInfo.valid = await tryLogin();
qbInfo.version = qbInfo.valid ? (await get("/app/version", null)) : null;
return qbInfo;
}
}

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,
@ -75,8 +91,8 @@ export async function tryLogin(): Promise<boolean> {
}
qbInfo.valid = success;
return success;
} catch (error) {
console.error("登录报错:", error);
} catch (error:any) {
console.error("qb登录报错:" );
return false;
}

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": "1.6.0",
"core-js": "3.35.0",
"dayjs": "1.10.7",
"element-plus": "2.2.25",
"vue": "3.2.45",
"vue-router": "4.2.5"
},
"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": "1.6.0",
"core-js": "3.35.0",
"dayjs": "1.10.7",
"element-plus": "2.2.25",
"vue": "3.2.45",
"vue-i18n": "9.5.0",
"vue-router": "4.2.5"
},
"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

@ -1,73 +1,90 @@
<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="content">
<router-view/>
<div class="header">
<el-menu :default-active="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="footer">版本
<div class="content">
<router-view />
</div>
<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>
{{ 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>
{{ data.latestVersion }}</a>
</el-tooltip>
&nbsp;&nbsp;
</template>
开源地址:<a href="https://github.com/FleyX/open-renamer" target="_blank">open-renamer</a>
&nbsp;&nbsp;<a href="https://github.com/FleyX/open-renamer/issues" target="_blank">反馈</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.8.0",
latestVersion: null,
activeIndex: location.pathname,
showNewVersion: false
};
},
async beforeCreate() {
window.token = localStorage.getItem("token");
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);
const data = reactive({
version: "1.7.2",
latestVersion: null,
activeIndex: location.pathname,
showNewVersion: false,
curLangLabel: "",
langList: [{ code: "en", label: "English" },
{ code: "zh", label: "中文" }]
});
},
async mounted() {
console.log(this.$route);
console.log(location);
},
};
onBeforeMount(async () => {
window.token = localStorage.getItem("token");
window.isWindows = await httpUtil.get("/file/isWindows");
//
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) {
let versions = version.split(".");
let latestVersions = latestVersion.split('.');
let latestVersions = latestVersion.split(".");
for (let i = 0; i < versions.length; i++) {
if (i >= latestVersions.length) {
return false;
@ -109,6 +126,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>