From 84cae05f81cce3dd5a1130dccb30f8db12f44dea Mon Sep 17 00:00:00 2001 From: charyflys <167504273+charyflys@users.noreply.github.com> Date: Tue, 15 Oct 2024 09:41:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E9=83=A8?= =?UTF-8?q?=E5=88=86API=E8=AF=B7=E6=B1=82=E9=83=A8=E5=88=86=EF=BC=8C?= =?UTF-8?q?=E7=BB=9F=E5=90=88API=E8=87=B3=E7=BB=9F=E4=B8=80=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=20(#240)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 尝试对api进行整理,并对story相关api进行初步替换 * 对censor相关api进行修改 * refactor api: 为了方便调试,对请求的指向性方法修改为代理转发,并由.env控制 * refactor api: 对config路径下请求进行整合,并对相关依赖进行修改 * refactor api:对story相关api删除无用依赖 * refactor api: 对censor相关api删除无用依赖 * refactor api: 对im_connections路径下的请求进行整理并替换对应的依赖 * style(api):优化im_connection函数显示 * refactor(api):整合utils路径下的请求,并整理对应依赖项 * refactor(api):解耦im_connection路径下相关依赖,同时修改部分api函数参数 * refactor(api):整合dice路径下的请求,并整理对应依赖 * refactor(api):整合backup路径下请求,并整理相关依赖 * refactor(api):整合banconfig下的请求,并整理相关依赖 * refactor(api):整合group路径下的请求,并修改相关依赖 * refactor(api):整合牌堆管理相关请求,并整理相关依赖 * refactor(api):整合js路径下的请求,并整理相关依赖 * refactor(api):整合登陆相关请求,并修改相关依赖 * refactor(api):整合helpdoc路径请求,并整理相关依赖 * refactor(api):整合resource路径下请求,并整合相关依赖 --------- Co-authored-by: chary <920868587@qq.com> --- .env.development | 1 + package.json | 2 + pnpm-lock.yaml | 123 ++++ src/Main.vue | 8 +- src/api/backup/index.ts | 48 ++ src/api/banconfig/index.ts | 41 ++ src/api/censor/index.ts | 108 ++++ src/api/configs/index.ts | 116 ++++ src/api/deck/index.ts | 62 ++ src/api/dice/index.ts | 107 ++++ src/api/group/index.ts | 85 +++ src/api/helpdoc/index.ts | 36 ++ src/api/im_connections/index.ts | 357 +++++++++++ src/api/index.ts | 118 ++++ src/api/js/index.ts | 88 +++ src/api/others/index.ts | 55 ++ src/api/resource/index.ts | 26 + src/api/signin/index.ts | 12 + src/api/story/index.ts | 82 +++ src/api/utils/index.ts | 25 + src/backend.ts | 6 +- src/components/PageConnectInfoItems.vue | 29 +- src/components/PageHome.vue | 8 +- .../misc/PageMiscAdvancedSettings.vue | 7 +- src/components/misc/PageMiscBackup.vue | 15 +- src/components/misc/PageMiscGroup.vue | 7 +- src/components/misc/PageMiscSettings.vue | 6 +- src/components/misc/banList/BanConfig.vue | 8 +- src/components/misc/banList/BanList.vue | 11 +- src/components/mod/PageCensor.vue | 10 +- src/components/mod/PageCustomReply.vue | 25 +- src/components/mod/PageHelpDoc.vue | 25 +- src/components/mod/PageJs.vue | 43 +- src/components/mod/PageMiscDeck.vue | 31 +- src/components/mod/PageStory.vue | 40 +- src/components/mod/censor/CensorConfig.vue | 16 +- src/components/mod/censor/CensorFiles.vue | 16 +- src/components/mod/censor/CensorLog.vue | 15 +- src/components/mod/censor/CensorWords.vue | 6 +- src/components/mod/censor/censor.ts | 35 +- src/components/mod/story/StoryBackup.vue | 15 +- src/components/mod/story/story.ts | 41 -- src/components/tool/PageResource.vue | 7 +- src/components/tool/PageTest.vue | 9 +- src/components/utils/resource-render.vue | 5 +- src/store/index.ts | 581 ++---------------- src/type.d.ts | 2 +- vite.config.ts | 14 +- 48 files changed, 1746 insertions(+), 787 deletions(-) create mode 100644 .env.development create mode 100644 src/api/backup/index.ts create mode 100644 src/api/banconfig/index.ts create mode 100644 src/api/censor/index.ts create mode 100644 src/api/configs/index.ts create mode 100644 src/api/deck/index.ts create mode 100644 src/api/dice/index.ts create mode 100644 src/api/group/index.ts create mode 100644 src/api/helpdoc/index.ts create mode 100644 src/api/im_connections/index.ts create mode 100644 src/api/index.ts create mode 100644 src/api/js/index.ts create mode 100644 src/api/others/index.ts create mode 100644 src/api/resource/index.ts create mode 100644 src/api/signin/index.ts create mode 100644 src/api/story/index.ts create mode 100644 src/api/utils/index.ts delete mode 100644 src/components/mod/story/story.ts diff --git a/.env.development b/.env.development new file mode 100644 index 00000000..b1466193 --- /dev/null +++ b/.env.development @@ -0,0 +1 @@ +VITE_APP_APIURL="http://localhost:6394" \ No newline at end of file diff --git a/package.json b/package.json index 96ab4631..5484e431 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@codemirror/lang-javascript": "^6.2.2", "@element-plus/icons-vue": "^2.3.1", + "@types/qs": "^6.9.16", "@vueuse/core": "^10.11.0", "asmcrypto.js": "^2.3.2", "axios": "^1.7.2", @@ -28,6 +29,7 @@ "highlight.js": "^11.10.0", "lodash-es": "^4.17.21", "pinia": "^2.1.7", + "qs": "^6.13.0", "randomcolor": "^0.6.2", "vue": "^3.4.33", "vue-diff": "^1.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6722b1c1..02559a88 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@element-plus/icons-vue': specifier: ^2.3.1 version: 2.3.1(vue@3.4.33(typescript@5.5.3)) + '@types/qs': + specifier: ^6.9.16 + version: 6.9.16 '@vueuse/core': specifier: ^10.11.0 version: 10.11.0(vue@3.4.33(typescript@5.5.3)) @@ -53,6 +56,9 @@ importers: pinia: specifier: ^2.1.7 version: 2.1.7(typescript@5.5.3)(vue@3.4.33(typescript@5.5.3)) + qs: + specifier: ^6.13.0 + version: 6.13.0 randomcolor: specifier: ^0.6.2 version: 0.6.2 @@ -1156,6 +1162,9 @@ packages: '@types/node@20.14.11': resolution: {integrity: sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==} + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + '@types/randomcolor@0.5.9': resolution: {integrity: sha512-k58cfpkK15AKn1m+oRd9nh5BnuiowhbyvBBdAzcddtARMr3xRzP0VlFaAKovSG6N6Knx08EicjPlOMzDejerrQ==} @@ -1503,6 +1512,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1615,6 +1628,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -1660,6 +1677,14 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1807,6 +1832,10 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -1842,6 +1871,9 @@ packages: good-listener@1.2.2: resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} @@ -1853,6 +1885,17 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2136,6 +2179,10 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2273,6 +2320,10 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -2352,6 +2403,10 @@ packages: engines: {node: '>=10'} hasBin: true + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2360,6 +2415,10 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -3843,6 +3902,8 @@ snapshots: dependencies: undici-types: 5.26.5 + '@types/qs@6.9.16': {} + '@types/randomcolor@0.5.9': {} '@types/semver@7.5.8': {} @@ -4296,6 +4357,14 @@ snapshots: buffer-from@1.1.2: {} + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + callsites@3.1.0: {} camelcase-css@2.0.1: {} @@ -4405,6 +4474,12 @@ snapshots: deep-is@0.1.4: {} + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + delayed-stream@1.0.0: {} delegate@3.2.0: {} @@ -4454,6 +4529,12 @@ snapshots: entities@4.5.0: {} + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -4655,6 +4736,14 @@ snapshots: gensync@1.0.0-beta.2: {} + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + get-stream@6.0.1: {} glob-parent@5.1.2: @@ -4702,12 +4791,24 @@ snapshots: dependencies: delegate: 3.2.0 + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + graphemer@1.4.0: {} has-flag@3.0.0: {} has-flag@4.0.0: {} + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -4927,6 +5028,8 @@ snapshots: object-hash@3.0.0: {} + object-inspect@1.13.2: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -5042,6 +5145,10 @@ snapshots: punycode@2.3.1: {} + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + queue-microtask@1.2.3: {} randomcolor@0.6.2: {} @@ -5134,12 +5241,28 @@ snapshots: semver@7.6.2: {} + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + signal-exit@3.0.7: {} signal-exit@4.1.0: {} diff --git a/src/Main.vue b/src/Main.vue index 72bd193c..2367176b 100644 --- a/src/Main.vue +++ b/src/Main.vue @@ -133,6 +133,8 @@ import {CircleCloseFilled} from '@element-plus/icons-vue' import {passwordHash} from "./utils" import { delay, replace } from "lodash-es" +import { getNewUtils, postUtilsCheckNews } from './api/utils' +import { checkSecurity } from './api/others' dayjs.locale('zh-cn') dayjs.extend(relativeTime); @@ -149,7 +151,7 @@ const newsChecked = ref(true) const newsMark = ref('') const checkNews = async (close: any) => { console.log('newsMark', newsMark.value) - const ret = await store.checkNews(newsMark.value) + const ret = await postUtilsCheckNews(newsMark.value) if (ret?.result) { ElMessage.success('已阅读最新的海豹新闻') } else { @@ -159,7 +161,7 @@ const checkNews = async (close: any) => { close() } const updateNews = async () => { - const newsInfo = await store.news() + const newsInfo = await getNewUtils() if (newsInfo.result) { newsData.value = newsInfo.news newsChecked.value = newsInfo.checked @@ -190,7 +192,7 @@ const doUnlock = async () => { } const checkPassword = async () => { - if (!await store.checkSecurity()) { + if (!(await checkSecurity()).isOk) { ElMessageBox.alert('欢迎使用海豹核心。
如果您的服务开启在公网,为了保证您的安全性,请前往“综合设置->基本设置”界面,设置UI界面密码
或切换为只有本机可访问。
如果您不了解上面在说什么,请务必设置一个密码', '提示', {dangerouslyUseHTMLString: true}) } } diff --git a/src/api/backup/index.ts b/src/api/backup/index.ts new file mode 100644 index 00000000..5f405746 --- /dev/null +++ b/src/api/backup/index.ts @@ -0,0 +1,48 @@ +import { createRequest } from ".."; + +const baseUrl = '/backup/' +const request = createRequest(baseUrl) + +export function getBackupList() { + return request<{items:BackupInfo[]}>('get', 'list') +} + +export function getBackupConfig() { + return request('get', 'config_get') +} + +export function setBackupConfig(data: BackupConfig) { + return request('post', 'config_set', data) +} + +export function postDoBackup(selection: number) { + return request('post', 'do_backup', { selection }) +} + +export function postBackupDel(name: string) { + return request<{ success: boolean }>('post', 'delete?name=' + name, { name }) +} + +export function postBackupBatchDel(names: string[]) { + return request<{ result: true } | { + result: false, + fails: string[], + }>('post', 'batch_delete', { names }) +} + +type BackupConfig = { + autoBackupEnable: boolean, + autoBackupTime: string, + autoBackupSelection: number, + backupCleanStrategy: number, + backupCleanKeepCount: number, + backupCleanKeepDur: string, + backupCleanTrigger: number, + backupCleanCron: string, + autoBackupSelectionList: string[] +} +type BackupInfo = { + name: string, + fileSize: number, + selection: number +} \ No newline at end of file diff --git a/src/api/banconfig/index.ts b/src/api/banconfig/index.ts new file mode 100644 index 00000000..77784012 --- /dev/null +++ b/src/api/banconfig/index.ts @@ -0,0 +1,41 @@ +import type { BanConfig } from "~/type"; +import { createRequest } from ".."; +import type { UploadUserFile } from "element-plus"; + +const baseUrl = '/banconfig/' +const request = createRequest(baseUrl) + +export function getBanConfig() { + return request('get','get') +} + +export function setBanConfig(config: BanConfig) { + return request('post','set',config) +} + +export function getBanConfigList() { + return request('get','list') +} + +export function postMapDelOne(item: BanConfigItem) { + return request('post','map_delete_one',item) +} + +export function postMapAddOne(ID:string,rank:number,name:string,reason:string) { + return request('post','map_add_one',{ID,rank,name,reasons:reason?[reason]:[]}) +} + +export function importBanConfig(file: UploadUserFile|Blob) { + return request<{ result: true } | { + result: false, + err: string + }>('post','import',{file},'formdata') +} + +type BanConfigItem = { + ID:string + name:string + rank: number + reason: string + rankText?:string +} diff --git a/src/api/censor/index.ts b/src/api/censor/index.ts new file mode 100644 index 00000000..6c8b3976 --- /dev/null +++ b/src/api/censor/index.ts @@ -0,0 +1,108 @@ +import { createRequest } from ".."; + +const baseUrl = '/censor/' +const request = createRequest(baseUrl) + +export function getCensorStatus() { + return request<{ result: false } | { + result: true, + enable: boolean, + isLoading: boolean + }>('get', 'status') +} + +export function postCensorRestart(token: string) { + return request<{ result: false } | { + result: true, + enable: boolean, + isLoading: boolean + }>('post', 'restart', { token }) +} + +export function postCensorStop(token: string) { + return request<{ result: true } | { + result: false, + err: string + }>('post', 'stop', { token }) +} + +export function getCensorConfig() { + return request<{ result: false } | CensorConfig & { result: true }>('get', 'config') +} + +export function postCensorConfig(modify: CensorConfig) { + return request<{ result: true } | { result: false, err: string }>('post', 'config', modify) +} + +export function uploadCensorFile(file: Blob) { + return request<{ result: true } | { result: false, err: string }>('post', 'files/upload', { file }, 'formdata') +} + +export function getCensorFiles() { + return request<{ result: false } | { + result: true, + data: SensitiveWordFile[] + }>('get', 'files') +} +export function deleteCensorFiles(keys: string[]) { + return request<{ result: true } | { result: false, err: string }> + ('delete', 'files', { keys }) +} + +export function getCensorLogs(pageNum: number, pageSize: number) { + return request<{ result: false } | { + result: true, + data: CensorLog[], + total: number + }>('get', 'logs/page', { pageNum, pageSize }) +} + +export function getCensorWords() { + return request<{ result: false } | { + result: true, + data: SensitiveWord[] + }>('get', 'words') +} + + +interface CensorConfig { + mode: number, + caseSensitive: boolean + matchPinyin: boolean + filterRegex: string + levelConfig: LeverConfig +} + +type LeverConfig = { + [key in 'notice' | 'caution' | 'warning' | 'danger']: { + threshold: number; + handlers: string[]; + score: number; + }; +}; + + +interface SensitiveWordFile { + key: string + path: string, + counter: number[] +} + +interface CensorLog { + id: number + msgType: string + userId: string + groupId: string + content: string + highestLevel: string + createAt: number +} +interface SensitiveWord { + main: string + level: number + related: SensitiveRelatedWord[] +} +interface SensitiveRelatedWord { + word: string + reason: string +} \ No newline at end of file diff --git a/src/api/configs/index.ts b/src/api/configs/index.ts new file mode 100644 index 00000000..c07a2161 --- /dev/null +++ b/src/api/configs/index.ts @@ -0,0 +1,116 @@ +import { createRequest } from ".."; + +const baseUrl = '/configs/' +const request = createRequest(baseUrl) + +export function saveCustomText(category: string, data: { [k: string]: string[][]; }) { + return request('post', 'customText/save', { data, category }) +} + +export function getCustomText() { + return request('get', 'customText') +} + +export function saveCustomReply(data: CustomReply) { + return request('post', 'custom_reply/save', data) +} + +export function getCustomReply(filename: string) { + return request('get', 'custom_reply', {filename}) +} + +export function postCustomReplyNew(filename: string) { + return request<{success: boolean}>('post', 'custom_reply/file_new', {filename}) +} + +export function postCustomReplyDel(filename: string) { + return request<{success: boolean}>('post', 'custom_reply/file_delete', {filename}) +} + +export function getCustomReplyDownload(filename: string) { + return request('get', 'custom_reply/file_download', {filename}) +} + +export function uploadCustomReply(file: Blob) { + return request('post', 'custom_reply/file_upload', {file}, 'formdata') +} + +export function getCustomReplyFileList() { + return request<{items:ReplyFileInfo[]}>('get', 'custom_reply/file_list') +} + +export function getCustomReplyDebug() { + return request<{value: boolean}>('get', 'custom_reply/debug_mode') +} + +export function postCustomReplyDebug(value: boolean) { + return request<{value: boolean}>('post', 'custom_reply/debug_mode', {value}) +} + +type CustomTexts = { + texts: { + [k: string]: { + [k: string]: string[][]; + }; + } + helpInfo: { + [k: string]: { + [k: string]: { + filename: string[]; + origin: (string[])[]; + vars: string[]; + modified: boolean; + notBuiltin: boolean; + topOrder: number; + subType: string; + extraText: string; + } + } + } + previewInfo: { + [key: string]: { + version: string; + textV2: string; + textV1: string; + presetExists: boolean; + errV1: string; + errV2: string; + } + } +} + +type CustomReply = { + author: [] + conditions:ReplyCondition[] + createTimestamp: number + desc:string + enable:false + filename:string + interval:number + items:CustomReplyItem[] + name:string + updateTimestamp:number + version:string +} +type CustomReplyItem = { + conditions:ReplyCondition[] + enable: boolean + results: ReplyResult[] +} + +type ReplyCondition = { + condType: string + matchType: string + value: string +} + +type ReplyResult= { + resultType: string + delay: number + message: [string,number][] +} + +type ReplyFileInfo = { + enable: boolean + filename: string +} \ No newline at end of file diff --git a/src/api/deck/index.ts b/src/api/deck/index.ts new file mode 100644 index 00000000..273ef90d --- /dev/null +++ b/src/api/deck/index.ts @@ -0,0 +1,62 @@ +import type { UploadRawFile } from "element-plus"; +import { createRequest } from ".."; + +const baseUrl = '/deck/'; +const request = createRequest(baseUrl); + +export function getDeckList() { + return request('get', 'list'); +} + +export function reloadDeck() { + return request<{testMode:boolean}>('post', 'reload'); +} + +export function enableDeck(index:number,enable:boolean) { + return request('post', 'enable', {index,enable}); +} + +export function deleteDeck(index:number) { + return request('post', 'delete', {index}); +} + +export function uploadDeck(file:Blob| UploadRawFile) { + return request('post', 'upload', {file},'formdata'); +} + +export function checkDeckUpdate(index:number) { + return request<{ result: false, err: string } | { + result: true, + old: string, + new: string, + format: 'json' | 'yaml' | 'toml', + tempFileName: string, + }>('post', 'check_update', {index}); +} + +export function updateDeck(index:number, tempFileName:string) { + return request<{ result: false, err: string } | { + result: true, + }>('post', 'update', {index,tempFileName}); +} + + +type DeckConfig = { + enable: boolean; // 是否启用该牌堆 + errText: string; // 错误信息,如果为空则没有错误 + filename: string; // 牌堆文件路径 + format: string; // 牌堆格式 + formatVersion: number; // 牌堆格式的版本 + fileFormat: string; // 文件格式(如 "json") + name: string; // 牌堆名称 + version: string; // 牌堆版本 + author: string; // 牌堆作者 + license: string; // 牌堆许可信息(可能为空) + command: {[key:string]: boolean}; // 牌堆命令的配置 + date: string; // 牌堆的创建日期 + updateDate: string; // 牌堆的更新日期(可能为空) + desc: string; // 牌堆描述 + updateUrls: string[] | null; // 更新URL(可能为空) + etag: string; // 文件标签(可能为空) + cloud: boolean; // 是否为云端存储 +}; \ No newline at end of file diff --git a/src/api/dice/index.ts b/src/api/dice/index.ts new file mode 100644 index 00000000..a8323a6c --- /dev/null +++ b/src/api/dice/index.ts @@ -0,0 +1,107 @@ +import type { AdvancedConfig } from "~/type"; +import { createRequest } from ".."; + +const baseUrl = '/dice/' +const request = createRequest(baseUrl) + +export function getDiceConfig() { + return request('get','config/get') +} + +export function setDiceConfig(config: DiceConfig) { + return request('post','config/set',config) +} + +export function getAdvancedConfig() { + return request('get','config/advanced/get') +} + +export function setAdvancedConfig(config:AdvancedConfig) { + return request('post','config/advanced/set',config) +} + +export function postMailTest() { + return request<{ result: true } | { + result: false, + err: string + }>('post','config/mail_test') +} + +export function postExec(message:string, messageType:'private' | 'group') { + return request('post','exec',{message,messageType}) +} + +export function postUploadToUpgrade(files: Blob) { + return request('post','upload_to_upgrade',{files},'formdata') +} + +export function getRecentMessage() { + return request('get','recentMessage') +} + +export function postUpgrade() { + return request<{text:string}>('post','upgrade') +} + + +export type DiceConfig = { + commandPrefix: string[], // 包含允许的命令前缀符号 + diceMasters: string[], // 骰子大师的标识(如用户ID) + noticeIds: string[], // 通知ID的列表 + onlyLogCommandInGroup: boolean, // 是否仅在群组中记录命令 + onlyLogCommandInPrivate: boolean, // 是否仅在私聊中记录命令 + workInQQChannel: boolean, // 是否启用QQ频道功能 + messageDelayRangeStart: number, // 消息延迟的最小范围 + messageDelayRangeEnd: number, // 消息延迟的最大范围 + uiPassword: string, // UI密码 + helpDocEngineType: number, // 帮助文档引擎类型 + masterUnlockCode: string, // 主解锁码 + serveAddress: string, // 服务器地址 + masterUnlockCodeTime: number, // 解锁码的时间戳 + logPageItemLimit: number, // 日志页面的条目限制 + friendAddComment: string, // 添加好友时的备注 + QQChannelAutoOn: boolean, // QQ频道是否自动开启 + QQChannelLogMessage: boolean, // QQ频道是否记录消息 + refuseGroupInvite: boolean, // 是否拒绝群组邀请 + quitInactiveThreshold: number, // 退出不活跃状态的阈值 + quitInactiveBatchSize: number, // 每次退出不活跃的批量大小 + quitInactiveBatchWait: number, // 批量退出时的等待时间 + defaultCocRuleIndex: string, // 默认的COC规则索引 + maxExecuteTime: string, // 最大执行时间 + maxCocCardGen: string, // 最大COC卡片生成数量 + extDefaultSettings: ExtensionSettings[], // 扩展插件的默认设置 + botExtFreeSwitch: boolean, // 机器人扩展是否自由开关 + trustOnlyMode: boolean, // 是否启用信任模式 + aliveNoticeEnable: boolean, // 是否启用存活通知 + aliveNoticeValue: string, // 存活通知的值 + replyDebugMode: boolean, // 是否启用调试模式回复 + customReplyConfigEnable: boolean, // 是否启用自定义回复配置 + logSizeNoticeEnable: boolean, // 是否启用日志大小通知 + logSizeNoticeCount: number, // 日志大小通知的数量 + textCmdTrustOnly: boolean, // 仅信任的文本命令 + ignoreUnaddressedBotCmd: boolean, // 忽略未定向给机器人的命令 + QQEnablePoke: boolean, // 是否启用QQ戳一戳功能 + playerNameWrapEnable: boolean, // 是否启用玩家名包裹 + mailEnable: boolean, // 是否启用邮件功能 + mailFrom: string, // 邮件发件人 + mailPassword: string, // 邮件密码 + mailSmtp: string, // 邮件SMTP服务器地址 + rateLimitEnabled: boolean, // 是否启用速率限制 + personalReplenishRate: string, // 个人速率补充频率 + personalBurst: number, // 个人速率突发上限 + groupReplenishRate: string, // 群组速率补充频率 + groupBurst: number // 群组速率突发上限 +}; + +type ExtensionSettings = { + name: string, // 插件名称 + autoActive: boolean, // 是否自动激活 + disabledCommand: { [key: string]: boolean }, // 禁用的命令 + loaded: boolean // 是否加载 +}; + + +type RecentMsg = { + content: string + mode: string +} \ No newline at end of file diff --git a/src/api/group/index.ts b/src/api/group/index.ts new file mode 100644 index 00000000..31a58da3 --- /dev/null +++ b/src/api/group/index.ts @@ -0,0 +1,85 @@ +import { createRequest } from ".."; + +const baseUrl = '/group/' +const request = createRequest(baseUrl) + +export function getGroupList() { + return request<{ + items: GroupItem[]; + }>('get','list') +} + +export function setGroup(config:GroupDetail) { + return request('post','set_one',config) +} + +export function postQuitGroup(config:QuitGroupConfig) { + return request('post','quit_one',config) +} + + +type QuitGroupConfig = { + groupId: string; // 群组ID + diceId: string; // 骰子ID + silence: boolean; // 是否开启静默模式 + extraText: string; // 额外的文本信息 +}; + +type GroupItem = { + active: boolean; // 群组是否激活 + activatedExtList: Extension[]; // 已激活的扩展插件列表 + groupId: string; // 群组ID + guildId: string; // 公会ID(可能为空) + channelId: string; // 频道ID(可能为空) + groupName: string; // 群组名称 + diceIdActiveMap: { [diceId: string]: boolean }; // 激活的骰子ID映射 + diceIdExistsMap: { [diceId: string]: boolean }; // 存在的骰子ID映射 + // botList: { [botId: string]: any }; // 机器人列表(可能为空) + diceSideNum: number; // 骰子的面数 + system: string; // 使用的系统(如COC7) + // helpPackages: any; // 帮助包(可能为空) + cocRuleIndex: number; // COC规则索引 + logCurName: string; // 当前日志名称 + logOn: boolean; // 是否启用日志 + recentDiceSendTime: number; // 最近一次骰子发送时间 + showGroupWelcome: boolean; // 是否显示群组欢迎信息 + groupWelcomeMessage: string; // 群组欢迎消息 + enteredTime: number; // 加入时间 + inviteUserId: string; // 邀请用户的ID + tmpPlayerNum: number; // 临时玩家数量 + tmpExtList: string[]; // 临时扩展列表 + defaultHelpGroup: string; // 默认帮助组 +}; + +type GroupDetail = { + active: boolean; // 群组是否处于激活状态 + activatedExtList: Extension[]; // 已激活的扩展插件列表 + groupId: string; // 群组ID + guildId: string; // 公会ID(可能为空) + channelId: string; // 频道ID(可能为空) + groupName: string; // 群组名称 + diceIdActiveMap: { [diceId: string]: boolean }; // 激活的骰子ID映射 + diceIdExistsMap: { [diceId: string]: boolean }; // 存在的骰子ID映射 + // botList: { [botId: string]: any }; // 机器人列表 + diceSideNum: number; // 骰子的面数 + system: string; // 使用的系统(如 "coc7" 表示使用COC7规则) + // helpPackages: any; // 帮助包(可能为空) + cocRuleIndex: number; // COC规则索引 + logCurName: string; // 当前日志文件名称 + logOn: boolean; // 是否启用日志记录 + recentDiceSendTime: number; // 最近一次发送骰子的时间戳 + showGroupWelcome: boolean; // 是否显示群组欢迎消息 + groupWelcomeMessage: string; // 群组欢迎消息内容 + enteredTime: number; // 群组的加入时间戳 + inviteUserId: string; // 邀请用户的ID + tmpPlayerNum: number; // 临时玩家数量 + tmpExtList: string[]; // 临时激活的扩展插件列表 + defaultHelpGroup: string; // 默认帮助组 + changed: boolean; // 是否有变更 +}; + +type Extension = { + name: string; // 插件名称 + aliases: string[] | null; // 插件的别名(可能为空) + version: string; // 插件版本 +}; diff --git a/src/api/helpdoc/index.ts b/src/api/helpdoc/index.ts new file mode 100644 index 00000000..78a350bd --- /dev/null +++ b/src/api/helpdoc/index.ts @@ -0,0 +1,36 @@ +import type { HelpDoc, HelpTextItem, HelpTextItemQuery } from "~/type"; +import { createRequest } from ".."; +import type { UploadUserFile } from "element-plus"; + +const baseUrl = '/helpdoc/'; +const request = createRequest(baseUrl); + +export function getHelpDocTree() { + return request<{ result: true, data: HelpDoc[] } | { result: false, err?: string }>('get', 'tree'); +} + +export function reloadHelpDoc() { + return request<{ result: true } | { result: false, err?: string }>('post', 'reload'); +} + +export function uploadHelpDoc({files,group}:{files:UploadUserFile[],group:string}) { + return request<{ result: true } | { result: false, err?: string }>('post', 'upload', {files:files.map(v =>v.raw),group},'formdata'); +} + +export function deleteHelpDoc(keys:string[]) { + return request<{ result: true } | { result: false, err?: string }>('post', 'delete', {keys}); +} + +export function getHelpDocPage(param: HelpTextItemQuery) { + return request<{ result: true; total: number; data: HelpTextItem[] } | { result: false; err?: string }>('post', 'textitem/get_page', + param + ); +} + +export function getHelpDocConfig() { + return request<{ aliases: { [key: string]: string[] } }>('get', 'config', ); +} + +export function postHelpDocConfig(param: { aliases: { [key: string]: string[] } }) { + return request<{ result: true } | { result: false, err?: string }>('post', 'config', param); +} diff --git a/src/api/im_connections/index.ts b/src/api/im_connections/index.ts new file mode 100644 index 00000000..af8de1cf --- /dev/null +++ b/src/api/im_connections/index.ts @@ -0,0 +1,357 @@ +import { createRequest } from ".."; + +const baseUrl = '/im_connections/' +const request = createRequest(baseUrl) + +export function getConnectionList() { + return request('get', 'list') +} + +export function getConnectQQVersion() { + return request<{ result: true, versions: string[] } | { result: false }>('get', 'qq/get_versions') +} + +export function postGoCqHttpRelogin(id: string) { + return request('post', 'gocqhttpRelogin', { id }, 'json', { timeout: 65000 }) +} + +export function postAddGocq( + account: number, + password: string, + protocol: number, + appVersion: string, + useSignServer: boolean, + signServerConfig: SignServerConfig +) { + return request( + 'post', 'addGocq', + { account, password, protocol, appVersion, useSignServer, signServerConfig }, 'json', + { timeout: 65000 } + ) +} + +export function postAddWalleQ( + account: number, + password: string, + protocol: number +) { + return request('post', 'addWalleQ', + { account, password, protocol }, 'json', + { timeout: 65000 } + + ) +} + +export function postAddDiscord( + token: string, + proxyURL: string, + reverseProxyUrl: string, + reverseProxyCDNUrl: string +) { + return request('post', 'addDiscord', + { token, proxyURL, reverseProxyUrl, reverseProxyCDNUrl }, 'json', + { timeout: 65000 } + ) +} + +export function postAddKook( + token: string, +) { + return request('post', 'addKook', + { token }, 'json', + { timeout: 65000 } + ) +} + +export function postAddTelegram( + token: string, + proxyURL: string, +) { + return request('post', 'addTelegram', + { token, proxyURL }, 'json', + { timeout: 65000 } + ) +} + +export function postAddMinecraft(url: string) { + return request('post', 'addMinecraft', + { url }, 'json', + { timeout: 65000 } + ) +} + +export function postAddDodo(clientID: string, token: string) { + return request('post', 'addDodo', + { clientID, token }, 'json', + { timeout: 65000 } + ) +} + +export function postAddGocqSeparate( + relWorkDir: string, + connectUrl: string, + accessToken: string, + account: number +) { + return request('post', 'addGocqSeparate', + { relWorkDir, connectUrl, accessToken, account }, 'json', + { timeout: 65000 } + ) +} + +export function postAddRed( + host: string, + port: string, + token: string +) { + return request('post', 'addRed', + { host, port, token }, 'json', + { timeout: 65000 } + ) +} + +export function postAddDingtalk( + clientID: string, + token: string, + nickname: string, + robotCode: string +) { + return request('post', 'addDingtalk', + { clientID, token, nickname, robotCode }, 'json', + { timeout: 65000 } + ) +} + +export function postAddSlack( + botToken: string, + appToken: string +) { + return request('post', 'addSlack', + { botToken, appToken }, 'json', + { timeout: 65000 } + ) +} + +export function postAddOfficialQQ( + appID: number, + appSecret: string, + token: string, + onlyQQGuild: boolean +) { + return request('post', 'addOfficialQQ', + { appID, appSecret, token, onlyQQGuild }, 'json', + { timeout: 65000 } + ) +} + +export function postAddOnebot11ReverseWs( + account: number, + reverseAddr?: string +) { + return request('post', 'addOnebot11ReverseWs', + { account, reverseAddr }, 'json', + { timeout: 65000 } + ) +} + +export function postaddSealChat( + url: string, + token: string +) { + return request('post', 'addSealChat', + { url, token }, 'json', + { timeout: 65000 } + ) +} + +export function postAddSatori( + platform: string, + host: string, + port: string, + token: string +) { + return request('post', 'addSatori', + { platform, host, port, token }, 'json', + { timeout: 65000 } + ) +} + +export function postAddLagrange( + account: number, + signServerUrl: string, + signServerVersion: string +) { + return request('post', 'addLagrange', + { account, signServerUrl, signServerVersion }, 'json', + { timeout: 65000 } + ) +} + +export function postConnectionDel(id: string) { + return request('post', 'del', { id }) +} + +export function postConnectionQrcode(id: string) { + return request<{ img: string }>('post', 'qrcode', { id }) +} + +export function postSmsCodeSet(id: string, code: string) { + return request('post', 'sms_code_set', { id, code }) +} + +export function postGoCqCaptchaSet(id: string, code: string) { + return request('post', 'gocq_captcha_set', { id, code }) +} + +export function postConnectSetEnable(id: string, enable: boolean) { + return request('post', 'set_enable', { id, enable }) +} + +export function postConnectSetData( + id: string, + { protocol, appVersion, ignoreFriendRequest, useSignServer, signServerConfig }:{ protocol: number, appVersion: string, ignoreFriendRequest: boolean, useSignServer?: boolean, signServerConfig?: SignServerConfig} +) { + return request('post', 'set_data', { + id, + protocol, appVersion, ignoreFriendRequest, useSignServer, signServerConfig + }) +} + +export function postSetSignServer( + id: string, + signServerUrl: ''|"sealdice"|"lagrange", + w: boolean, + signServerVersion: string +) { + return request<{ result: false, err: string } | { result: true, signServerUrl: string, signServerVersion: string }>('post', 'set_sign_server', + { id, signServerUrl, w, signServerVersion } + ) +} + +interface DiceConnection { + id: string; + state: number; + platform: string; + workDir: string; + enable: boolean; + protocolType: string; + nickname: string; + userId: number; + groupNum: number; + cmdExecutedNum: number; + cmdExecutedLastTime: number; + onlineTotalTime: number; + + adapter: AdapterQQ; +} + +interface AdapterQQ { + DiceServing: boolean + connectUrl: string; + curLoginFailedReason: string + curLoginIndex: number + loginState: goCqHttpStateCode + inPackGoCqHttpLastRestricted: number + inPackGoCqHttpProtocol: number + inPackGoCqHttpAppVersion: string, + implementation: string + useInPackGoCqhttp: boolean; + goCqHttpLoginVerifyCode: string; + goCqHttpLoginDeviceLockUrl: string; + ignoreFriendRequest: boolean; + goCqHttpSmsNumberTip: string; + useSignServer: boolean; + signServerConfig: SignServerConfig; + redVersion: string; + host: string; + port: number; + appID: number; + isReverse: boolean; + reverseAddr: string; + builtinMode: 'gocq' | 'lagrange' +} +enum goCqHttpStateCode { + Init = 0, + InLogin = 1, + InLoginQrCode = 2, + InLoginBar = 3, + InLoginVerifyCode = 6, + InLoginDeviceLock = 7, + LoginSuccessed = 10, + LoginFailed = 11, + Closed = 20 +} +// type addImConnectionForm = { +// accountType: number, +// step: number, +// isEnd: false, +// account: string, +// nickname: string, +// password: string, +// protocol: number, +// appVersion: string, +// implementation: string, +// id: string, +// token: string, +// botToken: string, +// appToken: string, +// proxyURL: string, +// reverseProxyUrl: string, +// reverseProxyCDNUrl: string, +// url: string, +// clientID: string, +// robotCode: string, +// ignoreFriendRequest: false, +// extraArgs: string, +// endpoint: DiceConnection, + +// relWorkDir: string, +// accessToken: string, +// connectUrl: string, + +// host: string, +// port: undefined, + +// appID: undefined, +// appSecret: string, +// onlyQQGuild: true, + +// useSignServer: false, +// signServerConfig: { +// signServers: [ +// { +// url: string, +// key: string, +// authorization: string +// } +// ], +// ruleChangeSignServer: number, +// maxCheckCount: number, +// signServerTimeout: number, +// autoRegister: false, +// autoRefreshToken: false, +// refreshInterval: number +// }, +// signServerType: number, +// signServerUrl: string, +// signServerKey: string, +// signServerVersion: string, + +// reverseAddr: string, +// platform: string, +// } + +type SignServerConfig = { + signServers: ServerConfig[], + ruleChangeSignServer: number, + maxCheckCount: number, + signServerTimeout: number, + autoRegister: false, + autoRefreshToken: false, + refreshInterval: number +} +type ServerConfig = { + url: string, + key: string, + authorization: string +} \ No newline at end of file diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 00000000..20781bc4 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,118 @@ +import axios, { type AxiosRequestConfig } from "axios"; +import qs from "qs"; +const http = axios.create({ + baseURL: "/sd-api", + timeout: 10000, +}); + + + +http.interceptors.request.use((config) => { + // console.log(config.data) + try { + if ('ContentType' in config && config.ContentType === "application/x-www-form-urlencoded") { + config.data = + config.data && qs.stringify(config.data, { indices: false }); + } + const token = localStorage.getItem('t') + if (token) { + config.headers.Authorization = token + config.headers['token'] = token + } + } catch (e) { + // console.log(e); + } + // console.log(config); + return config; +}); + +http.interceptors.response.use( + async (response) => { + // HTTP响应状态码正常 + if (response.status === 200) { + return Promise.resolve(response) + // return Promise.reject(response.data) + } else { + console.error("服务器出错或者连接不到服务器") + return Promise.reject(response); + } + }, + (error) => { + + if (error.code === 'ECONNABORTED' || error.code === 'ERR_NETWORK') + // KMessage("连接不到服务器",'danger') + console.error("连接不到服务器") + + return Promise.reject(error); + } +); + + + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export default function request( + method: 'post' | 'get' | 'put' | 'delete', + url: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + submitData?: any, + ContentType?: 'form' | 'json' | 'formdata', config?: AxiosRequestConfig) { + let file: FormData, contentType: string + switch (ContentType) { + case "form": + contentType = "application/x-www-form-urlencoded"; + break; + case "formdata": + contentType = "multipart/form-data"; + file = new FormData(); + for (const key in submitData) { + if (!(submitData[key] instanceof Array)) { + // console.log(submitData[key]); + file.append(key, submitData[key]); + } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + submitData[key].forEach((item: any) => { + file.append(key, item); + }); + } + } + // for(let i:number = 0;i((resolve, reject) => { + const reqParams = Object.assign({ + method, + url, + [method.toLowerCase() === "get" //|| method.toLowerCase() === "delete" + ? "params" + : "data"]: submitData, + contentType, + }, config); + http(reqParams) + .then((res) => { + resolve(res.data); + }) + .catch((err) => { + console.error(err); + reject(err); + }); + }); +} + +export function createRequest(baseUrl: string) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return function ( + method: 'post' | 'get' | 'put' | 'delete', + url: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + submitData?: any, + ContentType?: 'form' | 'json' | 'formdata', + config?: AxiosRequestConfig + ) { + return request(method, baseUrl + url, submitData, ContentType, config) + } +} diff --git a/src/api/js/index.ts b/src/api/js/index.ts new file mode 100644 index 00000000..58573adc --- /dev/null +++ b/src/api/js/index.ts @@ -0,0 +1,88 @@ +import type { JsPluginConfig, JsScriptInfo } from "~/type"; +import { createRequest } from ".."; +import type { UploadRawFile } from "element-plus"; + +const baseUrl = '/js/'; +const request = createRequest(baseUrl); + +export function getJsStatus() { + return request<{ result: true, status: boolean } | { + result: false, err: string + }>('get', 'status'); +} + +export function getJsList() { + return request('get', 'list'); +} + +export function getJsConfigs() { + return request<{[key:string]: JsPluginConfig}>('get', 'get_configs'); +} + +export function setJsConfigs(config:{[key:string]: JsPluginConfig}) { + return request('post', 'set_configs', config); +} + +export function resetJsConfig(pluginName: string, key: string) { + return request('post', 'reset_config', {pluginName,key}); +} + +export function deleteUnusedJsConfig(pluginName: string, key: string) { + return request('post', 'delete_unused_config', {pluginName,key}); +} + +export function getJsRecord() { + return request<{ + outputs: string[] + }>('get', 'get_record'); +} + +export function uploadJs(file:UploadRawFile|Blob) { + return request('post', 'upload', {file}, 'formdata'); +} + +export function deleteJs(index:number) { + return request('post', 'delete', {index}); +} + +export function reloadJS() { + return request('post', 'reload'); +} + +export function shutDownJS() { + return request('post', 'shutdown'); +} + +export function executeJS(value: string) { + return request<{ + ret: unknown, + outputs: string[], + err: string, + }>('post', 'execute',{value}); +} + +export function enableJS(name:string) { + return request<{result:boolean}>('post', 'enable',{name}); +} + +export function disableJS(name:string) { + return request('post', 'disable',{name}); +} + +export function checkJsUpdate(index:number) { + return request<{ result: false, err: string } | { + result: true, + old: string, + new: string, + tempFileName: string, + }>('post', 'check_update', {index}); +} + +export function updateJs(tempFileName: string, index: number) { + return request<{ result: false, err: string } | { + result: true, + }>('post', 'update', {tempFileName,index}); +} + + + diff --git a/src/api/others/index.ts b/src/api/others/index.ts new file mode 100644 index 00000000..afa61846 --- /dev/null +++ b/src/api/others/index.ts @@ -0,0 +1,55 @@ +import request from ".."; + +export function getPreInfo() { + return request<{ + testMode: boolean + }>('get','preInfo',null,'form',{timeout:5000}) +} + +export function getBaseInfo() { + return request('get','baseInfo',null,'form',{timeout:5000}) +} + +export function getLogFetchAndClear() { + return request('get','log/fetchAndClear') +} + +export function getHello() { + return request('get','hello') +} + +export function checkSecurity() { + return request<{isOk:boolean}>('get','checkSecurity') +} + +export function postToolOnebot() { + return request<{ + ok: boolean, + ip: string, + errText: string + }>('post','/tool/onebot') +} +interface DiceBaseInfo { + appChannel: string + version: string + versionSimple: string + versionNew: string + versionNewNote: string + versionCode: number + versionNewCode: number + memoryAlloc: number + memoryUsedSys: number + uptime: number + OS: string + arch: string + justForTest: boolean + containerMode: boolean + extraTitle?: string + } + +type SysLog={ + level: string; + ts: number; + caller: string; + msg: string; +} \ No newline at end of file diff --git a/src/api/resource/index.ts b/src/api/resource/index.ts new file mode 100644 index 00000000..eb31b25e --- /dev/null +++ b/src/api/resource/index.ts @@ -0,0 +1,26 @@ +import type { Resource, ResourceType } from "~/store"; +import { createRequest } from ".."; +import type { UploadRawFile } from "element-plus"; + +const baseUrl = '/resource'; +const request = createRequest(baseUrl); + +export function getResourcePage(type: ResourceType) { + return request<{ result: false, err: string } | { + result: true, + total?: number, + data: Resource[] + }>('get', '/page',{type}); +} + +export function createResource(files:UploadRawFile|Blob) { + return request<{ result: false, err: string } | { result: true }>('post', '', {files},'formdata'); +} + +export function deleteResource(path: string) { + return request<{ result: false, err: string } | { result: true }>('delete', '',{path}); +} + +export function getResourceData(path: string, thumbnail: boolean = false) { + return request('get', '/data',{ path, thumbnail }); +} diff --git a/src/api/signin/index.ts b/src/api/signin/index.ts new file mode 100644 index 00000000..cb048e9d --- /dev/null +++ b/src/api/signin/index.ts @@ -0,0 +1,12 @@ +import { createRequest } from ".."; + +const baseUrl = '/signin'; +const request = createRequest(baseUrl); + +export function getSalt() { + return request<{salt:string}>('get', '/salt'); +} + +export function signin(password:string) { + return request<{token:string}>('post', '', {password}); +} diff --git a/src/api/story/index.ts b/src/api/story/index.ts new file mode 100644 index 00000000..1ce709c3 --- /dev/null +++ b/src/api/story/index.ts @@ -0,0 +1,82 @@ +import {createRequest} from ".."; + +const baseUrl = '/story/' +const request = createRequest(baseUrl) +export async function getStoryInfo() { + return await request<[number,number,number,number,]>('get','info') +} + +export async function getStoryLogPage(pageParams:PageParams) { + return await request<{ result: false, err?: string} | { + result: true + total: number, + data: Log[], + pageNum: number, + pageSize: number, + }>('get','logs/page',pageParams) +} + +export async function getStoryItemPage(pageParams:PageParams) { + return await request('get','items/page',pageParams) +} + +export async function deleteStoryLog(log: Log) { + return await request('delete','log', log) +} + +export async function postStoryLog(log: Log) { + return await request('post','uploadLog', log) +} + +export async function getStoryBackUpList() { + return await request<{ result: false, err?: string } | { + result: true, + data: Backup[] + }>('get','backup/list') +} + +export async function getStoryBackUpDownload(name: string) { + return await request('get','backup/download',{name}) +} + +export async function postStoryBatchDel(names: string[]) { + return await request<{ result: true } | {result: false,fails: string[]}>('post','backup/batch_delete',{names}) +} + + +type PageParams = { + pageNum: number + pageSize: number + name ?: string + groupId ?: string + logName? :string + createdTimeBegin ?: number + createdTimeEnd ?: number +} + +interface Log { + id: number + name: string + groupId: string + createdAt: number + updatedAt: number + size: number + pitch?: boolean + current?: number +} + +interface Backup { + name: string, + fileSize: number, +} + +interface Item { + id: number + logId: number + nickname: string + IMUserId: string + time: number + message: string + isDice: boolean + isEdit?: boolean +} \ No newline at end of file diff --git a/src/api/utils/index.ts b/src/api/utils/index.ts new file mode 100644 index 00000000..4082c40f --- /dev/null +++ b/src/api/utils/index.ts @@ -0,0 +1,25 @@ +import { createRequest } from ".."; + +const baseUrl = '/utils/' +const request = createRequest(baseUrl) + +export function getNewUtils() { + return request<{ result: true, checked: boolean, news: string, newsMark: string } | { result: false, err?: string }>('get','news') +} + +export function postUtilsCheckNews(newsMark: string) { + return request<{ result: true; newsMark: string; } | { result: false }>('post','check_news',{newsMark}) +} + +export function postUtilsCheckCronExpr(expr: string) { + return request('post','check_cron_expr',{expr}) +} + +export function getUtilsCheckNetWorkHealth() { + return request<{ + result: true, + total: number, + ok: string[], + timestamp: number + } | { result: false }>('get','check_network_health') +} diff --git a/src/backend.ts b/src/backend.ts index e466e47b..8761754e 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -28,9 +28,11 @@ export function newRequestClient(baseURL: string) { return client; } - +// charyflys:为了方便调试,现将发后端的请求修改为代理转发 +// 如果要设置测试转发端口,在.env文件下设置VITE_APP_APIURL="目标地址"即可 export const urlBase = process.env.NODE_ENV == 'development' ? - '//' + window.location.hostname + ":" + 3211 : + // '//' + window.location.hostname + ":" + 3211 : + '' : '//' + window.location.hostname + ":" + location.port // 逐渐使用ofetch替换axios diff --git a/src/components/PageConnectInfoItems.vue b/src/components/PageConnectInfoItems.vue index d8169d86..5606b350 100644 --- a/src/components/PageConnectInfoItems.vue +++ b/src/components/PageConnectInfoItems.vue @@ -1184,6 +1184,8 @@ import { sleep } from '~/utils' import * as dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { urlBase } from '~/backend'; +import { getConnectQQVersion, postConnectionDel, postConnectionQrcode, postConnectSetData, postConnectSetEnable, postGoCqCaptchaSet, postGoCqHttpRelogin, postSetSignServer, postSmsCodeSet } from '~/api/im_connections'; +import { postToolOnebot } from '~/api/others'; dayjs.extend(relativeTime) @@ -1308,7 +1310,7 @@ const closeCaptchaFrame = () => { } const submitCaptchaCode = async (i: DiceConnection, code: string) => { - store.ImConnectionsCaptchaSet(i, code) + postGoCqCaptchaSet(i.id, code) } const submitSmsCode = async (i: DiceConnection) => { @@ -1316,7 +1318,7 @@ const submitSmsCode = async (i: DiceConnection) => { if (!smsCode.value) return; const code = smsCode.value; smsCode.value = ''; - store.ImConnectionsSmsCodeSet(i, code) + postSmsCodeSet(i.id, code) } const setRecentLogin = () => { @@ -1330,7 +1332,7 @@ const setRecentLogin = () => { } const openSocks = async () => { - const ret = await store.toolOnebot() + const ret = await postToolOnebot() if (ret.ok) { const msg = h('p', null, [ h('div', null, '将在服务器上开启临时socks5服务,端口13325'), @@ -1407,7 +1409,7 @@ const formClose = async () => { } const setEnable = async (i: DiceConnection, val: boolean) => { - const ret = await store.getImConnectionsSetEnable(i, val) + const ret = await postConnectSetEnable(i.id, val) i.enable = ret.enable curCaptchaIdSet.value = ''; ElMessage.success('状态修改完成') @@ -1470,7 +1472,7 @@ const doSetData = async () => { signServerConfig: form.signServerConfig, } } - const ret = await store.getImConnectionsSetData(form.endpoint, param); + const ret = await postConnectSetData(form.endpoint.id, param); if (form.endpoint.adapter) { form.endpoint.adapter.inPackGoCqHttpProtocol = form.protocol; } @@ -1479,7 +1481,7 @@ const doSetData = async () => { } const showSetSignServerDialog = async (i: DiceConnection) => { form.endpoint = i; - const ret = await store.getImConnectionsSetSignServerUrl(form.endpoint, "",false, form.signServerVersion); + const ret = await postSetSignServer(form.endpoint.id, "",false, form.signServerVersion); if (ret.result) { form.signServerUrl = ret.signServerUrl switch (form.signServerUrl) { @@ -1511,7 +1513,12 @@ const doSetSignServer = async() =>{ form.signServerUrl = "lagrange"; break; } - const ret = await store.getImConnectionsSetSignServerUrl(form.endpoint, form.signServerUrl, true, form.signServerVersion); + const ret = await postSetSignServer( + form.endpoint.id, + ["sealdice","lagrange"].includes(form.signServerUrl) + ? form.signServerUrl as "sealdice"|"lagrange" : '', + true, + form.signServerVersion); if (ret.result) { ElMessage.success('修改完成,请手动启用账号以生效'); } else { @@ -1573,7 +1580,7 @@ const gocqhttpReLogin = async (i: DiceConnection) => { if (curConn.value && curConn.value.adapter) { curConn.value.adapter.loginState = goCqHttpStateCode.Init; } - store.gocqhttpReloginImConnection(i).then(theConn => { + postGoCqHttpRelogin(i.id).then(theConn => { curConnId.value = i.id; }).finally(() => { form.isEnd = true @@ -1716,7 +1723,7 @@ onBeforeMount(async () => { delete store.curDice.qrcodes[i.id] } - const versionsRes = await store.getSupportedQQVersions(); + const versionsRes = await getConnectQQVersion(); if (versionsRes.result) { supportedQQVersions.value = ['', ...versionsRes.versions] } @@ -1737,7 +1744,7 @@ onBeforeMount(async () => { // 获取二维码 if (i.adapter?.loginState === goCqHttpStateCode.InLoginQrCode) { - store.curDice.qrcodes[i.id] = (await store.getImConnectionsQrCode(i)).img + store.curDice.qrcodes[i.id] = (await postConnectionQrcode(i.id)).img } if (i.id === curConnId.value) { @@ -1777,7 +1784,7 @@ const doRemove = async (i: DiceConnection) => { type: 'warning', } ).then(async () => { - await store.removeImConnection(i) + await postConnectionDel(i.id) await store.getImConnections() ElMessage({ type: 'success', diff --git a/src/components/PageHome.vue b/src/components/PageHome.vue index fb7bd33c..91b588e9 100644 --- a/src/components/PageHome.vue +++ b/src/components/PageHome.vue @@ -171,6 +171,8 @@ import { CircleCheckFilled, CircleCloseFilled, } from '@element-plus/icons-vue' +import { getUtilsCheckNetWorkHealth } from '~/api/utils'; +import { postUpgrade } from '~/api/dice'; const store = useStore() @@ -194,8 +196,8 @@ const doUpgrade = async () => { upgradeDialogVisible.value = false ElMessageBox.alert('开始下载更新,请等待……
完成后将自动重启海豹,并进入更新流程', '升级', { dangerouslyUseHTMLString: true }) try { - const ret = await store.upgrade() - ElMessageBox.alert((ret as any).text + '
如果几分钟后服务没有恢复,检查一下海豹目录', '升级', { dangerouslyUseHTMLString: true }) + const ret = await postUpgrade() + ElMessageBox.alert((ret).text + '
如果几分钟后服务没有恢复,检查一下海豹目录', '升级', { dangerouslyUseHTMLString: true }) } catch (e) { // ElMessageBox.alert('升级失败', '升级') } @@ -236,7 +238,7 @@ const getWebsiteHealthComponent = (ok: boolean): VNode => <> const refreshNetworkHealth = async () => { networkHealth.value.timestamp = 0 - const ret = await store.checkNetworkHealth() + const ret = await getUtilsCheckNetWorkHealth() if (ret.result) { networkHealth.value = ret } diff --git a/src/components/misc/PageMiscAdvancedSettings.vue b/src/components/misc/PageMiscAdvancedSettings.vue index 2822fe14..a304175a 100644 --- a/src/components/misc/PageMiscAdvancedSettings.vue +++ b/src/components/misc/PageMiscAdvancedSettings.vue @@ -102,6 +102,7 @@ import {QuestionFilled} from "@element-plus/icons-vue"; import {useStore} from "~/store"; import {cloneDeep} from "lodash-es"; import type {AdvancedConfig} from "~/type.d.ts"; +import { getCustomReplyDebug, postCustomReplyDebug } from "~/api/configs"; const emit = defineEmits(['update:advanced-settings-show']) @@ -118,7 +119,7 @@ const replyDebugMode = ref(false); onBeforeMount(async () => { config.value = await store.diceAdvancedConfigGet() - replyDebugMode.value = (await store.customReplyDebugModeGet()).value + replyDebugMode.value = (await getCustomReplyDebug()).value nextTick(() => { modified.value = false }) @@ -136,7 +137,7 @@ watch(() => replyDebugMode.value, (newValue, oldValue) => { //直接监听 const submit = async () => { await store.diceAdvancedConfigSet(config.value) - store.customReplyDebugModeSet(replyDebugMode.value); + await postCustomReplyDebug(replyDebugMode.value); config.value = await store.diceAdvancedConfigGet() modified.value = false emit('update:advanced-settings-show', config.value.show) @@ -147,7 +148,7 @@ const submit = async () => { const submitGiveup = async () => { config.value = await store.diceAdvancedConfigGet() - replyDebugMode.value = (await store.customReplyDebugModeGet()).value + replyDebugMode.value = (await getCustomReplyDebug()).value modified.value = false nextTick(() => { modified.value = false diff --git a/src/components/misc/PageMiscBackup.vue b/src/components/misc/PageMiscBackup.vue index 5997f5c8..443f7f03 100644 --- a/src/components/misc/PageMiscBackup.vue +++ b/src/components/misc/PageMiscBackup.vue @@ -184,6 +184,7 @@ import { } from '@element-plus/icons-vue' import {sum} from "lodash-es"; import { dayjs } from 'element-plus' +import { getBackupConfig, getBackupList, postBackupBatchDel, postBackupDel, postDoBackup, setBackupConfig } from "~/api/backup"; const store = useStore() @@ -284,12 +285,12 @@ watch(() => cfg.value.autoBackupSelectionList, (v) => { }) const refreshList = async () => { - const lst = await store.backupList() + const lst = await getBackupList() data.value = lst } const configGet = async () => { - const data = await store.backupConfigGet() + const data = await getBackupConfig() cfg.value = data cfg.value.autoBackupSelectionList = parseSelection(data.autoBackupSelection) if (data.backupCleanTrigger) { @@ -311,7 +312,7 @@ const bakDeleteConfirm = async (name: string) => { type: 'warning' }) if (ret) { - const r = await store.backupDelete(name) + const r = await postBackupDel(name) if (!r.success) { ElMessage.error('删除失败') } else { @@ -349,7 +350,7 @@ const bakBatchDeleteConfirm = async () => { type: 'warning' }) if (ret) { - const res = await store.backupBatchDelete(selectedBaks.value.map(bak => bak.name)) + const res = await postBackupBatchDel(selectedBaks.value.map(bak => bak.name)) if (res.result) { ElMessage.success('已删除所选备份') } else { @@ -361,9 +362,7 @@ const bakBatchDeleteConfirm = async () => { } const doBackup = async () => { - const ret = await store.backupDoSimple({ - selection: formatSelection(backupSelections.value) - }) + const ret = await postDoBackup( formatSelection(backupSelections.value)) showBackup.value = false await refreshList() if (ret.testMode) { @@ -374,7 +373,7 @@ const doBackup = async () => { } const doSave = async () => { - await store.backupConfigSave(cfg.value) + await setBackupConfig(cfg.value) ElMessage.success('已保存') } diff --git a/src/components/misc/PageMiscGroup.vue b/src/components/misc/PageMiscGroup.vue index 70d09e07..c1d444a5 100644 --- a/src/components/misc/PageMiscGroup.vue +++ b/src/components/misc/PageMiscGroup.vue @@ -144,6 +144,7 @@ import { import * as dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { now, sortBy } from 'lodash-es' +import { getGroupList, postQuitGroup, setGroup } from '~/api/group' dayjs.extend(relativeTime) @@ -203,7 +204,7 @@ const groupItems = computed(() => { }) const refreshList = async () => { - const data = await store.groupList() + const data = await getGroupList() groupList.value = data } @@ -219,7 +220,7 @@ const quitTextSave = ref(false); const saveOne = async (i: any, index: number) => { // await store.backupConfigSave(cfg.value) // console.log(222, i, index) - await store.groupSetOne(i) + await setGroup(i) i.changed = false ElMessage.success('已保存') } @@ -250,7 +251,7 @@ const quitGroup = async (i: any, index: number, diceId: string) => { ]) } ).then(async (data) => { - await store.setGroupQuit({ + await postQuitGroup({ groupId: i.groupId, diceId, silence: data.value === 'NO', diff --git a/src/components/misc/PageMiscSettings.vue b/src/components/misc/PageMiscSettings.vue index 22b0a293..249e5535 100644 --- a/src/components/misc/PageMiscSettings.vue +++ b/src/components/misc/PageMiscSettings.vue @@ -592,6 +592,7 @@ import { Upload } from '@element-plus/icons-vue' import { cloneDeep, toNumber } from 'lodash-es'; +import { postMailTest, postUploadToUpgrade } from '~/api/dice'; import { useStore } from '~/store'; import { objDiff, passwordHash } from '~/utils'; @@ -608,7 +609,8 @@ const beforeUpload = async (file: any) => { // UploadRawFile let fd = new FormData() fd.append('files', file) try { - const resp = await store.diceUploadToUpgrade({ form: fd }); + // const resp = + await postUploadToUpgrade(file) ElMessage.success('上传完成,程序即将离线'); } catch (e: any) { ElMessage.error(e.toString()); @@ -735,7 +737,7 @@ const nameWrapUncheck = (v: boolean) => { } const mailTest = async () => { - const res = await store.diceMailTest() + const res = await postMailTest() if (res.result) { ElMessage.success("已尝试发送测试邮件") } else { diff --git a/src/components/misc/banList/BanConfig.vue b/src/components/misc/banList/BanConfig.vue index 0857230a..ebeed8da 100644 --- a/src/components/misc/banList/BanConfig.vue +++ b/src/components/misc/banList/BanConfig.vue @@ -1,15 +1,13 @@