diff --git a/cmd/server.go b/cmd/server.go index cc38545..c634677 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -9,14 +9,16 @@ var serverCmd = &cobra.Command{ Use: "server", Short: "启动 web 服务", Run: func(cmd *cobra.Command, args []string) { - server.Serve(Port, Silent) + server.Serve(port, silent, prefix) }, } -var Port string -var Silent bool +var port int +var silent bool +var prefix string func init() { - serverCmd.Flags().StringVarP(&Port, "port", "p", "7172", "指定端口") - serverCmd.Flags().BoolVarP(&Silent, "silent", "s", false, "静默启动") + serverCmd.Flags().IntVarP(&port, "port", "p", 7007, "指定端口") + serverCmd.Flags().BoolVarP(&silent, "silent", "s", false, "静默启动") + serverCmd.Flags().StringVarP(&prefix, "prefix", "d", "", "工作目录") } diff --git a/frontend/bun.lockb b/frontend/bun.lockb index be057d0..5adee1a 100644 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/components.d.ts b/frontend/components.d.ts index a9d6813..b082a1d 100644 --- a/frontend/components.d.ts +++ b/frontend/components.d.ts @@ -16,15 +16,20 @@ declare module "@vue/runtime-core" { CollisionDistBar: (typeof import("./src/components/Result/CollisionDistBar.vue"))["default"]; CombsDescription: (typeof import("./src/components/Result/CombsDescription.vue"))["default"]; CombsDistBar: (typeof import("./src/components/Result/CombsDistBar.vue"))["default"]; + Compare: (typeof import("./src/components/Compare.vue"))["default"]; ComparedBars: (typeof import("./src/components/Result/comparedBars.vue"))["default"]; + Data: (typeof import("./src/components/Data.vue"))["default"]; FingerPie: (typeof import("./src/components/Result/FingerPie.vue"))["default"]; FingersDescription: (typeof import("./src/components/Result/FingersDescription.vue"))["default"]; HandComp: (typeof import("./src/components/Result/HandComp.vue"))["default"]; HandsDescription: (typeof import("./src/components/Result/HandsDescription.vue"))["default"]; KeyHeatSorted: (typeof import("./src/components/Result/KeyHeatSorted.vue"))["default"]; Main: (typeof import("./src/components/Main.vue"))["default"]; + MultiResult: (typeof import("./src/components/MultiResult.vue"))["default"]; NButton: (typeof import("naive-ui"))["NButton"]; NCard: (typeof import("naive-ui"))["NCard"]; + NDescriptions: (typeof import("naive-ui"))["NDescriptions"]; + NDescriptionsItem: (typeof import("naive-ui"))["NDescriptionsItem"]; NDivider: (typeof import("naive-ui"))["NDivider"]; NDrawer: (typeof import("naive-ui"))["NDrawer"]; NDrawerContent: (typeof import("naive-ui"))["NDrawerContent"]; @@ -36,6 +41,7 @@ declare module "@vue/runtime-core" { NRadio: (typeof import("naive-ui"))["NRadio"]; NRadioGroup: (typeof import("naive-ui"))["NRadioGroup"]; NSelect: (typeof import("naive-ui"))["NSelect"]; + NSpace: (typeof import("naive-ui"))["NSpace"]; NSwitch: (typeof import("naive-ui"))["NSwitch"]; NTag: (typeof import("naive-ui"))["NTag"]; NText: (typeof import("naive-ui"))["NText"]; @@ -44,6 +50,7 @@ declare module "@vue/runtime-core" { Result: (typeof import("./src/components/Result/Result.vue"))["default"]; ResultBasic: (typeof import("./src/components/Result/ResultBasic.vue"))["default"]; ResultKeyHeat: (typeof import("./src/components/Result/ResultKeyHeat.vue"))["default"]; + Show: (typeof import("./src/components/Show.vue"))["default"]; Text: (typeof import("./src/components/Text.vue"))["default"]; WordsDescription: (typeof import("./src/components/Result/WordsDescription.vue"))["default"]; WordsDistBar: (typeof import("./src/components/Result/WordsDistBar.vue"))["default"]; diff --git a/frontend/src/components/Data.ts b/frontend/src/components/Data.ts new file mode 100644 index 0000000..49b6897 --- /dev/null +++ b/frontend/src/components/Data.ts @@ -0,0 +1,75 @@ +// Generated by https://quicktype.io + +export interface Data { + Info: Info; + Commit: Commit; + Pair: Pair; + Keys: { [key: string]: Key }; + Han: Han; + Dist: Dist; + CodeLen: CodeLen; + LeftHand: number; + RightHand: number; + Equivalent: number; +} + +export interface CodeLen { + Total: number; + PerChar: number; +} + +export interface Commit { + Count: number; + Word: number; + WordChars: number; + WordFirst: number; + Collision: number; + CollisionChars: number; +} + +export interface Dist { + CodeLen: number[]; + WordLen: number[]; + Collision: number[]; + Finger: number[]; +} + +export interface Han { + NotHan: string; + NotHans: number; + NotHanCount: number; + Lack: string; + Lacks: number; + LackCount: number; +} + +export interface Info { + TextName: string; + TextLen: number; + DictName: string; + DictLen: number; + Single: boolean; +} + +export interface Key { + Count: number; + Rate: number; +} + +export interface Pair { + Count: number; + SameFinger: number; + DoubleHit: number; + TribleHit: number; + SingleSpan: number; + MultiSpan: number; + Staggered: number; + Disturb: number; + LeftToLeft: number; + LeftToRight: number; + RightToLeft: number; + RightToRight: number; + DiffFinger: number; + SameHand: number; + DiffHand: number; +} diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index ee381fa..bbaa4da 100644 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -1,10 +1,9 @@ + + + + diff --git a/frontend/src/components/Result/Result.vue b/frontend/src/components/Result/Result.vue index ed511c5..96ddf0d 100644 --- a/frontend/src/components/Result/Result.vue +++ b/frontend/src/components/Result/Result.vue @@ -28,22 +28,22 @@ import CollisionDistBar from "./CollisionDistBar.vue"; import CodeLenDistBar from "./CodeLenDistBar.vue"; import CombsDistBar from "./CombsDistBar.vue"; import KeyHeatSorted from "./KeyHeatSorted.vue"; +import { Data } from "../Data"; -const p = defineProps(["data1", "data2"]); -const d1 = ref(p.data1); -const d2 = ref(p.data2); -watch(p, () => { - d1.value = p.data1; - d2.value = p.data2; -}); +const props = defineProps<{ + data1: Data; + data2: Data; +}>(); +const d1 = computed(() => props.data1); +const d2 = computed(() => props.data2); function shiftEmptyItems(schema: any) { schema.Words.Dist.shift(); schema.Collision.Dist.shift(); schema.CodeLen.Dist.shift(); } -shiftEmptyItems(p.data1); -shiftEmptyItems(p.data2); +shiftEmptyItems(d1); +shiftEmptyItems(d2); const isStraightKeyboard = ref(false); const logYAxis = ref(false); provide("logY", logYAxis); @@ -54,7 +54,7 @@ provide("schema2", d2); 赛码报告 - {{ p.data1.DictName }} VS {{ p.data2.DictName }} + {{ d1.Info.DictName }} VS {{ d1.Info.DictName }} 本报告中的条形图是否使用对数坐标轴?
@@ -62,9 +62,9 @@ provide("schema2", d2); 码表基本信息 - + - @@ -72,10 +72,10 @@ provide("schema2", d2); - + - + @@ -85,9 +85,9 @@ provide("schema2", d2); 打词 - + - + @@ -97,10 +97,10 @@ provide("schema2", d2); - + - + @@ -117,10 +117,10 @@ provide("schema2", d2); - - + @@ -129,8 +129,8 @@ provide("schema2", d2); 手指组合 - - + + @@ -139,10 +139,10 @@ provide("schema2", d2); 手指使用量 - + - + @@ -150,10 +150,10 @@ provide("schema2", d2); 双手使用量 - - - - + + + + diff --git a/frontend/src/components/Show.vue b/frontend/src/components/Show.vue new file mode 100644 index 0000000..eeb2273 --- /dev/null +++ b/frontend/src/components/Show.vue @@ -0,0 +1,84 @@ + + diff --git a/frontend/src/components/Text.vue b/frontend/src/components/Text.vue index 9df9594..177699d 100644 --- a/frontend/src/components/Text.vue +++ b/frontend/src/components/Text.vue @@ -11,8 +11,11 @@ export interface TextConfig { index: number | null; text: string | null; } - -const props = defineProps(["_type", "configList", "files"]); +const props = defineProps<{ + _type: "text" | "dict"; + configList: Array; + files: { text: string[]; dict: string[] }; +}>(); const emit = defineEmits<{ (e: "remove", idx: number): void; (e: "add", value: TextConfig): void; @@ -26,7 +29,6 @@ const srcOptions = [ { label: "剪切板", value: "clipboard" }, ]; -const route = "api/"; const conf = reactive({ source: "local" } as TextConfig); watch(conf, () => { emit("update", conf); @@ -35,7 +37,7 @@ watch(conf, () => { watch( () => conf.path, () => { - conf.name = conf.path?.replace(".txt", "") || ""; + conf.name = tidyPath(conf.path || ""); }, ); @@ -43,12 +45,22 @@ const _Type = computed(() => { return props._type === "text" ? "文章" : "码表"; }); +function tidyPath(path: string) { + const index = path.lastIndexOf(props._type); + let name = path; + if (index > 0) { + name = path.substring(index + 5); + } + name = name.replace(".txt", ""); + return name; +} + const opts = computed(() => { const tmp = props.files[props._type] as string[]; - return tmp.map((name: string) => { + return tmp.map((path: string) => { return { - label: name.replace(".txt", ""), - value: name, + label: tidyPath(path), + value: path, }; }); }); @@ -70,7 +82,7 @@ function upload(options: { file: UploadFileInfo; fileList: Array return; } - fetch(route + "file_index", { + fetch("/file_index", { method: "GET", }) .then((res) => { @@ -147,7 +159,7 @@ function add(value: TextConfig) {
- +
diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 379ea33..7d0c43d 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -22,10 +22,9 @@ export default defineConfig({ ], server: { proxy: { - "/api": { + "^/(list|upload|file_index|race)": { target: "http://127.0.0.1:7007", changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ""), }, }, }, diff --git a/main.go b/main.go index f2a2056..d22c505 100644 --- a/main.go +++ b/main.go @@ -11,7 +11,7 @@ func main() { _ = os.MkdirAll("dict", os.ModePerm) _ = os.MkdirAll("text", os.ModePerm) if len(os.Args) < 2 { - server.Serve("7007", false) + server.Serve(7007, false, "") } else { cmd.Execute() } diff --git a/pkg/server/server.go b/pkg/server/server.go index 37095c1..9a7218f 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -8,6 +8,7 @@ import ( "io" "io/fs" "net/http" + "path/filepath" "strconv" "sync" @@ -20,7 +21,7 @@ var dist embed.FS // 上传的文件列表 var files [][]byte = make([][]byte, 0) -func Serve(port string, silent bool) { +func Serve(port int, silent bool, prefix string) { mux := http.NewServeMux() dist, _ := fs.Sub(dist, "dist") mux.Handle("GET /", http.FileServer(http.FS(dist))) @@ -31,10 +32,8 @@ func Serve(port string, silent bool) { Text []string `json:"text"` Dict []string `json:"dict"` } - // text := util.WalkDirWithSuffix("./text/", ".txt") - // dict := util.WalkDirWithSuffix("./dict/", ".txt") - text := util.WalkDirWithSuffix(`D:\Code\go\gosmq\build\text`, ".txt") - dict := util.WalkDirWithSuffix(`D:\Code\go\gosmq\build\dict`, ".txt") + text := util.WalkDirWithSuffix(filepath.Join(prefix, "text"), ".txt") + dict := util.WalkDirWithSuffix(filepath.Join(prefix, "dict"), ".txt") res := Result{Text: text, Dict: dict} json.NewEncoder(w).Encode(res) @@ -73,7 +72,6 @@ func Serve(port string, silent bool) { setHeader(&w) logger.Info("POST /race") data := r.FormValue("data") - fmt.Printf(" data: %v\n", data) d := &Data{} err := json.Unmarshal([]byte(data), d) @@ -87,11 +85,12 @@ func Serve(port string, silent bool) { var wg sync.WaitGroup wg.Add(1) - port = ":" + port - url := "http://localhost" + port + + url := fmt.Sprintf("http://localhost:%d", port) go func() { fmt.Println("Listen and serve: ", url) - err := http.ListenAndServe(port, mux) + addr := ":" + strconv.Itoa(port) + err := http.ListenAndServe(addr, mux) if err != nil { fmt.Println(err) panic("...Serve failed.") diff --git a/pkg/server/server_test.go b/pkg/server/server_test.go index b1167cd..021f6bf 100644 --- a/pkg/server/server_test.go +++ b/pkg/server/server_test.go @@ -3,5 +3,5 @@ package server import "testing" func TestServer(t *testing.T) { - Serve("7007", false) + Serve(7008, false, `D:\Code\go\gosmq\build`) }