7.21 big change
This commit is contained in:
@@ -7,45 +7,36 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"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 {
|
||||
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) {
|
||||
a.ctx = ctx
|
||||
}
|
||||
|
||||
// Greet returns a greeting for the given name
|
||||
|
||||
func (a *App) Greet(name string) string {
|
||||
return fmt.Sprintf("Hello %s, It's show time!", name)
|
||||
}
|
||||
|
||||
func (a *App) Login() string {
|
||||
println("1111")
|
||||
return ""
|
||||
func (a *App) GormDB() (*gorm.DB, error) {
|
||||
db, err := gorm.Open(sqlite.Open("app.db"), &gorm.Config{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func (a *App) Register() string {
|
||||
println("1111")
|
||||
return ""
|
||||
}
|
||||
|
||||
func (a *App) UploadImage(data []byte, filename string) ImageResult {
|
||||
func (a *App) UploadImage(data []byte, filename string) Response {
|
||||
uploadsDir := "./uploads"
|
||||
err := os.MkdirAll(uploadsDir, 0755)
|
||||
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)
|
||||
@@ -54,26 +45,97 @@ func (a *App) UploadImage(data []byte, filename string) ImageResult {
|
||||
|
||||
err = os.WriteFile(filePath, data, 0644)
|
||||
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)
|
||||
fmt.Println("filePath", filePath)
|
||||
|
||||
data, err := os.ReadFile(filePath)
|
||||
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)
|
||||
mimeType := "image/jpeg"
|
||||
if ext == ".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"}
|
||||
}
|
||||
|
||||
Generated
+1680
File diff suppressed because it is too large
Load Diff
@@ -15,6 +15,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@preact/preset-vite": "^2.3.0",
|
||||
"sharp": "^0.35.3",
|
||||
"to-ico": "^1.1.5",
|
||||
"typescript": "^4.6.4",
|
||||
"vite": "^8.1.4"
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
@@ -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 |
@@ -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
|
||||
@@ -1,11 +1,9 @@
|
||||
export const Footer = () => {
|
||||
return (
|
||||
export const Footer = () => (
|
||||
<footer class="app-footer">
|
||||
<span>https://pytorch.org/</span>
|
||||
<span>📩 xiadongliang88@163.com</span>
|
||||
<span>|</span>
|
||||
<span>https://wails.io/</span>
|
||||
<span>📦 https://git.leonstack.com/owner</span>
|
||||
<span>|</span>
|
||||
<span>https://preactjs.com/</span>
|
||||
<span>🌏 https://www.leonstack.com/</span>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -1,82 +1,95 @@
|
||||
import { useState, useEffect } from 'preact/hooks'
|
||||
import { message } from '../utils/toast'
|
||||
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 = [
|
||||
{
|
||||
id: 1,
|
||||
breeds: '英短&1212',
|
||||
desc: 'The Maine Coon is a large, friendly cat breed known for its tufted ears.',
|
||||
img: '../../',
|
||||
date: 'Jan 15, 2024',
|
||||
},
|
||||
{
|
||||
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',
|
||||
},
|
||||
]
|
||||
interface IHistoryItem {
|
||||
id: number
|
||||
img: string
|
||||
breed: number
|
||||
date: number
|
||||
name: string
|
||||
brief: string
|
||||
}
|
||||
|
||||
const History = () => {
|
||||
const [page, setPage] = useState<number>(1)
|
||||
const pageSize = 5
|
||||
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) => {
|
||||
// setPage(page)
|
||||
// loadTranscript(currentNav, currentOpt, page).then(res => {
|
||||
// if (res && res.code === 0) {
|
||||
// setData(res.data.data)
|
||||
// setTotal(res.data.total)
|
||||
// }
|
||||
// }).catch(e => message.error(e.toString()))
|
||||
const fetchData = async(page: number) => {
|
||||
const result = await (window as any).go.main.App.GetHistory(page, pageSize)
|
||||
if (result.code === 0) {
|
||||
setHistoryList(result.data.list)
|
||||
setTotal(result.data.total)
|
||||
} else if (result.code === 1) {
|
||||
message.error(result.message)
|
||||
}
|
||||
}
|
||||
|
||||
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 (
|
||||
<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 class="card-left">
|
||||
<img src="../assets/images/0012.jpg" />
|
||||
</div>
|
||||
<div class="card-right">
|
||||
<div class="right-top">
|
||||
<h3>{item.breeds}</h3>
|
||||
<span>{item.date}</span>
|
||||
<h3>{item.name}</h3>
|
||||
<div class="card-actions">
|
||||
<span>{formatDate(item.date)}</span>
|
||||
<button onClick={() => handleDelete(item.id)} title="删除">
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-overview">
|
||||
{item.desc}
|
||||
{item.brief}
|
||||
</div>
|
||||
</div>
|
||||
</div>)
|
||||
}
|
||||
|
||||
<div class="history-pagination">
|
||||
<Pagination page={page} pagesize={5} total={total} onChange={handlePageChange} />
|
||||
<Pagination page={page} pagesize={pageSize} total={total} onChange={handlePageChange} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -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 fileInputRef = useRef<HTMLInputElement>(null)
|
||||
const [fileName, setFileName] = 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 target = e.target as HTMLInputElement
|
||||
@@ -56,13 +62,20 @@ const Main = () => {
|
||||
const handleDetect = () => {
|
||||
setStep(2)
|
||||
|
||||
setTimeout(() => {
|
||||
setTimeout(async() => {
|
||||
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)
|
||||
}
|
||||
|
||||
const handleTryOther = () => {
|
||||
setStep(0)
|
||||
setDetectResult(null)
|
||||
resetUpload()
|
||||
}
|
||||
|
||||
@@ -74,9 +87,14 @@ const Main = () => {
|
||||
发现<span>它</span>的<span>分类</span>
|
||||
</h1>
|
||||
<p>
|
||||
上传一张猫咪照片,让AI不仅认出它<span>是什么</span>
|
||||
上传一张猫咪照片,让AI认出它<span>是什么</span>
|
||||
</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 class={`upload${!(step == 0 || step == 1 || step == 2) ? ' hidden' : ''}`}>
|
||||
<div
|
||||
@@ -125,7 +143,7 @@ const Main = () => {
|
||||
}
|
||||
</div>
|
||||
{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">
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
@@ -142,60 +160,30 @@ const Main = () => {
|
||||
<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" />
|
||||
</svg>
|
||||
<h2>检测完成!</h2>
|
||||
<h2>完成!</h2>
|
||||
</div>
|
||||
<div class="result-main">
|
||||
<img />
|
||||
<div class="result-word">
|
||||
<div>
|
||||
<h3>异国短毛猫</h3>
|
||||
<h3>{detectResult?.name}</h3>
|
||||
<div>
|
||||
<div class="probability-bar">
|
||||
<div />
|
||||
</div>
|
||||
<span>可信度 78%</span>
|
||||
<span>置信度 {detectResult ? detectResult.confidence_level * 100 + '%' : ''}</span>
|
||||
</div>
|
||||
</div>
|
||||
<h4>关于英短</h4>
|
||||
<p>尽量快点附近的路口附近的联发科九点零分肌肤的路口附近登陆反对浪费空间 尽量快点附近的路口附近的联发科九点零分肌肤的路口附近登陆反对浪费空间</p>
|
||||
<p>{detectResult?.brief}</p>
|
||||
</div>
|
||||
</div>
|
||||
<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>
|
||||
</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>
|
||||
</main>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 handleClick = () => window.open('https://git.leonstack.com/Leon/Collage-Images', '_blank')
|
||||
const handleClick = () => window.open('https://git.leonstack.com/owner/Collage-Images', '_blank')
|
||||
|
||||
return (
|
||||
<nav class="app-navbar animate-fade-in">
|
||||
@@ -10,13 +10,12 @@ export const Navbar = () => {
|
||||
<svg class="icon" viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d={svgPath} />
|
||||
</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 class="container-right">
|
||||
<a href="/">主页</a>
|
||||
<a href="/history">历史记录</a>
|
||||
<a href="/dashboard">后台管理</a>
|
||||
<button onClick={handleClick}>代码仓库</button>
|
||||
<button onClick={handleClick}>查看代码</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
@@ -45,14 +45,17 @@ const Pagination = ({
|
||||
|
||||
const handleEnterPress = (e: KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (parseInt(value) <= seqNums.length && parseInt(value) > 0) {
|
||||
handleChangeNum(parseInt(value))
|
||||
} else if (parseInt(value) >= seqNums.length) {
|
||||
const target = e.target as HTMLInputElement
|
||||
const page = parseInt(target.value)
|
||||
if (page >= 1 && page <= seqNums.length) {
|
||||
handleChangeNum(page)
|
||||
onChange(page)
|
||||
} else if (page > seqNums.length) {
|
||||
handleChangeNum(seqNums.length)
|
||||
} else if (parseInt(value) < seqNums.length) {
|
||||
handleChangeNum(1)
|
||||
onChange(seqNums.length)
|
||||
} else {
|
||||
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
|
||||
@@ -2,26 +2,18 @@ import { Router, Route } from "preact-router"
|
||||
import { Navbar } from "../components/Navbar"
|
||||
import Main from "../components/Main"
|
||||
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 '../styles/base.sass'
|
||||
import '../styles/history.sass'
|
||||
import '../styles/pagination.sass'
|
||||
import '../styles/dashboard.sass'
|
||||
|
||||
|
||||
export function App(props: any) {
|
||||
export function App() {
|
||||
return (
|
||||
<div id="App">
|
||||
<Navbar />
|
||||
<Router>
|
||||
<Route path="/" component={Main} />
|
||||
<Route path="/dashboard" component={Dashboard} />
|
||||
<Route path="/history" component={History} />
|
||||
<Route path="/dashboard/datasets" component={TrainsetManagement} />
|
||||
<Route path="/dashboard/testsets" component={TestsetManagement} />
|
||||
</Router>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ body
|
||||
margin: 0
|
||||
color: white
|
||||
font-family: "Nunito", -apple-system, BlinkMacSystemFont, "Segoe UI"
|
||||
overflow: hidden
|
||||
|
||||
@font-face
|
||||
font-family: "Nunito"
|
||||
@@ -17,11 +18,16 @@ body
|
||||
font-family: "ZcoolHappy"
|
||||
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
|
||||
--primary: #3B82F6
|
||||
--title: #1e293b
|
||||
--text:#5f6874
|
||||
--textsub: #878d95
|
||||
--sub-title: #5f6874
|
||||
--text:#5D5D5D
|
||||
--textsub: #979797
|
||||
|
||||
#app
|
||||
height: 100vh
|
||||
@@ -41,7 +47,7 @@ body
|
||||
width: 100%
|
||||
margin: 0 auto
|
||||
padding: 0.6rem 1.2rem
|
||||
background-color: #FFFFFF
|
||||
background-color: white
|
||||
backdrop-filter: blur(8px)
|
||||
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)
|
||||
@@ -77,7 +83,7 @@ body
|
||||
width: 7rem
|
||||
height: 2.6rem
|
||||
margin-left: 1.5rem
|
||||
color: #FFFFFF
|
||||
color: white
|
||||
font-size: 0.9375rem
|
||||
background-color: var(--primary)
|
||||
border-radius: 0.5rem
|
||||
@@ -113,7 +119,7 @@ body
|
||||
|
||||
> p
|
||||
text-align: center
|
||||
color: var(--text)
|
||||
color: var(--sub-title)
|
||||
font-size: 1.0625rem
|
||||
margin-bottom: 1rem
|
||||
max-width: 42rem
|
||||
@@ -123,6 +129,8 @@ body
|
||||
color: var(--primary)
|
||||
|
||||
> i
|
||||
display: flex
|
||||
align-items: center
|
||||
font-style: normal
|
||||
text-align: center
|
||||
color: #FFD572
|
||||
@@ -130,7 +138,12 @@ body
|
||||
margin: 0 auto
|
||||
padding: 0.25rem 0.75rem
|
||||
background-color: #38383D
|
||||
border-radius: 0.2rem
|
||||
border-radius: 0.25rem
|
||||
gap: 0.25rem
|
||||
|
||||
> svg
|
||||
width: 0.625rem
|
||||
height: 0.625rem
|
||||
|
||||
.upload
|
||||
width: 32rem
|
||||
@@ -147,7 +160,6 @@ body
|
||||
border-width: 2px
|
||||
border-style: dashed
|
||||
border-color: #e2e8f0
|
||||
border-style: dashed
|
||||
text-align: center
|
||||
cursor: pointer
|
||||
|
||||
@@ -175,8 +187,7 @@ body
|
||||
|
||||
> img
|
||||
max-height: 10.5rem
|
||||
margin-left: auto
|
||||
margin-right: auto
|
||||
margin: 0 auto
|
||||
margin-bottom: 0.25rem
|
||||
border-radius: 1rem
|
||||
object-fit: cover
|
||||
@@ -195,7 +206,7 @@ body
|
||||
.zone-loading
|
||||
padding: 2rem
|
||||
text-align: center
|
||||
background-color: #FFFFFF
|
||||
background-color: white
|
||||
border-radius: 1.5rem
|
||||
|
||||
.loading-spinner
|
||||
@@ -223,25 +234,26 @@ body
|
||||
font-size: 1rem
|
||||
color: var(--textsub)
|
||||
|
||||
>button#detectBtn
|
||||
width: 12rem
|
||||
height: 3.5rem
|
||||
> button
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 9rem
|
||||
height: 3rem
|
||||
margin: 1rem auto 0 auto
|
||||
background-color: var(--primary)
|
||||
color: white
|
||||
font-weight: 600
|
||||
font-size: 1.125rem
|
||||
border-radius: 0.75rem
|
||||
border-radius: 0.5rem
|
||||
transition: background-color 200ms, color 200ms
|
||||
cursor: pointer
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
gap: 0.5rem
|
||||
|
||||
gap: 0.25rem
|
||||
|
||||
> svg
|
||||
width: 1.5rem
|
||||
height: 1.5rem
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
.result
|
||||
width: 35rem
|
||||
@@ -251,6 +263,7 @@ body
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
height: 2.25rem
|
||||
gap: 0.75rem
|
||||
margin-bottom: 1.5rem
|
||||
|
||||
@@ -260,8 +273,8 @@ body
|
||||
color: var(--primary)
|
||||
|
||||
> h2
|
||||
font-family: "ZcoolHappy"
|
||||
font-weight: 700
|
||||
font-family: "SANS_SC_BOLD"
|
||||
font-weight: bold
|
||||
font-size: 1.5rem
|
||||
color: var(--title)
|
||||
|
||||
@@ -270,7 +283,7 @@ body
|
||||
min-height: 10rem
|
||||
padding: 1rem 1rem
|
||||
margin-bottom: 1.5rem
|
||||
background-color: #ffffff
|
||||
background-color: white
|
||||
border-radius: 1rem
|
||||
border: 1px solid var(--color-border)
|
||||
gap: 2rem
|
||||
@@ -293,7 +306,7 @@ body
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
width: 100%
|
||||
padding-bottom: 1rem
|
||||
padding-bottom: 0.75rem
|
||||
margin-bottom: 1rem
|
||||
border-bottom: 1px solid #c6c6c6
|
||||
|
||||
@@ -333,14 +346,6 @@ body
|
||||
|
||||
> span
|
||||
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
|
||||
color: var(--text)
|
||||
@@ -348,17 +353,24 @@ body
|
||||
font-size: 0.875rem
|
||||
|
||||
> button
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
width: 9rem
|
||||
height: 3rem
|
||||
background-color: var(--primary)
|
||||
margin: 0 auto
|
||||
color: white
|
||||
font-weight: 600
|
||||
font-size: 1.125rem
|
||||
background-color: var(--primary)
|
||||
border-radius: 0.5rem
|
||||
transition: background-color 200ms, color 200ms
|
||||
cursor: pointer
|
||||
gap: 0.25rem
|
||||
|
||||
|
||||
> svg
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
.app-footer
|
||||
display: flex
|
||||
@@ -375,56 +387,44 @@ body
|
||||
font-size: 0.8rem
|
||||
margin: 0 0.5rem
|
||||
|
||||
@media (prefers-reduced-motion: reduce)
|
||||
.animate-fade-in,
|
||||
.animate-slide-up,
|
||||
.animate-pulse-slow
|
||||
animation: none !important
|
||||
transition: none !important
|
||||
.message
|
||||
width: 100%
|
||||
height: 2rem
|
||||
position: fixed
|
||||
top: 6.25rem
|
||||
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
|
||||
from
|
||||
opacity: 0
|
||||
to
|
||||
opacity: 1
|
||||
.success, .error
|
||||
display: inline-flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
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
|
||||
from
|
||||
opacity: 0
|
||||
transform: translateY(20px)
|
||||
to
|
||||
opacity: 1
|
||||
transform: translateY(0)
|
||||
> span
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
|
||||
@keyframes pulseSlow
|
||||
0%, 100%
|
||||
opacity: 1
|
||||
50%
|
||||
opacity: 0.7
|
||||
> svg
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
line-height: 2rem
|
||||
|
||||
.animate-fade-in
|
||||
animation: fadeIn 0.3s ease-out forwards
|
||||
|
||||
.animate-slide-up
|
||||
animation: slideUp 0.4s ease-out forwards
|
||||
|
||||
.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
|
||||
> p
|
||||
max-width: 24rem
|
||||
color: var(--text)
|
||||
overflow: hidden
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
@@ -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
|
||||
@@ -3,7 +3,18 @@
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
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
|
||||
display: flex
|
||||
@@ -33,25 +44,52 @@
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: space-between
|
||||
gap: 1rem
|
||||
|
||||
> h3
|
||||
width: 6rem
|
||||
color: #333333
|
||||
font-size: 1rem
|
||||
font-weight: bold
|
||||
text-align: left
|
||||
|
||||
.card-actions
|
||||
display: flex
|
||||
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
|
||||
width: 100%
|
||||
margin-top: 0.25rem
|
||||
color: #cccccc
|
||||
font-size: 0.9rem
|
||||
text-align: left
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
|
||||
.history-pagination
|
||||
width: calc(100% - 20rem)
|
||||
margin-top: 1rem
|
||||
margin-top: 0.5rem
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
|
||||
.pagination-word
|
||||
font-size: 0.75rem
|
||||
font-weight: bold
|
||||
margin: 0 0.3125rem 0 0.3125rem
|
||||
color: #333333
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
Vendored
+11
-6
@@ -1,13 +1,18 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// This file is automatically generated. DO NOT EDIT
|
||||
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 Login():Promise<string>;
|
||||
|
||||
export function Register():Promise<string>;
|
||||
|
||||
export function UploadImage(arg1:Array<number>,arg2:string):Promise<main.ImageResult>;
|
||||
export function UploadImage(arg1:Array<number>,arg2:string):Promise<main.Response>;
|
||||
|
||||
@@ -2,22 +2,30 @@
|
||||
// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
|
||||
// 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) {
|
||||
return window['go']['main']['App']['GetImage'](arg1);
|
||||
}
|
||||
|
||||
export function GormDB() {
|
||||
return window['go']['main']['App']['GormDB']();
|
||||
}
|
||||
|
||||
export function 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) {
|
||||
return window['go']['main']['App']['UploadImage'](arg1, arg2);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,343 @@
|
||||
export namespace main {
|
||||
export namespace clause {
|
||||
|
||||
export class ImageResult {
|
||||
code: number;
|
||||
message: string;
|
||||
data?: string;
|
||||
export class Clause {
|
||||
Name: string;
|
||||
BeforeExpression: any;
|
||||
AfterNameExpression: any;
|
||||
AfterExpression: any;
|
||||
Expression: 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 = {}) {
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,11 @@ module dissertation
|
||||
|
||||
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 (
|
||||
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/gorilla/websocket v1.5.3 // 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/gommon v0.4.2 // 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/mattn/go-colorable v0.1.13 // 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/errors v0.9.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
@@ -31,8 +38,8 @@ require (
|
||||
github.com/wailsapp/mimetype v1.4.1 // indirect
|
||||
golang.org/x/crypto v0.51.0 // indirect
|
||||
golang.org/x/net v0.54.0 // indirect
|
||||
golang.org/x/sys v0.44.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
golang.org/x/sys v0.46.0 // indirect
|
||||
golang.org/x/text v0.40.0 // indirect
|
||||
)
|
||||
|
||||
// replace github.com/wailsapp/wails/v2 v2.12.0 => C:\Users\夏东亮\go\pkg\mod
|
||||
|
||||
@@ -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/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/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/go.mod h1:o90YNEeQWjDozo584l7AwhJMHN0bOC4tAfg+Xox9q5g=
|
||||
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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
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/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
|
||||
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.1.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.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
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/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
|
||||
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=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
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=
|
||||
|
||||
@@ -17,9 +17,10 @@ func main() {
|
||||
|
||||
// Create application with options
|
||||
err := wails.Run(&options.App{
|
||||
Title: "dissertation",
|
||||
Title: "分类喵",
|
||||
Width: 1024,
|
||||
Height: 768,
|
||||
DisableResize: true,
|
||||
AssetServer: &assetserver.Options{
|
||||
Assets: assets,
|
||||
},
|
||||
|
||||
@@ -1,7 +1,55 @@
|
||||
package main
|
||||
|
||||
type ImageResult struct {
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type (
|
||||
App struct {
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
Response struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
Data string `json:"data,omitempty"` // 成功时返回文件路径
|
||||
}
|
||||
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"`
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user