Browse Source

更改

main
betaqi 2 weeks ago
parent
commit
84a4b3443f
  1. 7
      global.types/components.d.ts
  2. 39
      src/components/common/FormBuilder.vue
  3. 40
      src/components/drawerSetting/iconSetting.vue
  4. 21
      src/components/drawerSetting/indexSetting.vue
  5. 37
      src/components/drawerSetting/wallpaperSetting.vue
  6. 31
      src/schema/iconSchema.ts
  7. 31
      src/schema/schemaTypes.type.ts
  8. 6
      src/schema/utils.ts
  9. 10
      src/schema/wallpaperSchema.ts
  10. 2
      src/views/home/index.vue

7
global.types/components.d.ts vendored

@ -11,8 +11,10 @@ declare module 'vue' { @@ -11,8 +11,10 @@ declare module 'vue' {
AppSearch: typeof import('../src/components/apps/Search.vue')['default']
ContextMenu: typeof import('./../src/components/ContextMenu.vue')['default']
ContextMenuContainer: typeof import('./../src/components/ContextMenuContainer.vue')['default']
DrawerSetting: typeof import('./../src/components/drawerSetting/index.vue')['default']
DrawerSetting: typeof import('../src/components/drawerSetting/indexSetting.vue')['default']
FormBuilder: typeof import('./../src/components/common/FormBuilder.vue')['default']
IconSetting: typeof import('./../src/components/dialogs/iconSetting.vue')['default']
IndexSetting: typeof import('./../src/components/drawerSetting/indexSetting.vue')['default']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NColorPicker: typeof import('naive-ui')['NColorPicker']
@ -33,7 +35,8 @@ declare module 'vue' { @@ -33,7 +35,8 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
Search: typeof import('./../src/components/apps/Search.vue')['default']
Wallpaper: typeof import('./../src/components/wallpaper.vue')['default']
WallpaperSetting: typeof import('./../src/components/drawerSetting/wallpaperSetting.vue')['default']
Widget: typeof import('./../src/components/apps/widget.vue')['default']
WidgetSetting: typeof import('./../src/components/drawerSetting/widgetSetting.vue')['default']
WidgetSetting: typeof import('../src/components/drawerSetting/index.vue')['default']
}
}

39
src/components/common/FormBuilder.vue

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
<script setup lang="ts">
import { NColorPicker, NSlider, NSwitch } from 'naive-ui'
interface IBuilderProps {
type: string
propsOptions: any
context?: any
}
const modelValue = defineModel()
const componentMap: Record<string, Component | undefined> = {
slider: NSlider,
switch: NSwitch,
colorPicker: NColorPicker,
}
const props = defineProps<IBuilderProps>()
const realProps = computed(() => {
if (typeof props.propsOptions === 'function') {
if (!props.context) {
console.warn('[FormBuilder] propsOptions 为函数但未传 context,已自动使用空对象')
return props.propsOptions({})
}
return props.propsOptions(props.context)
}
return props.propsOptions
})
</script>
<template>
<component
:is="componentMap[props.type]"
v-bind="realProps"
v-model:value="modelValue"
/>
</template>
<style scoped lang="scss"></style>

40
src/components/drawerSetting/iconSetting.vue

@ -13,33 +13,13 @@ @@ -13,33 +13,13 @@
class="flex justify-between items-center gap-col-12px p-x-12 h-36"
>
<span>{{ config.label }}</span>
<!-- {{ config.value }} -->
<template v-if="config.type === 'slider' && config.value === 'iconRadius'">
<n-slider
class="flex-1"
v-model:value="values[config.value]"
v-bind="config.props"
:max="iconRadiusMax"
/>
</template>
<n-slider
v-else-if="config.type === 'slider'"
class="flex-1"
v-model:value="values[config.value]"
v-bind="config.props"
/>
<n-switch
size="small"
v-else-if="config.type === 'switch'"
v-model:value="values[config.value]"
/>
<n-color-picker
v-else-if="config.type === 'colorPicker'"
v-model:value="values[config.value]"
style="width: 28px; height: 28px"
:swatches="swatches"
<FormBuilder
v-model="values[config.value]"
:type="config.type"
:style="config.style"
:class="config.class"
:props-options="config.props"
:context="{ values }"
/>
<span v-if="config.unit">{{ values[config.value] }}{{ config.unit }}</span>
</div>
@ -49,14 +29,10 @@ @@ -49,14 +29,10 @@
<script setup lang="ts">
import { useIconStore } from '@/stores/icon'
import FormBuilder from '@/components/common/FormBuilder.vue'
import iconSchema from '@/schema/iconSchema'
import { storeToRefs } from 'pinia'
import { swatches } from '@/utils'
const iconStore = useIconStore()
const { values } = storeToRefs(iconStore)
const iconRadiusMax = computed(() => {
return values.value?.iconSize / 2
})
</script>

21
src/components/drawerSetting/widgetSetting.vue → src/components/drawerSetting/indexSetting.vue

@ -8,10 +8,10 @@ @@ -8,10 +8,10 @@
>
<n-drawer-content title="设置">
<div class="flex h-full w-full">
<n-menu :options="menuOptions" class="h-full w-130" v-model:value="currentMenu" />
<n-menu :options="menuOptions" class="h-full w-130" v-model:value="currentMenu"/>
<div class="flex-1 bg-[#f1f0f5]">
<IconSetting v-if="currentMenu === 'icon'" />
<WallpaperSetting v-if="currentMenu === 'wallpaper'" />
<IconSetting v-if="currentMenu === 'icon'"/>
<WallpaperSetting v-if="currentMenu === 'wallpaper'"/>
</div>
</div>
</n-drawer-content>
@ -19,10 +19,11 @@ @@ -19,10 +19,11 @@
</template>
<script setup lang="ts">
import type { MenuOption } from 'naive-ui'
import type {MenuOption} from 'naive-ui'
import IconSetting from './iconSetting.vue'
import WallpaperSetting from './index.vue'
const isShowDrawer = defineModel({ default: false })
import WallpaperSetting from './wallpaperSetting.vue'
const isShowDrawer = defineModel({default: false})
const props = defineProps()
@ -32,12 +33,12 @@ const menuOptions: MenuOption[] = [ @@ -32,12 +33,12 @@ const menuOptions: MenuOption[] = [
{
label: '图标',
key: 'icon',
icon: () => h('div', { class: 'i-mingcute:pic-ai-line font-size-16' }),
icon: () => h('div', {class: 'i-mingcute:pic-ai-line font-size-16'}),
},
{
label: '壁纸',
key: 'wallpaper',
icon: () => h('div', { class: 'i-mingcute:layout-6-line font-size-16' }),
icon: () => h('div', {class: 'i-mingcute:layout-6-line font-size-16'}),
},
]
@ -56,15 +57,19 @@ defineExpose({ @@ -56,15 +57,19 @@ defineExpose({
.n-drawer-body-content-wrapper {
padding: 0 !important;
}
.n-layout-scroll-container {
width: 100%;
}
.n-menu-item-content__icon {
margin-right: 0px !important;
}
.n-menu-item-content {
padding-left: 16px !important;
}
.n-card-header {
padding: 8px 12px !important;
}

37
src/components/drawerSetting/index.vue → src/components/drawerSetting/wallpaperSetting.vue

@ -7,27 +7,7 @@ @@ -7,27 +7,7 @@
hoverable
class="border-radius-6"
>
<div
v-for="(config, configIndex) in section.configs"
:key="configIndex"
class="flex justify-between items-center gap-col-12px p-x-12 line-height-36"
>
<span class="w-56">{{ config.label }}</span>
<n-slider
v-if="config.type === 'slider'"
class="flex-1"
v-model:value="values[config.value]"
v-bind="config.props"
/>
<n-upload
v-if="config.type === 'imgUpload'"
multiple
directory-dnd
:max="1"
@before-upload="beforeUpload"
>
<n-upload multiple directory-dnd :max="1" @before-upload="beforeUpload">
<n-upload-dragger>
<div class="flex flex-col items-center justify-center gap-y-10px p-t-14px">
<div class="i-mingcute:pic-ai-fill text-size-24px"></div>
@ -35,7 +15,21 @@ @@ -35,7 +15,21 @@
</div>
</n-upload-dragger>
</n-upload>
<div
v-for="(config, configIndex) in filterCustomConfigs(section.configs)"
:key="configIndex"
class="flex justify-between items-center gap-col-12px p-x-12 line-height-36"
>
<span class="w-56">{{ config.label }}</span>
<FormBuilder
v-model="values[config.value]"
:type="config.type"
:style="config.style"
:class="config.class"
:props-options="config.props"
:context="{ values }"
/>
<span v-if="config.unit">{{ values[config.value] }}{{ config.unit }}</span>
</div>
</n-card>
@ -48,6 +42,7 @@ import { useWallpaperStore } from '@/stores/wallpaper' @@ -48,6 +42,7 @@ import { useWallpaperStore } from '@/stores/wallpaper'
import { useMessage, type UploadFileInfo } from 'naive-ui'
import { storeToRefs } from 'pinia'
import { ref } from 'vue'
import { filterCustomConfigs } from '@/schema/utils'
const message = useMessage()
const wallpaperStore = useWallpaperStore()

31
src/schema/iconSchema.ts

@ -1,4 +1,7 @@ @@ -1,4 +1,7 @@
export default {
import type { SchemaType } from "./schemaTypes.type"
import { swatches } from '@/utils'
const iconSchema: SchemaType = {
icon: {
title: '图标',
type: 'icon',
@ -14,6 +17,7 @@ export default { @@ -14,6 +17,7 @@ export default {
step: 2,
},
cssVar: '--icon-size',
class: 'flex-1',
unit: 'px',
},
{
@ -21,12 +25,13 @@ export default { @@ -21,12 +25,13 @@ export default {
type: 'slider',
value: 'iconRadius',
defaultValue: 16,
props: {
props: (context) => ({
min: 0,
max: 100,
max: context?.values?.iconSize / 2 || 100,
step: 1,
},
}),
cssVar: '--icon-radius',
class: 'flex-1',
unit: 'px',
},
{
@ -34,7 +39,7 @@ export default { @@ -34,7 +39,7 @@ export default {
type: 'slider',
value: 'iconOpacity',
defaultValue: 100,
class: 'flex-1',
props: {
min: 0,
max: 100,
@ -55,6 +60,7 @@ export default { @@ -55,6 +60,7 @@ export default {
value: 'iconRowSpace',
unit: 'px',
defaultValue: 27,
class: 'flex-1',
props: {
min: 0,
max: 100,
@ -74,7 +80,9 @@ export default { @@ -74,7 +80,9 @@ export default {
value: 'nameTextShow',
defaultValue: true,
cssVar: '--icon-name',
props: {},
props: {
size: "small"
},
},
{
label: '名称颜色',
@ -82,11 +90,19 @@ export default { @@ -82,11 +90,19 @@ export default {
value: 'nameColor',
defaultValue: '#fff',
cssVar: '--icon-nameColor',
props: {
swatches: swatches,
},
style: {
width: '28px',
height: '28px'
}
},
{
label: '字体大小',
type: 'slider',
value: 'nameSize',
class: 'flex-1',
defaultValue: 14,
props: {
min: 12,
@ -107,6 +123,7 @@ export default { @@ -107,6 +123,7 @@ export default {
type: 'slider',
value: 'iconGridWidth',
defaultValue: 900,
class: 'flex-1',
props: {
min: 900,
max: 2000,
@ -118,3 +135,5 @@ export default { @@ -118,3 +135,5 @@ export default {
],
},
}
export default iconSchema

31
src/schema/schemaTypes.type.ts

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
// custom 组件不做类型约束
export interface FormBuilderContext {
values: Record<string, any>
}
export type ConfigProps =
| Record<string, any>
| ((context: FormBuilderContext) => Record<string, any>)
export interface ConfigItem {
label: string;
type: string;
value: string;
class?: string;
style?: Record<string, string>
defaultValue: number | boolean | string;
props?: ConfigProps;
cssVar?: string;
unit?: string;
}
export interface SchemaSection {
title: string;
type: string;
configs: ConfigItem[];
}
export type SchemaType = Record<string, SchemaSection>;

6
src/schema/utils.ts

@ -0,0 +1,6 @@ @@ -0,0 +1,6 @@
import type { ConfigItem } from "./schemaTypes.type";
// 过滤type中 包含 custom 的配置项
export function filterCustomConfigs(configs: ConfigItem[]) {
return configs.filter(config => !config.type.includes('custom'));
}

10
src/schema/wallpaperSchema.ts

@ -1,11 +1,13 @@ @@ -1,11 +1,13 @@
export default {
import type { SchemaType } from "./schemaTypes.type";
const wallpaperSchema: SchemaType = {
wallpaper: {
title: '壁纸',
type: 'wallpaper',
configs: [
{
label: '壁纸',
type: 'imgUpload',
type: 'custom-imgUpload',
value: 'wallpaperImg',
defaultValue: '',
},
@ -13,6 +15,7 @@ export default { @@ -13,6 +15,7 @@ export default {
label: '模糊度',
type: 'slider',
value: 'wallpaperBlur',
class: 'flex-1',
defaultValue: 0,
props: {
min: 0,
@ -25,6 +28,7 @@ export default { @@ -25,6 +28,7 @@ export default {
label: '遮罩浓度',
type: 'slider',
value: 'wallpaperMask',
class: 'flex-1',
defaultValue: 0,
props: {
min: 0,
@ -36,3 +40,5 @@ export default { @@ -36,3 +40,5 @@ export default {
],
},
}
export default wallpaperSchema

2
src/views/home/index.vue

@ -26,7 +26,7 @@ import Search from '@/components/apps/Search.vue' @@ -26,7 +26,7 @@ import Search from '@/components/apps/Search.vue'
import Widget from '@/components/apps/widget.vue'
import type { IContextMenu, IWidget } from '../../utils/types'
import { useContextMenuManager } from '@/composables/useContextMenu'
import DrawerSetting from '@/components/drawerSetting/widgetSetting.vue'
import DrawerSetting from '@/components/drawerSetting/indexSetting.vue'
import IconSetting from '@/components/dialogs/iconSetting.vue'
import { storeToRefs } from 'pinia'
import { useWidgetStore } from '@/stores/widget'

Loading…
Cancel
Save