Skip to content

Commit 2fd4a0c

Browse files
committed
拖放替换谱面
1 parent 7f83c0b commit 2fd4a0c

File tree

9 files changed

+112
-4
lines changed

9 files changed

+112
-4
lines changed

AquaMai

MaiChartManager/Controllers/Charts/ChartController.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,4 +93,17 @@ public void EditChartEnable(int id, int level, [FromBody] bool value, string ass
9393
}
9494
}
9595
}
96+
97+
[HttpPost]
98+
public void ReplaceChart(int id, int level, IFormFile file, string assetDir)
99+
{
100+
var music = settings.GetMusic(id, assetDir);
101+
if (music == null || file == null) return;
102+
var targetChart = music.Charts[level];
103+
targetChart.Path = $"{id:000000}_0{level}.ma2";
104+
using var stream = System.IO.File.Open(Path.Combine(StaticSettings.StreamingAssets, assetDir, "music", $"music{id:000000}", targetChart.Path), FileMode.Create);
105+
file.CopyTo(stream);
106+
targetChart.Problems.Clear();
107+
stream.Close();
108+
}
96109
}

MaiChartManager/Front/src/client/apiGen.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,31 @@ export class Api<SecurityDataType extends unknown> extends HttpClient<SecurityDa
943943
...params,
944944
}),
945945

946+
/**
947+
* No description
948+
*
949+
* @tags Chart
950+
* @name ReplaceChart
951+
* @request POST:/MaiChartManagerServlet/ReplaceChartApi/{assetDir}/{id}/{level}
952+
*/
953+
ReplaceChart: (
954+
id: number,
955+
level: number,
956+
assetDir: string,
957+
data: {
958+
/** @format binary */
959+
file?: File;
960+
},
961+
params: RequestParams = {},
962+
) =>
963+
this.request<void, any>({
964+
path: `/MaiChartManagerServlet/ReplaceChartApi/${assetDir}/${id}/${level}`,
965+
method: "POST",
966+
body: data,
967+
type: ContentType.FormData,
968+
...params,
969+
}),
970+
946971
/**
947972
* No description
948973
*
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { t } from '@/locales';
2+
import { globalCapture, selectedADir, selectedLevel, selectedMusic, selectMusicId, updateMusicList } from '@/store/refs';
3+
import { NButton, NFlex, NModal, useMessage } from 'naive-ui';
4+
import { defineComponent, PropType, ref, computed, watch, shallowRef } from 'vue';
5+
import JacketBox from '../JacketBox';
6+
import { DIFFICULTY, LEVEL_COLOR } from '@/consts';
7+
import api from '@/client/api';
8+
9+
export const replaceChartFileHandle = shallowRef<FileSystemFileHandle | null>(null);
10+
11+
export default defineComponent({
12+
// props: {
13+
// },
14+
setup(props, { emit }) {
15+
const message = useMessage();
16+
17+
const replaceChart = async () => {
18+
if (!replaceChartFileHandle.value) return;
19+
try {
20+
const file = await replaceChartFileHandle.value.getFile();
21+
replaceChartFileHandle.value = null;
22+
await api.ReplaceChart(selectMusicId.value, selectedLevel.value, selectedADir.value, { file });
23+
message.success(t('music.edit.replaceChartSuccess'));
24+
await updateMusicList();
25+
} catch (error) {
26+
globalCapture(error, t('music.edit.replaceChartFailed'));
27+
console.error(error);
28+
}
29+
}
30+
31+
return () => <NModal
32+
preset="card"
33+
class="w-[min(90vw,50em)]"
34+
title={t('music.edit.replaceChart')}
35+
show={replaceChartFileHandle.value !== null}
36+
onUpdateShow={() => replaceChartFileHandle.value = null}
37+
>{{
38+
default: () => <div class="flex flex-col gap-2">
39+
{t('music.edit.replaceChartConfirm', { level: DIFFICULTY[selectedLevel.value!] })}
40+
<div class="text-4.5 text-center">{replaceChartFileHandle.value?.name}</div>
41+
<div class="text-6 text-center"></div>
42+
<div class="flex justify-center gap-2">
43+
<JacketBox info={selectedMusic.value!} class="h-8em w-8em" upload={false} />
44+
<div class="flex flex-col gap-1 max-w-24em justify-end">
45+
<div class="text-3.5 op-70">#{selectMusicId.value}</div>
46+
<div class="text-2xl overflow-hidden text-ellipsis whitespace-nowrap">{selectedMusic.value!.name}</div>
47+
<div class="flex">
48+
<div class="c-white rounded-full px-2" style={{ backgroundColor: LEVEL_COLOR[selectedLevel.value!] }}>
49+
{selectedMusic.value!.charts![selectedLevel.value!]?.level}.{selectedMusic.value!.charts![selectedLevel.value!]?.levelDecimal}
50+
</div>
51+
</div>
52+
</div>
53+
</div>
54+
</div>,
55+
footer: () => <NFlex justify="end">
56+
<NButton onClick={() => replaceChartFileHandle.value = null}>{t('common.cancel')}</NButton>
57+
<NButton onClick={replaceChart} type="primary">{t('common.confirm')}</NButton>
58+
</NFlex>
59+
}}</NModal>;
60+
},
61+
});

MaiChartManager/Front/src/components/DragDropDispatcher/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { uploadFlow as uploadFlowMovie } from '@/components/MusicEdit/SetMovieBu
55
import { uploadFlow as uploadFlowAcbAwb } from '@/components/MusicEdit/AcbAwb';
66
import { selectedADir, selectedMusic } from '@/store/refs';
77
import { upload as uploadJacket } from '@/components/JacketBox';
8+
import ReplaceChartModal, { replaceChartFileHandle } from './ReplaceChartModal';
89

910
export const mainDivRef = shallowRef<HTMLDivElement>();
1011

@@ -43,6 +44,9 @@ export default defineComponent({
4344
else if (file.kind === 'file' && (firstType.startsWith('image/') || file.name.endsWith('.jpeg') || file.name.endsWith('.jpg') || file.name.endsWith('.png'))) {
4445
uploadJacket(file);
4546
}
47+
else if (file.kind === 'file' && file.name.endsWith('.ma2')) {
48+
replaceChartFileHandle.value = file;
49+
}
4650
}
4751
}
4852
const dropType = ref<DropType>(DropType.None);
@@ -92,6 +96,7 @@ export default defineComponent({
9296
松开鼠标导入谱面
9397
</div>} */}
9498
</div>}
99+
<ReplaceChartModal />
95100
</>;
96101
},
97102
});

MaiChartManager/Front/src/components/JacketBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ export default defineComponent({
6464
}
6565
}
6666

67-
return () => <img src={jacketUrl.value} class={`object-fill rounded-lg ${props.upload && 'cursor-pointer'}`} onClick={() => upload()} />
67+
return () => <img src={jacketUrl.value} class={`object-fill rounded-lg ${props.upload && 'cursor-pointer'}`} onClick={props.upload ? () => upload() : undefined} />
6868
}
6969
})

MaiChartManager/Front/src/components/MusicEdit/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { computed, defineComponent, onMounted, PropType, ref, watch } from "vue";
22
import { Chart, GenreXml, MusicXmlWithABJacket } from "@/client/apiGen";
3-
import { addVersionList, genreList, globalCapture, selectedADir, selectedMusic as info, selectMusicId, updateAddVersionList, updateGenreList, updateMusicList } from "@/store/refs";
3+
import { addVersionList, genreList, globalCapture, selectedADir, selectedMusic as info, selectMusicId, updateAddVersionList, updateGenreList, updateMusicList, selectedLevel } from "@/store/refs";
44
import api from "@/client/api";
55
import { NButton, NFlex, NForm, NFormItem, NInput, NInputNumber, NSelect, NSwitch, NTabPane, NTabs, SelectOption, useDialog, useMessage } from "naive-ui";
66
import JacketBox from "../JacketBox";
@@ -19,7 +19,6 @@ import { t } from "@/locales";
1919

2020
const Component = defineComponent({
2121
setup() {
22-
const selectedLevel = ref(0);
2322
const message = useMessage();
2423

2524
const firstEnabledChart = info.value?.charts?.findIndex(chart => chart.enable);

MaiChartManager/Front/src/locales/zh.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ music:
122122
里面。这个值还会控制按上线时间排序时的顺序
123123
idConflictWarning: 以下目录中存在冲突的 ID
124124
confirmSetMovie: 确认要使用 {filename} 替换当前的 PV 吗
125+
replaceChart: 替换谱面
126+
replaceChartConfirm: 确认要替换 {level} 谱面吗?
127+
replaceChartFailed: 替换谱面失败
128+
replaceChartSuccess: 替换谱面成功
125129
batch:
126130
title: 批量操作
127131
batchAndSearch: 批量操作与搜索

MaiChartManager/Front/src/store/refs.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const modInfo = ref<GameModInfo>();
5353

5454
export const musicList = computed(() => musicListAll.value.filter(m => m.assetDir === selectedADir.value));
5555
export const selectedMusic = computed(() => musicList.value.find(m => m.id === selectMusicId.value));
56+
export const selectedLevel = ref(0);
5657

5758
export const aquaMaiConfig = ref<ConfigDto>()
5859
export const modUpdateInfo = ref<Awaited<ReturnType<typeof aquaMaiVersionConfig.getGetConfig>>['data']>([{

0 commit comments

Comments
 (0)