mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-07 02:46:55 +08:00
更新项目配置,删除不必要的文件,优化依赖项,修复类型定义,添加新歌单样式
This commit is contained in:
@@ -1,139 +1,167 @@
|
||||
<script setup lang="ts">
|
||||
import { getImageUploadModel } from '@/Utils';
|
||||
import { QueryPostAPI } from '@/api/query';
|
||||
import { TemplateConfig, TemplateConfigImageItem } from '@/data/VTsuruTypes'
|
||||
import { FILE_BASE_URL, VTSURU_API_URL } from '@/data/constants';
|
||||
import { NButton, NEmpty, NForm, NFormItem, NInput, NUpload, UploadFileInfo, useMessage } from 'naive-ui'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { getImageUploadModel } from '@/Utils';
|
||||
import { QueryPostAPI } from '@/api/query';
|
||||
import { ConfigItemDefinition, TemplateConfigImageItem } from '@/data/VTsuruTypes';
|
||||
import { FILE_BASE_URL, VTSURU_API_URL } from '@/data/constants';
|
||||
import { NButton, NColorPicker, NEmpty, NForm, NFormItem, NGrid, NInput, NInputNumber, NSlider, NUpload, UploadFileInfo, useMessage } from 'naive-ui';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const message = useMessage()
|
||||
const message = useMessage();
|
||||
|
||||
const props = defineProps<{
|
||||
configData: any
|
||||
config: TemplateConfig<any> | undefined
|
||||
}>()
|
||||
const props = defineProps<{
|
||||
name?: string;
|
||||
configData: any;
|
||||
config: ConfigItemDefinition[] | undefined;
|
||||
}>();
|
||||
|
||||
const fileList = ref<{ [key: string]: UploadFileInfo[] }>({})
|
||||
const fileList = ref<{ [key: string]: UploadFileInfo[]; }>({});
|
||||
|
||||
const isUploading = ref(false)
|
||||
const isUploading = ref(false);
|
||||
|
||||
function OnFileListChange(key: string, files: UploadFileInfo[]) {
|
||||
if (files.length == 1) {
|
||||
var file = files[0]
|
||||
if ((file.file?.size ?? 0) > 10 * 1024 * 1024) {
|
||||
message.error('文件大小不能超过10MB')
|
||||
fileList.value[key] = []
|
||||
function OnFileListChange(key: string, files: UploadFileInfo[]) {
|
||||
if (files.length == 1) {
|
||||
var file = files[0];
|
||||
if ((file.file?.size ?? 0) > 10 * 1024 * 1024) {
|
||||
message.error('文件大小不能超过10MB');
|
||||
fileList.value[key] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async function onSubmit() {
|
||||
try {
|
||||
isUploading.value = true
|
||||
let images = {} as {
|
||||
[key: string]: {
|
||||
existImages: string[],
|
||||
newImagesBase64: string[],
|
||||
}
|
||||
}
|
||||
for (const item of props.config!.items) {
|
||||
if (item.type == 'image') {
|
||||
const key = (item as TemplateConfigImageItem<any>).key
|
||||
images[key] = await getImageUploadModel(fileList.value[key])
|
||||
}
|
||||
}
|
||||
const resp = await QueryPostAPI<any>(VTSURU_API_URL + 'set-config', {
|
||||
name: props.config!.name,
|
||||
json: JSON.stringify(props.configData),
|
||||
images: images,
|
||||
})
|
||||
if (resp.code == 200) {
|
||||
message.success('已保存至服务器')
|
||||
props.config?.items.forEach(item => {
|
||||
switch (item.type) {
|
||||
case 'image':
|
||||
item.onUploaded?.(resp.data[item.key], props.configData)
|
||||
break
|
||||
async function onSubmit() {
|
||||
try {
|
||||
isUploading.value = true;
|
||||
let images = {} as {
|
||||
[key: string]: {
|
||||
existImages: string[],
|
||||
newImagesBase64: string[],
|
||||
};
|
||||
};
|
||||
for (const item of props.config!) {
|
||||
if (item.type == 'image') {
|
||||
const key = (item as TemplateConfigImageItem<any>).key;
|
||||
images[key] = await getImageUploadModel(fileList.value[key]);
|
||||
}
|
||||
})
|
||||
} else {
|
||||
message.error('保存失败: ' + resp.message)
|
||||
}
|
||||
const resp = await QueryPostAPI<any>(VTSURU_API_URL + 'set-config', {
|
||||
name: props.name,
|
||||
json: JSON.stringify(props.configData),
|
||||
images: images,
|
||||
public: 'true',
|
||||
});
|
||||
if (resp.code == 200) {
|
||||
message.success('已保存至服务器');
|
||||
props.config?.forEach(item => {
|
||||
if (item.type === 'render') {
|
||||
item.onUploaded?.(props.configData[item.key], props.configData);
|
||||
}
|
||||
else {
|
||||
item.onUploaded?.call(item, props.configData[item.key], props.configData);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
message.error('保存失败: ' + resp.message);
|
||||
}
|
||||
} catch (err) {
|
||||
message.error('保存失败: ' + err);
|
||||
}
|
||||
finally {
|
||||
isUploading.value = false;
|
||||
}
|
||||
} catch (err) {
|
||||
message.error('保存失败: ' + err)
|
||||
}
|
||||
finally {
|
||||
isUploading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function getItems() { }
|
||||
onMounted(() => {
|
||||
props.config?.items.forEach(item => {
|
||||
if (item.type == 'image') {
|
||||
const configItem = props.configData[item.key]
|
||||
if (configItem) {
|
||||
fileList.value[item.key] = configItem.map((i: string) => ({
|
||||
id: i,
|
||||
thumbnailUrl: FILE_BASE_URL + i,
|
||||
name: '',
|
||||
status: 'finished',
|
||||
}))
|
||||
function getItems() { }
|
||||
onMounted(() => {
|
||||
props.config?.forEach(item => {
|
||||
if (item.default && !props.configData[item.key]) {
|
||||
props.configData[item.key] = item.default;
|
||||
}
|
||||
else {
|
||||
fileList.value[item.key] = []
|
||||
if (item.type == 'image') {
|
||||
const configItem = props.configData[item.key];
|
||||
if (configItem) {
|
||||
fileList.value[item.key] = configItem.map((i: string) => ({
|
||||
id: i,
|
||||
thumbnailUrl: FILE_BASE_URL + i,
|
||||
name: '',
|
||||
status: 'finished',
|
||||
}));
|
||||
}
|
||||
else {
|
||||
fileList.value[item.key] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NEmpty
|
||||
v-if="!config"
|
||||
v-if="!config || config.length == 0"
|
||||
description="此模板不支持配置"
|
||||
/>
|
||||
<NForm v-else>
|
||||
<NFormItem
|
||||
v-for="item in config.items"
|
||||
:key="item.name.toString()"
|
||||
:label="item.name.toString()"
|
||||
<NGrid
|
||||
x-gap="10"
|
||||
y-gap="10"
|
||||
cols="1 600:2 1200:3 1600:4"
|
||||
>
|
||||
<component
|
||||
:is="item.render(configData)"
|
||||
v-if="item.type == 'render'"
|
||||
/>
|
||||
<template v-else-if="item.type == 'string'">
|
||||
<NInput
|
||||
v-if="item.data"
|
||||
<NFormItemGi
|
||||
v-for="item in config"
|
||||
:key="item.name.toString()"
|
||||
:label="item.name.toString()"
|
||||
>
|
||||
<component
|
||||
:is="item.render(configData)"
|
||||
v-if="item.type == 'render'"
|
||||
/>
|
||||
<template v-else-if="item.type == 'string'">
|
||||
<NInput
|
||||
:value="configData[item.key]"
|
||||
:placeholder="item.placeholder"
|
||||
@update:value="configData[item.key] = $event"
|
||||
:type="item.inputType"
|
||||
/>
|
||||
</template>
|
||||
<NColorPicker
|
||||
v-else-if="item.type == 'color'"
|
||||
:value="configData[item.key]"
|
||||
:show-alpha="item.showAlpha ?? false"
|
||||
@update:value="configData[item.key] = $event"
|
||||
/>
|
||||
<NInput
|
||||
v-else
|
||||
v-model:value="configData[item.key]"
|
||||
<NInputNumber
|
||||
v-else-if="item.type == 'number'"
|
||||
:value="configData[item.key]"
|
||||
:min="item.min"
|
||||
@update:value="configData[item.key] = $event"
|
||||
/>
|
||||
</template>
|
||||
<NUpload
|
||||
v-else-if="item.type == 'image'"
|
||||
v-model:file-list="fileList[item.key]"
|
||||
accept=".png,.jpg,.jpeg,.gif,.svg,.webp,.ico"
|
||||
list-type="image-card"
|
||||
:default-upload="false"
|
||||
:max="item.imageLimit"
|
||||
im
|
||||
@update:file-list="file => OnFileListChange(item.key, file)"
|
||||
>
|
||||
上传图片
|
||||
</NUpload>
|
||||
</NFormItem>
|
||||
<NFormItem>
|
||||
<NButton
|
||||
type="primary"
|
||||
:loading="isUploading"
|
||||
@click="onSubmit"
|
||||
>
|
||||
提交
|
||||
</NButton>
|
||||
</NFormItem>
|
||||
<NSlider
|
||||
v-else-if="item.type == 'sliderNumber'"
|
||||
:value="configData[item.key]"
|
||||
:min="item.min"
|
||||
:max="item.max"
|
||||
:step="item.step"
|
||||
@update:value="configData[item.key] = $event"
|
||||
/>
|
||||
<NUpload
|
||||
v-else-if="item.type == 'image'"
|
||||
v-model:file-list="fileList[item.key]"
|
||||
accept=".png,.jpg,.jpeg,.gif,.svg,.webp,.ico"
|
||||
list-type="image-card"
|
||||
:default-upload="false"
|
||||
:max="item.imageLimit"
|
||||
im
|
||||
@update:file-list="file => OnFileListChange(item.key, file)"
|
||||
>
|
||||
上传图片
|
||||
</NUpload>
|
||||
</NFormItemGi>
|
||||
</NGrid>
|
||||
|
||||
<NButton
|
||||
type="primary"
|
||||
:loading="isUploading"
|
||||
@click="onSubmit"
|
||||
>
|
||||
提交
|
||||
</NButton>
|
||||
</NForm>
|
||||
</template>
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import { SongFrom, SongLanguage, SongRequestOption, SongsInfo } from '@/api/api-models'
|
||||
import { QueryGetAPI, QueryPostAPI } from '@/api/query'
|
||||
import { SONG_API_URL } from '@/data/constants'
|
||||
import FiveSingIcon from '@/svgs/fivesing.svg'
|
||||
import NeteaseIcon from '@/svgs/netease.svg'
|
||||
import { SongFrom, SongRequestOption, SongsInfo } from '@/api/api-models';
|
||||
import { QueryGetAPI, QueryPostAPI } from '@/api/query';
|
||||
import { SONG_API_URL } from '@/data/constants';
|
||||
import {
|
||||
Delete24Filled,
|
||||
Info24Filled,
|
||||
NotepadEdit20Filled,
|
||||
Play24Filled,
|
||||
SquareArrowForward24Filled,
|
||||
} from '@vicons/fluent'
|
||||
import { refDebounced, useLocalStorage } from '@vueuse/core'
|
||||
import { List } from 'linqts'
|
||||
Play24Filled
|
||||
} from '@vicons/fluent';
|
||||
import { refDebounced, useLocalStorage } from '@vueuse/core';
|
||||
import { List } from 'linqts';
|
||||
import {
|
||||
DataTableBaseColumn,
|
||||
DataTableColumns,
|
||||
@@ -42,9 +39,10 @@ import {
|
||||
NText,
|
||||
NTooltip,
|
||||
useMessage,
|
||||
} from 'naive-ui'
|
||||
import { VNodeChild, computed, h, onMounted, ref, watch } from 'vue'
|
||||
import SongPlayer from './SongPlayer.vue'
|
||||
} from 'naive-ui';
|
||||
import { VNodeChild, computed, h, onMounted, ref, watch } from 'vue';
|
||||
import SongPlayer from './SongPlayer.vue';
|
||||
import { GetPlayButton } from '@/Utils';
|
||||
|
||||
const props = defineProps<{
|
||||
songs: SongsInfo[]
|
||||
@@ -393,72 +391,6 @@ function createColumns(): DataTableColumns<SongsInfo> {
|
||||
]
|
||||
}
|
||||
|
||||
function GetPlayButton(song: SongsInfo) {
|
||||
switch (song.from) {
|
||||
case SongFrom.FiveSing: {
|
||||
return h(NTooltip, null, {
|
||||
trigger: () =>
|
||||
h(
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#00BBB3',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(`http://5sing.kugou.com/bz/${song.id}.html`)
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: () => h(FiveSingIcon, { class: 'svg-icon fivesing' }),
|
||||
},
|
||||
),
|
||||
),
|
||||
default: () => '在5sing打开',
|
||||
})
|
||||
}
|
||||
case SongFrom.Netease:
|
||||
return h(NTooltip, null, {
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#C20C0C',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(`https://music.163.com/#/song?id=${song.id}`)
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: () => h(NeteaseIcon, { class: 'svg-icon netease' }),
|
||||
},
|
||||
),
|
||||
default: () => '在网易云打开',
|
||||
})
|
||||
case SongFrom.Custom:
|
||||
return song.url
|
||||
? h(NTooltip, null, {
|
||||
trigger: () =>
|
||||
h(
|
||||
NButton,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#6b95bd',
|
||||
ghost: true,
|
||||
onClick: () => {
|
||||
window.open(song.url)
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: () => h(NIcon, { component: SquareArrowForward24Filled }),
|
||||
},
|
||||
),
|
||||
default: () => '打开链接',
|
||||
})
|
||||
: null
|
||||
}
|
||||
}
|
||||
function renderCell(value: string | number) {
|
||||
if (!value) {
|
||||
return h(NText, { depth: 3 }, { default: () => '未填写' })
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import { useAccount } from '@/api/account';
|
||||
import { useLoadingBarStore } from '@/store/useLoadingBarStore'
|
||||
import { useStorage } from '@vueuse/core';
|
||||
import { NSpin, useLoadingBar, useMessage } from 'naive-ui'
|
||||
import { NSpin, useLoadingBar, useMessage, useModal } from 'naive-ui'
|
||||
import { onMounted } from 'vue'
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
@@ -14,6 +14,7 @@ onMounted(() => {
|
||||
window.$loadingBar = useLoadingBar()
|
||||
window.$message = useMessage()
|
||||
window.$route = useRoute()
|
||||
window.$modal = useModal()
|
||||
const providerStore = useLoadingBarStore()
|
||||
providerStore.setLoadingBar(window.$loadingBar)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user