Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
N
Neos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
love_飞影
Neos
Commits
da5f8e50
Commit
da5f8e50
authored
Aug 10, 2023
by
Chunchi Che
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update sqlite
parent
0d3c3239
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
52 deletions
+88
-52
src/api/cards.ts
src/api/cards.ts
+3
-6
src/middleware/sqlite/fts.ts
src/middleware/sqlite/fts.ts
+74
-0
src/middleware/sqlite/index.ts
src/middleware/sqlite/index.ts
+6
-40
src/ui/BuildDeck/DeckSelect.tsx
src/ui/BuildDeck/DeckSelect.tsx
+1
-1
src/ui/BuildDeck/index.tsx
src/ui/BuildDeck/index.tsx
+4
-5
No files found.
src/api/cards.ts
View file @
da5f8e50
import
sqliteMiddleWare
,
{
sqliteCmd
}
from
"
@/middleware/sqlite
"
;
import
sqliteMiddleWare
,
{
sqliteCmd
}
from
"
@/middleware/sqlite
"
;
import
{
FtsParams
}
from
"
@/middleware/sqlite/fts
"
;
export
interface
CardMeta
{
export
interface
CardMeta
{
id
:
number
;
id
:
number
;
...
@@ -62,14 +63,10 @@ export async function fetchCard(id: number): Promise<CardMeta> {
...
@@ -62,14 +63,10 @@ export async function fetchCard(id: number): Promise<CardMeta> {
* @returns 卡片数据
* @returns 卡片数据
*
*
* */
* */
export
async
function
searchCards
(
export
async
function
searchCards
(
params
:
FtsParams
):
Promise
<
CardMeta
[]
>
{
query
:
string
,
type
?:
number
):
Promise
<
CardMeta
[]
>
{
// TODO: 让type支持多种filter类型
const
res
=
await
sqliteMiddleWare
({
const
res
=
await
sqliteMiddleWare
({
cmd
:
sqliteCmd
.
FTS
,
cmd
:
sqliteCmd
.
FTS
,
payload
:
{
query
,
type
},
payload
:
{
ftsParams
:
params
},
});
});
return
res
.
ftsResult
??
[];
return
res
.
ftsResult
??
[];
}
}
...
...
src/middleware/sqlite/fts.ts
0 → 100644
View file @
da5f8e50
import
{
Database
}
from
"
sql.js
"
;
import
{
CardData
,
CardMeta
,
CardText
}
from
"
@/api
"
;
interface
FtsConditions
{
// 过滤条件
types
?:
number
[];
// 卡片类型
levels
?:
number
[];
// 星阶/刻度/link值
atk
?:
[
number
,
number
];
// 攻击力区间
def
?:
[
number
,
number
];
// 防御力区间
race
?:
number
;
// 种族
attribute
?:
number
;
// 属性
}
export
interface
FtsParams
{
query
:
string
;
// 用于全文检索的query
conditions
:
FtsConditions
;
// 过滤条件
}
export
function
invokeFts
(
db
:
Database
,
params
:
FtsParams
):
CardMeta
[]
{
const
{
query
,
conditions
}
=
params
;
const
ftsTexts
:
CardText
[]
=
[];
const
ftsMetas
:
CardMeta
[]
=
[];
const
textStmt
=
db
.
prepare
(
"
SELECT * FROM texts WHERE name LIKE $query
"
);
textStmt
.
bind
({
$query
:
`%
${
query
}
%`
});
while
(
textStmt
.
step
())
{
const
row
=
textStmt
.
getAsObject
();
ftsTexts
.
push
(
row
);
}
for
(
const
text
of
ftsTexts
)
{
const
id
=
text
.
id
;
if
(
id
)
{
const
sql
=
`SELECT * FROM datas
${
getFtsCondtions
(
conditions
)}
`
;
const
dataStmt
=
db
.
prepare
(
sql
);
const
data
:
CardData
=
dataStmt
.
getAsObject
({
$id
:
id
});
ftsMetas
.
push
({
id
,
data
,
text
});
}
}
return
ftsMetas
;
}
function
getFtsCondtions
(
conditions
:
FtsConditions
):
string
{
const
{
types
,
levels
,
atk
,
def
,
race
,
attribute
}
=
conditions
;
const
typesCondition
=
types
?.
map
((
type
)
=>
`(types &
${
type
}
) > 0`
)
.
join
(
"
OR
"
);
const
levelsCondition
=
levels
?.
map
((
level
)
=>
`level =
${
level
}
`
)
.
join
(
"
OR
"
);
const
atkCondition
=
atk
?
`atk BETWEEN
${
atk
[
0
]}
AND
${
atk
[
1
]}
`
:
undefined
;
const
defCondition
=
def
?
`def BETWEEN
${
def
[
0
]}
AND
${
def
[
1
]}
`
:
undefined
;
const
raceCondition
=
race
!==
undefined
?
`race =
${
race
}
`
:
undefined
;
const
attributeCondition
=
attribute
!==
undefined
?
`attribute =
${
attribute
}
`
:
undefined
;
const
merged
=
[
typesCondition
,
levelsCondition
,
atkCondition
,
defCondition
,
raceCondition
,
attributeCondition
,
]
.
filter
((
condition
)
=>
condition
!==
undefined
)
.
map
((
condition
)
=>
`(
${
condition
}
)`
)
.
join
(
"
AND
"
);
return
merged
!==
""
?
`WHERE
${
merged
}
`
:
""
;
}
src/middleware/sqlite.ts
→
src/middleware/sqlite
/index
.ts
View file @
da5f8e50
...
@@ -11,6 +11,8 @@ import { CardData, CardMeta, CardText } from "@/api/cards";
...
@@ -11,6 +11,8 @@ import { CardData, CardMeta, CardText } from "@/api/cards";
import
{
useConfig
}
from
"
@/config
"
;
import
{
useConfig
}
from
"
@/config
"
;
import
{
pfetch
}
from
"
@/infra
"
;
import
{
pfetch
}
from
"
@/infra
"
;
import
{
FtsParams
,
invokeFts
}
from
"
./fts
"
;
const
NeosConfig
=
useConfig
();
const
NeosConfig
=
useConfig
();
export
enum
sqliteCmd
{
export
enum
sqliteCmd
{
...
@@ -29,11 +31,9 @@ export interface sqliteAction {
...
@@ -29,11 +31,9 @@ export interface sqliteAction {
dbUrl
:
string
;
dbUrl
:
string
;
progressCallback
?:
(
progress
:
number
)
=>
void
;
// 用于获取读取进度
progressCallback
?:
(
progress
:
number
)
=>
void
;
// 用于获取读取进度
};
};
// 需要读取卡牌数据的ID
payload
?:
{
payload
?:
{
id
?:
number
;
// 卡牌ID
id
?:
number
;
// 卡牌ID
query
?:
string
;
// 用于全文检索的query
ftsParams
?:
FtsParams
;
// 用于全文检索的参数
type
?:
number
;
// 通过`type`过滤
};
};
}
}
...
@@ -89,44 +89,10 @@ export default async function (action: sqliteAction): Promise<sqliteResult> {
...
@@ -89,44 +89,10 @@ export default async function (action: sqliteAction): Promise<sqliteResult> {
return
{};
return
{};
}
}
case
sqliteCmd
.
FTS
:
{
case
sqliteCmd
.
FTS
:
{
if
(
YGODB
&&
action
.
payload
&&
action
.
payload
.
query
)
{
if
(
YGODB
&&
action
.
payload
&&
action
.
payload
.
ftsParams
)
{
// TODO: 这里应该可以优化为联表查询
const
metas
=
invokeFts
(
YGODB
,
action
.
payload
.
ftsParams
);
const
query
=
action
.
payload
.
query
;
const
type
=
action
.
payload
.
type
;
const
ftsTexts
:
CardText
[]
=
[];
const
ftsMetas
:
CardMeta
[]
=
[];
const
textStmt
=
YGODB
.
prepare
(
"
SELECT * FROM texts WHERE name LIKE $query
"
);
textStmt
.
bind
({
$query
:
`%
${
query
}
%`
});
while
(
textStmt
.
step
())
{
const
row
=
textStmt
.
getAsObject
();
ftsTexts
.
push
(
row
);
}
for
(
const
text
of
ftsTexts
)
{
const
id
=
text
.
id
;
if
(
id
&&
type
!==
undefined
)
{
const
sql
=
"
SELECT * FROM datas WHERE ID = $id AND type = $type
"
;
const
dataStmt
=
YGODB
.
prepare
(
sql
);
const
data
:
CardData
=
dataStmt
.
getAsObject
({
$id
:
id
,
$type
:
type
,
});
ftsMetas
.
push
({
id
,
data
,
text
});
}
else
if
(
id
)
{
const
sql
=
"
SELECT * FROM datas WHERE ID = $id
"
;
const
dataStmt
=
YGODB
.
prepare
(
sql
);
const
data
:
CardData
=
dataStmt
.
getAsObject
({
$id
:
id
});
ftsMetas
.
push
({
id
,
data
,
text
});
}
}
return
{
ftsResult
:
ftsM
etas
};
return
{
ftsResult
:
m
etas
};
}
else
{
}
else
{
console
.
warn
(
"
ygo db not init or query not provied!
"
);
console
.
warn
(
"
ygo db not init or query not provied!
"
);
}
}
...
...
src/ui/BuildDeck/DeckSelect.tsx
View file @
da5f8e50
import
{
import
{
DeleteOutlined
,
DeleteOutlined
,
DownloadOutlined
,
DownloadOutlined
,
PlusOutlined
,
FileAddOutlined
,
FileAddOutlined
,
PlusOutlined
,
}
from
"
@ant-design/icons
"
;
}
from
"
@ant-design/icons
"
;
import
{
Button
,
Dropdown
,
MenuProps
}
from
"
antd
"
;
import
{
Button
,
Dropdown
,
MenuProps
}
from
"
antd
"
;
...
...
src/ui/BuildDeck/index.tsx
View file @
da5f8e50
...
@@ -13,10 +13,10 @@ import {
...
@@ -13,10 +13,10 @@ import {
Button
,
Button
,
ConfigProvider
,
ConfigProvider
,
Input
,
Input
,
Dropdown
,
Space
,
Space
,
type
ThemeConfig
,
type
ThemeConfig
,
}
from
"
antd
"
;
}
from
"
antd
"
;
import
classNames
from
"
classnames
"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"
react
"
;
import
{
memo
,
useEffect
,
useRef
,
useState
}
from
"
react
"
;
import
{
DndProvider
,
useDrag
,
useDrop
}
from
"
react-dnd
"
;
import
{
DndProvider
,
useDrag
,
useDrop
}
from
"
react-dnd
"
;
import
{
HTML5Backend
}
from
"
react-dnd-html5-backend
"
;
import
{
HTML5Backend
}
from
"
react-dnd-html5-backend
"
;
...
@@ -48,7 +48,6 @@ import {
...
@@ -48,7 +48,6 @@ import {
iDeckToEditingDeck
,
iDeckToEditingDeck
,
type
Type
,
type
Type
,
}
from
"
./utils
"
;
}
from
"
./utils
"
;
import
classNames
from
"
classnames
"
;
const
theme
:
ThemeConfig
=
{
const
theme
:
ThemeConfig
=
{
components
:
{
components
:
{
...
@@ -209,9 +208,9 @@ const Search: React.FC = () => {
...
@@ -209,9 +208,9 @@ const Search: React.FC = () => {
const
[
searchWord
,
setSearchWord
]
=
useState
(
""
);
const
[
searchWord
,
setSearchWord
]
=
useState
(
""
);
const
[
searchResult
,
setSearchResult
]
=
useState
<
CardMeta
[]
>
([]);
const
[
searchResult
,
setSearchResult
]
=
useState
<
CardMeta
[]
>
([]);
const
handleSearch
=
async
()
=>
{
const
handleSearch
=
async
()
=>
{
const
result
=
(
await
searchCards
(
searchWord
)).
filter
(
const
result
=
(
(
card
)
=>
!
isToken
(
card
.
data
.
type
??
0
)
await
searchCards
({
query
:
searchWord
,
conditions
:
{}
}
)
);
// 衍生物不显示
)
.
filter
((
card
)
=>
!
isToken
(
card
.
data
.
type
??
0
))
;
// 衍生物不显示
setSearchResult
(
result
);
setSearchResult
(
result
);
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment