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
+1680
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -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.

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 = () => {
return (
<footer class="app-footer">
<span>https://pytorch.org/</span>
<span>|</span>
<span>https://wails.io/</span>
<span>|</span>
<span>https://preactjs.com/</span>
</footer>
)
}
export const Footer = () => (
<footer class="app-footer">
<span>📩 xiadongliang88@163.com</span>
<span>|</span>
<span>📦 https://git.leonstack.com/owner</span>
<span>|</span>
<span>🌏 https://www.leonstack.com/</span>
</footer>
)
+64 -51
View File
@@ -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>
)
+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 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(() => {
setStep(3)
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>
)
+3 -4
View File
@@ -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>
+8 -5
View File
@@ -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
+1 -9
View File
@@ -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>
+83 -83
View File
@@ -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
-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
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,15 +44,39 @@
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
> span
color: #cccccc
font-size: 0.8rem
.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%
@@ -49,9 +84,12 @@
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
-1
View File
@@ -59,7 +59,6 @@
.pagination-word
font-size: 0.75rem
font-weight: bold
margin: 0 0.3125rem 0 0.3125rem
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
// 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>;
+16 -8
View File
@@ -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);
}
+710 -6
View File
@@ -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;
}
}
}