Skip to content

Commit a840ac1

Browse files
committed
feat: 歌曲搜索
1 parent 3a597f5 commit a840ac1

File tree

6 files changed

+59
-80
lines changed

6 files changed

+59
-80
lines changed

AquaMai

MaiChartManager/Front/package.json

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@
1111
},
1212
"devDependencies": {
1313
"@fontsource/nerko-one": "^5.1.0",
14-
"@iconify-json/fluent": "^1.2.2",
15-
"@iconify-json/ic": "^1.2.0",
16-
"@iconify-json/material-symbols": "^1.2.2",
17-
"@iconify-json/mdi": "^1.2.0",
18-
"@iconify-json/ph": "^1.2.0",
19-
"@iconify-json/ri": "^1.2.0",
14+
"@iconify/json": "^2.2.308",
2015
"@microsoft/fetch-event-source": "^2.0.1",
2116
"@modyfi/vite-plugin-yaml": "^1.1.0",
2217
"@sentry/vite-plugin": "^2.22.5",

MaiChartManager/Front/pnpm-lock.yaml

Lines changed: 7 additions & 56 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MaiChartManager/Front/src/components/MusicList/BatchActionButton/MusicSelector.tsx

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,39 @@
1-
import { computed, defineComponent, PropType } from "vue";
2-
import { DataTableColumns, NButton, NDataTable, NFlex } from "naive-ui";
3-
import { addVersionList, genreList, musicList, musicListAll, version } from "@/store/refs";
1+
import { computed, defineComponent, PropType, reactive, ref } from "vue";
2+
import { DataTableBaseColumn, DataTableColumns, NButton, NDataTable, NFlex, NInput } from "naive-ui";
3+
import { addVersionList, genreList, musicList, musicListAll, selectedADir, selectMusicId, version } from "@/store/refs";
44
import { MusicXmlWithABJacket } from "@/client/apiGen";
55
import JacketBox from "@/components/JacketBox";
66
import { GenreOption } from "@/components/GenreInput";
77
import { LEVEL_COLOR, LEVELS } from "@/consts";
88
import _ from "lodash";
9+
import { watchDebounced } from "@vueuse/core";
910

1011
export default defineComponent({
1112
props: {
1213
selectedMusicIds: Array as PropType<MusicXmlWithABJacket[]>,
13-
continue: {type: Function, required: true},
14+
continue: { type: Function, required: true },
15+
cancel: { type: Function, required: true },
1416
},
15-
setup(props, {emit}) {
17+
setup(props, { emit }) {
18+
const filter = ref('')
19+
const nameColumn = reactive({
20+
title: '标题', key: 'name',
21+
filterOptionValue: null as string | null,
22+
filter: (value, row) => {
23+
if (!value) return true;
24+
value = value.toString().toLowerCase();
25+
return row.name!.toLowerCase().includes(value) || row.artist!.toLowerCase().includes(value) || row.charts!.some(chart => chart.designer?.toLowerCase().includes(value));
26+
}
27+
} satisfies DataTableBaseColumn<MusicXmlWithABJacket>)
1628
const columns = computed(() => [
17-
{type: 'selection'},
18-
{title: '资源目录', key: 'assetDir', width: '8em', filter: "default", filterOptions: _.uniq(musicListAll.value.map(it => it.assetDir!)).map(it => ({label: it, value: it}))},
29+
{ type: 'selection' },
30+
{ title: '资源目录', key: 'assetDir', width: '8em', filter: "default", filterOptions: _.uniq(musicListAll.value.map(it => it.assetDir!)).map(it => ({ label: it, value: it })) },
1931
{
2032
title: 'ID',
2133
key: 'id',
2234
width: '7em',
2335
sorter: 'default',
24-
filterOptions: ['标准', 'DX', '宴会场'].map(it => ({label: it, value: it})),
36+
filterOptions: ['标准', 'DX', '宴会场'].map(it => ({ label: it, value: it })),
2537
filter: (value, row) => {
2638
switch (value) {
2739
case '标准':
@@ -41,13 +53,13 @@ export default defineComponent({
4153
render: (row) => <JacketBox info={row} upload={false} class="h-20"/>,
4254
width: '8rem'
4355
},
44-
{title: '标题', key: 'name'},
56+
nameColumn,
4557
{
4658
title: '版本',
4759
key: 'version',
4860
width: '8em',
4961
sorter: 'default',
50-
filterOptions: ['B35', 'B15'].map(it => ({label: it, value: it})),
62+
filterOptions: ['B35', 'B15'].map(it => ({ label: it, value: it })),
5163
filter: (value, row) => {
5264
const type = row.version! < 20000 + version.value!.gameVersion! * 100 ? 'B35' : 'B15';
5365
return value === type;
@@ -58,30 +70,50 @@ export default defineComponent({
5870
key: 'addVersionId',
5971
render: (row) => <GenreOption genre={addVersionList.value.find(it => it.id === row.addVersionId)}/>,
6072
filter: "default",
61-
filterOptions: addVersionList.value.map(it => ({label: it.genreName!, value: it.id!}))
73+
filterOptions: addVersionList.value.map(it => ({ label: it.genreName!, value: it.id! }))
6274
},
6375
{
6476
title: '流派',
6577
key: 'genreId',
6678
render: (row) => <GenreOption genre={genreList.value.find(it => it.id === row.genreId)}/>,
6779
filter: "default",
68-
filterOptions: genreList.value.map(it => ({label: it.genreName!, value: it.id!}))
80+
filterOptions: genreList.value.map(it => ({ label: it.genreName!, value: it.id! }))
6981
},
7082
{
7183
title: '谱面',
7284
key: 'charts',
7385
render: (row) => <NFlex class="pt-1 text-sm" size="small">
7486
{
7587
(row.charts || []).map((chart, index) =>
76-
chart.enable && <div key={index} class="c-white rounded-full px-2" style={{backgroundColor: LEVEL_COLOR[index!]}}>{LEVELS[chart.levelId!]}</div>)
88+
chart.enable && <div key={index} class="c-white rounded-full px-2" style={{ backgroundColor: LEVEL_COLOR[index!] }}>{LEVELS[chart.levelId!]}</div>)
7789
}
7890
</NFlex>,
7991
width: '20em',
80-
filterOptions: ['绿', '黄', '红', '紫', '白'].map((label, value) => ({label, value})),
92+
filterOptions: ['绿', '黄', '红', '紫', '白'].map((label, value) => ({ label, value })),
8193
filter: (value, row) => row.charts![value as number].enable!
8294
},
95+
{
96+
title: '跳转',
97+
key: 'jump',
98+
width: '5em',
99+
render: (row) => <NButton quaternary class="p-2" onClick={() => {
100+
selectedADir.value = row.assetDir!;
101+
selectMusicId.value = row.id!;
102+
props.cancel();
103+
}}>
104+
<span class="i-tabler:external-link c-neutral-5"/>
105+
</NButton>,
106+
},
83107
] satisfies DataTableColumns<MusicXmlWithABJacket>)
84108

109+
watchDebounced(
110+
filter,
111+
() => {
112+
nameColumn.filterOptionValue = filter.value
113+
},
114+
{ debounce: 200 },
115+
)
116+
85117
const selectedMusicIds = computed<string[]>({
86118
get: () => props.selectedMusicIds!.map(it => `${it.assetDir}:${it.id}`),
87119
set: (value) => emit('update:selectedMusicIds', value.map(it => {
@@ -96,6 +128,7 @@ export default defineComponent({
96128
{/* emit('update:selectedMusicIds', musicListAll.value.filter(it => !props.selectedMusicIds!.includes(it)));*/}
97129
{/* }}>反选</NButton>*/}
98130
{/*</NFlex>*/}
131+
<NInput placeholder="搜索" v-model:value={filter.value}/>
99132
<NDataTable
100133
columns={columns.value}
101134
data={musicListAll.value}

MaiChartManager/Front/src/components/MusicList/BatchActionButton/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default defineComponent({
2525
}
2626

2727
return () => <NButton secondary onClick={show}>
28-
批量操作
28+
批量操作与搜索
2929

3030
<NModal
3131
preset="card"
@@ -37,7 +37,7 @@ export default defineComponent({
3737
closable={step.value !== STEP.ProgressDisplay}
3838
closeOnEsc={step.value !== STEP.ProgressDisplay}
3939
>
40-
{step.value === STEP.Select && <MusicSelector v-model:selectedMusicIds={selectedMusic.value} continue={() => step.value = STEP.ChooseAction}/>}
40+
{step.value === STEP.Select && <MusicSelector v-model:selectedMusicIds={selectedMusic.value} continue={() => step.value = STEP.ChooseAction} cancel={() => step.value = STEP.None}/>}
4141
{step.value === STEP.ChooseAction && <ChooseAction selectedMusic={selectedMusic.value} continue={(action: STEP) => step.value = action}/>}
4242
{step.value === STEP.EditProps && <EditProps selectedMusicIds={selectedMusic.value} closeModal={() => step.value = STEP.None}/>}
4343
{step.value === STEP.ProgressDisplay && <ProgressDisplay/>}

MaiChartManager/Front/src/components/MusicList/MusicEntry.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export default defineComponent({
2424

2525
return () => (
2626
<div class={`flex gap-5 h-20 w-full p-2 m-y-1 hover:bg-op-40 rd-md relative ${props.selected ? 'bg-[var(--selected-bg)]' : 'hover:bg-zinc-3'}`} onClick={props.onClick} title={props.music.name!}>
27-
<img src={jacketUrl.value} class="h-16 w-16 object-fill shrink-0"/>
27+
<img src={jacketUrl.value} class="h-16 w-16 object-fill shrink-0" key={props.music.id}/>
2828
<div class="flex flex-col grow-1 w-0">
2929
<NFlex class="text-xs c-gray-5" align="center" size="small">
3030
{props.music.modified && <NBadge dot type="warning"/>}

0 commit comments

Comments
 (0)