From ed7617aa90fdd11136f0d3ee11116f294ed9a264 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Thu, 29 Feb 2024 19:22:25 +0800 Subject: [PATCH 01/43] =?UTF-8?q?UI:=20=E4=BC=98=E5=8C=96=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app.html | 7 ++ .../components/ProjectTab/index.svelte | 90 ++++++++++--------- src/routes/global.css | 80 ++++++++--------- 3 files changed, 95 insertions(+), 82 deletions(-) diff --git a/src/app.html b/src/app.html index d4ae80b..e314284 100644 --- a/src/app.html +++ b/src/app.html @@ -5,9 +5,16 @@ + %sveltekit.head%
%sveltekit.body%
+ diff --git a/src/lib/modules/TypeModule/components/ProjectTab/index.svelte b/src/lib/modules/TypeModule/components/ProjectTab/index.svelte index f067c19..be71089 100644 --- a/src/lib/modules/TypeModule/components/ProjectTab/index.svelte +++ b/src/lib/modules/TypeModule/components/ProjectTab/index.svelte @@ -3,7 +3,7 @@ import TabBar from '@smui/tab-bar'; import Button from '@smui/button'; import type { Config, SuccessResponse } from '@/types/public'; - import { onMount } from 'svelte'; + import { SvelteComponent, onMount } from 'svelte'; import Category from './Category.svelte'; import { request } from '@/utils'; import { toast } from '@zerodevx/svelte-toast'; @@ -108,48 +108,54 @@ -
- - - -
-
- (banInitModal = false)} - label="搜索" - > - - -
- -{#if active.project_id} - project.project_id} - let:tab - bind:active - > - - - - -
-
- - +
+
+
+ + + +
+
+ (banInitModal = false)} + label="搜索" + > + +
- + {#if active.project_id} + project.project_id} + let:tab + bind:active + > + + + + +
+
+ + +
+
+ {/if} +
+ + {#if active.project_id} + {#each active.categories as category} {/each} - -
-{/if} + + {/if} +
diff --git a/src/routes/global.css b/src/routes/global.css index f89ccc4..4616249 100644 --- a/src/routes/global.css +++ b/src/routes/global.css @@ -1,40 +1,40 @@ -.flex{ - display: flex; - } - - .flex-inline { - display: inline-flex; - } - - .flex-1{ - flex: 1; - } - - .items-center{ - align-items: center; - } - - .items-end { - align-items: end; - } - - .justify-center{ - justify-content: center; - } - - .justify-between{ - justify-content: space-between; - } - - .justify-arround { - justify-content: space-around; - } - - .justify-end { - justify-content: end; - } - - .w-full { - width: 100%; - } - \ No newline at end of file + +.flex { + display: flex; +} + +.flex-inline { + display: inline-flex; +} + +.flex-1 { + flex: 1; +} + +.items-center { + align-items: center; +} + +.items-end { + align-items: end; +} + +.justify-center { + justify-content: center; +} + +.justify-between { + justify-content: space-between; +} + +.justify-arround { + justify-content: space-around; +} + +.justify-end { + justify-content: end; +} + +.w-full { + width: 100%; +} \ No newline at end of file From 01ef4db22c004f591f6718e0fb2319236d6af8b9 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Thu, 29 Feb 2024 19:22:48 +0800 Subject: [PATCH 02/43] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20legalName=20?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E8=A2=AB=20request=20=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pnpm-lock.yaml | 16 ---------------- src-tauri/src/structs/request.rs | 14 +++++++------- 2 files changed, 7 insertions(+), 23 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c9ee841..cafaa28 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ dependencies: '@smui/linear-progress': specifier: 7.0.0-beta.16 version: 7.0.0-beta.16(svelte@4.2.8)(typescript@5.3.3) - '@smui/snackbar': - specifier: 7.0.0-beta.16 - version: 7.0.0-beta.16(svelte@4.2.8)(typescript@5.3.3) '@smui/tab': specifier: 7.0.0-beta.16 version: 7.0.0-beta.16(svelte@4.2.8)(typescript@5.3.3) @@ -70,9 +67,6 @@ devDependencies: '@zerodevx/svelte-toast': specifier: ^0.9.5 version: 0.9.5(svelte@4.2.8) - carbon-components-svelte: - specifier: ^0.82.0 - version: 0.82.4 eslint: specifier: ^8.28.0 version: 8.55.0 @@ -2053,12 +2047,6 @@ packages: engines: {node: '>=6'} dev: true - /carbon-components-svelte@0.82.4: - resolution: {integrity: sha512-fuqMl+KNJXMlGhuwK4M11ZnGcbHF6nR7TOiiq6UJr5ALCCen4jk71sMAOurUWbOTOVe4DXM4z+Sb6/BV/Gf1Ag==} - dependencies: - flatpickr: 4.6.9 - dev: true - /chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} @@ -2432,10 +2420,6 @@ packages: rimraf: 3.0.2 dev: true - /flatpickr@4.6.9: - resolution: {integrity: sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw==} - dev: true - /flatted@3.2.9: resolution: {integrity: sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==} dev: true diff --git a/src-tauri/src/structs/request.rs b/src-tauri/src/structs/request.rs index 71eaea7..69a09ed 100644 --- a/src-tauri/src/structs/request.rs +++ b/src-tauri/src/structs/request.rs @@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::utils::is_string_in_file; -use super::{config::Config, context::Context}; +use super::{config::Config, context::Context, resolver::utils::get_legal_name}; #[derive(Serialize, Deserialize, Debug)] pub struct RequestNode { @@ -186,8 +186,8 @@ impl Request { // 检查生成service的 type 文件是否有 Request/Response interface fn check_file(&self, file_path: &PathBuf, file_name_without_ext: &String) -> bool { - let req = format!("{}Request", file_name_without_ext); - let resp = format!("{}Response", file_name_without_ext); + let req = format!("{}Request", get_legal_name(file_name_without_ext) ); + let resp = format!("{}Response", get_legal_name(file_name_without_ext)); if is_string_in_file(&file_path, &req) && is_string_in_file(&file_path, &resp) { return true; @@ -208,8 +208,8 @@ impl Request { .type_import_template .clone() .unwrap() - .replace("$1", &format!("{}Request", &file_name_string)) - .replace("$2", &format!("{}Response", &file_name_string)) + .replace("$1", &format!("{}Request", get_legal_name(&file_name_string))) + .replace("$2", &format!("{}Response", get_legal_name(&file_name_string))) .replace("$3", &format!("{}/{}", sub_path_unix, file_name_string)) + "\n"; @@ -233,8 +233,8 @@ impl Request { .clone() .unwrap() .replace("$1", &file_name_string) - .replace("$2", &format!("{}Request", &file_name_string)) - .replace("$3", &format!("{}Response", &file_name_string)) + .replace("$2", &format!("{}Request", get_legal_name(&file_name_string) )) + .replace("$3", &format!("{}Response", get_legal_name(&file_name_string))) .replace( "$4", &format!("{}/{}", sub_path_unix.as_str(), &file_name_string), From 6338c0cadc9c90d716c64352f3086ff88d70e606 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Thu, 29 Feb 2024 19:25:08 +0800 Subject: [PATCH 03/43] =?UTF-8?q?UI:=20=E4=BC=98=E5=8C=96=E9=A1=B5?= =?UTF-8?q?=E9=9D=A2=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ServiceModule/components/TypesTree.svelte | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/lib/modules/ServiceModule/components/TypesTree.svelte b/src/lib/modules/ServiceModule/components/TypesTree.svelte index 25c6bdb..488a001 100644 --- a/src/lib/modules/ServiceModule/components/TypesTree.svelte +++ b/src/lib/modules/ServiceModule/components/TypesTree.svelte @@ -18,7 +18,7 @@ }); function get_data() { - request('get_request_list', { key: "" }) + request('get_request_list', { key: '' }) // @ts-expect-error .then((res: SuccessResponse) => { full_list = sort(res.data); @@ -91,19 +91,25 @@ } -
-
-
对应的接口树:
- -
-
- - +
+
+
+
对应的接口树:
+ +
+
+ + +
- {#each list as item} - - {/each} +
+ {#each list as item} + + {/each} +
diff --git a/src/lib/components/Menu.svelte b/src/lib/components/Menu.svelte deleted file mode 100644 index f6c83a2..0000000 --- a/src/lib/components/Menu.svelte +++ /dev/null @@ -1,94 +0,0 @@ - - -
- - -
- {#if activeMenu === '1'} - - {:else if activeMenu === '2'} - - {:else if activeMenu === '3'} - - {/if} -
-
- - diff --git a/src/lib/components/Prompt.svelte b/src/lib/components/Prompt.svelte index bb788ec..ec5481f 100644 --- a/src/lib/components/Prompt.svelte +++ b/src/lib/components/Prompt.svelte @@ -1,13 +1,10 @@ + + + + diff --git a/src/lib/modules/TypeModule/components/ProjectTab/AddProjectModal.svelte b/src/lib/modules/TypeModule/components/ProjectTab/AddProjectModal.svelte deleted file mode 100644 index 72d0e8c..0000000 --- a/src/lib/modules/TypeModule/components/ProjectTab/AddProjectModal.svelte +++ /dev/null @@ -1,84 +0,0 @@ - - - -
- 新增项目 - -
- - - - -
- - -
-
diff --git a/src/lib/modules/TypeModule/index.svelte b/src/lib/modules/TypeModule/index.svelte deleted file mode 100644 index 155f874..0000000 --- a/src/lib/modules/TypeModule/index.svelte +++ /dev/null @@ -1,16 +0,0 @@ - - -{#if need_init} - -{/if} - -{#if load_project} - -{/if} diff --git a/src/lib/store.ts b/src/lib/store.ts index 496ffef..69c6496 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -3,3 +3,4 @@ import { writable } from "svelte/store"; export let processingModalOpen = writable(false); export let processingModalTotal = writable(0); export let runningTask = writable(false) +export let sourcePath = writable("") \ No newline at end of file diff --git a/src/lib/types/public.ts b/src/lib/types/public.ts index fd65488..6e941ef 100644 --- a/src/lib/types/public.ts +++ b/src/lib/types/public.ts @@ -1,10 +1,6 @@ export interface Config { - source_path?: string base_url?: string - rate_limit?: number - types_path?: string - types_full_path?: string, - break_seconds?: number, + types_path_relative?: string project_list?: ProjectList[], request_path?: string, request_template?: string, diff --git a/src/lib/types/yapi.ts b/src/lib/types/yapi.ts new file mode 100644 index 0000000..22b7fc0 --- /dev/null +++ b/src/lib/types/yapi.ts @@ -0,0 +1,45 @@ +export type ProjectBaseInfo = { + _id: number, + desc: string, + name: string +} + +export type CategoryMenuList = { + _id: number, + name: string, + interfaces?: CategoryDataList +}[] + +export type CategoryDataList = { + count: number, + total: number, + list: CategoryDataItem[] +} + +export type CategoryDataItem = { + _id: number, + catid: number, + title: string, + path: string, +} + +export type QueueLog = { + msg: string, + processd_number: number, + is_success: boolean, + resolved_interface: ResolvedInterface +} + +export type ResolvedInterface = { + interface: InterfaceData, + ts_string: string, +} + +export type InterfaceData = { + _id: number, + path: string, + project_id: number, + title: string, + catid: number, + method: string, +} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 652ac6a..b8feab8 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,6 +1,10 @@ import { invoke } from "@tauri-apps/api/tauri"; +import type { SuccessResponse } from "./types/public"; +import { toast } from "@zerodevx/svelte-toast"; +import { toastTheme } from "./consts"; +import { processingModalOpen, processingModalTotal } from "./store"; -export function request(name: string, data?: Record) { +export function request(name: string, data?: Record): any { let json = JSON.stringify(data); return invoke(name, { data: json }); } @@ -16,22 +20,21 @@ export function isEmpty(obj: Record) { } function getComputedStyle(node?: HTMLUListElement) { - return { - height: node.offsetHeight, - width: node.offsetWidth, - }; + return { + height: node?.offsetHeight, + width: node?.offsetWidth, + }; } export function wop(node?: HTMLUListElement, params?: { duration?: number }) { const { height, width } = getComputedStyle(node); - const { duration = 300 } = params; + const { duration = 300 } = params || {}; return { duration, css: (t: number) => ` - clip-path: polygon(0 0, ${t * 100}% 0, ${t * 100}% ${t * 100}%, 0 ${ - t * 100 - }%); + clip-path: polygon(0 0, ${t * 100}% 0, ${t * 100}% ${t * 100}%, 0 ${t * 100 + }%); margin-right: calc((${t - 1})*${width}px); margin-bottom: calc((${t - 1})*${height}px); overflow-y:hidden @@ -39,4 +42,13 @@ export function wop(node?: HTMLUListElement, params?: { duration?: number }) { }; } +export function startTask(){ + invoke>('start_task').then((res) => { + toast.push(res.message, toastTheme.success); + processingModalOpen.update(() => true); + console.log(res); + + processingModalTotal.update(() => res.data); + }); +} \ No newline at end of file diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index d4f7636..7949d30 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,11 +1,75 @@
-
- -
+ + {#if existProject} + +
+ +
+ {:else} + + {/if}
+ diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 69da172..af507e7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,5 +1 @@ - - - +
hello world
\ No newline at end of file diff --git a/src/lib/modules/ConfigModule/index.svelte b/src/routes/config/+page.svelte similarity index 92% rename from src/lib/modules/ConfigModule/index.svelte rename to src/routes/config/+page.svelte index f9eb751..699ee21 100644 --- a/src/lib/modules/ConfigModule/index.svelte +++ b/src/routes/config/+page.svelte @@ -11,10 +11,9 @@ import { onMount } from 'svelte'; let init_form: Config = { - source_path: '', base_url: '', rate_limit: 0, - types_path: '', + types_path_relative: '', types_full_path: '', break_seconds: 0, request_path: '', @@ -28,8 +27,7 @@ let form = init_form; onMount(() => { - // @ts-expect-error - request('get_config', {}).then((res: SuccessResponse) => { + request('get_global_config', {}).then((res: SuccessResponse) => { form = res.data; }); }); @@ -39,7 +37,7 @@ toast.push('请输入Yapi地址根路径', toastTheme.error); return; } - if (!form.types_path) { + if (!form.types_path_relative) { toast.push('请输入项目类型目录文件夹路径', toastTheme.error); return; } @@ -74,7 +72,6 @@ return; } - // @ts-expect-error request('update_config', form).then((res: SuccessResponse) => { toast.push(res.message, toastTheme.success); }); @@ -84,11 +81,10 @@
- { request('check_request_config') - // @ts-expect-error .then((res: SuccessResponse) => { load_types = true; }) diff --git a/src/lib/modules/ServiceModule/components/ConfigModal.svelte b/src/routes/request/components/ConfigModal.svelte similarity index 100% rename from src/lib/modules/ServiceModule/components/ConfigModal.svelte rename to src/routes/request/components/ConfigModal.svelte diff --git a/src/lib/modules/ServiceModule/components/Node.svelte b/src/routes/request/components/Node.svelte similarity index 100% rename from src/lib/modules/ServiceModule/components/Node.svelte rename to src/routes/request/components/Node.svelte diff --git a/src/lib/modules/ServiceModule/components/TypesTree.svelte b/src/routes/request/components/TypesTree.svelte similarity index 100% rename from src/lib/modules/ServiceModule/components/TypesTree.svelte rename to src/routes/request/components/TypesTree.svelte diff --git a/src/routes/type/+page.svelte b/src/routes/type/+page.svelte new file mode 100644 index 0000000..33657c5 --- /dev/null +++ b/src/routes/type/+page.svelte @@ -0,0 +1,55 @@ + + +{#if need_init} + +{/if} + +{#if load_project} + +{/if} diff --git a/src/lib/modules/TypeModule/components/ConfigModal.svelte b/src/routes/type/components/ConfigModal.svelte similarity index 64% rename from src/lib/modules/TypeModule/components/ConfigModal.svelte rename to src/routes/type/components/ConfigModal.svelte index 08d3861..9ea407f 100644 --- a/src/lib/modules/TypeModule/components/ConfigModal.svelte +++ b/src/routes/type/components/ConfigModal.svelte @@ -1,20 +1,20 @@ + + +
+ 新增项目 + +
+ + + +
+ + +
+
diff --git a/src/lib/modules/TypeModule/components/ProjectTab/Category.svelte b/src/routes/type/components/ProjectTab/Category.svelte similarity index 100% rename from src/lib/modules/TypeModule/components/ProjectTab/Category.svelte rename to src/routes/type/components/ProjectTab/Category.svelte diff --git a/src/lib/modules/TypeModule/components/ProjectTab/Interface.svelte b/src/routes/type/components/ProjectTab/Interface.svelte similarity index 100% rename from src/lib/modules/TypeModule/components/ProjectTab/Interface.svelte rename to src/routes/type/components/ProjectTab/Interface.svelte diff --git a/src/lib/components/ProcessingModal.svelte b/src/routes/type/components/ProjectTab/ProcessingModal.svelte similarity index 58% rename from src/lib/components/ProcessingModal.svelte rename to src/routes/type/components/ProjectTab/ProcessingModal.svelte index 77b34f1..29ab602 100644 --- a/src/lib/components/ProcessingModal.svelte +++ b/src/routes/type/components/ProjectTab/ProcessingModal.svelte @@ -2,7 +2,7 @@ import { listen } from '@tauri-apps/api/event'; import Dialog, { Title, Content, Header } from '@smui/dialog'; import { onDestroy, onMount } from 'svelte'; - import { runningTask, processingModalOpen, processingModalTotal } from '../store'; + import { runningTask, processingModalOpen, processingModalTotal } from '../../../../lib/store'; import { request } from '@/utils'; import type { SuccessResponse } from '@/types/public'; import { toast } from '@zerodevx/svelte-toast'; @@ -10,6 +10,9 @@ import { tweened } from 'svelte/motion'; import { cubicOut } from 'svelte/easing'; import LinearProgress from '@smui/linear-progress'; + import type { QueueLog, ResolvedInterface } from '@/types/yapi'; + import Checkbox from '@smui/checkbox'; + import Button from '@smui/button'; const progress = tweened(0, { duration: 400, @@ -18,26 +21,16 @@ let log_area: HTMLDivElement; - let log_list: { - msg: string; - is_success: boolean; - }[] = []; + let checkList: (ResolvedInterface & { checked: boolean })[] = []; let unlistenLog: () => void; onMount(async () => { - unlistenLog = await listen<{ - msg: string; - success_number: number; - is_success: boolean; - }>('log', (event) => { - log_list.push({ - msg: event.payload.msg, - is_success: event.payload.is_success - }); - log_list = log_list; + unlistenLog = await listen('queue_log', (event) => { + checkList.push({ ...event.payload.resolved_interface, checked: true }); + checkList = checkList; log_area.scrollTop = log_area.scrollHeight; - progress.set(event.payload.success_number / $processingModalTotal); + progress.set(checkList.length / $processingModalTotal); }); }); @@ -46,11 +39,10 @@ }); function onClose() { - const over = log_list.length === $processingModalTotal; + const over = checkList.length === $processingModalTotal; if (!over) { - request('pause') - // @ts-expect-error + request('cancel_task') .then((res: SuccessResponse) => { toast.push(JSON.stringify(res.message), toastTheme.success); $processingModalOpen = false; @@ -60,7 +52,7 @@ }); } - log_list = []; + checkList = []; $processingModalTotal = 0; progress.set(0); runningTask.update(() => false); @@ -76,18 +68,27 @@ >
日志 - +
-
- {#each log_list as log} - {#if log.is_success} -

{log.msg}

- {:else} -

{log.msg}

- {/if} +
请勾选想要生成 ts 类型的接口:
+
+ {#each checkList as log} +
+ + {log.interface.title} + {log.interface.path} +
{/each}
+
+ +
diff --git a/src/lib/modules/TypeModule/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte similarity index 76% rename from src/lib/modules/TypeModule/components/ProjectTab/index.svelte rename to src/routes/type/components/ProjectTab/index.svelte index ab5c2d3..a39bc26 100644 --- a/src/lib/modules/TypeModule/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -10,56 +10,58 @@ import { toastTheme } from '@/consts'; import AddProjectModal from './AddProjectModal.svelte'; import { listen } from '@tauri-apps/api/event'; - import ProcessingModal from '@/components/ProcessingModal.svelte'; + import ProcessingModal from './ProcessingModal.svelte'; import { processingModalOpen, processingModalTotal, runningTask } from '@/store'; import { confirm } from '@tauri-apps/api/dialog'; import { slide } from 'svelte/transition'; import Textfield from '@smui/textfield'; import Accordion from '@smui-extra/accordion'; - let config: Config | undefined; + export let config: Config | undefined; let openAddModal = false; - let ready = false; let searchKey = ''; - let banInitModal = false; $: project_list = config?.project_list || []; - let active: NonNullable[number] = { + + let active : NonNullable[number] = { project_id: '', categories: [], token: '' }; - $: { - if (!banInitModal && ready && project_list.length == 0) { - openAddModal = true; - } - } + + // $: { + // if (project_list.length == 0) { + // openAddModal = true; + // } + // } onMount(() => { - getConfig(); + // getConfig(); + active = project_list[0]; + openAddModal = true; }); listen('task_completed', (_) => { toast.push('任务已完成'); - getConfig(); + // getConfig(); }); - function getConfig() { - request('get_config', { key: searchKey }) - // @ts-expect-error - .then((res: SuccessResponse) => { - config = res.data; - if (config?.project_list?.length) { - active = config?.project_list?.[0]; - } - }) - .catch((e) => { - toast.push(JSON.stringify(e), toastTheme.error); - }) - .finally(() => { - ready = true; - }); - } + // function getConfig() { + // request('get_global_config', { key: searchKey }) + // // @ts-expect-error + // .then((res: SuccessResponse) => { + // config = res.data; + // if (config?.project_list?.length) { + // active = config?.project_list?.[0]; + // } + // }) + // .catch((e) => { + // toast.push(JSON.stringify(e), toastTheme.error); + // }) + // .finally(() => { + // ready = true; + // }); + // } async function fetchProjects(is_full_update: boolean, project_id?: string) { if ($runningTask) { @@ -83,7 +85,6 @@ } toast.push('正在添加任务...'); request('update_projects', { projects, is_full_update }) - // @ts-expect-error .then((res: SuccessResponse) => { if (res.data === 0) { toast.push('无待执行的任务'); @@ -100,13 +101,13 @@ } function search() { - banInitModal = true; - getConfig(); + // banInitModal = true; + // getConfig(); } - +
@@ -116,17 +117,11 @@
- (banInitModal = false)} - label="搜索" - > +
- {#if active.project_id} + {#if active?.project_id} - {#if active.project_id} + {#if active?.project_id} {#each active.categories as category} diff --git a/tsconfig.json b/tsconfig.json index a53a86d..01350b9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,7 @@ "skipLibCheck": true, "sourceMap": true, "strict": true, + "noImplicitAny": false, "moduleResolution": "bundler", "baseUrl": "./", "paths": { From 82c23ad93f2078e65e759739aa42da0d2b22ce21 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Mon, 4 Mar 2024 22:06:46 +0800 Subject: [PATCH 07/43] =?UTF-8?q?feat:=20=E7=94=9F=E6=88=90ts=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/yapi/category.rs | 57 +++-------------- src-tauri/src/commands/yapi/config.rs | 27 ++------ src-tauri/src/commands/yapi/interface.rs | 22 ++++++- src-tauri/src/commands/yapi/project.rs | 57 +---------------- src-tauri/src/main.rs | 7 ++- src-tauri/src/models/yapi/queue.rs | 11 +--- src-tauri/src/services/yapi/category.rs | 18 +----- src-tauri/src/services/yapi/config.rs | 9 +-- src-tauri/src/services/yapi/interface.rs | 61 +++++++++++-------- src-tauri/src/services/yapi/project.rs | 22 ++----- .../services/yapi/resolver/json_resolver.rs | 2 +- .../ProjectTab/ProcessingModal.svelte | 28 ++++++++- 12 files changed, 115 insertions(+), 206 deletions(-) diff --git a/src-tauri/src/commands/yapi/category.rs b/src-tauri/src/commands/yapi/category.rs index 05a866b..15e31e0 100644 --- a/src-tauri/src/commands/yapi/category.rs +++ b/src-tauri/src/commands/yapi/category.rs @@ -1,15 +1,9 @@ use serde_json::json; -use tauri::{AppHandle, Manager, State}; +use tauri::AppHandle; use crate::{ - models::{ - notification::NotificationDesc, - web_response::WebResponse, - yapi::{interface::InterfaceFetchParams, queue::Queue}, - }, - services::{ - log::log_error, notification::notification, yapi::category::fetch_cat_interface_list, - }, + models::web_response::WebResponse, + services::{log::log_error, yapi::category::fetch_cat_interface_list}, }; #[tauri::command] @@ -19,46 +13,11 @@ pub async fn get_cat_interface_list( cat_id: u32, source_path: &str, ) -> Result { - // let queue: State<'_, Queue> = app_handle.state(); - - // notification( - // &app_handle, - // NotificationDesc::Success, - // &format!("正在获取分类{}的接口信息...", cat_id), - // ); - match fetch_cat_interface_list( - cat_id, - token.to_string(), - source_path.to_string(), - &app_handle, - ) - .await - { - Ok(res) => { - Ok(WebResponse { - data: Some(json!(res)), - message: format!("获取分类{}的接口信息成功", cat_id), - }) - - // for item in res.list { - // queue - // .add_task(InterfaceFetchParams { - // interface_id: item._id, - // token: token.to_string(), - // app_handle: app_handle.clone(), - // source_path: source_path.to_string(), - // }) - // .await; - // } - - // match queue.start_execute(&app_handle).await { - // Ok(_) => Ok(WebResponse { - // data: None, - // message: format!("已将分类{}下的所有接口加入任务队列", cat_id), - // }), - // Err(err) => log_error(&app_handle, err.to_string()), - // } - } + match fetch_cat_interface_list(cat_id, token.to_string(), source_path, &app_handle).await { + Ok(res) => Ok(WebResponse { + data: Some(json!(res)), + message: format!("获取分类{}的接口信息成功", cat_id), + }), Err(err) => log_error(&app_handle, err.to_string()), } } diff --git a/src-tauri/src/commands/yapi/config.rs b/src-tauri/src/commands/yapi/config.rs index 5d703f7..7659a02 100644 --- a/src-tauri/src/commands/yapi/config.rs +++ b/src-tauri/src/commands/yapi/config.rs @@ -1,37 +1,20 @@ use tauri::AppHandle; use crate::{ - models::{ - web_response::WebResponse, - yapi::config::{YapiConfig, YapiConfigRequest}, - }, + models::{web_response::WebResponse, yapi::config::YapiConfigRequest}, services::{ - log::{log, log_error}, + log::log_error, yapi::config::{get_project_config, init_project_config, write_project_config}, }, }; -// #[tauri::command] -// pub fn init_project_config( -// source_path: &str, -// app_handle: AppHandle, -// ) -> Result { -// match write_project_config(source_path.to_string(), YapiConfig::default()) { -// Ok(_) => Ok(WebResponse { -// message: String::from("初始化成功!"), -// data: None, -// }), -// Err(e) => log_error(&app_handle, e.to_string()), -// } -// } - #[tauri::command] pub fn update_project_config( source_path: &str, data: YapiConfigRequest, app_handle: AppHandle, ) -> Result { - let config = get_project_config(source_path.to_string()); + let config = get_project_config(source_path); match config { Ok(mut config) => { config.merge_from_request(data); @@ -50,11 +33,11 @@ pub fn update_project_config( #[tauri::command] pub fn load_project(source_path: &str, app_handle: AppHandle) -> Result { - match get_project_config(source_path.to_string()) { + match get_project_config(source_path) { Ok(config) => { if config.base_url.is_empty() { return Err("请初始化配置".to_string()); - } + } Ok(WebResponse { message: String::from("获取项目成功!"), data: Some(config.into()), diff --git a/src-tauri/src/commands/yapi/interface.rs b/src-tauri/src/commands/yapi/interface.rs index 45e4dd2..7858011 100644 --- a/src-tauri/src/commands/yapi/interface.rs +++ b/src-tauri/src/commands/yapi/interface.rs @@ -6,7 +6,7 @@ use crate::{ web_response::WebResponse, yapi::{interface::InterfaceFetchParams, queue::Queue}, }, - services::log::log_error, + services::{log::log_error, yapi::interface::write_content_to_interface_path}, }; #[tauri::command] @@ -43,9 +43,25 @@ pub async fn start_task(app_handle: AppHandle) -> Result { #[tauri::command] pub async fn cancel_task(app_handle: AppHandle) -> Result { let queue: State<'_, Queue> = app_handle.state(); - queue.cancel_execute(); + queue.cancel_execute().await; Ok(WebResponse { data: None, message: "已停止跑批任务".to_string(), }) -} \ No newline at end of file +} + +#[tauri::command] +pub fn write_to_file( + path: String, + content: String, + source_path: &str, + app_handle: AppHandle, +) -> Result { + match write_content_to_interface_path(path, source_path, content) { + Err(e) => log_error(&app_handle, e.to_string()), + Ok(_) => Ok(WebResponse { + data: None, + message: "已写入文件".to_string(), + }), + } +} diff --git a/src-tauri/src/commands/yapi/project.rs b/src-tauri/src/commands/yapi/project.rs index 6e2f27f..6a9a774 100644 --- a/src-tauri/src/commands/yapi/project.rs +++ b/src-tauri/src/commands/yapi/project.rs @@ -2,23 +2,20 @@ use serde_json::json; use tauri::AppHandle; use crate::{ - models::{notification::NotificationDesc, web_response::WebResponse}, + models::web_response::WebResponse, services::{ log::{log, log_error}, - notification::notification, yapi::project::{fetch_project_base_info, fetch_project_cat_menu}, }, }; -use super::category::get_cat_interface_list; - #[tauri::command] pub async fn get_yapi_project_base_info( app_handle: AppHandle, token: &str, source_path: &str, ) -> Result { - match fetch_project_base_info(token.to_string(), source_path.to_string(), &app_handle).await { + match fetch_project_base_info(token.to_string(), source_path, &app_handle).await { Ok(yapi_project_base_info) => { log( &app_handle, @@ -28,47 +25,6 @@ pub async fn get_yapi_project_base_info( message: format!("获取yapi项目{}成功", yapi_project_base_info.name), data: Some(json!(yapi_project_base_info)), }) - // match fetch_project_cat_menu( - // yapi_project_base_info._id, - // token.to_string(), - // source_path.to_string(), - // &app_handle, - // ) - // .await - // { - // Ok(cat_menu) => { - // for cat in cat_menu { - // match get_cat_interface_list( - // app_handle.clone(), - // token, - // cat._id, - // source_path, - // ) - // .await - // { - // Ok(res) => { - // log(&app_handle, res.message); - // } - // Err(err) => { - // notification( - // &app_handle, - // NotificationDesc::Error, - // &format!("类目{}更新失败", cat.name), - // ); - // log(&app_handle, err); - // } - // } - // } - // return Ok(WebResponse { - // message: format!( - // "已将项目{}的所有接口加入任务队列", - // yapi_project_base_info.name - // ), - // data: None, - // }); - // } - // Err(err) => log_error(&app_handle, err.to_string()), - // } } Err(err) => log_error(&app_handle, err.to_string()), } @@ -81,14 +37,7 @@ pub async fn get_yapi_project_cat_menu( project_id: u32, source_path: &str, ) -> Result { - match fetch_project_cat_menu( - project_id, - token.to_string(), - source_path.to_string(), - &app_handle, - ) - .await - { + match fetch_project_cat_menu(project_id, token.to_string(), source_path, &app_handle).await { Ok(res) => Ok(WebResponse { message: "获取yapi项目分类菜单成功".to_string(), data: Some(json!(res)), diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fa07a98..fb675fd 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use models::yapi::queue::Queue; use services::{ conversion::path_buf_to_string, - global_config::{get_global_config, init_config}, + global_config::init_config, }; use structs::context::ContextGlobal; use tauri::{api::dialog, CustomMenuItem, Manager, Menu, MenuItem, Submenu}; @@ -25,7 +25,7 @@ use crate::commands::{ global_config::{add_project, load_latest_project, update_config}, yapi::category::get_cat_interface_list, yapi::config::{load_project, update_project_config}, - yapi::interface::{add_interface_task, cancel_task, start_task}, + yapi::interface::{add_interface_task, cancel_task, start_task, write_to_file}, yapi::project::{get_yapi_project_base_info, get_yapi_project_cat_menu}, }; @@ -134,7 +134,8 @@ fn main() { get_cat_interface_list, add_interface_task, start_task, - cancel_task + cancel_task, + write_to_file ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/models/yapi/queue.rs b/src-tauri/src/models/yapi/queue.rs index 3e52840..9dae8bf 100644 --- a/src-tauri/src/models/yapi/queue.rs +++ b/src-tauri/src/models/yapi/queue.rs @@ -1,6 +1,5 @@ use std::{ collections::VecDeque, - io, sync::{ atomic::{AtomicBool, Ordering}, Arc, @@ -31,7 +30,6 @@ pub struct Queue { pub waiting_queue: Arc>>, pub total_count: Arc>, pub running: Arc, - pub result_queue: Arc>, pub app_handle: Arc>, } @@ -56,9 +54,6 @@ impl Queue { waiting_queue: Arc::new(Mutex::new(VecDeque::new())), running: Arc::new(AtomicBool::new(true)), total_count: Arc::new(Mutex::new(0)), - result_queue: Arc::new(Mutex::new(ResultQueue { - list: vec![], - })), app_handle: Arc::new(Mutex::new(app_handle.clone())), } } @@ -68,6 +63,8 @@ impl Queue { .lock() .await .push_back(interface_fetch_params); + + self.running.store(true, Ordering::Release); } pub async fn cancel_execute(&self) { @@ -75,9 +72,6 @@ impl Queue { } pub async fn clear(&self) { - *self.result_queue.lock().await = ResultQueue { - list: vec![], - }; *self.total_count.lock().await = 0; } @@ -93,7 +87,6 @@ impl Queue { queue.pop_front() }; let app_handle = Arc::clone(&self.app_handle); - let result_queue = Arc::clone(&self.result_queue); let sem = self.semaphore.clone(); match interface_data { diff --git a/src-tauri/src/services/yapi/category.rs b/src-tauri/src/services/yapi/category.rs index 5b4251d..a658e3e 100644 --- a/src-tauri/src/services/yapi/category.rs +++ b/src-tauri/src/services/yapi/category.rs @@ -3,14 +3,8 @@ use std::io; use tauri::AppHandle; use crate::{ - models::{ - notification::NotificationDesc, - yapi::{category::CategoryDataList, web_response::YapiResponse}, - }, - services::{ - notification::notification, - reqwest::{get_data, get_reqwest_client}, - }, + models::yapi::{category::CategoryDataList, web_response::YapiResponse}, + services::reqwest::{get_data, get_reqwest_client}, }; use super::config::get_project_config; @@ -20,7 +14,7 @@ const INTERFACE_LIST_CAT_API: &str = "api/interface/list_cat"; pub async fn fetch_cat_interface_list( cat_id: u32, token: String, - source_path: String, + source_path: &str, app_handle: &AppHandle, ) -> Result { let client = get_reqwest_client(&app_handle)?; @@ -31,12 +25,6 @@ pub async fn fetch_cat_interface_list( project_config.base_url, INTERFACE_LIST_CAT_API, token, cat_id ); - // notification( - // &app_handle, - // NotificationDesc::Success, - // "正在获取分类下的接口列表,,,", - // ); - match get_data::>(client, url).await { Ok(res) => Ok(res.data), Err(err) => Err(io::Error::new( diff --git a/src-tauri/src/services/yapi/config.rs b/src-tauri/src/services/yapi/config.rs index de2c470..6522731 100644 --- a/src-tauri/src/services/yapi/config.rs +++ b/src-tauri/src/services/yapi/config.rs @@ -5,10 +5,7 @@ use std::{ use serde_json::{from_str, json}; -use crate::{ - models::yapi::config::YapiConfig, - services::conversion::string_to_path_buf, -}; +use crate::{models::yapi::config::YapiConfig, services::conversion::string_to_path_buf}; pub const PROJECT_CONFIG_NAME: &str = "yapi.json"; @@ -28,10 +25,10 @@ pub fn init_project_config(source_path: String) -> Result<(), io::Error> { Ok(()) } -pub fn get_project_config(source_path: String) -> Result { +pub fn get_project_config(source_path: &str) -> Result { let mut file = OpenOptions::new() .read(true) - .open(string_to_path_buf(source_path).join(PROJECT_CONFIG_NAME))?; + .open(string_to_path_buf(source_path.to_string()).join(PROJECT_CONFIG_NAME))?; let mut contents = String::new(); file.read_to_string(&mut contents)?; Ok(from_str(&contents)?) diff --git a/src-tauri/src/services/yapi/interface.rs b/src-tauri/src/services/yapi/interface.rs index 2e29a70..2f57c6d 100644 --- a/src-tauri/src/services/yapi/interface.rs +++ b/src-tauri/src/services/yapi/interface.rs @@ -1,53 +1,41 @@ -use std::io; +use std::{fs, io, path::PathBuf}; -use serde_json::json; use tauri::AppHandle; use crate::{ - models::{ - notification::NotificationDesc, - yapi::{ - interface::{FormType, InterfaceData, InterfaceFetchParams, WebType}, - web_response::YapiResponse, - }, - }, - services::{ - notification::notification, - reqwest::{get_data, get_reqwest_client}, + models::yapi::{ + interface::{FormType, InterfaceData, InterfaceFetchParams, WebType}, + web_response::YapiResponse, }, + services::reqwest::{get_data, get_reqwest_client}, }; use super::{ config::get_project_config, resolver::{ - common::{get_req_body_type, get_request_json}, + common::{get_json, get_path_arr, get_req_body_type, get_request_json}, form_resolver, json_resolver, }, }; -const add_interface_task_API: &str = "api/interface/get"; +const ADD_INTERFACE_TASK_API: &str = "api/interface/get"; +// 获取接口详情 pub async fn fetch_interface_detail( fetch_interface_params: InterfaceFetchParams, app_handle: &AppHandle, ) -> Result { let client = get_reqwest_client(&app_handle)?; - let project_config = get_project_config(fetch_interface_params.source_path)?; + let project_config = get_project_config(&fetch_interface_params.source_path)?; let url = format!( "{}{}?token={}&id={}", project_config.base_url, - add_interface_task_API, + ADD_INTERFACE_TASK_API, fetch_interface_params.token, fetch_interface_params.interface_id ); - // notification( - // &fetch_interface_params.app_handle, - // NotificationDesc::Success, - // "正在获取接口详情...", - // ); - match get_data::>(client, url).await { Ok(res) => Ok(res.data), Err(err) => Err(io::Error::new( @@ -57,6 +45,7 @@ pub async fn fetch_interface_detail( } } +// 接口转ts字符串 pub fn get_interface_ts_string(data: &InterfaceData) -> Result { if let Err(e) = is_legal(data) { return Err(e); @@ -65,11 +54,11 @@ pub fn get_interface_ts_string(data: &InterfaceData) -> Result { let resp_ts_string = json_resolver::get_ts_string( WebType::Response, data, - &json!(data.res_body.clone().unwrap_or("".to_string())), + &get_json(data.res_body.clone().unwrap_or("".to_string())), ); let req_ts_string; - let request_json = json!(get_request_json(data)); + let request_json = get_json(get_request_json(data)); if data.method == "POST" { // post请求可能是json也可能是form @@ -94,3 +83,27 @@ fn is_legal(data: &InterfaceData) -> Result<(), String> { } Ok(()) } + +pub fn write_content_to_interface_path( + path: String, + source_path: &str, + content: String, +) -> Result<(), io::Error> { + let project_config = get_project_config(source_path)?; + let path_arr = get_path_arr(path); + let mut file_path = PathBuf::from(source_path).join(project_config.types_path_relative); + + for p in path_arr { + file_path.push(p); + } + + let dir_path = file_path.parent().unwrap(); + + fs::create_dir_all(dir_path).unwrap(); + + let file_full_name = format!("{}.ts", file_path.to_str().unwrap().to_string()); + + fs::write(file_full_name, content).unwrap(); + + Ok(()) +} diff --git a/src-tauri/src/services/yapi/project.rs b/src-tauri/src/services/yapi/project.rs index e4bd5ef..d13f9fa 100644 --- a/src-tauri/src/services/yapi/project.rs +++ b/src-tauri/src/services/yapi/project.rs @@ -3,16 +3,10 @@ use std::io; use tauri::AppHandle; use crate::{ - models::{ - notification::NotificationDesc, - yapi::{ - category::CategoryMenuItem, project::YapiProjectBaseInfo, web_response::YapiResponse, - }, - }, - services::{ - notification::notification, - reqwest::{get_data, get_reqwest_client}, + models::yapi::{ + category::CategoryMenuItem, project::YapiProjectBaseInfo, web_response::YapiResponse, }, + services::reqwest::{get_data, get_reqwest_client}, }; use super::config::get_project_config; @@ -22,7 +16,7 @@ const CATEGORY_MENU_API: &str = "api/interface/getCatMenu"; pub async fn fetch_project_base_info( token: String, - source_path: String, + source_path: &str, app_handle: &AppHandle, ) -> Result { let project_config = get_project_config(source_path)?; @@ -47,7 +41,7 @@ pub async fn fetch_project_base_info( pub async fn fetch_project_cat_menu( project_id: u32, token: String, - source_path: String, + source_path: &str, app_handle: &AppHandle, ) -> Result, io::Error> { let client = get_reqwest_client(&app_handle)?; @@ -58,12 +52,6 @@ pub async fn fetch_project_cat_menu( project_config.base_url, CATEGORY_MENU_API, project_id, token ); - // notification( - // &app_handle, - // NotificationDesc::Success, - // "正在获取分类列表...", - // ); - match get_data::>>(client, url).await { Ok(res) => Ok(res.data), Err(err) => Err(io::Error::new( diff --git a/src-tauri/src/services/yapi/resolver/json_resolver.rs b/src-tauri/src/services/yapi/resolver/json_resolver.rs index 3efa4ca..51d5395 100644 --- a/src-tauri/src/services/yapi/resolver/json_resolver.rs +++ b/src-tauri/src/services/yapi/resolver/json_resolver.rs @@ -17,7 +17,7 @@ pub fn get_ts_string( get_root_ts(root) } -fn get_root_ts(root: Root) -> String{ +fn get_root_ts(root: Root) -> String { let ts_name = get_ts_interface_name(&root.interface_name, &root.key); let header = format!("// {}\n", root.interface_desc); let mut res_string = String::from(header); diff --git a/src/routes/type/components/ProjectTab/ProcessingModal.svelte b/src/routes/type/components/ProjectTab/ProcessingModal.svelte index 29ab602..5ced2d1 100644 --- a/src/routes/type/components/ProjectTab/ProcessingModal.svelte +++ b/src/routes/type/components/ProjectTab/ProcessingModal.svelte @@ -2,7 +2,12 @@ import { listen } from '@tauri-apps/api/event'; import Dialog, { Title, Content, Header } from '@smui/dialog'; import { onDestroy, onMount } from 'svelte'; - import { runningTask, processingModalOpen, processingModalTotal } from '../../../../lib/store'; + import { + runningTask, + processingModalOpen, + processingModalTotal, + sourcePath + } from '../../../../lib/store'; import { request } from '@/utils'; import type { SuccessResponse } from '@/types/public'; import { toast } from '@zerodevx/svelte-toast'; @@ -13,6 +18,7 @@ import type { QueueLog, ResolvedInterface } from '@/types/yapi'; import Checkbox from '@smui/checkbox'; import Button from '@smui/button'; + import { invoke } from '@tauri-apps/api'; const progress = tweened(0, { duration: 400, @@ -57,6 +63,22 @@ progress.set(0); runningTask.update(() => false); } + + function onConfirm() { + for (let task of checkList) { + if (!task.checked) continue; + invoke('write_to_file', { + path: task.interface.path, + content: task.ts_string, + sourcePath: $sourcePath + }).catch((e) => { + toast.push(JSON.stringify(e), toastTheme.error); + }); + } + + toast.push('生成成功', toastTheme.success); + $processingModalOpen = false; + } {/each}
+
- +
- From 1bab5916f93ef5ee6d7a56d17135210b6a358a02 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Mon, 4 Mar 2024 22:44:43 +0800 Subject: [PATCH 08/43] =?UTF-8?q?feat:=20=E7=BC=93=E5=AD=98yai=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/yapi/config.rs | 2 +- src-tauri/src/commands/yapi/project.rs | 37 +++++++++++--- src-tauri/src/services/yapi/config.rs | 4 +- .../ProjectTab/AddProjectModal.svelte | 50 +++++++------------ .../type/components/ProjectTab/index.svelte | 32 +++--------- 5 files changed, 57 insertions(+), 68 deletions(-) diff --git a/src-tauri/src/commands/yapi/config.rs b/src-tauri/src/commands/yapi/config.rs index 7659a02..98ab91a 100644 --- a/src-tauri/src/commands/yapi/config.rs +++ b/src-tauri/src/commands/yapi/config.rs @@ -19,7 +19,7 @@ pub fn update_project_config( Ok(mut config) => { config.merge_from_request(data); - match write_project_config(source_path.to_string(), config) { + match write_project_config(source_path, config) { Ok(_) => Ok(WebResponse { message: String::from("更新成功!"), data: None, diff --git a/src-tauri/src/commands/yapi/project.rs b/src-tauri/src/commands/yapi/project.rs index 6a9a774..4a52177 100644 --- a/src-tauri/src/commands/yapi/project.rs +++ b/src-tauri/src/commands/yapi/project.rs @@ -2,10 +2,13 @@ use serde_json::json; use tauri::AppHandle; use crate::{ - models::web_response::WebResponse, + models::{web_response::WebResponse, yapi::config::YapiProject}, services::{ log::{log, log_error}, - yapi::project::{fetch_project_base_info, fetch_project_cat_menu}, + yapi::{ + config::{get_project_config, write_project_config}, + project::{fetch_project_base_info, fetch_project_cat_menu}, + }, }, }; @@ -17,10 +20,32 @@ pub async fn get_yapi_project_base_info( ) -> Result { match fetch_project_base_info(token.to_string(), source_path, &app_handle).await { Ok(yapi_project_base_info) => { - log( - &app_handle, - format!("获取yapi项目{}成功", yapi_project_base_info.name), - ); + match get_project_config(source_path) { + Ok(mut config) => { + // if config.project_list has not new project, add its to config + if !config.project_list.iter().any(|project| { + project.project_id == format!("{}", yapi_project_base_info._id) + }) { + config.project_list.push(YapiProject { + token: token.to_string(), + project_id: format!("{}", yapi_project_base_info._id), + project_name: Some(yapi_project_base_info.name.clone()), + categories: vec![], + }); + + // write config + match write_project_config(source_path, config) { + Ok(_) => {} + Err(e) => { + log(&app_handle, e.to_string()); + } + }; + } + } + Err(e) => { + log(&app_handle, e.to_string()); + } + } Ok(WebResponse { message: format!("获取yapi项目{}成功", yapi_project_base_info.name), data: Some(json!(yapi_project_base_info)), diff --git a/src-tauri/src/services/yapi/config.rs b/src-tauri/src/services/yapi/config.rs index 6522731..86d313d 100644 --- a/src-tauri/src/services/yapi/config.rs +++ b/src-tauri/src/services/yapi/config.rs @@ -34,10 +34,10 @@ pub fn get_project_config(source_path: &str) -> Result { Ok(from_str(&contents)?) } -pub fn write_project_config(source_path: String, yapi_config: YapiConfig) -> Result<(), io::Error> { +pub fn write_project_config(source_path: &str, yapi_config: YapiConfig) -> Result<(), io::Error> { let mut file = OpenOptions::new() .write(true) - .open(string_to_path_buf(source_path).join(PROJECT_CONFIG_NAME))?; + .open(string_to_path_buf(source_path.to_string()).join(PROJECT_CONFIG_NAME))?; file.write_all(json!(yapi_config).to_string().as_bytes())?; Ok(()) } diff --git a/src/routes/type/components/ProjectTab/AddProjectModal.svelte b/src/routes/type/components/ProjectTab/AddProjectModal.svelte index 0a4138a..238a498 100644 --- a/src/routes/type/components/ProjectTab/AddProjectModal.svelte +++ b/src/routes/type/components/ProjectTab/AddProjectModal.svelte @@ -1,12 +1,11 @@ diff --git a/src/routes/type/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte index a39bc26..36c2f7e 100644 --- a/src/routes/type/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -28,41 +28,21 @@ token: '' }; - - // $: { - // if (project_list.length == 0) { - // openAddModal = true; - // } - // } + $: { + if (project_list.length == 0) { + openAddModal = true; + } + } onMount(() => { // getConfig(); active = project_list[0]; - openAddModal = true; }); listen('task_completed', (_) => { toast.push('任务已完成'); - // getConfig(); }); - // function getConfig() { - // request('get_global_config', { key: searchKey }) - // // @ts-expect-error - // .then((res: SuccessResponse) => { - // config = res.data; - // if (config?.project_list?.length) { - // active = config?.project_list?.[0]; - // } - // }) - // .catch((e) => { - // toast.push(JSON.stringify(e), toastTheme.error); - // }) - // .finally(() => { - // ready = true; - // }); - // } - async function fetchProjects(is_full_update: boolean, project_id?: string) { if ($runningTask) { toast.push('正在执行任务...请稍等', toastTheme.error); @@ -107,7 +87,7 @@ - +
From 9be49936fda5ce8198d4acb64042c4cba259cab5 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Mon, 4 Mar 2024 22:56:30 +0800 Subject: [PATCH 09/43] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E5=90=8E=E9=87=8D=E6=96=B0=E5=8A=A0=E8=BD=BD=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/yapi/config.rs | 2 +- src-tauri/src/main.rs | 4 ++-- src/routes/type/+page.svelte | 4 ++-- src/routes/type/components/ProjectTab/AddProjectModal.svelte | 3 +++ src/routes/type/components/ProjectTab/index.svelte | 4 +++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src-tauri/src/commands/yapi/config.rs b/src-tauri/src/commands/yapi/config.rs index 98ab91a..9aa966a 100644 --- a/src-tauri/src/commands/yapi/config.rs +++ b/src-tauri/src/commands/yapi/config.rs @@ -32,7 +32,7 @@ pub fn update_project_config( } #[tauri::command] -pub fn load_project(source_path: &str, app_handle: AppHandle) -> Result { +pub fn load_project_config(source_path: &str, app_handle: AppHandle) -> Result { match get_project_config(source_path) { Ok(config) => { if config.base_url.is_empty() { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fb675fd..f656b1a 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -24,7 +24,7 @@ use crate::services::{ use crate::commands::{ global_config::{add_project, load_latest_project, update_config}, yapi::category::get_cat_interface_list, - yapi::config::{load_project, update_project_config}, + yapi::config::{load_project_config, update_project_config}, yapi::interface::{add_interface_task, cancel_task, start_task, write_to_file}, yapi::project::{get_yapi_project_base_info, get_yapi_project_cat_menu}, }; @@ -127,7 +127,7 @@ fn main() { update_request, add_project, load_latest_project, - load_project, + load_project_config, update_project_config, get_yapi_project_base_info, get_yapi_project_cat_menu, diff --git a/src/routes/type/+page.svelte b/src/routes/type/+page.svelte index 33657c5..844d4e0 100644 --- a/src/routes/type/+page.svelte +++ b/src/routes/type/+page.svelte @@ -17,7 +17,7 @@ } function loadProject() { - invoke>('load_project', { sourcePath: $sourcePath }) + invoke>('load_project_config', { sourcePath: $sourcePath }) .then((res) => { toast.push(res.message, toastTheme.success); config = res.data; @@ -51,5 +51,5 @@ {/if} {#if load_project} - + {/if} diff --git a/src/routes/type/components/ProjectTab/AddProjectModal.svelte b/src/routes/type/components/ProjectTab/AddProjectModal.svelte index 238a498..67a0b55 100644 --- a/src/routes/type/components/ProjectTab/AddProjectModal.svelte +++ b/src/routes/type/components/ProjectTab/AddProjectModal.svelte @@ -16,6 +16,7 @@ export let open: boolean; export let project_list: Config['project_list']; + export let loadProject: ()=> void let form = initForm; @@ -44,6 +45,8 @@ toast.push('项目已存在', toastTheme.error); return; } + + loadProject() toast.push('正在获取项目分类...', toastTheme.success); const menuList = await invoke>( diff --git a/src/routes/type/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte index 36c2f7e..391fad0 100644 --- a/src/routes/type/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -18,8 +18,10 @@ import Accordion from '@smui-extra/accordion'; export let config: Config | undefined; + export let loadProject: ()=> void let openAddModal = false; let searchKey = ''; + $: project_list = config?.project_list || []; let active : NonNullable[number] = { @@ -87,7 +89,7 @@ - +
From af9c2be14c3ff860e7d0802b18e1c3db8d362b23 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Tue, 5 Mar 2024 19:55:55 +0800 Subject: [PATCH 10/43] =?UTF-8?q?UI:=20=E6=A0=B7=E5=BC=8F=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/global_config.rs | 27 +- src-tauri/src/main.rs | 12 +- src-tauri/src/models/yapi/config.rs | 20 +- src-tauri/src/services/global_config.rs | 168 ----------- src-tauri/src/services/yapi/interface.rs | 2 +- src/lib/types/public.ts | 11 +- src/routes/+page.svelte | 2 +- src/routes/config/+page.svelte | 277 ++++++++++-------- .../request/components/ConfigModal.svelte | 2 +- src/routes/type/components/ConfigModal.svelte | 6 +- 10 files changed, 205 insertions(+), 322 deletions(-) diff --git a/src-tauri/src/commands/global_config.rs b/src-tauri/src/commands/global_config.rs index 4b9455d..4ca13f5 100644 --- a/src-tauri/src/commands/global_config.rs +++ b/src-tauri/src/commands/global_config.rs @@ -2,14 +2,29 @@ use serde_json::json; use tauri::{AppHandle, Manager}; use crate::{ - models::{global_config::{self, GlobalConfigRequest}, web_response::WebResponse}, + models::{ + global_config::GlobalConfigRequest, + web_response::WebResponse, + }, services::{ - global_config::{get_global_config, get_latest_project_source_path, update_project, write_config}, - log::{log, log_error}, - yapi::config::get_project_config, + global_config::{ + get_global_config, get_latest_project_source_path, update_project, write_config, + }, + log::log_error, }, }; +#[tauri::command] +pub fn load_global_config(app_handle: tauri::AppHandle) -> Result { + match get_global_config(&app_handle) { + Ok(global_config) => Ok(WebResponse { + message: String::from("获取全局配置成功!"), + data: Some(json!(global_config)), + }), + Err(e) => log_error(&app_handle, e.to_string()), + } +} + // 初始化 #[tauri::command] pub fn add_project(source_path: &str, app_handle: AppHandle) -> Result { @@ -52,12 +67,12 @@ pub fn load_latest_project(app_handle: tauri::AppHandle) -> Result Result { let config = get_global_config(&app_handle); - match config { + match config { Ok(mut global_config) => { global_config.merge_from_request(data); diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index f656b1a..a46da6e 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,10 +4,7 @@ use std::sync::Arc; use models::yapi::queue::Queue; -use services::{ - conversion::path_buf_to_string, - global_config::init_config, -}; +use services::{conversion::path_buf_to_string, global_config::init_config}; use structs::context::ContextGlobal; use tauri::{api::dialog, CustomMenuItem, Manager, Menu, MenuItem, Submenu}; use tokio::sync::Mutex; @@ -22,7 +19,7 @@ use crate::services::{ }; use crate::commands::{ - global_config::{add_project, load_latest_project, update_config}, + global_config::{add_project, load_global_config, load_latest_project, update_global_config}, yapi::category::get_cat_interface_list, yapi::config::{load_project_config, update_project_config}, yapi::interface::{add_interface_task, cancel_task, start_task, write_to_file}, @@ -115,7 +112,7 @@ fn main() { }) .invoke_handler(tauri::generate_handler![ read_config, - update_config, + update_global_config, // get_global_config, update_categories, update_interface, @@ -135,7 +132,8 @@ fn main() { add_interface_task, start_task, cancel_task, - write_to_file + write_to_file, + load_global_config ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/models/yapi/config.rs b/src-tauri/src/models/yapi/config.rs index be54b46..f3cedba 100644 --- a/src-tauri/src/models/yapi/config.rs +++ b/src-tauri/src/models/yapi/config.rs @@ -4,9 +4,9 @@ use serde_json::{json, Value}; #[derive(Deserialize, Serialize, Clone, Debug)] pub struct YapiConfig { pub base_url: String, - pub types_path_relative: String, + pub types_path: String, pub project_list: Vec, - pub request_path_relative: String, + pub request_path: String, pub request_template: String, pub header_template: String, pub file_name_template: String, @@ -17,9 +17,9 @@ impl Default for YapiConfig { fn default() -> Self { Self { base_url: String::new(), - types_path_relative: String::new(), + types_path: String::new(), project_list: Vec::new(), - request_path_relative: String::new(), + request_path: String::new(), request_template: String::new(), header_template: String::new(), file_name_template: String::new(), @@ -43,11 +43,11 @@ impl YapiConfig { if let Some(base_url) = yapi_config_request.base_url { self.base_url = base_url; } - if let Some(types_path_relative) = yapi_config_request.types_path_relative { - self.types_path_relative = types_path_relative; + if let Some(types_path) = yapi_config_request.types_path { + self.types_path = types_path; } - if let Some(request_path_relative) = yapi_config_request.request_path_relative { - self.request_path_relative = request_path_relative; + if let Some(request_path) = yapi_config_request.request_path { + self.request_path = request_path; } if let Some(request_template) = yapi_config_request.request_template { self.request_template = request_template; @@ -67,8 +67,8 @@ impl YapiConfig { #[derive(Debug, Deserialize, Serialize, Clone)] pub struct YapiConfigRequest { pub base_url: Option, - pub types_path_relative: Option, - pub request_path_relative: Option, + pub types_path: Option, + pub request_path: Option, pub request_template: Option, pub header_template: Option, pub file_name_template: Option, diff --git a/src-tauri/src/services/global_config.rs b/src-tauri/src/services/global_config.rs index 96a7c92..5e09d61 100644 --- a/src-tauri/src/services/global_config.rs +++ b/src-tauri/src/services/global_config.rs @@ -60,175 +60,7 @@ pub async fn read_config(data: String, handle: tauri::AppHandle) -> Result Result { -// let params = from_str::(&data).unwrap(); -// let cx: State<'_, ContextGlobal> = handle.state(); -// let path = cx.source_path.lock().await.clone(); -// if let Some(path) = &path { -// let config = Config::new(&path); - -// match config.read_config() { -// Ok(mut data) => { -// match params.key { -// Some(key) => { -// if !key.is_empty() { -// data.project_list -// .retain_mut(|project| filter_categories(project, &key)); -// } -// } -// None => {} -// } -// Ok(CustomResponse { -// message: String::from("获取配置成功!"), -// data: Some(json!(data)), -// }) -// } -// Err(_) => { -// return Err(String::from("read config error")); -// } -// } -// } else { -// return Err(String::from("path is None")); -// } -// } - -// fn filter_categories(project: &mut ProjectShort, key: &String) -> bool { -// project.categories.retain_mut(|category| { -// if category.name.contains(key) { -// true -// } else { -// filter_interfaces(category, key) -// } -// }); - -// if project.categories.len() != 0 { -// true -// } else { -// false -// } -// } - -// fn filter_interfaces(category: &mut CategoryShort, key: &String) -> bool { -// category.interfaces.retain_mut(|interface| { -// if let Some(name) = &interface.name { -// if name.contains(key) { -// return true; -// } -// } - -// if let Some(path) = &interface.path { -// if path.contains(key) { -// return true; -// } -// } - -// false -// }); - -// if category.interfaces.len() != 0 { -// true -// } else { -// false -// } -// } - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct UpdateConfigRequest { - pub source_path: Option, - pub base_url: Option, - pub types_path: Option, - pub rate_limit: Option, - pub break_seconds: Option, - pub request_template: Option, - pub header_template: Option, - pub type_import_template: Option, - pub proxy: Option, - pub request_path: Option, - pub file_name_template: Option, -} - -// 更新类型配置 -// #[tauri::command] -// pub async fn update_config( -// data: String, -// handle: tauri::AppHandle, -// ) -> Result { -// let form = from_str::(&data).unwrap(); -// let cx: State<'_, ContextGlobal> = handle.state(); -// let path = cx.source_path.lock().await.clone().unwrap(); -// let queue: State<'_, Queue> = handle.state(); - -// let config = Config::new(&path); - -// let mut config_json = match config.read_config() { -// Ok(data) => data, -// Err(_) => ConfigJson::new(path.clone()), -// }; - -// if let Some(base_url) = &form.base_url { -// let mut url = base_url.clone(); -// if url.ends_with("/") { -// url.pop(); -// } -// config_json.base_url = Some(url); -// } - -// if let Some(types_path) = &form.types_path { -// config_json.types_path = Some(PathBuf::from(types_path)); -// config_json.types_full_path = Some(join_path( -// &config_json.source_path.clone().unwrap(), -// types_path.clone(), -// )); -// } - -// if let Some(rate_limit) = &form.rate_limit { -// config_json.rate_limit = Some(rate_limit.clone()); -// } - -// if let Some(break_seconds) = &form.break_seconds { -// config_json.break_seconds = Some(break_seconds.clone()); -// } - -// if let Some(request_template) = &form.request_template { -// config_json.request_template = Some(request_template.clone()); -// } - -// if let Some(header_template) = &form.header_template { -// config_json.header_template = Some(header_template.clone()); -// } - -// if let Some(type_import_template) = &form.type_import_template { -// config_json.type_import_template = Some(type_import_template.clone()); -// } - -// if let Some(file_name_template) = &form.file_name_template { -// config_json.file_name_template = Some(file_name_template.clone()); -// } - -// if let Some(request_path) = &form.request_path { -// config_json.request_path = Some(PathBuf::from(request_path)); -// config_json.request_full_path = Some(join_path( -// &config_json.source_path.clone().unwrap(), -// request_path.clone(), -// )); -// } - -// if let Some(proxy) = &form.proxy { -// config_json.proxy = Some(proxy.clone()); -// } - -// update_queue(&queue, &config_json).await; - -// config.write_config(&config_json); - -// return Ok(CustomResponse { -// message: String::from("更新配置成功!"), -// data: None, -// }); -// } async fn init_queue(queue: &State<'_, Queue>, config: &Config) { let mut queue_config = queue.config.lock().await; diff --git a/src-tauri/src/services/yapi/interface.rs b/src-tauri/src/services/yapi/interface.rs index 2f57c6d..de35d02 100644 --- a/src-tauri/src/services/yapi/interface.rs +++ b/src-tauri/src/services/yapi/interface.rs @@ -91,7 +91,7 @@ pub fn write_content_to_interface_path( ) -> Result<(), io::Error> { let project_config = get_project_config(source_path)?; let path_arr = get_path_arr(path); - let mut file_path = PathBuf::from(source_path).join(project_config.types_path_relative); + let mut file_path = PathBuf::from(source_path).join(project_config.types_path); for p in path_arr { file_path.push(p); diff --git a/src/lib/types/public.ts b/src/lib/types/public.ts index 6e941ef..8e84b97 100644 --- a/src/lib/types/public.ts +++ b/src/lib/types/public.ts @@ -1,13 +1,18 @@ export interface Config { base_url?: string - types_path_relative?: string + types_path?: string project_list?: ProjectList[], request_path?: string, request_template?: string, header_template?: string file_name_template?: string type_import_template?: string - proxy?:string +} + +export interface GlobalConfig { + proxy?: string + rate_limit?: number + break_seconds?: number } @@ -34,7 +39,7 @@ export interface SuccessResponse { } export interface QueueStatus { - total:number; + total: number; // success:number; // fail:number; } diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index af507e7..281c686 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1 +1 @@ -
hello world
\ No newline at end of file +
\ No newline at end of file diff --git a/src/routes/config/+page.svelte b/src/routes/config/+page.svelte index 699ee21..b9159ce 100644 --- a/src/routes/config/+page.svelte +++ b/src/routes/config/+page.svelte @@ -1,157 +1,190 @@
- - - - - - - - + - -

$1: 请求名

-

$2: 请求类型

-

$3: 返回类型

-

$4: 接口地址

-
-
- - - +
+ { + update_project_config(); + }} > - -

$1: Request Type 类型

-

$2: Response Type 类型

-

$3: 类型文件相对地址(请在前面添加类型文件夹别名)

-
- - - - - - +
+ - - -

$1: 文件名

-
- - - - +
+
+ +
+
+ +
+ +
+ + + +

$1: 请求名

+

$2: 请求类型

+

$3: 返回类型

+

$4: 接口地址

+
+
+
+
+ + + +

$1: Request Type 类型

+

$2: Response Type 类型

+

$3: 类型文件相对地址(请在前面添加类型文件夹别名)

+
+
+
+ +
+ +
+ +
+ + + + +

$1: 文件名

+
+
+
+ +
+ { + update_global_config(); + }} + > +
-
- -
diff --git a/src/routes/request/components/ConfigModal.svelte b/src/routes/request/components/ConfigModal.svelte index d91bab1..6e6debc 100644 --- a/src/routes/request/components/ConfigModal.svelte +++ b/src/routes/request/components/ConfigModal.svelte @@ -42,7 +42,7 @@ return; } - request('update_config', form) + request('update_global_config', form) // @ts-expect-error .then((res: SuccessResponse) => { toast.push(res.message, toastTheme.success); diff --git a/src/routes/type/components/ConfigModal.svelte b/src/routes/type/components/ConfigModal.svelte index 9ea407f..5fe5f92 100644 --- a/src/routes/type/components/ConfigModal.svelte +++ b/src/routes/type/components/ConfigModal.svelte @@ -14,7 +14,7 @@ let init_form: Config = { base_url: '', - types_path_relative: 'src/types' + types_path: 'src/types' }; $: form = init_form; @@ -30,7 +30,7 @@ return; } - if (!form.types_path_relative) { + if (!form.types_path) { toast.push('请输入项目类型目录文件夹路径', toastTheme.error); return; } @@ -63,7 +63,7 @@ From 798fddf9cf832d52950ade87d08c4dab25172477 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Tue, 5 Mar 2024 20:53:32 +0800 Subject: [PATCH 11/43] feat: config page --- src/routes/config/+page.svelte | 53 ++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/routes/config/+page.svelte b/src/routes/config/+page.svelte index b9159ce..3398c52 100644 --- a/src/routes/config/+page.svelte +++ b/src/routes/config/+page.svelte @@ -1,11 +1,9 @@ @@ -77,6 +70,9 @@ variant="outlined" bind:value={projectConfig.base_url} label="Yapi地址根路径" + on:blur={() => { + update_project_config(); + }} >
@@ -95,8 +91,11 @@ style="width:100%" type="number" variant="outlined" - bind:value={initGlobalConfig.rate_limit} + bind:value={globalConfig.rate_limit} label="请求yapi-openapi最大并行请求数" + on:blur={() => { + update_global_config(); + }} >
@@ -104,8 +103,11 @@ style="width:100%" type="number" variant="outlined" - bind:value={initGlobalConfig.break_seconds} + bind:value={globalConfig.break_seconds} label="请求yapi-openapi时间间隔" + on:blur={() => { + update_global_config(); + }} >
@@ -114,6 +116,9 @@ variant="outlined" bind:value={projectConfig.request_path} label="你想要把定义 request 的 ts 文件放到哪个文件夹下?" + on:blur={() => { + update_project_config(); + }} >
@@ -124,6 +129,9 @@ variant="outlined" bind:value={projectConfig.request_template} label="请求模板字符串" + on:blur={() => { + update_project_config(); + }} >

$1: 请求名

@@ -140,6 +148,9 @@ variant="outlined" bind:value={projectConfig.type_import_template} label="import类型模板" + on:blur={() => { + update_project_config(); + }} >

$1: Request Type 类型

@@ -155,6 +166,9 @@ variant="outlined" bind:value={projectConfig.header_template} label="请求文件首部字符串" + on:blur={() => { + update_project_config(); + }} >
@@ -165,6 +179,9 @@ variant="outlined" bind:value={projectConfig.file_name_template} label="文件名模板字符串" + on:blur={() => { + update_project_config(); + }} > From 6e46366326c736dbcc61a1fd7094eebb260841bd Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Tue, 5 Mar 2024 21:50:46 +0800 Subject: [PATCH 12/43] feat: merge category & interface to project config --- src-tauri/src/commands/yapi/category.rs | 30 ++++++-- src-tauri/src/commands/yapi/project.rs | 59 ++++++++------- src-tauri/src/models/yapi/category.rs | 4 +- src-tauri/src/services/yapi/config.rs | 95 ++++++++++++++++++++++++- src-tauri/src/structs/web_response.rs | 4 +- src/lib/types/yapi.ts | 4 +- 6 files changed, 157 insertions(+), 39 deletions(-) diff --git a/src-tauri/src/commands/yapi/category.rs b/src-tauri/src/commands/yapi/category.rs index 15e31e0..6f35833 100644 --- a/src-tauri/src/commands/yapi/category.rs +++ b/src-tauri/src/commands/yapi/category.rs @@ -3,7 +3,10 @@ use tauri::AppHandle; use crate::{ models::web_response::WebResponse, - services::{log::log_error, yapi::category::fetch_cat_interface_list}, + services::{ + log::{log, log_error}, + yapi::{category::fetch_cat_interface_list, config::merge_interface_to_project_config}, + }, }; #[tauri::command] @@ -14,10 +17,27 @@ pub async fn get_cat_interface_list( source_path: &str, ) -> Result { match fetch_cat_interface_list(cat_id, token.to_string(), source_path, &app_handle).await { - Ok(res) => Ok(WebResponse { - data: Some(json!(res)), - message: format!("获取分类{}的接口信息成功", cat_id), - }), + Ok(res) => { + for interface in &res.list { + match merge_interface_to_project_config(interface, source_path, &cat_id.to_string()) + { + Ok(_) => { + log( + &app_handle, + format!("分类{}的接口{}合并到配置文件成功", cat_id, interface._id), + ); + } + Err(err) => { + log(&app_handle, err.to_string()); + } + } + } + + Ok(WebResponse { + data: Some(json!(res)), + message: format!("获取分类{}的接口信息成功", cat_id), + }) + } Err(err) => log_error(&app_handle, err.to_string()), } } diff --git a/src-tauri/src/commands/yapi/project.rs b/src-tauri/src/commands/yapi/project.rs index 4a52177..d96399f 100644 --- a/src-tauri/src/commands/yapi/project.rs +++ b/src-tauri/src/commands/yapi/project.rs @@ -2,11 +2,11 @@ use serde_json::json; use tauri::AppHandle; use crate::{ - models::{web_response::WebResponse, yapi::config::YapiProject}, + models::web_response::WebResponse, services::{ log::{log, log_error}, yapi::{ - config::{get_project_config, write_project_config}, + config::{merge_category_to_project_config, merge_yapi_project_to_project_config}, project::{fetch_project_base_info, fetch_project_cat_menu}, }, }, @@ -20,27 +20,13 @@ pub async fn get_yapi_project_base_info( ) -> Result { match fetch_project_base_info(token.to_string(), source_path, &app_handle).await { Ok(yapi_project_base_info) => { - match get_project_config(source_path) { - Ok(mut config) => { - // if config.project_list has not new project, add its to config - if !config.project_list.iter().any(|project| { - project.project_id == format!("{}", yapi_project_base_info._id) - }) { - config.project_list.push(YapiProject { - token: token.to_string(), - project_id: format!("{}", yapi_project_base_info._id), - project_name: Some(yapi_project_base_info.name.clone()), - categories: vec![], - }); - - // write config - match write_project_config(source_path, config) { - Ok(_) => {} - Err(e) => { - log(&app_handle, e.to_string()); - } - }; - } + match merge_yapi_project_to_project_config(source_path, &yapi_project_base_info, token) + { + Ok(_) => { + log( + &app_handle, + format!("更新项目{}至配置文件成功", yapi_project_base_info.name), + ); } Err(e) => { log(&app_handle, e.to_string()); @@ -63,10 +49,29 @@ pub async fn get_yapi_project_cat_menu( source_path: &str, ) -> Result { match fetch_project_cat_menu(project_id, token.to_string(), source_path, &app_handle).await { - Ok(res) => Ok(WebResponse { - message: "获取yapi项目分类菜单成功".to_string(), - data: Some(json!(res)), - }), + Ok(res) => { + for category in &res { + match merge_category_to_project_config( + category, + source_path, + &project_id.to_string(), + ) { + Ok(_) => { + log( + &app_handle, + format!("更新类目{}至配置文件成功", category.name), + ); + } + Err(e) => { + log(&app_handle, e.to_string()); + } + } + } + Ok(WebResponse { + message: "获取yapi项目分类菜单成功".to_string(), + data: Some(json!(res)), + }) + } Err(err) => log_error(&app_handle, err.to_string()), } } diff --git a/src-tauri/src/models/yapi/category.rs b/src-tauri/src/models/yapi/category.rs index e878fe3..818a0bf 100644 --- a/src-tauri/src/models/yapi/category.rs +++ b/src-tauri/src/models/yapi/category.rs @@ -14,12 +14,12 @@ pub struct CategoryMenuItem { pub struct CategoryDataList { pub count : u32, pub total : u32, - pub list : Vec + pub list : Vec } // 分类详情 #[derive(Debug, Deserialize, Serialize , Clone)] -pub struct CategoryDataItem { +pub struct InterfaceDataItem { pub _id : u32, pub catid : u32, pub title : String, diff --git a/src-tauri/src/services/yapi/config.rs b/src-tauri/src/services/yapi/config.rs index 86d313d..4113339 100644 --- a/src-tauri/src/services/yapi/config.rs +++ b/src-tauri/src/services/yapi/config.rs @@ -5,7 +5,14 @@ use std::{ use serde_json::{from_str, json}; -use crate::{models::yapi::config::YapiConfig, services::conversion::string_to_path_buf}; +use crate::{ + models::yapi::{ + category::{CategoryMenuItem, InterfaceDataItem}, + config::{YapiCategory, YapiConfig, YapiInterface, YapiProject}, + project::YapiProjectBaseInfo, + }, + services::conversion::string_to_path_buf, +}; pub const PROJECT_CONFIG_NAME: &str = "yapi.json"; @@ -41,3 +48,89 @@ pub fn write_project_config(source_path: &str, yapi_config: YapiConfig) -> Resul file.write_all(json!(yapi_config).to_string().as_bytes())?; Ok(()) } + +pub fn merge_yapi_project_to_project_config( + source_path: &str, + yapi_project_base_info: &YapiProjectBaseInfo, + token: &str, +) -> Result<(), io::Error> { + let mut yapi_config = get_project_config(source_path)?; + if !yapi_config + .project_list + .iter() + .any(|project| project.project_id == format!("{}", yapi_project_base_info._id)) + { + yapi_config.project_list.push(YapiProject { + token: token.to_string(), + project_id: format!("{}", yapi_project_base_info._id), + project_name: Some(yapi_project_base_info.name.clone()), + categories: vec![], + }) + }; + + write_project_config(source_path, yapi_config)?; + Ok(()) +} + +pub fn merge_category_to_project_config( + category_menu_item: &CategoryMenuItem, + source_path: &str, + project_id: &str, +) -> Result<(), io::Error> { + let mut yapi_config = get_project_config(source_path)?; + // get the project match project_id in the yapi_config + let project = yapi_config + .project_list + .iter_mut() + .find(|project| project.project_id == project_id); + + if let Some(project) = project { + if !project + .categories + .iter() + .any(|category| category.id == category_menu_item._id.to_string()) + { + project.categories.push(YapiCategory { + id: category_menu_item._id.to_string(), + name: category_menu_item.name.clone(), + interfaces: vec![], + }) + } + } + + write_project_config(source_path, yapi_config)?; + + Ok(()) +} + +pub fn merge_interface_to_project_config( + interface_data_item: &InterfaceDataItem, + source_path: &str, + cat_id: &str, +) -> Result<(), io::Error> { + let mut yapi_config = get_project_config(source_path)?; + + 'project: for project in &mut yapi_config.project_list { + for category in &mut project.categories { + if category.id == cat_id { + if !category + .interfaces + .iter() + .any(|interface| interface.id == interface_data_item._id.to_string()) + { + category.interfaces.push(YapiInterface { + id: interface_data_item._id.to_string(), + name: interface_data_item.title.clone(), + path: Some(interface_data_item.path.clone()), + lock: Some(false), + }) + } + break 'project; + } + } + } + + write_project_config(source_path, yapi_config)?; + + Ok(()) +} diff --git a/src-tauri/src/structs/web_response.rs b/src-tauri/src/structs/web_response.rs index f8299f3..6bb061f 100644 --- a/src-tauri/src/structs/web_response.rs +++ b/src-tauri/src/structs/web_response.rs @@ -22,12 +22,12 @@ pub struct CategoryMenuItem { pub struct CategoryDataList { pub count : u32, pub total : u32, - pub list : Vec + pub list : Vec } // 分类详情 #[derive(Debug, Deserialize, Serialize , Clone)] -pub struct CategoryDataItem { +pub struct InterfaceDataItem { pub _id : u32, pub catid : u32, pub title : String, diff --git a/src/lib/types/yapi.ts b/src/lib/types/yapi.ts index 22b7fc0..8ccad99 100644 --- a/src/lib/types/yapi.ts +++ b/src/lib/types/yapi.ts @@ -13,10 +13,10 @@ export type CategoryMenuList = { export type CategoryDataList = { count: number, total: number, - list: CategoryDataItem[] + list: InterfaceDataItem[] } -export type CategoryDataItem = { +export type InterfaceDataItem = { _id: number, catid: number, title: string, From 4301b961ca6593d6cffb3666e37250c2d972cf17 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Tue, 5 Mar 2024 22:38:24 +0800 Subject: [PATCH 13/43] feat: supple UI logic --- src/lib/utils.ts | 2 - .../ProjectTab/AddProjectModal.svelte | 4 +- .../components/ProjectTab/Category.svelte | 73 ++++++------ .../ProjectTab/ProcessingModal.svelte | 4 + .../type/components/ProjectTab/index.svelte | 112 +++++++++--------- 5 files changed, 93 insertions(+), 102 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index b8feab8..164d67f 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -46,8 +46,6 @@ export function startTask(){ invoke>('start_task').then((res) => { toast.push(res.message, toastTheme.success); processingModalOpen.update(() => true); - console.log(res); - processingModalTotal.update(() => res.data); }); diff --git a/src/routes/type/components/ProjectTab/AddProjectModal.svelte b/src/routes/type/components/ProjectTab/AddProjectModal.svelte index 67a0b55..5b971a7 100644 --- a/src/routes/type/components/ProjectTab/AddProjectModal.svelte +++ b/src/routes/type/components/ProjectTab/AddProjectModal.svelte @@ -60,7 +60,7 @@ for await (let catMenu of menuList.data) { toast.push(`正在获取分类${catMenu.name}下接口...`, toastTheme.success); - const categoryDataList = await invoke>( + const interfaceList = await invoke>( 'get_cat_interface_list', { token: form.token, @@ -69,7 +69,7 @@ } ); - for await (let i of categoryDataList.data.list) { + for await (let i of interfaceList.data.list) { await invoke('add_interface_task', { data: { token: form.token, diff --git a/src/routes/type/components/ProjectTab/Category.svelte b/src/routes/type/components/ProjectTab/Category.svelte index a458efe..603a4d2 100644 --- a/src/routes/type/components/ProjectTab/Category.svelte +++ b/src/routes/type/components/ProjectTab/Category.svelte @@ -2,12 +2,12 @@ import { Panel, Header, Content } from '@smui-extra/accordion'; import type { CategoryType, SuccessResponse } from '@/types/public'; import Interface from './Interface.svelte'; - import { request } from '@/utils'; import { toast } from '@zerodevx/svelte-toast'; import { toastTheme } from '@/consts'; - import { processingModalTotal, processingModalOpen, runningTask } from '@/store'; - import { confirm } from '@tauri-apps/api/dialog'; + import { sourcePath } from '@/store'; import Tooltip, { Wrapper } from '@smui/tooltip'; + import { invoke } from '@tauri-apps/api'; + import type { CategoryDataList } from '@/types/yapi'; export let data: CategoryType; export let token: string; @@ -15,38 +15,33 @@ $: interfaces = data.interfaces; async function update_category(id: string, name: string, is_full_update: boolean) { - if ($runningTask) { - toast.push('正在执行任务...请稍等', toastTheme.error); - return; - } - - const confirmed = await confirm('操作将重新生成ts文件,请确保本地代码已经保存!'); - - if (!confirmed) return; - - let categories = [ - { - id, - name - } - ]; + try { + toast.push(`正在获取分类${name}下接口...`, toastTheme.success); + const interfaceList = await invoke>( + 'get_cat_interface_list', + { + token, + sourcePath: $sourcePath, + catId: id + } + ); - toast.push('正在添加任务...'); - request('update_categories', { categories, token, is_full_update }) - // @ts-expect-error - .then((res: SuccessResponse) => { - if (res.data === 0) { - toast.push('无待执行的任务'); - } else { - toast.push(res.message, toastTheme.success); - processingModalOpen.update(() => true); - processingModalTotal.update(() => res.data); - runningTask.update(() => true); + for await (let i of interfaceList.data.list) { + if (!is_full_update) { + let oldCategory = data; + if (oldCategory.interfaces.find((old_i) => old_i.id === String(i._id))) continue; } - }) - .catch((e) => { - toast.push(JSON.stringify(e), toastTheme.error); - }); + await invoke('add_interface_task', { + data: { + token, + source_path: $sourcePath, + interface_id: i._id + } + }); + } + } catch (e) { + toast.push(JSON.stringify(e), toastTheme.error); + } } @@ -66,8 +61,8 @@ > 全量更新分类下的接口 - 全量更新分类下的接口 - + 更新分类下的所有接口 +
- - 增量更新分类下的接口 - 增量更新分类下的接口 - + + 增量更新分类下的接口 + 更新分类下新增的接口 +
diff --git a/src/routes/type/components/ProjectTab/ProcessingModal.svelte b/src/routes/type/components/ProjectTab/ProcessingModal.svelte index 5ced2d1..d164b4e 100644 --- a/src/routes/type/components/ProjectTab/ProcessingModal.svelte +++ b/src/routes/type/components/ProjectTab/ProcessingModal.svelte @@ -65,6 +65,10 @@ } function onConfirm() { + const confirmed = confirm('操作将重新生成ts文件,请确保本地代码已经保存!'); + + if (!confirmed) return; + for (let task of checkList) { if (!task.checked) continue; invoke('write_to_file', { diff --git a/src/routes/type/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte index 391fad0..c62c3f2 100644 --- a/src/routes/type/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -3,28 +3,27 @@ import TabBar from '@smui/tab-bar'; import Button from '@smui/button'; import type { Config, SuccessResponse } from '@/types/public'; - import { SvelteComponent, onMount } from 'svelte'; + import { onMount } from 'svelte'; import Category from './Category.svelte'; - import { request } from '@/utils'; + import { startTask } from '@/utils'; import { toast } from '@zerodevx/svelte-toast'; import { toastTheme } from '@/consts'; import AddProjectModal from './AddProjectModal.svelte'; - import { listen } from '@tauri-apps/api/event'; import ProcessingModal from './ProcessingModal.svelte'; - import { processingModalOpen, processingModalTotal, runningTask } from '@/store'; - import { confirm } from '@tauri-apps/api/dialog'; - import { slide } from 'svelte/transition'; + import { sourcePath } from '@/store'; import Textfield from '@smui/textfield'; import Accordion from '@smui-extra/accordion'; + import { invoke } from '@tauri-apps/api'; + import type { CategoryDataList, CategoryMenuList } from '@/types/yapi'; export let config: Config | undefined; - export let loadProject: ()=> void + export let loadProject: () => void; let openAddModal = false; let searchKey = ''; $: project_list = config?.project_list || []; - let active : NonNullable[number] = { + let active: NonNullable[number] = { project_id: '', categories: [], token: '' @@ -37,49 +36,52 @@ } onMount(() => { - // getConfig(); active = project_list[0]; }); - listen('task_completed', (_) => { - toast.push('任务已完成'); - }); - async function fetchProjects(is_full_update: boolean, project_id?: string) { - if ($runningTask) { - toast.push('正在执行任务...请稍等', toastTheme.error); - return; - } - - const confirmed = await confirm('操作将重新生成ts文件,请确保本地代码已经保存!'); - - if (!confirmed) return; - - let project_list = config?.project_list || []; + const project = project_list.find((p) => p.project_id === project_id); + + try { + toast.push('正在获取项目分类...', toastTheme.success); + const categoryList = await invoke>( + 'get_yapi_project_cat_menu', + { + token: project?.token, + sourcePath: $sourcePath, + projectId: project_id + } + ); - let projects = project_list.map((project) => ({ - id: project.project_id, - token: project.token - })); + for await (let category of categoryList.data) { + if (!is_full_update) { + if (project?.categories.find((c) => c.id === String(category._id))) continue; + } + toast.push(`正在获取分类${category.name}下接口...`, toastTheme.success); + const interfaceList = await invoke>( + 'get_cat_interface_list', + { + token: project?.token, + sourcePath: $sourcePath, + catId: category._id + } + ); + + for await (let i of interfaceList.data.list) { + await invoke('add_interface_task', { + data: { + token: project?.token, + source_path: $sourcePath, + interface_id: i._id + } + }); + } + } - if (project_id) { - projects = projects.filter((project) => project.id === project_id); + startTask(); + } catch (e) { + toast.push(JSON.stringify(e), toastTheme.error); } - toast.push('正在添加任务...'); - request('update_projects', { projects, is_full_update }) - .then((res: SuccessResponse) => { - if (res.data === 0) { - toast.push('无待执行的任务'); - } else { - toast.push(res.message, toastTheme.success); - processingModalOpen.update(() => true); - processingModalTotal.update(() => res.data); - runningTask.update(() => true); - } - }) - .catch((e) => { - toast.push(JSON.stringify(e), toastTheme.error); - }); } function search() { @@ -89,19 +91,21 @@ - +
- - + +
- -
{#if active?.project_id} {tab.project_id} -
-
- - -
-
{/if}
From 9ed1f3a09b492d74b1c06d188ed6f173472da9de Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Tue, 5 Mar 2024 23:30:12 +0800 Subject: [PATCH 14/43] feat: Type search --- src/lib/types/public.ts | 2 + src/routes/+layout.svelte | 1 - src/routes/type/+page.svelte | 14 --- .../type/components/ProjectTab/Project.svelte | 107 ++++++++++++++++++ .../type/components/ProjectTab/index.svelte | 82 ++------------ 5 files changed, 116 insertions(+), 90 deletions(-) create mode 100644 src/routes/type/components/ProjectTab/Project.svelte diff --git a/src/lib/types/public.ts b/src/lib/types/public.ts index 8e84b97..5c8a23e 100644 --- a/src/lib/types/public.ts +++ b/src/lib/types/public.ts @@ -31,6 +31,8 @@ export interface CategoryType { export interface InterfaceType { id: string name?: string + path?: string + lock?: boolean } export interface SuccessResponse { diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7949d30..53bacc5 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -28,7 +28,6 @@ unlistenLoadProjectError = await listen('load_project_error', (event) => { toast.push(event.payload, toastTheme.error); - // todo: 请查看日志获取更多信息,日志地址xxx }); unlistenNotification = await listen<{ message: string; desc: 'Success' | 'Error' }>( diff --git a/src/routes/type/+page.svelte b/src/routes/type/+page.svelte index 844d4e0..a6e075c 100644 --- a/src/routes/type/+page.svelte +++ b/src/routes/type/+page.svelte @@ -1,5 +1,4 @@ {#if need_init} diff --git a/src/routes/type/components/ProjectTab/Project.svelte b/src/routes/type/components/ProjectTab/Project.svelte new file mode 100644 index 0000000..ea55385 --- /dev/null +++ b/src/routes/type/components/ProjectTab/Project.svelte @@ -0,0 +1,107 @@ + + + +
+ + +
+ + {#each filtered_category_list as category} + + {/each} + diff --git a/src/routes/type/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte index c62c3f2..7e7972b 100644 --- a/src/routes/type/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -2,24 +2,15 @@ import Tab, { Label } from '@smui/tab'; import TabBar from '@smui/tab-bar'; import Button from '@smui/button'; - import type { Config, SuccessResponse } from '@/types/public'; + import type { Config } from '@/types/public'; import { onMount } from 'svelte'; - import Category from './Category.svelte'; - import { startTask } from '@/utils'; - import { toast } from '@zerodevx/svelte-toast'; - import { toastTheme } from '@/consts'; import AddProjectModal from './AddProjectModal.svelte'; import ProcessingModal from './ProcessingModal.svelte'; - import { sourcePath } from '@/store'; - import Textfield from '@smui/textfield'; - import Accordion from '@smui-extra/accordion'; - import { invoke } from '@tauri-apps/api'; - import type { CategoryDataList, CategoryMenuList } from '@/types/yapi'; + import Project from './Project.svelte'; export let config: Config | undefined; export let loadProject: () => void; let openAddModal = false; - let searchKey = ''; $: project_list = config?.project_list || []; @@ -38,56 +29,6 @@ onMount(() => { active = project_list[0]; }); - - async function fetchProjects(is_full_update: boolean, project_id?: string) { - const project = project_list.find((p) => p.project_id === project_id); - - try { - toast.push('正在获取项目分类...', toastTheme.success); - const categoryList = await invoke>( - 'get_yapi_project_cat_menu', - { - token: project?.token, - sourcePath: $sourcePath, - projectId: project_id - } - ); - - for await (let category of categoryList.data) { - if (!is_full_update) { - if (project?.categories.find((c) => c.id === String(category._id))) continue; - } - toast.push(`正在获取分类${category.name}下接口...`, toastTheme.success); - const interfaceList = await invoke>( - 'get_cat_interface_list', - { - token: project?.token, - sourcePath: $sourcePath, - catId: category._id - } - ); - - for await (let i of interfaceList.data.list) { - await invoke('add_interface_task', { - data: { - token: project?.token, - source_path: $sourcePath, - interface_id: i._id - } - }); - } - } - - startTask(); - } catch (e) { - toast.push(JSON.stringify(e), toastTheme.error); - } - } - - function search() { - // banInitModal = true; - // getConfig(); - } @@ -97,15 +38,6 @@
- - -
-
-
{#if active?.project_id} {#if active?.project_id} - - {#each active.categories as category} - - {/each} - + {/if}
From 98c4cda8d094c246470071615349d8c79ee3b573 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Wed, 6 Mar 2024 17:31:02 +0800 Subject: [PATCH 15/43] =?UTF-8?q?feat:=20request=20service=20=E6=9A=82?= =?UTF-8?q?=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/services/request.rs | 123 ++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/src-tauri/src/services/request.rs b/src-tauri/src/services/request.rs index ff874fa..8f587ad 100644 --- a/src-tauri/src/services/request.rs +++ b/src-tauri/src/services/request.rs @@ -79,3 +79,126 @@ pub async fn update_request( data: None, }) } + +// ---------------------------- + +// 获取 type 文件的相对路径 +fn get_type_relative_path(&self, path: &PathBuf) -> Option { + let types_root_path = self.context.types_full_path.clone().unwrap(); + match path == &types_root_path { + true => None, + false => Some(path.strip_prefix(&types_root_path).unwrap().to_path_buf()), + } +} + +// 获取写入 service 文件的路径 +fn get_write_path(&self, sub_path: &Option) -> PathBuf { + match &sub_path { + Some(sub_path) => { + let mut write_path = self.request_full_path.clone().unwrap().join(&sub_path); + + if let Some(template) = self.file_name_template.clone() { + if let Some(file_name) = write_path.file_name() { + let real_file_name = template.replace("$1", file_name.to_str().unwrap()); + write_path.set_file_name(real_file_name); + } + } + + write_path + } + None => self.request_full_path.clone().unwrap().join("index"), + } +} + +// 检查生成service的 type 文件是否有 Request/Response interface +fn check_file(&self, file_path: &PathBuf, file_name_without_ext: &String) -> bool { + let req = format!("{}Request", get_legal_name(file_name_without_ext)); + let resp = format!("{}Response", get_legal_name(file_name_without_ext)); + + if is_string_in_file(&file_path, &req) && is_string_in_file(&file_path, &resp) { + return true; + } + false +} + +// 把import ts 定义字符串添加进import_list +fn op_import_list( + type_import_template: String, + sub_path: &Option, + file_name: &String, +) -> Vec { + let mut import_list = vec![]; + + let sub_path_unix = get_sub_path_unix(sub_path); + + let import_string = type_import_template + .replace("$1", &format!("{}Request", get_legal_name(&file_name))) + .replace("$2", &format!("{}Response", get_legal_name(&file_name))) + .replace("$3", &format!("{}/{}", sub_path_unix, file_name)) + + "\n"; + + import_list.push(import_string); + + import_list +} + +// 把export ts 定义字符串添加进export_list +fn get_export_list( + request_template: String, + file_path: &PathBuf, + sub_path: &Option, +) -> Vec { + let mut export_list = vec![]; + + let comment = get_comment(file_path.clone()); + + let sub_path_unix = get_sub_path_unix(sub_path); + + let file_name = get_file_name_without_ext(&file_path); + + let export_string = request_template + .replace("$1", &file_name) + .replace("$2", &format!("{}Request", get_legal_name(&file_name))) + .replace("$3", &format!("{}Response", get_legal_name(&file_name))) + .replace("$4", &format!("{}/{}", sub_path_unix.as_str(), &file_name)) + + "\n"; + + let export_string_with_comment = format!("{}\n{}", comment, export_string); + + export_list.push(export_string_with_comment); + + export_list +} + +fn get_sub_path_unix(sub_path: &Option) -> String { + match sub_path { + Some(sub_path) => format!( + "/{}", + sub_path + .to_str() + .unwrap() + .replace("\\", "/") + .replace("//", "/") + ), + None => "".to_string(), + } +} + +fn get_comment(ts_file: PathBuf) -> String { + let file = File::open(ts_file).unwrap(); + let reader = BufReader::new(file); + + let mut iteror = reader.lines().into_iter(); + let first_line = iteror.next().unwrap().unwrap(); + + if first_line.starts_with("//") { + return first_line; + } + + String::from("") +} + +fn get_file_name_without_ext(file_path: &PathBuf) -> String { + let file_name_osstr = Path::file_stem(&file_path).unwrap(); + file_name_osstr.to_os_string().into_string().unwrap() +} From 8669e0fb09f2bcf4f7d7091cfc02fc68d19cc4d5 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Wed, 6 Mar 2024 23:29:41 +0800 Subject: [PATCH 16/43] feat: change request module from oop to fp --- src-tauri/src/commands/interface.rs | 59 ------ src-tauri/src/commands/mod.rs | 8 +- src-tauri/src/commands/request.rs | 81 -------- src-tauri/src/commands/yapi/mod.rs | 3 +- src-tauri/src/commands/yapi/request.rs | 18 ++ src-tauri/src/main.rs | 4 +- src-tauri/src/models/file.rs | 10 + src-tauri/src/models/mod.rs | 3 +- src-tauri/src/services/request.rs | 190 +++++++++++++++--- .../request/components/TypesTree.svelte | 7 +- 10 files changed, 202 insertions(+), 181 deletions(-) delete mode 100644 src-tauri/src/commands/interface.rs delete mode 100644 src-tauri/src/commands/request.rs create mode 100644 src-tauri/src/commands/yapi/request.rs create mode 100644 src-tauri/src/models/file.rs diff --git a/src-tauri/src/commands/interface.rs b/src-tauri/src/commands/interface.rs deleted file mode 100644 index 94981c7..0000000 --- a/src-tauri/src/commands/interface.rs +++ /dev/null @@ -1,59 +0,0 @@ -use serde::{Deserialize, Serialize}; -use serde_json::{from_str, json}; -use tauri::{Manager, State}; - -use crate::structs::{context::{Context, ContextGlobal}, interface::Interface, queue::Queue}; - -use super::common::CustomResponse; - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct InterfaceList { - pub id: String, -} - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct UpdateInterfaces { - pub interfaces: Vec, - pub token: String, -} - -// 更新接口 -#[tauri::command] -pub async fn update_interface( - data: String, - handle: tauri::AppHandle, -) -> Result { - let context_global: State<'_, ContextGlobal> = handle.state(); - let queue: State<'_, Queue> = handle.state(); - let handle_clone = handle.clone(); - - let source_path = context_global.source_path.lock().await.clone().unwrap(); - let context = Context::from_source_path(&source_path); - - let data = from_str::(&data).unwrap(); - let token = data.token; - - let interfaces: Vec<_> = data - .interfaces - .iter() - .map(|item| Interface::new(token.clone(), context.clone(), item.id.to_string())) - .collect(); - - add_interfaces_task(&queue, interfaces).await; - - tauri::async_runtime::spawn(async move { - let queue: State<'_, Queue> = handle_clone.state(); - queue.start_task().await; - }); - - return Ok(CustomResponse { - message: String::from("添加任务成功"), - data: Some(json!(queue.total_count.lock().await.clone())), - }); -} - -pub async fn add_interfaces_task(queue: &State<'_, Queue>, interfaces: Vec) { - for interface in interfaces { - queue.add_task(interface).await; - } -} diff --git a/src-tauri/src/commands/mod.rs b/src-tauri/src/commands/mod.rs index 8d328ce..1f8071c 100644 --- a/src-tauri/src/commands/mod.rs +++ b/src-tauri/src/commands/mod.rs @@ -1,8 +1,2 @@ pub mod global_config; -// pub mod project; -pub mod yapi; -// pub mod category; -// pub mod common; -// pub mod interface; -// pub mod project; -// pub mod request; \ No newline at end of file +pub mod yapi; \ No newline at end of file diff --git a/src-tauri/src/commands/request.rs b/src-tauri/src/commands/request.rs deleted file mode 100644 index ff874fa..0000000 --- a/src-tauri/src/commands/request.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::path::PathBuf; - -use serde::{Deserialize, Serialize}; -use serde_json::{from_str, json}; -use tauri::{Manager, State}; - -use crate::structs::{ - context::ContextGlobal, - request::{Request, RequestNode}, -}; - -use super::common::{CustomResponse, SearchRequest}; - -#[tauri::command] -pub async fn check_request_config(handle: tauri::AppHandle) -> Result { - let context_global: State<'_, ContextGlobal> = handle.state(); - let source_path = context_global.source_path.lock().await.clone().unwrap(); - - let request = Request::from_source_path(source_path); - - if request.request_full_path.is_none() - || request.header_template.is_none() - || request.request_template.is_none() - || request.type_import_template.is_none() - { - return Err("请初始化数据".to_string()); - } - - Ok(CustomResponse { - message: "已读取配置".to_string(), - data: None, - }) -} - -#[tauri::command] -pub async fn get_request_list(handle: tauri::AppHandle) -> Result { - let context_global: State<'_, ContextGlobal> = handle.state(); - let source_path = context_global.source_path.lock().await.clone().unwrap(); - - let request = Request::from_source_path(source_path); - - let list = request.get_node_list(None); - - let root_node = RequestNode { - full_path: request.context.types_full_path.clone().unwrap(), - name: "root".to_string(), - children: list, - }; - - Ok(CustomResponse { - message: "获取成功".to_string(), - data: Some(json!(Vec::from([root_node]))), - }) -} - -#[derive(Debug, Deserialize, Serialize, Clone)] -pub struct UpdateRequest { - full_path: Vec, -} - -#[tauri::command] -pub async fn update_request( - data: String, - handle: tauri::AppHandle, -) -> Result { - let form = from_str::(&data).unwrap(); - let context_global: State<'_, ContextGlobal> = handle.state(); - let source_path = context_global.source_path.lock().await.clone().unwrap(); - - let request = Request::from_source_path(source_path); - - for fp in form.full_path { - let path = PathBuf::from(fp); - request.write_ts(&path); - } - - Ok(CustomResponse { - message: "已成功写入ts文件".to_string(), - data: None, - }) -} diff --git a/src-tauri/src/commands/yapi/mod.rs b/src-tauri/src/commands/yapi/mod.rs index 311482a..604ab0c 100644 --- a/src-tauri/src/commands/yapi/mod.rs +++ b/src-tauri/src/commands/yapi/mod.rs @@ -1,4 +1,5 @@ pub mod category; pub mod config; pub mod interface; -pub mod project; \ No newline at end of file +pub mod project; +pub mod request; \ No newline at end of file diff --git a/src-tauri/src/commands/yapi/request.rs b/src-tauri/src/commands/yapi/request.rs new file mode 100644 index 0000000..a1ed952 --- /dev/null +++ b/src-tauri/src/commands/yapi/request.rs @@ -0,0 +1,18 @@ +use serde_json::json; +use tauri::AppHandle; + +use crate::{ + models::web_response::WebResponse, + services::{log::log_error, request::get_file_tree, yapi::config::get_project_config}, +}; + +#[tauri::command] +pub fn load_file_tree(source_path: &str, app_handle: AppHandle) -> Result { + match get_file_tree(source_path, None) { + Ok(file_tree) => Ok(WebResponse { + data: Some(json!(file_tree)), + message: "获取types文件树成功".to_string(), + }), + Err(err) => log_error(&app_handle, err.to_string()), + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index a46da6e..91a17f2 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -24,6 +24,7 @@ use crate::commands::{ yapi::config::{load_project_config, update_project_config}, yapi::interface::{add_interface_task, cancel_task, start_task, write_to_file}, yapi::project::{get_yapi_project_base_info, get_yapi_project_cat_menu}, + yapi::request::load_file_tree, }; pub mod commands; @@ -133,7 +134,8 @@ fn main() { start_task, cancel_task, write_to_file, - load_global_config + load_global_config, + load_file_tree ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/models/file.rs b/src-tauri/src/models/file.rs new file mode 100644 index 0000000..c9b8523 --- /dev/null +++ b/src-tauri/src/models/file.rs @@ -0,0 +1,10 @@ +use std::path::PathBuf; + +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct FileTree { + pub full_path: PathBuf, + pub name: String, + pub children: Box>, +} \ No newline at end of file diff --git a/src-tauri/src/models/mod.rs b/src-tauri/src/models/mod.rs index 32d9063..704d8d4 100644 --- a/src-tauri/src/models/mod.rs +++ b/src-tauri/src/models/mod.rs @@ -1,4 +1,5 @@ pub mod web_response; pub mod global_config; pub mod yapi; -pub mod notification; \ No newline at end of file +pub mod notification; +pub mod file; \ No newline at end of file diff --git a/src-tauri/src/services/request.rs b/src-tauri/src/services/request.rs index 8f587ad..ab0cb86 100644 --- a/src-tauri/src/services/request.rs +++ b/src-tauri/src/services/request.rs @@ -1,15 +1,25 @@ -use std::path::PathBuf; +use std::{ + fs::{self, File}, + io::{self, BufRead, BufReader, Write}, + path::{Path, PathBuf}, +}; use serde::{Deserialize, Serialize}; use serde_json::{from_str, json}; use tauri::{Manager, State}; -use crate::structs::{ - context::ContextGlobal, - request::{Request, RequestNode}, +use crate::{ + models::file::FileTree, + structs::{ + context::ContextGlobal, + request::{Request, RequestNode}, + }, }; -use super::common::{CustomResponse, SearchRequest}; +use super::{ + common::{CustomResponse, SearchRequest}, + yapi::{config::get_project_config, resolver::common::get_legal_name}, +}; #[tauri::command] pub async fn check_request_config(handle: tauri::AppHandle) -> Result { @@ -82,9 +92,125 @@ pub async fn update_request( // ---------------------------- +pub fn get_file_tree( + source_path: &str, + search_path: Option, +) -> Result>, io::Error> { + let project_config = get_project_config(source_path)?; + let types_full_path = PathBuf::from(source_path).join(project_config.types_path); + let search_path = match search_path { + Some(path) => path, + None => types_full_path, + }; + let read_dir = fs::read_dir(search_path)?; + + let list: Vec<_> = read_dir + .into_iter() + .map(|dir_result| { + let dir = dir_result.unwrap(); + let file_type = dir.file_type().unwrap(); + let file_path = dir.path(); + let file_name = dir.file_name().into_string().unwrap(); + + if file_type.is_file() { + let node = FileTree { + full_path: file_path.clone(), + name: file_name.clone(), + children: Box::new(vec![]), + }; + node + } else { + let node = FileTree { + full_path: file_path.clone(), + name: file_name.clone(), + children: match get_file_tree(source_path, Some(dir.path())) { + Ok(children) => children, + Err(_) => Box::new(vec![]), + }, + }; + node + } + }) + .collect(); + + Ok(Box::new(list)) +} + +pub fn get_request_ts_string(source_path: &str, path: &PathBuf) -> Result { + let project_config = get_project_config(source_path)?; + let sub_path = get_type_relative_path(source_path, project_config.types_path, path); + + let mut ts_string = format!("{}\n", project_config.header_template.clone()); + + let mut import_list: Vec = vec![]; + let mut export_list: Vec = vec![]; + + for dir in fs::read_dir(path)?.into_iter() { + let dir = dir?; + let file_type = dir.file_type()?; + let file_path = dir.path(); + let file_name_without_ext = get_file_name_without_ext(&file_path); + + if file_type.is_file() { + if check_file(&file_path, &file_name_without_ext) { + op_import_list( + project_config.type_import_template.clone(), + &sub_path, + &file_name_without_ext, + &mut import_list, + ); + op_export_list( + project_config.request_template.clone(), + &file_path, + &sub_path, + &mut export_list, + ); + } + } + } + + if import_list.len() == 0 && export_list.len() == 0 { + return Ok(String::new()); + } + + for str in import_list { + ts_string += str.as_str(); + } + + for str in export_list { + ts_string += str.as_str(); + } + + Ok(ts_string) +} + +pub fn write_request_ts_file( + source_path: &str, + path: &PathBuf, + content: String, +) -> Result<(), io::Error> { + let project_config = get_project_config(source_path)?; + let sub_path = get_type_relative_path(source_path, project_config.types_path, path); + let write_path = get_write_path( + project_config.request_path, + source_path, + project_config.file_name_template, + &sub_path, + ); + let parent = write_path.parent().unwrap(); + + fs::create_dir_all(parent)?; + + let mut file = fs::File::create(format!("{}.ts", write_path.to_str().unwrap()))?; + + file.write_all(content.as_bytes())?; + + Ok(()) +} + // 获取 type 文件的相对路径 -fn get_type_relative_path(&self, path: &PathBuf) -> Option { - let types_root_path = self.context.types_full_path.clone().unwrap(); +fn get_type_relative_path(source_path: &str, type_path: String, path: &PathBuf) -> Option { + let types_root_path = PathBuf::from(source_path).join(type_path); match path == &types_root_path { true => None, false => Some(path.strip_prefix(&types_root_path).unwrap().to_path_buf()), @@ -92,26 +218,30 @@ fn get_type_relative_path(&self, path: &PathBuf) -> Option { } // 获取写入 service 文件的路径 -fn get_write_path(&self, sub_path: &Option) -> PathBuf { +fn get_write_path( + request_path: String, + source_path: &str, + file_name_template: String, + sub_path: &Option, +) -> PathBuf { + let request_full_path = PathBuf::from(source_path).join(request_path); match &sub_path { Some(sub_path) => { - let mut write_path = self.request_full_path.clone().unwrap().join(&sub_path); + let mut write_path = request_full_path.join(&sub_path); - if let Some(template) = self.file_name_template.clone() { - if let Some(file_name) = write_path.file_name() { - let real_file_name = template.replace("$1", file_name.to_str().unwrap()); - write_path.set_file_name(real_file_name); - } + if let Some(file_name) = write_path.file_name() { + let real_file_name = file_name_template.replace("$1", file_name.to_str().unwrap()); + write_path.set_file_name(real_file_name); } write_path } - None => self.request_full_path.clone().unwrap().join("index"), + None => request_full_path.join("index"), } } // 检查生成service的 type 文件是否有 Request/Response interface -fn check_file(&self, file_path: &PathBuf, file_name_without_ext: &String) -> bool { +fn check_file(file_path: &PathBuf, file_name_without_ext: &String) -> bool { let req = format!("{}Request", get_legal_name(file_name_without_ext)); let resp = format!("{}Response", get_legal_name(file_name_without_ext)); @@ -121,14 +251,25 @@ fn check_file(&self, file_path: &PathBuf, file_name_without_ext: &String) -> boo false } +pub fn is_string_in_file(ts_file: &PathBuf, string: &str) -> bool { + let file = File::open(ts_file).unwrap(); + let reader = BufReader::new(file); + + for line in reader.lines() { + if line.unwrap().contains(string) { + return true; + } + } + false +} + // 把import ts 定义字符串添加进import_list fn op_import_list( type_import_template: String, sub_path: &Option, file_name: &String, -) -> Vec { - let mut import_list = vec![]; - + import_list: &mut Vec, +) { let sub_path_unix = get_sub_path_unix(sub_path); let import_string = type_import_template @@ -138,18 +279,15 @@ fn op_import_list( + "\n"; import_list.push(import_string); - - import_list } // 把export ts 定义字符串添加进export_list -fn get_export_list( +fn op_export_list( request_template: String, file_path: &PathBuf, sub_path: &Option, -) -> Vec { - let mut export_list = vec![]; - + export_list: &mut Vec, +) { let comment = get_comment(file_path.clone()); let sub_path_unix = get_sub_path_unix(sub_path); @@ -166,8 +304,6 @@ fn get_export_list( let export_string_with_comment = format!("{}\n{}", comment, export_string); export_list.push(export_string_with_comment); - - export_list } fn get_sub_path_unix(sub_path: &Option) -> String { diff --git a/src/routes/request/components/TypesTree.svelte b/src/routes/request/components/TypesTree.svelte index 45631ed..034e21e 100644 --- a/src/routes/request/components/TypesTree.svelte +++ b/src/routes/request/components/TypesTree.svelte @@ -8,6 +8,7 @@ import Button from '@smui/button'; import { confirm } from '@tauri-apps/api/dialog'; import Textfield from '@smui/textfield'; + import { invoke } from '@tauri-apps/api'; let full_list: TypesTree[] = []; let list: TypesTree[] = []; @@ -18,9 +19,8 @@ }); function get_data() { - request('get_request_list') - // @ts-expect-error - .then((res: SuccessResponse) => { + invoke>('load_file_tree') + .then((res) => { full_list = sort(res.data); list = sort(res.data); toast.push(JSON.stringify(res.message), toastTheme.success); @@ -65,7 +65,6 @@ const full_path = list.map((item) => item.full_path); request('update_request', { full_path }) - // @ts-expect-error .then((res: SuccessResponse) => { toast.push(JSON.stringify(res.message), toastTheme.success); }) From be80fdc675a3348642035ab2a3a8da50facce450 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Thu, 7 Mar 2024 21:02:13 +0800 Subject: [PATCH 17/43] feat: store config to svelte/store --- src/lib/store.ts | 28 ++++++++++++++++++- src/routes/type/+page.svelte | 22 +++++---------- src/routes/type/components/ConfigModal.svelte | 2 -- .../type/components/ProjectTab/index.svelte | 4 +-- 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/lib/store.ts b/src/lib/store.ts index 69c6496..9f07451 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -1,6 +1,32 @@ import { writable } from "svelte/store"; +import type { Config, SuccessResponse } from "./types/public"; +import { invoke } from "@tauri-apps/api"; +import { toast } from "@zerodevx/svelte-toast"; +import { toastTheme } from "./consts"; export let processingModalOpen = writable(false); export let processingModalTotal = writable(0); export let runningTask = writable(false) -export let sourcePath = writable("") \ No newline at end of file +export let sourcePath = writable("") +export let config = writable({ + base_url: "", + types_path: "", + project_list: [], + request_path: "", + request_template: "", + header_template: "", + file_name_template: "", + type_import_template: "", +}) + +export function loadProject(sourcePath: string) { + return invoke>('load_project_config', { sourcePath }) + .then((res) => { + toast.push(res.message, toastTheme.success); + config.set(res.data); + return res + }) + .catch((e) => { + toast.push(JSON.stringify(e), toastTheme.error); + }); +} \ No newline at end of file diff --git a/src/routes/type/+page.svelte b/src/routes/type/+page.svelte index a6e075c..6dc9317 100644 --- a/src/routes/type/+page.svelte +++ b/src/routes/type/+page.svelte @@ -1,31 +1,23 @@ {#if need_init} - + {/if} {#if load_project} - + {/if} diff --git a/src/routes/type/components/ConfigModal.svelte b/src/routes/type/components/ConfigModal.svelte index 5fe5f92..8501560 100644 --- a/src/routes/type/components/ConfigModal.svelte +++ b/src/routes/type/components/ConfigModal.svelte @@ -41,8 +41,6 @@ }) .then((res) => { toast.push(res.message, toastTheme.success); - // open = false; - // load_project = true; loadProject(); }) .catch((e) => { diff --git a/src/routes/type/components/ProjectTab/index.svelte b/src/routes/type/components/ProjectTab/index.svelte index 7e7972b..f606b29 100644 --- a/src/routes/type/components/ProjectTab/index.svelte +++ b/src/routes/type/components/ProjectTab/index.svelte @@ -7,12 +7,12 @@ import AddProjectModal from './AddProjectModal.svelte'; import ProcessingModal from './ProcessingModal.svelte'; import Project from './Project.svelte'; + import { config } from '@/store'; - export let config: Config | undefined; export let loadProject: () => void; let openAddModal = false; - $: project_list = config?.project_list || []; + $: project_list = $config?.project_list || []; let active: NonNullable[number] = { project_id: '', From 26c98c786870d9705aa822b45ccf0aa97817bc46 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Thu, 7 Mar 2024 21:30:17 +0800 Subject: [PATCH 18/43] refactor: Request UI --- src/lib/store.ts | 11 --------- src/lib/utils.ts | 17 ++++++++++--- src/routes/request/+page.svelte | 18 +++++--------- .../request/components/ConfigModal.svelte | 24 ++++++------------- .../request/components/TypesTree.svelte | 18 ++++++++------ src/routes/type/+page.svelte | 2 +- 6 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/lib/store.ts b/src/lib/store.ts index 9f07451..7a98eb7 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -19,14 +19,3 @@ export let config = writable({ type_import_template: "", }) -export function loadProject(sourcePath: string) { - return invoke>('load_project_config', { sourcePath }) - .then((res) => { - toast.push(res.message, toastTheme.success); - config.set(res.data); - return res - }) - .catch((e) => { - toast.push(JSON.stringify(e), toastTheme.error); - }); -} \ No newline at end of file diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 164d67f..2a72d2a 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,8 +1,8 @@ import { invoke } from "@tauri-apps/api/tauri"; -import type { SuccessResponse } from "./types/public"; +import type { Config, SuccessResponse } from "./types/public"; import { toast } from "@zerodevx/svelte-toast"; import { toastTheme } from "./consts"; -import { processingModalOpen, processingModalTotal } from "./store"; +import { config, processingModalOpen, processingModalTotal } from "./store"; export function request(name: string, data?: Record): any { let json = JSON.stringify(data); @@ -42,11 +42,22 @@ export function wop(node?: HTMLUListElement, params?: { duration?: number }) { }; } -export function startTask(){ +export function startTask() { invoke>('start_task').then((res) => { toast.push(res.message, toastTheme.success); processingModalOpen.update(() => true); processingModalTotal.update(() => res.data); }); +} +export function loadProject(sourcePath: string) { + return invoke>('load_project_config', { sourcePath }) + .then((res) => { + toast.push(res.message, toastTheme.success); + config.set(res.data); + return res + }) + .catch((e) => { + toast.push(JSON.stringify(e), toastTheme.error); + }); } \ No newline at end of file diff --git a/src/routes/request/+page.svelte b/src/routes/request/+page.svelte index f9c5ade..b7bad67 100644 --- a/src/routes/request/+page.svelte +++ b/src/routes/request/+page.svelte @@ -1,24 +1,18 @@ diff --git a/src/routes/request/components/ConfigModal.svelte b/src/routes/request/components/ConfigModal.svelte index 6e6debc..0599b71 100644 --- a/src/routes/request/components/ConfigModal.svelte +++ b/src/routes/request/components/ConfigModal.svelte @@ -7,6 +7,8 @@ import type { Config, SuccessResponse } from '@/types/public'; import Dialog, { Actions, Header, Content } from '@smui/dialog'; import Button, { Label } from '@smui/button'; + import { sourcePath } from '@/store'; + import { invoke } from '@tauri-apps/api'; export let open: boolean; export let load_types: boolean; @@ -42,9 +44,11 @@ return; } - request('update_global_config', form) - // @ts-expect-error - .then((res: SuccessResponse) => { + invoke>('update_project_config', { + sourcePath: $sourcePath, + data: form + }) + .then((res) => { toast.push(res.message, toastTheme.success); open = false; load_types = true; @@ -110,19 +114,5 @@
- - diff --git a/src/routes/request/components/TypesTree.svelte b/src/routes/request/components/TypesTree.svelte index 034e21e..fd5787e 100644 --- a/src/routes/request/components/TypesTree.svelte +++ b/src/routes/request/components/TypesTree.svelte @@ -9,6 +9,7 @@ import { confirm } from '@tauri-apps/api/dialog'; import Textfield from '@smui/textfield'; import { invoke } from '@tauri-apps/api'; + import { sourcePath } from '@/store'; let full_list: TypesTree[] = []; let list: TypesTree[] = []; @@ -19,7 +20,7 @@ }); function get_data() { - invoke>('load_file_tree') + invoke>('load_file_tree', { sourcePath: $sourcePath }) .then((res) => { full_list = sort(res.data); list = sort(res.data); @@ -97,16 +98,19 @@
- - +
-
+
{#each list as item} - + {/each}
diff --git a/src/routes/type/+page.svelte b/src/routes/type/+page.svelte index 6dc9317..e57dba5 100644 --- a/src/routes/type/+page.svelte +++ b/src/routes/type/+page.svelte @@ -2,7 +2,7 @@ import ConfigModal from './components/ConfigModal.svelte'; import ProjectTab from './components/ProjectTab/index.svelte'; import { sourcePath } from '@/store'; - import { loadProject as _loadProject } from '@/store'; + import { loadProject as _loadProject } from '@/utils'; let need_init = false; let load_project = false; From ca3ae4fd15453a975fea27cc05ae98f781575597 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Thu, 7 Mar 2024 23:05:56 +0800 Subject: [PATCH 19/43] feat: request module --- src-tauri/src/commands/yapi/request.rs | 39 ++++++- src-tauri/src/main.rs | 6 +- src-tauri/src/services/request.rs | 4 +- src/lib/store.ts | 6 +- src/lib/types/public.ts | 7 ++ .../request/components/CheckListModal.svelte | 79 ++++++++++++++ src/routes/request/components/Node.svelte | 57 +++++----- .../request/components/TypesTree.svelte | 100 ++++++++++++------ .../components/ProjectTab/Category.svelte | 3 + .../ProjectTab/ProcessingModal.svelte | 4 +- 10 files changed, 231 insertions(+), 74 deletions(-) create mode 100644 src/routes/request/components/CheckListModal.svelte diff --git a/src-tauri/src/commands/yapi/request.rs b/src-tauri/src/commands/yapi/request.rs index a1ed952..2ab173d 100644 --- a/src-tauri/src/commands/yapi/request.rs +++ b/src-tauri/src/commands/yapi/request.rs @@ -1,9 +1,15 @@ +use std::path::PathBuf; + use serde_json::json; use tauri::AppHandle; use crate::{ models::web_response::WebResponse, - services::{log::log_error, request::get_file_tree, yapi::config::get_project_config}, + services::{ + log::log_error, + request::{get_file_tree, get_request_ts_string, write_request_ts_file}, + yapi::config::get_project_config, + }, }; #[tauri::command] @@ -16,3 +22,34 @@ pub fn load_file_tree(source_path: &str, app_handle: AppHandle) -> Result log_error(&app_handle, err.to_string()), } } + +#[tauri::command] +pub fn get_request_string( + source_path: &str, + app_handle: AppHandle, + path: &str, +) -> Result { + match get_request_ts_string(source_path, &PathBuf::from(path)) { + Ok(request_string) => Ok(WebResponse { + data: Some(json!(request_string)), + message: "获取请求字符串成功".to_string(), + }), + Err(err) => log_error(&app_handle, err.to_string()), + } +} + +#[tauri::command] +pub fn write_request_to_file( + source_path: &str, + app_handle: AppHandle, + path: &str, + content: String, +) -> Result { + match write_request_ts_file(source_path, &PathBuf::from(path), content) { + Ok(_) => Ok(WebResponse { + data: None, + message: "写入文件成功".to_string(), + }), + Err(err) => log_error(&app_handle, err.to_string()), + } +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 91a17f2..303beb3 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -24,7 +24,7 @@ use crate::commands::{ yapi::config::{load_project_config, update_project_config}, yapi::interface::{add_interface_task, cancel_task, start_task, write_to_file}, yapi::project::{get_yapi_project_base_info, get_yapi_project_cat_menu}, - yapi::request::load_file_tree, + yapi::request::{get_request_string, load_file_tree, write_request_to_file}, }; pub mod commands; @@ -135,7 +135,9 @@ fn main() { cancel_task, write_to_file, load_global_config, - load_file_tree + load_file_tree, + get_request_string, + write_request_to_file ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/services/request.rs b/src-tauri/src/services/request.rs index ab0cb86..56f3d86 100644 --- a/src-tauri/src/services/request.rs +++ b/src-tauri/src/services/request.rs @@ -217,7 +217,7 @@ fn get_type_relative_path(source_path: &str, type_path: String, path: &PathBuf) } } -// 获取写入 service 文件的路径 +// 获取写入 request 文件的路径 fn get_write_path( request_path: String, source_path: &str, @@ -240,7 +240,7 @@ fn get_write_path( } } -// 检查生成service的 type 文件是否有 Request/Response interface +// 检查用于生成 request 的 type 文件是否有 Request/Response interface fn check_file(file_path: &PathBuf, file_name_without_ext: &String) -> bool { let req = format!("{}Request", get_legal_name(file_name_without_ext)); let resp = format!("{}Response", get_legal_name(file_name_without_ext)); diff --git a/src/lib/store.ts b/src/lib/store.ts index 7a98eb7..331f808 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -1,12 +1,8 @@ import { writable } from "svelte/store"; -import type { Config, SuccessResponse } from "./types/public"; -import { invoke } from "@tauri-apps/api"; -import { toast } from "@zerodevx/svelte-toast"; -import { toastTheme } from "./consts"; +import type { Config } from "./types/public"; export let processingModalOpen = writable(false); export let processingModalTotal = writable(0); -export let runningTask = writable(false) export let sourcePath = writable("") export let config = writable({ base_url: "", diff --git a/src/lib/types/public.ts b/src/lib/types/public.ts index 5c8a23e..1dfba18 100644 --- a/src/lib/types/public.ts +++ b/src/lib/types/public.ts @@ -50,4 +50,11 @@ export interface TypesTree { full_path: string name: string children: TypesTree[] +} + +export interface RequestString { + full_path: string + name: string + content: string + checked: boolean } \ No newline at end of file diff --git a/src/routes/request/components/CheckListModal.svelte b/src/routes/request/components/CheckListModal.svelte new file mode 100644 index 0000000..01cef70 --- /dev/null +++ b/src/routes/request/components/CheckListModal.svelte @@ -0,0 +1,79 @@ + + + +
+ 日志 + +
+ +
请勾选想要生成 ts 类型的接口:
+
+ {#each checkList as log} +
+ + {log.name} + {log.full_path} +
+ {/each} +
+ +
+ +
+
+
+ + diff --git a/src/routes/request/components/Node.svelte b/src/routes/request/components/Node.svelte index cad2a93..fbf6e94 100644 --- a/src/routes/request/components/Node.svelte +++ b/src/routes/request/components/Node.svelte @@ -1,63 +1,64 @@
- {#if children.length} + {#if data.children.length} + {/if}
{#if expanded}
    - {#each children as child} + {#each data.children as child}
  • diff --git a/src/routes/request/components/TypesTree.svelte b/src/routes/request/components/TypesTree.svelte index fd5787e..c31d7ba 100644 --- a/src/routes/request/components/TypesTree.svelte +++ b/src/routes/request/components/TypesTree.svelte @@ -1,7 +1,6 @@ +
    -
    对应的接口树:
    - +
    根据文件夹架构生成request:
    +
    + + +
    - {#each list as item} - + {#each filtered_list as item} + {/each}
    diff --git a/src/routes/type/components/ProjectTab/Category.svelte b/src/routes/type/components/ProjectTab/Category.svelte index 603a4d2..6bd5e81 100644 --- a/src/routes/type/components/ProjectTab/Category.svelte +++ b/src/routes/type/components/ProjectTab/Category.svelte @@ -8,6 +8,7 @@ import Tooltip, { Wrapper } from '@smui/tooltip'; import { invoke } from '@tauri-apps/api'; import type { CategoryDataList } from '@/types/yapi'; + import { startTask } from '@/utils'; export let data: CategoryType; export let token: string; @@ -39,6 +40,8 @@ } }); } + + startTask(); } catch (e) { toast.push(JSON.stringify(e), toastTheme.error); } diff --git a/src/routes/type/components/ProjectTab/ProcessingModal.svelte b/src/routes/type/components/ProjectTab/ProcessingModal.svelte index d164b4e..29a099d 100644 --- a/src/routes/type/components/ProjectTab/ProcessingModal.svelte +++ b/src/routes/type/components/ProjectTab/ProcessingModal.svelte @@ -3,7 +3,6 @@ import Dialog, { Title, Content, Header } from '@smui/dialog'; import { onDestroy, onMount } from 'svelte'; import { - runningTask, processingModalOpen, processingModalTotal, sourcePath @@ -61,11 +60,10 @@ checkList = []; $processingModalTotal = 0; progress.set(0); - runningTask.update(() => false); } function onConfirm() { - const confirmed = confirm('操作将重新生成ts文件,请确保本地代码已经保存!'); + const confirmed = confirm('操作将重新生成文件,请确保本地代码已经保存!'); if (!confirmed) return; From f06718a717675f0450a2d4c4dcd620888b93e36f Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Thu, 7 Mar 2024 23:06:43 +0800 Subject: [PATCH 20/43] refactor: simgle interface add to task --- .../components/ProjectTab/Interface.svelte | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/src/routes/type/components/ProjectTab/Interface.svelte b/src/routes/type/components/ProjectTab/Interface.svelte index 202186f..fcae82d 100644 --- a/src/routes/type/components/ProjectTab/Interface.svelte +++ b/src/routes/type/components/ProjectTab/Interface.svelte @@ -1,41 +1,22 @@ @@ -51,7 +32,10 @@ role="button" tabindex="0" > - 更新接口 + + 更新接口 + 更新接口 +
From dccd33149927d81e08ea05bb027364ad9dbc6026 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Thu, 7 Mar 2024 23:35:47 +0800 Subject: [PATCH 21/43] feat: queue restore initial state after task completed --- src-tauri/src/models/yapi/queue.rs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src-tauri/src/models/yapi/queue.rs b/src-tauri/src/models/yapi/queue.rs index 9dae8bf..77d3e51 100644 --- a/src-tauri/src/models/yapi/queue.rs +++ b/src-tauri/src/models/yapi/queue.rs @@ -28,7 +28,6 @@ pub struct ResolvedInterface { pub struct Queue { pub semaphore: Arc, pub waiting_queue: Arc>>, - pub total_count: Arc>, pub running: Arc, pub app_handle: Arc>, } @@ -52,8 +51,7 @@ impl Queue { Queue { semaphore: Arc::new(Semaphore::new(global_config.rate_limit)), waiting_queue: Arc::new(Mutex::new(VecDeque::new())), - running: Arc::new(AtomicBool::new(true)), - total_count: Arc::new(Mutex::new(0)), + running: Arc::new(AtomicBool::new(false)), app_handle: Arc::new(Mutex::new(app_handle.clone())), } } @@ -64,15 +62,12 @@ impl Queue { .await .push_back(interface_fetch_params); - self.running.store(true, Ordering::Release); + self.running.store(true, Ordering::Release); } pub async fn cancel_execute(&self) { self.running.store(false, Ordering::Relaxed); - } - - pub async fn clear(&self) { - *self.total_count.lock().await = 0; + self.clear().await; } pub async fn start_execute(&self, app_handle: &AppHandle) { @@ -128,6 +123,7 @@ impl Queue { } sleep(Duration::from_secs(global_config.break_seconds)).await; + // 补充一个令牌 sem.add_permits(1); }); @@ -135,11 +131,17 @@ impl Queue { None => { self.running.store(false, Ordering::Relaxed); self.clear().await; + // 补充一个令牌 + sem.add_permits(1); } } } } + async fn clear(&self) { + self.waiting_queue.lock().await.clear(); + } + async fn acquire(&self) { let permit = self.semaphore.acquire().await.unwrap(); permit.forget(); From b7f8898ac2cdbb81e267c20049602fbacf5a96e4 Mon Sep 17 00:00:00 2001 From: soul <1041707577@qq.com> Date: Fri, 8 Mar 2024 15:25:33 +0800 Subject: [PATCH 22/43] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E6=97=A5=E5=BF=97=E7=9B=AE=E5=BD=95=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=98=BE=E7=A4=BA=E5=9C=A8?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E4=B8=8A=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此更改向现有表单页面添加了一个变量,以存储通过异步函数获取的应用程序日志目录路径,并在页面上显示。这使用户能够直接查看应用程序日志目录路径,提高了用户体验和访问信息的便捷性。 --- src/routes/config/+page.svelte | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/routes/config/+page.svelte b/src/routes/config/+page.svelte index 3398c52..2eaf5e2 100644 --- a/src/routes/config/+page.svelte +++ b/src/routes/config/+page.svelte @@ -4,10 +4,10 @@ import { toast } from '@zerodevx/svelte-toast'; import Tooltip, { Wrapper } from '@smui/tooltip'; import Textfield from '@smui/textfield'; - import { onMount } from 'svelte'; import { sourcePath } from '@/store'; import { invoke } from '@tauri-apps/api'; + import { appLogDir } from '@tauri-apps/api/path'; let initProjectConfig: Config = { base_url: '', @@ -24,6 +24,7 @@ rate_limit: 5, break_seconds: 1 }; + let appLogDirPath = '' let projectConfig = initProjectConfig; let globalConfig = initGlobalConfig; @@ -41,6 +42,10 @@ projectConfig = res.data; } ); + + appLogDir().then(res => { + appLogDirPath = res + }); }); function update_project_config() { @@ -201,6 +206,8 @@ }} > + + {appLogDirPath} diff --git a/src/routes/request/components/TypesTree.svelte b/src/routes/request/components/TypesTree.svelte index 8b9764c..51333f9 100644 --- a/src/routes/request/components/TypesTree.svelte +++ b/src/routes/request/components/TypesTree.svelte @@ -80,7 +80,9 @@ await fetch(node.full_path || '', node.name); check_list_modal_open = true; } else { - await fetch($config.types_path || '', 'root.ts'); + if (!isExistFileInRootPath()) return toast.push('根目录下没有类型文件'); + + await fetch(`${$sourcePath}/${$config.types_path}` || '', 'index'); check_list_modal_open = true; } } @@ -90,18 +92,38 @@ await fetch(node.full_path || '', node.name); if (node.children) { for (let subNode of node.children) { - await update_request_recursive(subNode); + await recur(subNode); } } check_list_modal_open = true; } else { - await fetch($config.types_path || '', 'root.ts'); + if (isExistFileInRootPath()) { + await fetch(`${$sourcePath}/${$config.types_path}` || '', 'index'); + } + for (let subNode of full_list) { await update_request_recursive(subNode); } check_list_modal_open = true; } + + async function recur(node: TypesTree) { + if (!node.children.length) { + return; + } + + await fetch(node.full_path || '', node.name); + if (node.children) { + for (let subNode of node.children) { + await recur(subNode); + } + } + } + } + + function isExistFileInRootPath() { + return !!full_list.find((type) => !type.children.length); } async function fetch(path: string, name: string) { @@ -113,7 +135,7 @@ full_path: path, checked: true }); - over_list = over_list + over_list = over_list; }) .catch((e) => { toast.push(JSON.stringify(e), toastTheme.error); @@ -121,7 +143,6 @@ } -
From 9e01de7f1908cb98a7f31f47f2651f0cf2183104 Mon Sep 17 00:00:00 2001 From: soul <104170577@qq.com> Date: Sat, 9 Mar 2024 13:58:09 +0800 Subject: [PATCH 42/43] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=8A=9F=E8=83=BD=EF=BC=8C=E5=85=81=E8=AE=B8?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=9F=A5=E7=9C=8B=E7=94=9F=E6=88=90=E7=9A=84?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=EF=BC=8C=E6=8F=90=E5=8D=87=E4=BA=86=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E4=BD=93=E9=AA=8C=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/commands/yapi/interface.rs | 30 ++++++++++---- src/lib/types/yapi.ts | 13 +++--- .../ProjectTab/AddInterfaceModal.svelte | 2 +- .../components/ProjectTab/Interface.svelte | 41 +++++++++++++++++-- 4 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src-tauri/src/commands/yapi/interface.rs b/src-tauri/src/commands/yapi/interface.rs index ed7ee9e..5357cd4 100644 --- a/src-tauri/src/commands/yapi/interface.rs +++ b/src-tauri/src/commands/yapi/interface.rs @@ -6,7 +6,12 @@ use crate::{ web_response::WebResponse, yapi::{interface::InterfaceFetchParams, queue::Queue}, }, - services::{log::log_error, yapi::interface::{fetch_interface_detail, write_content_to_interface_path}}, + services::{ + log::log_error, + yapi::interface::{ + fetch_interface_detail, get_interface_ts_string, write_content_to_interface_path, + }, + }, }; #[tauri::command] @@ -67,14 +72,21 @@ pub fn write_to_file( } #[tauri::command] -pub async fn get_interface_detail( app_handle: AppHandle ,data: InterfaceFetchParams) -> Result { - match fetch_interface_detail(data , &app_handle).await { +pub async fn get_interface_detail( + app_handle: AppHandle, + data: InterfaceFetchParams, +) -> Result { + match fetch_interface_detail(data, &app_handle).await { Err(e) => log_error(&app_handle, e.to_string()), - Ok(res) => { - Ok(WebResponse { - data: Some(json!(res)), + Ok(res) => match get_interface_ts_string(&res) { + Ok(ts) => Ok(WebResponse { + data: Some(json!({ + "interface_data" : res, + "ts": ts + })), message: "获取成功".to_string(), - }) - } + }), + Err(e) => log_error(&app_handle, e.to_string()), + }, } -} \ No newline at end of file +} diff --git a/src/lib/types/yapi.ts b/src/lib/types/yapi.ts index 4914a96..55ae94a 100644 --- a/src/lib/types/yapi.ts +++ b/src/lib/types/yapi.ts @@ -17,11 +17,14 @@ export type CategoryDataList = { } export type InterfaceDataItem = { - _id: number, - catid: number, - title: string, - path: string, - project_id?: number; + interface_data: { + _id: number, + catid: number, + title: string, + path: string, + project_id?: number; + }, + ts: string } export type QueueLog = { diff --git a/src/routes/type/components/ProjectTab/AddInterfaceModal.svelte b/src/routes/type/components/ProjectTab/AddInterfaceModal.svelte index fb86850..281d0f3 100644 --- a/src/routes/type/components/ProjectTab/AddInterfaceModal.svelte +++ b/src/routes/type/components/ProjectTab/AddInterfaceModal.svelte @@ -37,7 +37,7 @@ interface_id: Number(form.interface_id) } } - ).then((res) => res.data); + ).then((res) => res.data.interface_data); if (isCategoryExist(interfaceDataItem.catid, categories)) { toast.push(`接口所在分类已存在`, toastTheme.success); diff --git a/src/routes/type/components/ProjectTab/Interface.svelte b/src/routes/type/components/ProjectTab/Interface.svelte index e4b5896..1f962f0 100644 --- a/src/routes/type/components/ProjectTab/Interface.svelte +++ b/src/routes/type/components/ProjectTab/Interface.svelte @@ -1,9 +1,12 @@
{data.name}
-
+
update_interface(data.id)} @@ -33,14 +51,29 @@ tabindex="0" > - 更新接口 + 更新接口 更新接口
+