7.21 big change

This commit is contained in:
2026-07-21 17:57:04 +08:00
parent 4806ca6bc0
commit 6f6bde4a24
29 changed files with 2893 additions and 338 deletions
BIN
View File
Binary file not shown.
+90 -28
View File
@@ -7,45 +7,36 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
) )
// App struct
type App struct {
ctx context.Context
}
// NewApp creates a new App application struct
func NewApp() *App { func NewApp() *App {
return &App{} return &App{}
} }
// startup is called when the app starts. The context is saved
// so we can call the runtime methods
func (a *App) startup(ctx context.Context) { func (a *App) startup(ctx context.Context) {
a.ctx = ctx a.ctx = ctx
} }
// Greet returns a greeting for the given name
func (a *App) Greet(name string) string { func (a *App) Greet(name string) string {
return fmt.Sprintf("Hello %s, It's show time!", name) return fmt.Sprintf("Hello %s, It's show time!", name)
} }
func (a *App) Login() string { func (a *App) GormDB() (*gorm.DB, error) {
println("1111") db, err := gorm.Open(sqlite.Open("app.db"), &gorm.Config{})
return "" if err != nil {
return nil, err
}
return db, nil
} }
func (a *App) Register() string { func (a *App) UploadImage(data []byte, filename string) Response {
println("1111")
return ""
}
func (a *App) UploadImage(data []byte, filename string) ImageResult {
uploadsDir := "./uploads" uploadsDir := "./uploads"
err := os.MkdirAll(uploadsDir, 0755) err := os.MkdirAll(uploadsDir, 0755)
if err != nil { if err != nil {
return ImageResult{Code: 1, Message: "failed", Data: fmt.Sprintf("创建目录失败: %v", err)} return Response{Code: 1, Message: "failed", Data: err.Error()}
} }
ext := filepath.Ext(filename) ext := filepath.Ext(filename)
@@ -54,26 +45,97 @@ func (a *App) UploadImage(data []byte, filename string) ImageResult {
err = os.WriteFile(filePath, data, 0644) err = os.WriteFile(filePath, data, 0644)
if err != nil { if err != nil {
return ImageResult{Code: 1, Message: "failed", Data: fmt.Sprintf("保存文件失败: %v", err)} return Response{Code: 1, Message: "failed", Data: err.Error()}
} }
return ImageResult{Code: 0, Message: "success", Data: newFilename} return Response{Code: 0, Message: "success", Data: newFilename}
} }
func (a *App) GetImage(filename string) ImageResult { func (a *App) GetImage(filename string) Response {
filePath := filepath.Join("./uploads", filename) filePath := filepath.Join("./uploads", filename)
fmt.Println("filePath", filePath)
data, err := os.ReadFile(filePath) data, err := os.ReadFile(filePath)
if err != nil { if err != nil {
return ImageResult{Code: 1, Message: "failed", Data: fmt.Sprintf("打开文件路径失败: %v", err)} return Response{Code: 1, Message: "failed", Data: err.Error()}
} }
ext := filepath.Ext(filename) ext := filepath.Ext(filename)
mimeType := "image/jpeg" mimeType := "image/jpeg"
if ext == ".png" { if ext == ".png" {
mimeType = "image/png" mimeType = "image/png"
} }
// app.go - GetImage
return ImageResult{Code: 0, Message: "success", Data: fmt.Sprintf("data:image/%s;base64,%s", mimeType, base64.StdEncoding.EncodeToString(data))}
// return ImageResult{Code: 1, Message: "failed", Data: data} base64Data := base64.StdEncoding.EncodeToString(data)
dataURL := "data:image/" + mimeType + ";base64," + base64Data
return Response{Code: 0, Message: "success", Data: dataURL}
}
func (a *App) GetHistory(page int, pageSize int) Response {
db, err := a.GormDB()
if err != nil {
return Response{Code: 1, Message: err.Error()}
}
var total int64
db.Table("history_test").Count(&total)
var historyList []HistoryWithBreed
err = db.Table("history_test").Select("history_test.*, breeds_test.brief, breeds_test.name").
Joins("LEFT JOIN breeds_test ON history_test.breed = breeds_test.id").
Order("history_test.id DESC").Limit(pageSize).Offset((page - 1) * pageSize).Find(&historyList).Error
if err != nil {
return Response{Code: 1, Message: err.Error()}
}
historyData := HistoryData{Page: page, PageSize: pageSize, Total: total, List: historyList}
return Response{Code: 0, Message: "success", Data: historyData}
}
func (a *App) Detect(img string) Response {
db, err := a.GormDB()
if err != nil {
return Response{Code: 1, Message: err.Error()}
}
var breed Breed
detectRet := "british_shorthair"
err = db.Table("breeds_test").Where("code = ?", detectRet).First(&breed).Error
if err != nil {
return Response{Code: 1, Message: err.Error()}
}
now := int(time.Now().Unix())
one := HistoryItem{Img: img, Breed: int(breed.Id), Date: now}
result := db.Table("history_test").Create(&one)
if result.Error != nil {
return Response{Code: 1, Message: result.Error.Error()}
}
detectData := DetectData{
Id: breed.Id,
Code: breed.Code,
Name: breed.Name,
Brief: breed.Brief,
ConfidenceLevel: 0.98,
}
return Response{Code: 0, Message: "success", Data: detectData}
}
func (a *App) DeleteOneHistory(id uint) Response {
db, err := a.GormDB()
if err != nil {
return Response{Code: 1, Message: err.Error()}
}
result := db.Table("history_test").Delete(&HistoryItem{}, id)
if result.Error != nil {
return Response{Code: 1, Message: result.Error.Error()}
}
return Response{Code: 0, Message: "success"}
} }
+1680
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -15,6 +15,8 @@
}, },
"devDependencies": { "devDependencies": {
"@preact/preset-vite": "^2.3.0", "@preact/preset-vite": "^2.3.0",
"sharp": "^0.35.3",
"to-ico": "^1.1.5",
"typescript": "^4.6.4", "typescript": "^4.6.4",
"vite": "^8.1.4" "vite": "^8.1.4"
} }
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">
<path d="M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4.5 4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm9 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-9.5 3.5c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zm11 0c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zM12 18c-2.21 0-4 1.79-4 4h8c0-2.21-1.79-4-4-4z"/>
</svg>

After

Width:  |  Height:  |  Size: 466 B

-18
View File
@@ -1,18 +0,0 @@
import { route } from "preact-router"
const Dashboard = () => {
return (
<div class="app-dashboard">
<div class="dashboard-sidebar">
<a href="/dashboard/datasets" onClick={(e) => { e.preventDefault(); route("/dashboard/datasets") }}></a>
<a href="/dashboard/testsets" onClick={(e) => { e.preventDefault(); route("/dashboard/testsets") }}></a>
<a href="/dashboard/logs" onClick={(e) => { e.preventDefault(); route("/dashboard/logs") }}></a>
</div>
<div class="dashboard-content">
{/* 子页面内容通过 Router 渲染到这里 */}
</div>
</div>
)
}
export default Dashboard
+9 -11
View File
@@ -1,11 +1,9 @@
export const Footer = () => { export const Footer = () => (
return ( <footer class="app-footer">
<footer class="app-footer"> <span>📩 xiadongliang88@163.com</span>
<span>https://pytorch.org/</span> <span>|</span>
<span>|</span> <span>📦 https://git.leonstack.com/owner</span>
<span>https://wails.io/</span> <span>|</span>
<span>|</span> <span>🌏 https://www.leonstack.com/</span>
<span>https://preactjs.com/</span> </footer>
</footer> )
)
}
+64 -51
View File
@@ -1,82 +1,95 @@
import { useState, useEffect } from 'preact/hooks' import { useState, useEffect } from 'preact/hooks'
import { message } from '../utils/toast'
import Pagination from './Pagination' import Pagination from './Pagination'
const formatDate = (timestamp: number) => {
const date = new Date(timestamp * 1000)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
})
}
const historyList = [ interface IHistoryItem {
{ id: number
id: 1, img: string
breeds: '英短&1212', breed: number
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.', date: number
img: '../../', name: string
date: 'Jan 15, 2024', brief: string
}, }
{
id: 2,
breeds: '英短&fdfd',
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.',
img: '../../',
date: 'Jan 15, 2024',
},
{
id: 3,
breeds: '英短&11111',
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.',
img: '../../',
date: 'Jan 15, 2024',
},
{
id: 4,
breeds: '英短&4545',
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.',
img: '../../',
date: 'Jan 15, 2024',
},
{
id: 5,
breeds: '英短&fff',
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.',
img: '../../',
date: 'Jan 15, 2024',
},
]
const History = () => { const History = () => {
const [page, setPage] = useState<number>(1) const [page, setPage] = useState<number>(1)
const pageSize = 5
const [total, setTotal] = useState<number>(50) const [total, setTotal] = useState<number>(50)
const [historyList, setHistoryList] = useState<IHistoryItem[]>([])
useEffect(() => {
if (!(window as any).go?.main?.App?.GetHistory) {
message.error('Wails runtime not ready')
return
}
fetchData(page)
}, [])
const handlePageChange = (page: number) => { const fetchData = async(page: number) => {
// setPage(page) const result = await (window as any).go.main.App.GetHistory(page, pageSize)
// loadTranscript(currentNav, currentOpt, page).then(res => { if (result.code === 0) {
// if (res && res.code === 0) { setHistoryList(result.data.list)
// setData(res.data.data) setTotal(result.data.total)
// setTotal(res.data.total) } else if (result.code === 1) {
// } message.error(result.message)
// }).catch(e => message.error(e.toString())) }
} }
const handlePageChange = (page: number) => {
setPage(page)
fetchData(page)
}
const handleDelete = async(id: number) => {
const result = await (window as any).go.main.App.DeleteOneHistory(id)
if (result.code === 0) {
message.success('删除成功')
fetchData(page)
} else if (result.code === 1) {
message.error(result.message)
}
}
return ( return (
<div class="app-history"> <div class="app-history">
{historyList.map((item) => <div class="history-clear">
<a></a>
</div>
{historyList.map((item: IHistoryItem) =>
<div key={item.id} class="history-card"> <div key={item.id} class="history-card">
<div class="card-left"> <div class="card-left">
<img src="../assets/images/0012.jpg" /> <img src="../assets/images/0012.jpg" />
</div> </div>
<div class="card-right"> <div class="card-right">
<div class="right-top"> <div class="right-top">
<h3>{item.breeds}</h3> <h3>{item.name}</h3>
<span>{item.date}</span> <div class="card-actions">
<span>{formatDate(item.date)}</span>
<button onClick={() => handleDelete(item.id)} title="删除">
×
</button>
</div>
</div> </div>
<div class="right-overview"> <div class="right-overview">
{item.desc} {item.brief}
</div> </div>
</div> </div>
</div>) </div>)
} }
<div class="history-pagination"> <div class="history-pagination">
<Pagination page={page} pagesize={5} total={total} onChange={handlePageChange} /> <Pagination page={page} pagesize={pageSize} total={total} onChange={handlePageChange} />
</div> </div>
</div> </div>
) )
+36 -48
View File
@@ -1,16 +1,22 @@
import { useState, useEffect, useRef } from 'preact/hooks' import { useState, useRef } from 'preact/hooks'
import { message } from '../utils/toast'
interface IDetectResult {
id: number
code: string
name: number
brief: string
confidence_level: number
}
const Main = () => { const Main = () => {
const fileInputRef = useRef<HTMLInputElement>(null) const fileInputRef = useRef<HTMLInputElement>(null)
const [fileName, setFileName] = useState<string>('') const [fileName, setFileName] = useState<string>('')
const [fileSrc, setFileSrc] = useState<string>('') const [fileSrc, setFileSrc] = useState<string>('')
const [step, setStep] = useState<number>(0)
const [detectResult, setDetectResult] = useState<IDetectResult | null>(null)
const [step, setStep] = useState(0) const handleUploadClick = () => fileInputRef.current?.click()
const handleUploadClick = () => {
fileInputRef.current?.click()
}
const handleFileChange = (e: Event) => { const handleFileChange = (e: Event) => {
const target = e.target as HTMLInputElement const target = e.target as HTMLInputElement
@@ -56,13 +62,20 @@ const Main = () => {
const handleDetect = () => { const handleDetect = () => {
setStep(2) setStep(2)
setTimeout(() => { setTimeout(async() => {
setStep(3) const result = await (window as any).go.main.App.Detect(fileName)
if (result.code === 0) {
setDetectResult(result.data)
setStep(3)
} else if (result.code === 1) {
message.error(result.message)
}
}, 1000) }, 1000)
} }
const handleTryOther = () => { const handleTryOther = () => {
setStep(0) setStep(0)
setDetectResult(null)
resetUpload() resetUpload()
} }
@@ -74,9 +87,14 @@ const Main = () => {
<span></span><span></span> <span></span><span></span>
</h1> </h1>
<p> <p>
AI不仅认出它<span></span> AI认出它<span></span>
</p> </p>
<i></i> <i>
<svg viewBox="0 0 24 24" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/>
</svg>
<span></span>
</i>
</div> </div>
<div class={`upload${!(step == 0 || step == 1 || step == 2) ? ' hidden' : ''}`}> <div class={`upload${!(step == 0 || step == 1 || step == 2) ? ' hidden' : ''}`}>
<div <div
@@ -125,7 +143,7 @@ const Main = () => {
} }
</div> </div>
{fileSrc.length > 0 && step == 1 ? {fileSrc.length > 0 && step == 1 ?
<button id="detectBtn" onClick={handleDetect}> <button onClick={handleDetect}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path <path
stroke-linecap="round" stroke-linecap="round"
@@ -142,60 +160,30 @@ const Main = () => {
<svg viewBox="0 0 24 24" fill="currentColor"> <svg viewBox="0 0 24 24" fill="currentColor">
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" /> <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" />
</svg> </svg>
<h2></h2> <h2></h2>
</div> </div>
<div class="result-main"> <div class="result-main">
<img /> <img />
<div class="result-word"> <div class="result-word">
<div> <div>
<h3></h3> <h3>{detectResult?.name}</h3>
<div> <div>
<div class="probability-bar"> <div class="probability-bar">
<div /> <div />
</div> </div>
<span> 78%</span> <span> {detectResult ? detectResult.confidence_level * 100 + '%' : ''}</span>
</div> </div>
</div> </div>
<h4></h4> <p>{detectResult?.brief}</p>
<p> </p>
</div> </div>
</div> </div>
<button onClick={handleTryOther}> <button onClick={handleTryOther}>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99" />
</svg>
</button> </button>
</div> </div>
{/* <div id="featuresSection" class="grid grid-cols-1 md:grid-cols-3 gap-6 mt-16">
<div class="bg-white rounded-2xl border border-border p-6 text-center cursor-pointer hover:shadow-lg transition-shadow duration-200">
<div class="w-14 h-14 mx-auto mb-4 bg-primary/10 rounded-2xl flex items-center justify-center">
<svg class="w-7 h-7 text-primary" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 13.5l10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75z" />
</svg>
</div>
<h3 class="font-heading font-semibold text-lg text-text mb-2">Lightning Fast</h3>
<p class="text-text/60 text-sm">Get results in under 3 seconds with our optimized AI model</p>
</div>
<div class="bg-white rounded-2xl border border-border p-6 text-center cursor-pointer hover:shadow-lg transition-shadow duration-200">
<div class="w-14 h-14 mx-auto mb-4 bg-cta/10 rounded-2xl flex items-center justify-center">
<svg class="w-7 h-7 text-cta" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 6.75V15m6-6v8.25m.503 3.498l4.875-2.437c.381-.19.622-.58.622-1.006V4.82c0-.836-.88-1.38-1.628-1.006l-3.869 1.934c-.317.159-.69.159-1.006 0L9.503 3.252a1.125 1.125 0 00-1.006 0L3.622 5.689C3.24 5.88 3 6.27 3 6.695V19.18c0 .836.88 1.38 1.628 1.006l3.869-1.934c.317-.159.69-.159 1.006 0l4.994 2.497c.317.158.69.158 1.006 0z" />
</svg>
</div>
<h3 class="font-heading font-semibold text-lg text-text mb-2">98% Accuracy</h3>
<p class="text-text/60 text-sm">Trained on 50,000+ cat images across 60+ breeds</p>
</div>
<div class="bg-white rounded-2xl border border-border p-6 text-center cursor-pointer hover:shadow-lg transition-shadow duration-200">
<div class="w-14 h-14 mx-auto mb-4 bg-green-100 rounded-2xl flex items-center justify-center">
<svg class="w-7 h-7 text-green-600" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418" />
</svg>
</div>
<h3 class="font-heading font-semibold text-lg text-text mb-2">Always Free</h3>
<p class="text-text/60 text-sm">No hidden fees, no subscriptions. Detect away!</p>
</div>
</div> */}
</div> </div>
</main> </main>
) )
+3 -4
View File
@@ -1,7 +1,7 @@
export const Navbar = () => { export const Navbar = () => {
const svgPath = "M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4.5 4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm9 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-9.5 3.5c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zm11 0c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zM12 18c-2.21 0-4 1.79-4 4h8c0-2.21-1.79-4-4-4z" const svgPath = "M12 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-4.5 4c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm9 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-9.5 3.5c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zm11 0c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5zM12 18c-2.21 0-4 1.79-4 4h8c0-2.21-1.79-4-4-4z"
const handleClick = () => window.open('https://git.leonstack.com/Leon/Collage-Images', '_blank') const handleClick = () => window.open('https://git.leonstack.com/owner/Collage-Images', '_blank')
return ( return (
<nav class="app-navbar animate-fade-in"> <nav class="app-navbar animate-fade-in">
@@ -10,13 +10,12 @@ export const Navbar = () => {
<svg class="icon" viewBox="0 0 24 24" fill="currentColor"> <svg class="icon" viewBox="0 0 24 24" fill="currentColor">
<path d={svgPath} /> <path d={svgPath} />
</svg> </svg>
<span class="font-heading font-semibold text-xl text-text">miao</span> <span class="font-heading font-semibold text-xl text-text"></span>
</div> </div>
<div class="container-right"> <div class="container-right">
<a href="/"></a> <a href="/"></a>
<a href="/history"></a> <a href="/history"></a>
<a href="/dashboard"></a> <button onClick={handleClick}></button>
<button onClick={handleClick}></button>
</div> </div>
</div> </div>
</nav> </nav>
+8 -5
View File
@@ -45,14 +45,17 @@ const Pagination = ({
const handleEnterPress = (e: KeyboardEvent) => { const handleEnterPress = (e: KeyboardEvent) => {
if (e.key === 'Enter') { if (e.key === 'Enter') {
if (parseInt(value) <= seqNums.length && parseInt(value) > 0) { const target = e.target as HTMLInputElement
handleChangeNum(parseInt(value)) const page = parseInt(target.value)
} else if (parseInt(value) >= seqNums.length) { if (page >= 1 && page <= seqNums.length) {
handleChangeNum(page)
onChange(page)
} else if (page > seqNums.length) {
handleChangeNum(seqNums.length) handleChangeNum(seqNums.length)
} else if (parseInt(value) < seqNums.length) { onChange(seqNums.length)
handleChangeNum(1)
} else { } else {
handleChangeNum(1) handleChangeNum(1)
onChange(1)
} }
} }
} }
@@ -1,7 +0,0 @@
const TestsetManagement = () => {
return (
<div></div>
)
}
export default TestsetManagement
@@ -1,7 +0,0 @@
const TrainsetManagement = () => {
return (
<div></div>
)
}
export default TrainsetManagement
+1 -9
View File
@@ -2,26 +2,18 @@ import { Router, Route } from "preact-router"
import { Navbar } from "../components/Navbar" import { Navbar } from "../components/Navbar"
import Main from "../components/Main" import Main from "../components/Main"
import History from "../components/History" import History from "../components/History"
import Dashboard from "../components/Dashboard"
import TrainsetManagement from "../components/TrainsetManagement"
import TestsetManagement from "../components/TestsetManagement"
import { Footer } from "../components/Footer" import { Footer } from "../components/Footer"
import '../styles/base.sass' import '../styles/base.sass'
import '../styles/history.sass' import '../styles/history.sass'
import '../styles/pagination.sass' import '../styles/pagination.sass'
import '../styles/dashboard.sass'
export function App() {
export function App(props: any) {
return ( return (
<div id="App"> <div id="App">
<Navbar /> <Navbar />
<Router> <Router>
<Route path="/" component={Main} /> <Route path="/" component={Main} />
<Route path="/dashboard" component={Dashboard} />
<Route path="/history" component={History} /> <Route path="/history" component={History} />
<Route path="/dashboard/datasets" component={TrainsetManagement} />
<Route path="/dashboard/testsets" component={TestsetManagement} />
</Router> </Router>
<Footer /> <Footer />
</div> </div>
+83 -83
View File
@@ -6,6 +6,7 @@ body
margin: 0 margin: 0
color: white color: white
font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI" font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI"
overflow: hidden
@font-face @font-face
font-family: "Nunito" font-family: "Nunito"
@@ -17,11 +18,16 @@ body
font-family: "ZcoolHappy" font-family: "ZcoolHappy"
src: url("../assets/fonts/站酷快乐体.ttf") format("truetype") src: url("../assets/fonts/站酷快乐体.ttf") format("truetype")
@font-face
font-family: "SANS_SC_BOLD"
src: url("../assets/fonts/HARMONYOS_SANS_SC_BOLD.TTF") format("truetype")
:root :root
--primary: #3B82F6 --primary: #3B82F6
--title: #1e293b --title: #1e293b
--text:#5f6874 --sub-title: #5f6874
--textsub: #878d95 --text:#5D5D5D
--textsub: #979797
#app #app
height: 100vh height: 100vh
@@ -41,7 +47,7 @@ body
width: 100% width: 100%
margin: 0 auto margin: 0 auto
padding: 0.6rem 1.2rem padding: 0.6rem 1.2rem
background-color: #FFFFFF background-color: white
backdrop-filter: blur(8px) backdrop-filter: blur(8px)
border-radius: 0.6rem border-radius: 0.6rem
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)
@@ -77,7 +83,7 @@ body
width: 7rem width: 7rem
height: 2.6rem height: 2.6rem
margin-left: 1.5rem margin-left: 1.5rem
color: #FFFFFF color: white
font-size: 0.9375rem font-size: 0.9375rem
background-color: var(--primary) background-color: var(--primary)
border-radius: 0.5rem border-radius: 0.5rem
@@ -113,7 +119,7 @@ body
> p > p
text-align: center text-align: center
color: var(--text) color: var(--sub-title)
font-size: 1.0625rem font-size: 1.0625rem
margin-bottom: 1rem margin-bottom: 1rem
max-width: 42rem max-width: 42rem
@@ -123,6 +129,8 @@ body
color: var(--primary) color: var(--primary)
> i > i
display: flex
align-items: center
font-style: normal font-style: normal
text-align: center text-align: center
color: #FFD572 color: #FFD572
@@ -130,7 +138,12 @@ body
margin: 0 auto margin: 0 auto
padding: 0.25rem 0.75rem padding: 0.25rem 0.75rem
background-color: #38383D background-color: #38383D
border-radius: 0.2rem border-radius: 0.25rem
gap: 0.25rem
> svg
width: 0.625rem
height: 0.625rem
.upload .upload
width: 32rem width: 32rem
@@ -147,7 +160,6 @@ body
border-width: 2px border-width: 2px
border-style: dashed border-style: dashed
border-color: #e2e8f0 border-color: #e2e8f0
border-style: dashed
text-align: center text-align: center
cursor: pointer cursor: pointer
@@ -175,8 +187,7 @@ body
> img > img
max-height: 10.5rem max-height: 10.5rem
margin-left: auto margin: 0 auto
margin-right: auto
margin-bottom: 0.25rem margin-bottom: 0.25rem
border-radius: 1rem border-radius: 1rem
object-fit: cover object-fit: cover
@@ -195,7 +206,7 @@ body
.zone-loading .zone-loading
padding: 2rem padding: 2rem
text-align: center text-align: center
background-color: #FFFFFF background-color: white
border-radius: 1.5rem border-radius: 1.5rem
.loading-spinner .loading-spinner
@@ -223,25 +234,26 @@ body
font-size: 1rem font-size: 1rem
color: var(--textsub) color: var(--textsub)
>button#detectBtn > button
width: 12rem display: flex
height: 3.5rem align-items: center
justify-content: center
width: 9rem
height: 3rem
margin: 1rem auto 0 auto margin: 1rem auto 0 auto
background-color: var(--primary) background-color: var(--primary)
color: white color: white
font-weight: 600 font-weight: 600
font-size: 1.125rem font-size: 1.125rem
border-radius: 0.75rem border-radius: 0.5rem
transition: background-color 200ms, color 200ms transition: background-color 200ms, color 200ms
cursor: pointer cursor: pointer
display: flex
align-items: center gap: 0.25rem
justify-content: center
gap: 0.5rem
> svg > svg
width: 1.5rem width: 1.25rem
height: 1.5rem height: 1.25rem
.result .result
width: 35rem width: 35rem
@@ -251,6 +263,7 @@ body
display: flex display: flex
align-items: center align-items: center
justify-content: center justify-content: center
height: 2.25rem
gap: 0.75rem gap: 0.75rem
margin-bottom: 1.5rem margin-bottom: 1.5rem
@@ -260,8 +273,8 @@ body
color: var(--primary) color: var(--primary)
> h2 > h2
font-family: "ZcoolHappy" font-family: "SANS_SC_BOLD"
font-weight: 700 font-weight: bold
font-size: 1.5rem font-size: 1.5rem
color: var(--title) color: var(--title)
@@ -270,7 +283,7 @@ body
min-height: 10rem min-height: 10rem
padding: 1rem 1rem padding: 1rem 1rem
margin-bottom: 1.5rem margin-bottom: 1.5rem
background-color: #ffffff background-color: white
border-radius: 1rem border-radius: 1rem
border: 1px solid var(--color-border) border: 1px solid var(--color-border)
gap: 2rem gap: 2rem
@@ -293,7 +306,7 @@ body
justify-content: space-between justify-content: space-between
align-items: center align-items: center
width: 100% width: 100%
padding-bottom: 1rem padding-bottom: 0.75rem
margin-bottom: 1rem margin-bottom: 1rem
border-bottom: 1px solid #c6c6c6 border-bottom: 1px solid #c6c6c6
@@ -333,14 +346,6 @@ body
> span > span
color: var(--title) color: var(--title)
// font-size: 0.725rem
> h4
color: var(--title)
text-align: left
font-size: 1rem
font-weight: bold
margin-bottom: 0.5rem
> p > p
color: var(--text) color: var(--text)
@@ -348,17 +353,24 @@ body
font-size: 0.875rem font-size: 0.875rem
> button > button
display: flex
align-items: center
justify-content: center
width: 9rem width: 9rem
height: 3rem height: 3rem
background-color: var(--primary) margin: 0 auto
color: white color: white
font-weight: 600 font-weight: 600
font-size: 1.125rem font-size: 1.125rem
background-color: var(--primary)
border-radius: 0.5rem border-radius: 0.5rem
transition: background-color 200ms, color 200ms transition: background-color 200ms, color 200ms
cursor: pointer cursor: pointer
gap: 0.25rem
> svg
width: 1.25rem
height: 1.25rem
.app-footer .app-footer
display: flex display: flex
@@ -375,56 +387,44 @@ body
font-size: 0.8rem font-size: 0.8rem
margin: 0 0.5rem margin: 0 0.5rem
@media (prefers-reduced-motion: reduce) .message
.animate-fade-in, width: 100%
.animate-slide-up, height: 2rem
.animate-pulse-slow position: fixed
animation: none !important top: 6.25rem
transition: none !important z-index: 1000
background: none
-moz-transition: all 0.5s ease-in
-webkit-transition: all 0.5s ease-in
-o-transition: all 0.5s ease-in
transition: all 0.5s ease-in
@keyframes fadeIn .success, .error
from display: inline-flex
opacity: 0 justify-content: center
to align-items: center
opacity: 1 height: 2rem
margin: 0 auto
padding: 0 1.125rem
font-size: 0.875rem
background: white
border: 1px solid var(--border)
border-radius: 0.375rem
box-shadow: 0rem 0.25rem 0.25rem rgb(0 0 0 / 0.1)
gap: 0.25rem
@keyframes slideUp > span
from width: 1rem
opacity: 0 height: 1rem
transform: translateY(20px)
to
opacity: 1
transform: translateY(0)
@keyframes pulseSlow > svg
0%, 100% width: 1rem
opacity: 1 height: 1rem
50% line-height: 2rem
opacity: 0.7
.animate-fade-in > p
animation: fadeIn 0.3s ease-out forwards max-width: 24rem
color: var(--text)
.animate-slide-up overflow: hidden
animation: slideUp 0.4s ease-out forwards white-space: nowrap
text-overflow: ellipsis
.animate-pulse-slow
animation: pulseSlow 2s ease-in-out infinite
.drop-zone
transition: all 0.2s ease-out
.drop-zone.dragover
border-color: #3B82F6
background-color: #EFF6FF
transform: scale(1.01)
.breed-card
transition: all 0.2s ease-out
&:hover
transform: translateY(-4px)
box-shadow: 0 12px 24px -8px rgba(59, 130, 246, 0.25)
.confidence-bar
transition: width 0.8s ease-out
-26
View File
@@ -1,26 +0,0 @@
.app-dashboard
display: flex
height: 648px
padding: 7rem 1.5rem 4rem 1.5rem
.dashboard-sidebar
display: flex
flex-direction: column
align-items: center
width: 18%
height: 100%
border-right: 1px solid #9AAAC6
> a
display: inline-flex
height: 2.5rem
line-height: 2.5rem
font-size: 0.9375rem
color: #8E8E8E
border-bottom: 1px solid #9AAAC6
cursor: pointer
.dashboard-content
width: 82%
height: 100%
// background-color: #555
+43 -5
View File
@@ -3,7 +3,18 @@
flex-direction: column flex-direction: column
align-items: center align-items: center
height: 651px height: 651px
padding: 7rem 1rem 4rem 1rem padding: 6.5rem 1rem 4rem 1rem
.history-clear
width: calc(100% - 20rem)
text-align: right
margin-bottom: 0.5rem
> a
font-size: 0.875rem
color: var(--primary)
cursor: pointer
// text-decoration: underline
.history-card .history-card
display: flex display: flex
@@ -33,15 +44,39 @@
display: flex display: flex
align-items: center align-items: center
justify-content: space-between justify-content: space-between
gap: 1rem
> h3 > h3
width: 6rem
color: #333333 color: #333333
font-size: 1rem font-size: 1rem
font-weight: bold font-weight: bold
text-align: left
> span .card-actions
color: #cccccc display: flex
font-size: 0.8rem flex: 1
justify-content: space-between
align-items: flex-start
gap: 0.75rem
> span
color: #cccccc
font-size: 0.8rem
> button
display: flex
align-items: center
justify-content: center
width: 1rem
height: 1rem
font-size: 1rem
padding: 0
background: none
border: none
border-radius: 0.35rem
color: #9ca3af
cursor: pointer
.right-overview .right-overview
width: 100% width: 100%
@@ -49,9 +84,12 @@
color: #cccccc color: #cccccc
font-size: 0.9rem font-size: 0.9rem
text-align: left text-align: left
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
.history-pagination .history-pagination
width: calc(100% - 20rem) width: calc(100% - 20rem)
margin-top: 1rem margin-top: 0.5rem
-1
View File
@@ -59,7 +59,6 @@
.pagination-word .pagination-word
font-size: 0.75rem font-size: 0.75rem
font-weight: bold
margin: 0 0.3125rem 0 0.3125rem margin: 0 0.3125rem 0 0.3125rem
color: #333333 color: #333333
+53
View File
@@ -0,0 +1,53 @@
interface MessageAPI {
success: (text: string) => void
error: (text: string) => void
}
export const message: MessageAPI = {
success: (text: string) => {
const div = document.createElement('div')
div.className = 'message'
const subDiv = document.createElement('div')
subDiv.className = 'success'
const subSpan = document.createElement('span')
subSpan.innerHTML = `<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="9" fill="#22c55e"/><path d="M6 10L9 13L14 7" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>`
const subP = document.createElement('p')
subP.innerText = text
subDiv.appendChild(subSpan)
subDiv.appendChild(subP)
div.appendChild(subDiv)
document.body.appendChild(div)
setTimeout(() => {
div.remove()
}, 3000)
},
error: (text: string) => {
const div = document.createElement('div')
div.className = 'message'
const subDiv = document.createElement('div')
subDiv.className = 'error'
const subSpan = document.createElement('span')
subSpan.innerHTML = `<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="10" cy="10" r="9" fill="#ef4444"/><path d="M7 7L13 13M13 7L7 13" stroke="white" stroke-width="2" stroke-linecap="round"/></svg>`
const subP = document.createElement('p')
subP.innerText = text
subDiv.appendChild(subSpan)
subDiv.appendChild(subP)
div.appendChild(subDiv)
document.body.appendChild(div)
setTimeout(() => {
div.remove()
}, 3000)
}
}
+11 -6
View File
@@ -1,13 +1,18 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
import {main} from '../models'; import {main} from '../models';
import {gorm} from '../models';
export function GetImage(arg1:string):Promise<main.ImageResult>; export function DeleteOneHistory(arg1:number):Promise<main.Response>;
export function Detect(arg1:string):Promise<main.Response>;
export function GetHistory(arg1:number,arg2:number):Promise<main.Response>;
export function GetImage(arg1:string):Promise<main.Response>;
export function GormDB():Promise<gorm.DB>;
export function Greet(arg1:string):Promise<string>; export function Greet(arg1:string):Promise<string>;
export function Login():Promise<string>; export function UploadImage(arg1:Array<number>,arg2:string):Promise<main.Response>;
export function Register():Promise<string>;
export function UploadImage(arg1:Array<number>,arg2:string):Promise<main.ImageResult>;
+16 -8
View File
@@ -2,22 +2,30 @@
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL // Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
// This file is automatically generated. DO NOT EDIT // This file is automatically generated. DO NOT EDIT
export function DeleteOneHistory(arg1) {
return window['go']['main']['App']['DeleteOneHistory'](arg1);
}
export function Detect(arg1) {
return window['go']['main']['App']['Detect'](arg1);
}
export function GetHistory(arg1, arg2) {
return window['go']['main']['App']['GetHistory'](arg1, arg2);
}
export function GetImage(arg1) { export function GetImage(arg1) {
return window['go']['main']['App']['GetImage'](arg1); return window['go']['main']['App']['GetImage'](arg1);
} }
export function GormDB() {
return window['go']['main']['App']['GormDB']();
}
export function Greet(arg1) { export function Greet(arg1) {
return window['go']['main']['App']['Greet'](arg1); return window['go']['main']['App']['Greet'](arg1);
} }
export function Login() {
return window['go']['main']['App']['Login']();
}
export function Register() {
return window['go']['main']['App']['Register']();
}
export function UploadImage(arg1, arg2) { export function UploadImage(arg1, arg2) {
return window['go']['main']['App']['UploadImage'](arg1, arg2); return window['go']['main']['App']['UploadImage'](arg1, arg2);
} }
+710 -6
View File
@@ -1,12 +1,343 @@
export namespace main { export namespace clause {
export class ImageResult { export class Clause {
code: number; Name: string;
message: string; BeforeExpression: any;
data?: string; AfterNameExpression: any;
AfterExpression: any;
Expression: any;
static createFrom(source: any = {}) { static createFrom(source: any = {}) {
return new ImageResult(source); return new Clause(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.BeforeExpression = source["BeforeExpression"];
this.AfterNameExpression = source["AfterNameExpression"];
this.AfterExpression = source["AfterExpression"];
this.Expression = source["Expression"];
}
}
export class Expr {
SQL: string;
Vars: any[];
WithoutParentheses: boolean;
static createFrom(source: any = {}) {
return new Expr(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.SQL = source["SQL"];
this.Vars = source["Vars"];
this.WithoutParentheses = source["WithoutParentheses"];
}
}
export class Where {
Exprs: any[];
static createFrom(source: any = {}) {
return new Where(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Exprs = source["Exprs"];
}
}
}
export namespace gorm {
export class result {
Result: any;
RowsAffected: number;
Error: any;
static createFrom(source: any = {}) {
return new result(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Result = source["Result"];
this.RowsAffected = source["RowsAffected"];
this.Error = source["Error"];
}
}
export class join {
Name: string;
Alias: string;
Conds: any[];
On?: clause.Where;
Selects: string[];
Omits: string[];
Expression: any;
JoinType: string;
static createFrom(source: any = {}) {
return new join(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.Alias = source["Alias"];
this.Conds = source["Conds"];
this.On = this.convertValues(source["On"], clause.Where);
this.Selects = source["Selects"];
this.Omits = source["Omits"];
this.Expression = source["Expression"];
this.JoinType = source["JoinType"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Statement {
SkipDefaultTransaction: boolean;
DefaultTransactionTimeout: number;
DefaultContextTimeout: number;
NamingStrategy: any;
FullSaveAssociations: boolean;
Logger: any;
DryRun: boolean;
PrepareStmt: boolean;
PrepareStmtMaxSize: number;
PrepareStmtTTL: number;
DisableAutomaticPing: boolean;
DisableForeignKeyConstraintWhenMigrating: boolean;
IgnoreRelationshipsWhenMigrating: boolean;
DisableNestedTransaction: boolean;
AllowGlobalUpdate: boolean;
QueryFields: boolean;
CreateBatchSize: number;
TranslateError: boolean;
PropagateUnscoped: boolean;
ClauseBuilders: Record<string, ClauseBuilder>;
ConnPool: any;
Dialector: any;
Plugins: Record<string, any>;
Error: any;
RowsAffected: number;
Statement?: Statement;
TableExpr?: clause.Expr;
Table: string;
Model: any;
Unscoped: boolean;
Dest: any;
// Go type: reflect
ReflectValue: any;
Clauses: Record<string, clause.Clause>;
BuildClauses: string[];
Distinct: boolean;
Selects: string[];
Omits: string[];
ColumnMapping: Record<string, string>;
Joins: join[];
Preloads: Record<string, Array<any>>;
// Go type: sync
Settings: any;
ConnPool: any;
Schema?: schema.Schema;
Context: any;
RaiseErrorOnNotFound: boolean;
SkipHooks: boolean;
// Go type: strings
SQL: any;
Vars: any[];
CurDestIndex: number;
Result?: result;
static createFrom(source: any = {}) {
return new Statement(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.SkipDefaultTransaction = source["SkipDefaultTransaction"];
this.DefaultTransactionTimeout = source["DefaultTransactionTimeout"];
this.DefaultContextTimeout = source["DefaultContextTimeout"];
this.NamingStrategy = source["NamingStrategy"];
this.FullSaveAssociations = source["FullSaveAssociations"];
this.Logger = source["Logger"];
this.DryRun = source["DryRun"];
this.PrepareStmt = source["PrepareStmt"];
this.PrepareStmtMaxSize = source["PrepareStmtMaxSize"];
this.PrepareStmtTTL = source["PrepareStmtTTL"];
this.DisableAutomaticPing = source["DisableAutomaticPing"];
this.DisableForeignKeyConstraintWhenMigrating = source["DisableForeignKeyConstraintWhenMigrating"];
this.IgnoreRelationshipsWhenMigrating = source["IgnoreRelationshipsWhenMigrating"];
this.DisableNestedTransaction = source["DisableNestedTransaction"];
this.AllowGlobalUpdate = source["AllowGlobalUpdate"];
this.QueryFields = source["QueryFields"];
this.CreateBatchSize = source["CreateBatchSize"];
this.TranslateError = source["TranslateError"];
this.PropagateUnscoped = source["PropagateUnscoped"];
this.ClauseBuilders = source["ClauseBuilders"];
this.ConnPool = source["ConnPool"];
this.Dialector = source["Dialector"];
this.Plugins = source["Plugins"];
this.Error = source["Error"];
this.RowsAffected = source["RowsAffected"];
this.Statement = this.convertValues(source["Statement"], Statement);
this.TableExpr = this.convertValues(source["TableExpr"], clause.Expr);
this.Table = source["Table"];
this.Model = source["Model"];
this.Unscoped = source["Unscoped"];
this.Dest = source["Dest"];
this.ReflectValue = this.convertValues(source["ReflectValue"], null);
this.Clauses = this.convertValues(source["Clauses"], clause.Clause, true);
this.BuildClauses = source["BuildClauses"];
this.Distinct = source["Distinct"];
this.Selects = source["Selects"];
this.Omits = source["Omits"];
this.ColumnMapping = source["ColumnMapping"];
this.Joins = this.convertValues(source["Joins"], join);
this.Preloads = source["Preloads"];
this.Settings = this.convertValues(source["Settings"], null);
this.ConnPool = source["ConnPool"];
this.Schema = this.convertValues(source["Schema"], schema.Schema);
this.Context = source["Context"];
this.RaiseErrorOnNotFound = source["RaiseErrorOnNotFound"];
this.SkipHooks = source["SkipHooks"];
this.SQL = this.convertValues(source["SQL"], null);
this.Vars = source["Vars"];
this.CurDestIndex = source["CurDestIndex"];
this.Result = this.convertValues(source["Result"], result);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class DB {
SkipDefaultTransaction: boolean;
DefaultTransactionTimeout: number;
DefaultContextTimeout: number;
NamingStrategy: any;
FullSaveAssociations: boolean;
Logger: any;
DryRun: boolean;
PrepareStmt: boolean;
PrepareStmtMaxSize: number;
PrepareStmtTTL: number;
DisableAutomaticPing: boolean;
DisableForeignKeyConstraintWhenMigrating: boolean;
IgnoreRelationshipsWhenMigrating: boolean;
DisableNestedTransaction: boolean;
AllowGlobalUpdate: boolean;
QueryFields: boolean;
CreateBatchSize: number;
TranslateError: boolean;
PropagateUnscoped: boolean;
ClauseBuilders: Record<string, ClauseBuilder>;
ConnPool: any;
Dialector: any;
Plugins: Record<string, any>;
Error: any;
RowsAffected: number;
Statement?: Statement;
static createFrom(source: any = {}) {
return new DB(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.SkipDefaultTransaction = source["SkipDefaultTransaction"];
this.DefaultTransactionTimeout = source["DefaultTransactionTimeout"];
this.DefaultContextTimeout = source["DefaultContextTimeout"];
this.NamingStrategy = source["NamingStrategy"];
this.FullSaveAssociations = source["FullSaveAssociations"];
this.Logger = source["Logger"];
this.DryRun = source["DryRun"];
this.PrepareStmt = source["PrepareStmt"];
this.PrepareStmtMaxSize = source["PrepareStmtMaxSize"];
this.PrepareStmtTTL = source["PrepareStmtTTL"];
this.DisableAutomaticPing = source["DisableAutomaticPing"];
this.DisableForeignKeyConstraintWhenMigrating = source["DisableForeignKeyConstraintWhenMigrating"];
this.IgnoreRelationshipsWhenMigrating = source["IgnoreRelationshipsWhenMigrating"];
this.DisableNestedTransaction = source["DisableNestedTransaction"];
this.AllowGlobalUpdate = source["AllowGlobalUpdate"];
this.QueryFields = source["QueryFields"];
this.CreateBatchSize = source["CreateBatchSize"];
this.TranslateError = source["TranslateError"];
this.PropagateUnscoped = source["PropagateUnscoped"];
this.ClauseBuilders = source["ClauseBuilders"];
this.ConnPool = source["ConnPool"];
this.Dialector = source["Dialector"];
this.Plugins = source["Plugins"];
this.Error = source["Error"];
this.RowsAffected = source["RowsAffected"];
this.Statement = this.convertValues(source["Statement"], Statement);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
}
export namespace main {
export class Response {
code: number;
message: string;
data?: any;
static createFrom(source: any = {}) {
return new Response(source);
} }
constructor(source: any = {}) { constructor(source: any = {}) {
@@ -17,5 +348,378 @@ export namespace main {
} }
} }
}
export namespace reflect {
export class StructField {
Name: string;
PkgPath: string;
Type: any;
Tag: string;
Offset: any;
Index: number[];
Anonymous: boolean;
static createFrom(source: any = {}) {
return new StructField(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.PkgPath = source["PkgPath"];
this.Type = source["Type"];
this.Tag = source["Tag"];
this.Offset = source["Offset"];
this.Index = source["Index"];
this.Anonymous = source["Anonymous"];
}
}
}
export namespace schema {
export class Reference {
PrimaryKey?: Field;
PrimaryValue: string;
ForeignKey?: Field;
OwnPrimaryKey: boolean;
static createFrom(source: any = {}) {
return new Reference(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.PrimaryKey = this.convertValues(source["PrimaryKey"], Field);
this.PrimaryValue = source["PrimaryValue"];
this.ForeignKey = this.convertValues(source["ForeignKey"], Field);
this.OwnPrimaryKey = source["OwnPrimaryKey"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Polymorphic {
PolymorphicID?: Field;
PolymorphicType?: Field;
Value: string;
static createFrom(source: any = {}) {
return new Polymorphic(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.PolymorphicID = this.convertValues(source["PolymorphicID"], Field);
this.PolymorphicType = this.convertValues(source["PolymorphicType"], Field);
this.Value = source["Value"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Relationship {
Name: string;
Type: string;
Field?: Field;
Polymorphic?: Polymorphic;
References: Reference[];
Schema?: Schema;
FieldSchema?: Schema;
JoinTable?: Schema;
static createFrom(source: any = {}) {
return new Relationship(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.Type = source["Type"];
this.Field = this.convertValues(source["Field"], Field);
this.Polymorphic = this.convertValues(source["Polymorphic"], Polymorphic);
this.References = this.convertValues(source["References"], Reference);
this.Schema = this.convertValues(source["Schema"], Schema);
this.FieldSchema = this.convertValues(source["FieldSchema"], Schema);
this.JoinTable = this.convertValues(source["JoinTable"], Schema);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Relationships {
HasOne: Relationship[];
BelongsTo: Relationship[];
HasMany: Relationship[];
Many2Many: Relationship[];
Relations: Record<string, Relationship>;
EmbeddedRelations: Record<string, Relationships>;
// Go type: sync
Mux: any;
static createFrom(source: any = {}) {
return new Relationships(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.HasOne = this.convertValues(source["HasOne"], Relationship);
this.BelongsTo = this.convertValues(source["BelongsTo"], Relationship);
this.HasMany = this.convertValues(source["HasMany"], Relationship);
this.Many2Many = this.convertValues(source["Many2Many"], Relationship);
this.Relations = this.convertValues(source["Relations"], Relationship, true);
this.EmbeddedRelations = this.convertValues(source["EmbeddedRelations"], Relationships, true);
this.Mux = this.convertValues(source["Mux"], null);
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Schema {
Name: string;
ModelType: any;
Table: string;
PrioritizedPrimaryField?: Field;
DBNames: string[];
PrimaryFields: Field[];
PrimaryFieldDBNames: string[];
Fields: Field[];
FieldsByName: Record<string, Field>;
FieldsByBindName: Record<string, Field>;
FieldsByDBName: Record<string, Field>;
FieldsWithDefaultDBValue: Field[];
Relationships: Relationships;
CreateClauses: any[];
QueryClauses: any[];
UpdateClauses: any[];
DeleteClauses: any[];
BeforeCreate: boolean;
AfterCreate: boolean;
BeforeUpdate: boolean;
AfterUpdate: boolean;
BeforeDelete: boolean;
AfterDelete: boolean;
BeforeSave: boolean;
AfterSave: boolean;
AfterFind: boolean;
static createFrom(source: any = {}) {
return new Schema(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.ModelType = source["ModelType"];
this.Table = source["Table"];
this.PrioritizedPrimaryField = this.convertValues(source["PrioritizedPrimaryField"], Field);
this.DBNames = source["DBNames"];
this.PrimaryFields = this.convertValues(source["PrimaryFields"], Field);
this.PrimaryFieldDBNames = source["PrimaryFieldDBNames"];
this.Fields = this.convertValues(source["Fields"], Field);
this.FieldsByName = this.convertValues(source["FieldsByName"], Field, true);
this.FieldsByBindName = this.convertValues(source["FieldsByBindName"], Field, true);
this.FieldsByDBName = this.convertValues(source["FieldsByDBName"], Field, true);
this.FieldsWithDefaultDBValue = this.convertValues(source["FieldsWithDefaultDBValue"], Field);
this.Relationships = this.convertValues(source["Relationships"], Relationships);
this.CreateClauses = source["CreateClauses"];
this.QueryClauses = source["QueryClauses"];
this.UpdateClauses = source["UpdateClauses"];
this.DeleteClauses = source["DeleteClauses"];
this.BeforeCreate = source["BeforeCreate"];
this.AfterCreate = source["AfterCreate"];
this.BeforeUpdate = source["BeforeUpdate"];
this.AfterUpdate = source["AfterUpdate"];
this.BeforeDelete = source["BeforeDelete"];
this.AfterDelete = source["AfterDelete"];
this.BeforeSave = source["BeforeSave"];
this.AfterSave = source["AfterSave"];
this.AfterFind = source["AfterFind"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
export class Field {
Name: string;
DBName: string;
BindNames: string[];
EmbeddedBindNames: string[];
DataType: string;
GORMDataType: string;
PrimaryKey: boolean;
AutoIncrement: boolean;
AutoIncrementIncrement: number;
Creatable: boolean;
Updatable: boolean;
Readable: boolean;
AutoCreateTime: number;
AutoUpdateTime: number;
HasDefaultValue: boolean;
DefaultValue: string;
DefaultValueInterface: any;
NotNull: boolean;
Unique: boolean;
Comment: string;
Size: number;
Precision: number;
Scale: number;
IgnoreMigration: boolean;
FieldType: any;
IndirectFieldType: any;
StructField: reflect.StructField;
Tag: string;
TagSettings: Record<string, string>;
Schema?: Schema;
EmbeddedSchema?: Schema;
OwnerSchema?: Schema;
Serializer: any;
NewValuePool: any;
UniqueIndex: string;
static createFrom(source: any = {}) {
return new Field(source);
}
constructor(source: any = {}) {
if ('string' === typeof source) source = JSON.parse(source);
this.Name = source["Name"];
this.DBName = source["DBName"];
this.BindNames = source["BindNames"];
this.EmbeddedBindNames = source["EmbeddedBindNames"];
this.DataType = source["DataType"];
this.GORMDataType = source["GORMDataType"];
this.PrimaryKey = source["PrimaryKey"];
this.AutoIncrement = source["AutoIncrement"];
this.AutoIncrementIncrement = source["AutoIncrementIncrement"];
this.Creatable = source["Creatable"];
this.Updatable = source["Updatable"];
this.Readable = source["Readable"];
this.AutoCreateTime = source["AutoCreateTime"];
this.AutoUpdateTime = source["AutoUpdateTime"];
this.HasDefaultValue = source["HasDefaultValue"];
this.DefaultValue = source["DefaultValue"];
this.DefaultValueInterface = source["DefaultValueInterface"];
this.NotNull = source["NotNull"];
this.Unique = source["Unique"];
this.Comment = source["Comment"];
this.Size = source["Size"];
this.Precision = source["Precision"];
this.Scale = source["Scale"];
this.IgnoreMigration = source["IgnoreMigration"];
this.FieldType = source["FieldType"];
this.IndirectFieldType = source["IndirectFieldType"];
this.StructField = this.convertValues(source["StructField"], reflect.StructField);
this.Tag = source["Tag"];
this.TagSettings = source["TagSettings"];
this.Schema = this.convertValues(source["Schema"], Schema);
this.EmbeddedSchema = this.convertValues(source["EmbeddedSchema"], Schema);
this.OwnerSchema = this.convertValues(source["OwnerSchema"], Schema);
this.Serializer = source["Serializer"];
this.NewValuePool = source["NewValuePool"];
this.UniqueIndex = source["UniqueIndex"];
}
convertValues(a: any, classs: any, asMap: boolean = false): any {
if (!a) {
return a;
}
if (a.slice && a.map) {
return (a as any[]).map(elem => this.convertValues(elem, classs));
} else if ("object" === typeof a) {
if (asMap) {
for (const key of Object.keys(a)) {
a[key] = new classs(a[key]);
}
return a;
}
return new classs(a);
}
return a;
}
}
} }
+10 -3
View File
@@ -2,7 +2,11 @@ module dissertation
go 1.25.0 go 1.25.0
require github.com/wailsapp/wails/v2 v2.13.0 require (
github.com/wailsapp/wails/v2 v2.13.0
gorm.io/driver/sqlite v1.6.0
gorm.io/gorm v1.31.2
)
require ( require (
git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect git.sr.ht/~jackmordaunt/go-toast/v2 v2.0.3 // indirect
@@ -12,6 +16,8 @@ require (
github.com/google/uuid v1.6.0 // indirect github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/websocket v1.5.3 // indirect github.com/gorilla/websocket v1.5.3 // indirect
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/labstack/echo/v4 v4.13.3 // indirect github.com/labstack/echo/v4 v4.13.3 // indirect
github.com/labstack/gommon v0.4.2 // indirect github.com/labstack/gommon v0.4.2 // indirect
github.com/leaanthony/go-ansi-parser v1.6.1 // indirect github.com/leaanthony/go-ansi-parser v1.6.1 // indirect
@@ -20,6 +26,7 @@ require (
github.com/leaanthony/u v1.1.1 // indirect github.com/leaanthony/u v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-sqlite3 v1.14.48 // indirect
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
github.com/pkg/errors v0.9.1 // indirect github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
@@ -31,8 +38,8 @@ require (
github.com/wailsapp/mimetype v1.4.1 // indirect github.com/wailsapp/mimetype v1.4.1 // indirect
golang.org/x/crypto v0.51.0 // indirect golang.org/x/crypto v0.51.0 // indirect
golang.org/x/net v0.54.0 // indirect golang.org/x/net v0.54.0 // indirect
golang.org/x/sys v0.44.0 // indirect golang.org/x/sys v0.46.0 // indirect
golang.org/x/text v0.37.0 // indirect golang.org/x/text v0.40.0 // indirect
) )
// replace github.com/wailsapp/wails/v2 v2.12.0 => C:\Users\夏东亮\go\pkg\mod // replace github.com/wailsapp/wails/v2 v2.12.0 => C:\Users\夏东亮\go\pkg\mod
+14 -4
View File
@@ -14,6 +14,10 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e h1:Q3+PugElBCf4PFpxhErSzU3/PY5sFL5Z6rfv4AbGAck=
github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs= github.com/jchv/go-winloader v0.0.0-20210711035445-715c2860da7e/go.mod h1:alcuEEnZsY1WQsagKhZDsoPCRoOijYqhZvPwLG0kzVs=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY= github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g= github.com/labstack/echo/v4 v4.13.3/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
@@ -36,6 +40,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.48 h1:7XHIgl0a8HwOaiK4E47ozLkST78rR9+OtNGx27D/TFs=
github.com/mattn/go-sqlite3 v1.14.48/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -72,12 +78,16 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/gorm v1.31.2 h1:3o8FXNo9v9S858gil+3LlZA1LkCOzgb4g5BL64FgaCo=
gorm.io/gorm v1.31.2/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
+4 -3
View File
@@ -17,9 +17,10 @@ func main() {
// Create application with options // Create application with options
err := wails.Run(&options.App{ err := wails.Run(&options.App{
Title: "dissertation", Title: "分类喵",
Width: 1024, Width: 1024,
Height: 768, Height: 768,
DisableResize: true,
AssetServer: &assetserver.Options{ AssetServer: &assetserver.Options{
Assets: assets, Assets: assets,
}, },
+53 -5
View File
@@ -1,7 +1,55 @@
package main package main
type ImageResult struct { import (
Code int `json:"code"` "context"
Message string `json:"message"` )
Data string `json:"data,omitempty"` // 成功时返回文件路径
} type (
App struct {
ctx context.Context
}
Response struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data,omitempty"`
}
HistoryItem struct {
Id uint `gorm:"primaryKey"`
Img string `gorm:"column:img"`
Breed int `gorm:"column:breed"`
Date int `gorm:"column:date"`
}
HistoryWithBreed struct {
Id uint `gorm:"column:id" json:"id"`
Img string `gorm:"column:img" json:"img"`
Breed int `gorm:"column:breed" json:"breed"`
Date int `gorm:"column:date" json:"date"`
Name string `gorm:"column:name" json:"name"`
Brief string `gorm:"column:brief" json:"brief"`
}
HistoryData struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
Total int64 `json:"total"`
List []HistoryWithBreed `json:"list"`
}
Breed struct {
Id uint `gorm:"primaryKey"`
Code string `gorm:"column:code"`
Name string `gorm:"column:name"`
Brief string `gorm:"column:brief"`
}
DetectData struct {
Id uint `json:"id"`
Code string `json:"code"`
Name string `json:"name"`
Brief string `json:"brief"`
ConfidenceLevel float32 `json:"confidence_level"`
}
)