From 5ef3c9b0795dc7feb905d3aefcc1a1c650a3f6c8 Mon Sep 17 00:00:00 2001 From: nopdan Date: Tue, 12 Mar 2024 21:42:26 +0800 Subject: [PATCH] refactor: fix @yb6b 's result page --- frontend/bun.lockb | Bin 73912 -> 79840 bytes frontend/components.d.ts | 2 + frontend/src/App.vue | 22 +- frontend/src/components/Data.ts | 173 ++++++++++++++++ frontend/src/components/Main.vue | 241 ++++++++++++++++------ frontend/src/components/MultiResult.vue | 58 ++---- frontend/src/components/OldData.ts | 73 +++++++ frontend/src/components/Result/Result.vue | 46 ++++- frontend/src/components/Show.vue | 73 ++----- pkg/server/race.go | 64 +++--- pkg/server/server.go | 6 +- 11 files changed, 557 insertions(+), 201 deletions(-) create mode 100644 frontend/src/components/OldData.ts diff --git a/frontend/bun.lockb b/frontend/bun.lockb index 5adee1a82035e5b0c6d8a41375d665582062f33e..9486ed412a90ad1c308b46812483a211ada1e921 100644 GIT binary patch delta 8086 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
+
昙花赛码器
@@ -13,7 +14,26 @@ import Main from "./components/Main.vue"; diff --git a/frontend/src/components/Data.ts b/frontend/src/components/Data.ts index 3dcc6c3..d0990b3 100644 --- a/frontend/src/components/Data.ts +++ b/frontend/src/components/Data.ts @@ -1,5 +1,7 @@ // Generated by https://quicktype.io +import { OldData } from "./OldData"; + export interface Data { Info: Info; Commit: Char; @@ -67,3 +69,174 @@ export interface Pair { SameHand: number; DiffHand: number; } + +export class DataUtils { + data: Data; + constructor(data: Data) { + this.data = data; + } + _commitRate(count: number): number { + return count / this.data.Commit.Count; + } + _charRate(count: number): number { + return count / this.data.Char.Count; + } + _keyRate(count: number): number { + return count / this.data.Keys.Count; + } + _pairRate(count: number): number { + return count / this.data.Pair.Count; + } + + commitRate(count: number, fixed = 2): string { + return (this._commitRate(count) * 100).toFixed(fixed) + "%"; + } + + charRate(count: number, fixed = 2): string { + return (this._charRate(count) * 100).toFixed(fixed) + "%"; + } + + keyRate(count: number, fixed = 2): string { + return (this._keyRate(count) * 100).toFixed(fixed) + "%"; + } + + pairRate(count: number, fixed = 2): string { + return (this._pairRate(count) * 100).toFixed(fixed) + "%"; + } +} + +export function New2Old(_new: Data): OldData { + const util = new DataUtils(_new); + const _old: OldData = { + TextName: _new.Info.TextName, + TextLen: _new.Info.TextLen, + DictName: _new.Info.DictName, + DictLen: _new.Info.DictLen, + Single: _new.Info.Single, + Basic: { + NotHan: _new.Han.NotHan, + NotHans: _new.Han.NotHans, + NotHanCount: _new.Han.NotHanCount, + Lack: _new.Han.Lack, + Lacks: _new.Han.Lacks, + LackCount: _new.Han.LackCount, + Commits: _new.Commit.Count, + }, + Words: { + Commits: { + Count: _new.Commit.Word, + Rate: util._commitRate(_new.Commit.Word), + }, + Chars: { + Count: _new.Char.Word, + Rate: util._charRate(_new.Char.Word), + }, + Dist: _new.Dist.WordLen, + }, + Collision: { + Commits: { + Count: _new.Commit.Collision, + Rate: util._commitRate(_new.Commit.Collision), + }, + Chars: { + Count: _new.Char.Collision, + Rate: util._charRate(_new.Char.Collision), + }, + Dist: _new.Dist.Collision, + }, + CodeLen: { + Total: _new.Keys.Count, + PerChar: _new.Keys.CodeLen, + Dist: _new.Dist.CodeLen, + }, + Keys: {}, + Combs: { + Count: _new.Pair.Count, + Equivalent: util._pairRate(_new.Pair.Equivalent), + DoubleHit: { + Count: _new.Pair.DoubleHit, + Rate: util._pairRate(_new.Pair.DoubleHit), + }, + TribleHit: { + Count: _new.Pair.TribleHit, + Rate: util._pairRate(_new.Pair.TribleHit), + }, + SingleSpan: { + Count: _new.Pair.SingleSpan, + Rate: util._pairRate(_new.Pair.SingleSpan), + }, + MultiSpan: { + Count: _new.Pair.MultiSpan, + Rate: util._pairRate(_new.Pair.MultiSpan), + }, + LongFingersDisturb: { + Count: _new.Pair.Staggered, + Rate: util._pairRate(_new.Pair.Staggered), + }, + LittleFingersDisturb: { + Count: _new.Pair.Disturb, + Rate: util._pairRate(_new.Pair.Disturb), + }, + }, + Fingers: { + Dist: [], + Same: { + Count: _new.Pair.SameFinger, + Rate: util._pairRate(_new.Pair.SameFinger), + }, + Diff: { + Count: _new.Pair.DiffFinger, + Rate: util._pairRate(_new.Pair.DiffFinger), + }, + }, + Hands: { + Left: { + Count: _new.Keys.LeftHand, + Rate: util._keyRate(_new.Keys.LeftHand), + }, + Right: { + Count: _new.Keys.RightHand, + Rate: util._keyRate(_new.Keys.RightHand), + }, + Same: { + Count: _new.Pair.SameHand, + Rate: util._pairRate(_new.Pair.SameHand), + }, + Diff: { + Count: _new.Pair.DiffHand, + Rate: util._pairRate(_new.Pair.DiffHand), + }, + LeftToLeft: { + Count: _new.Pair.LeftToLeft, + Rate: util._pairRate(_new.Pair.LeftToLeft), + }, + LeftToRight: { + Count: _new.Pair.LeftToRight, + Rate: util._pairRate(_new.Pair.LeftToRight), + }, + RightToLeft: { + Count: _new.Pair.RightToLeft, + Rate: util._pairRate(_new.Pair.RightToLeft), + }, + RightToRight: { + Count: _new.Pair.RightToRight, + Rate: util._pairRate(_new.Pair.RightToRight), + }, + }, + }; + + for (const key in _new.Dist.Key) { + _old.Keys[key] = { + Count: _new.Dist.Key[key], + Rate: util._keyRate(_new.Dist.Key[key]), + }; + } + + for (const key in _new.Dist.Finger) { + _old.Fingers.Dist.push({ + Count: _new.Dist.Finger[key], + Rate: util._keyRate(_new.Dist.Finger[key]), + }); + } + return _old; +} diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index bbaa4da..35ded79 100644 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -1,25 +1,48 @@ @@ -285,12 +366,48 @@ async function race() { display: flex; align-items: center; min-height: 30px; - margin: 10px 0; + margin: 20px 0; - & .name { - min-width: 84px; + & > .name { + min-width: 80px; text-align: right; - padding-right: 21px; + padding-right: 30px; + color: #111; + font-size: 125%; + font-weight: bold; + font-family: Baskerville, "Times New Roman", "Liberation Serif", STFangsong, FangSong, FangSong_GB2312, "CWTEX\-F", + serif; + } +} + +.clipboard { + display: flex; + justify-content: center; + width: 100%; + min-height: 120px; + border: 1px dashed #e0e0e6; + border-radius: 3px; + padding: 14px; + background-color: #fafafc; + cursor: pointer; + align-items: center; + + & .empty { + text-align: center; + } + + &:hover { + border-color: #18a058; } + + &:active { + background-color: #f0f0f0; + } +} + +.text-preview { + color: #999; + width: 600px; + margin-right: 14px; } diff --git a/frontend/src/components/MultiResult.vue b/frontend/src/components/MultiResult.vue index be7c77d..15f599a 100644 --- a/frontend/src/components/MultiResult.vue +++ b/frontend/src/components/MultiResult.vue @@ -1,5 +1,5 @@ + diff --git a/pkg/server/race.go b/pkg/server/race.go index c1bc54d..b99ecb5 100644 --- a/pkg/server/race.go +++ b/pkg/server/race.go @@ -8,18 +8,17 @@ import ( ) type Data struct { - Text []Text `json:"text"` - Dict []Dict `json:"dict"` - Clean bool `json:"clean"` -} - -type Dict struct { Source string `json:"source"` - Name string `json:"name"` Path string `json:"path"` - Index int `json:"index"` Text string `json:"text"` + Merge bool `json:"merge"` + Clean bool `json:"clean"` + + Dict []Dict `json:"dict"` +} +type Dict struct { + Path string `json:"path"` Format string `json:"format"` Push int `json:"push"` Keys string `json:"keys"` @@ -28,47 +27,35 @@ type Dict struct { Space string `json:"space"` } -type Text struct { - Source string `json:"source"` - Name string `json:"name"` - Path string `json:"path"` - Index int `json:"index"` - Text string `json:"text"` -} - func (d *Data) Race() []byte { smq := &smq.Config{ + Merge: d.Merge, Clean: d.Clean, } - for _, v := range d.Text { - t := &data.Text{ - Name: v.Name, + if d.Merge { + for _, text := range textList { + t := &data.Text{ + Path: text, + } + smq.AddText(t) } - switch v.Source { + } else { + t := &data.Text{} + switch d.Source { case "local": - t.Path = v.Path - case "upload": - t.Bytes = files[v.Index] + t.Path = d.Path case "clipboard": - t.String = v.Text + t.String = d.Text + t.Name = "剪贴板" default: - logger.Warn("不支持的数据源", "source", v.Source) + logger.Warn("不支持的数据源", "source", d.Source) } smq.AddText(t) } + for _, v := range d.Dict { t := &data.Text{ - Name: v.Name, - } - switch v.Source { - case "local": - t.Path = v.Path - case "upload": - t.Bytes = files[v.Index] - case "clipboard": - t.String = v.Text - default: - logger.Warn("不支持的数据源", "source", v.Source) + Path: v.Path, } d := &data.Dict{ Text: t, @@ -82,7 +69,10 @@ func (d *Data) Race() []byte { smq.AddDict(d) } res := smq.Race() - data, err := json.Marshal(res) + if len(res) < 1 { + return []byte{} + } + data, err := json.Marshal(res[0]) if err != nil { logger.With("error", err).Error("json marshal") return []byte{} diff --git a/pkg/server/server.go b/pkg/server/server.go index 9a7218f..1a1dc06 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -21,6 +21,8 @@ var dist embed.FS // 上传的文件列表 var files [][]byte = make([][]byte, 0) +var textList = make([]string, 0) + func Serve(port int, silent bool, prefix string) { mux := http.NewServeMux() dist, _ := fs.Sub(dist, "dist") @@ -32,9 +34,9 @@ func Serve(port int, silent bool, prefix string) { Text []string `json:"text"` Dict []string `json:"dict"` } - text := util.WalkDirWithSuffix(filepath.Join(prefix, "text"), ".txt") + textList = util.WalkDirWithSuffix(filepath.Join(prefix, "text"), ".txt") dict := util.WalkDirWithSuffix(filepath.Join(prefix, "dict"), ".txt") - res := Result{Text: text, Dict: dict} + res := Result{Text: textList, Dict: dict} json.NewEncoder(w).Encode(res) })