96 UI optimization (#136)

* fix(home): 🐛 解决多次切换路由后页面卡顿的问题 #96

卸载路由时清除requestAnimationFrame

* feat:  文件存储使用Blob格式

* style: 💄 修改部分类型any为具体类型

* feat:  界面设置中模块使用瀑布流布局 #96

* fix: 🐛 md文档更换文件夹解决控制台警告

* style: 💄 switch按钮改回使用daisyui组件

* refactor: ♻️ 所有人员列表提取tableColumn

* style: 💄 奖项列表中的图片类型修复

* fix(globalConfig): 修复当前音乐项类型缺失问题

* feat:  single person not done

* feat:  可添加单人 #96

* build(.gitignore): 添加 auto-imports.d.ts 到忽略文件

* fix: 🐛 上传、下载excel文件时修复路径错误

打包成应用和网页端的baseUrl不一样,使用环境变量来表示

* fix: 🐛 导入人员列表时处理有值为空的情况

* style: 💄 改变toaster的组件

* fix: 🐛 上传文件、解析数据与存储/读取数据的处理

、

* fix(Config): 更新备案信息链接样式

将备案信息的段落标签替换为可点击的链接标签,使用户能够直接跳转到工信部备案查询页面。同时添加了悬停效果样式,提升用户体验。

* feat:  首页奖项列表样式修改 not done #96

* chore(deps): ✏️ 更新依赖版本

* chore: ✏️ gsap list demo

* build: 🏗️ docker构建优化

* chore: ✏️ gsap scroll demo

* style: 💄 gsap demno

* feat:  demo smooth scroll gsap scrolltrigger

* feat(Demo): 添加更多颜色选项并注释GSAP动画

* refactor(PrizeList): 重构奖品列表组件结构

* feat(PrizeList): 重构奖品列表组件并添加滚动动画

* feat:  增加定时抽取功能 #96

* feat:  添加定时抽取功能的说明

* feat:  优化gsap #96

项数不多时不触发gsap

* style: 💄 文本修改

* feat:  优化

* feat:  优化奖项列表

* fix(Home): 修复奖品列表滚动检测逻辑

* fix(home): 修复抽奖停止逻辑避免重复执行;调整卡片垂直居中位置计算

* feat:  播放中奖音频 #96
This commit is contained in:
LOG1997
2025-12-28 00:04:20 +08:00
committed by GitHub
parent a0223bda4f
commit bd5eac7d70
27 changed files with 4287 additions and 4439 deletions

View File

@@ -1,11 +1,44 @@
<script setup lang='ts'>
import { useI18n } from 'vue-i18n'
import GridWaterfall from '@/components/Waterfall/index.vue'
import { DataSetting, LayoutSetting, PatternSetting, TextSetting, ThemeSetting } from './parts'
import { AbilitySetting, DataSetting, LayoutSetting, PatternSetting, TextSetting, ThemeSetting } from './parts'
import { useViewModel } from './useViewModel'
const { t } = useI18n()
const { resetData, topTitleValue, languageValue, textSizeValue, currentFontValue, currentTitleFontValue, titleFontSyncGlobalValue, languageList, formErr, formData, cardSizeValue, isShowPrizeListValue, isShowAvatarValue, resetPersonLayout, isRowCountChange, themeValue, backgroundImageValue, cardColorValue, luckyCardColorValue, textColorValue, patternColorValue, imageList, rowCount, cardColor, patternColor, patternList, clearPattern, resetPattern, exportAllConfigData, importAllConfigData } = useViewModel()
const {
resetData,
topTitleValue,
languageValue,
textSizeValue,
currentFontValue,
currentTitleFontValue,
titleFontSyncGlobalValue,
languageList,
formErr,
formData,
cardSizeValue,
isShowPrizeListValue,
isShowAvatarValue,
resetPersonLayout,
isRowCountChange,
themeValue,
backgroundImageValue,
cardColorValue,
luckyCardColorValue,
textColorValue,
patternColorValue,
imageList,
rowCount,
cardColor,
patternColor,
patternList,
clearPattern,
resetPattern,
exportAllConfigData,
importAllConfigData,
definiteTimeValue,
isWinMusicValue,
} = useViewModel()
</script>
<template>
@@ -54,6 +87,8 @@ const { resetData, topTitleValue, languageValue, textSizeValue, currentFontValue
:clear-pattern="clearPattern"
:reset-pattern="resetPattern"
/>
<!-- 功能设置 -->
<AbilitySetting v-model:definite-time="definiteTimeValue" v-model:win-music="isWinMusicValue" />
</GridWaterfall>
<!-- </div> -->
</div>

View File

@@ -0,0 +1,44 @@
<script setup lang='ts'>
const definiteTime = defineModel<number | null>('definiteTime', { required: true })
const winMusic = defineModel<boolean>('winMusic', { required: true })
</script>
<template>
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
功能设置
</legend>
<label class="flex flex-row items-center form-control">
<div class="">
<div class="label flex flex-col justify-start items-start">
<label class="label">
<span class="label-text text-left">定时停止</span>
<div class="tooltip" data-tip="开始抽奖过后定时停止默认为0单位为秒0为关闭定时停止功能">
<button class="btn btn-circle h-4 hover:bg-base-300">
?
</button>
</div>
</label>
<input
v-model="definiteTime" type="number" placeholder="开始后定时抽取"
class="w-full max-w-xs input input-bordered"
>
</div>
</div>
</label>
<div class="flex items-center justify-between w-full max-w-xs gap-2 mb-3 form-control">
<div class="label">
<span class="label-text">播放获奖音乐</span>
</div>
<input
type="checkbox" :checked="winMusic" class="border-solid checkbox checkbox-secondary border"
@change="winMusic = !winMusic"
>
</div>
</fieldset>
</template>
<style scoped>
</style>

View File

@@ -38,7 +38,7 @@ const isShowAvatarValue = defineModel<boolean>('isShowAvatarValue', { required:
class="w-full input input-bordered join-item"
>
<div class="tooltip join-item" :data-tip="t('tooltip.resetLayout')">
<button class="btn btn-neutral w-[120px] join-item" :disabled="isRowCountChange !== 1" @click="resetPersonLayout">
<button class="btn btn-neutral w-30 join-item" :disabled="isRowCountChange !== 1" @click="resetPersonLayout">
<span>{{ t('button.setLayout') }}</span>
<span v-show="isRowCountChange === 2" class="loading loading-ring loading-md" />
</button>

View File

@@ -1,3 +1,4 @@
export { default as AbilitySetting } from './AbilitySetting.vue'
export { default as DataSetting } from './DataSetting.vue'
export { default as LayoutSetting } from './LayoutSetting.vue'
export { default as PatternSetting } from './PatternSetting.vue'

View File

@@ -11,7 +11,28 @@ export function useViewModel() {
const globalConfig = useStore().globalConfig
const personConfig = useStore().personConfig
const prizeConfig = useStore().prizeConfig
const { getGlobalConfig: globalConfigData, getTopTitle: topTitle, getTheme: localTheme, getPatterColor: patternColor, getPatternList: patternList, getCardColor: cardColor, getLuckyColor: luckyCardColor, getTextColor: textColor, getCardSize: cardSize, getTextSize: textSize, getRowCount: rowCount, getIsShowPrizeList: isShowPrizeList, getLanguage: userLanguage, getBackground: backgroundImage, getFont: currentFont, getTitleFont: currentTitleFont, getTitleFontSyncGlobal: titleFontSyncGlobal, getImageList: imageList, getIsShowAvatar: isShowAvatar,
const {
getGlobalConfig: globalConfigData,
getTopTitle: topTitle,
getTheme: localTheme,
getPatterColor: patternColor,
getPatternList: patternList,
getCardColor: cardColor,
getLuckyColor: luckyCardColor,
getTextColor: textColor,
getCardSize: cardSize,
getTextSize: textSize,
getRowCount: rowCount,
getIsShowPrizeList: isShowPrizeList,
getLanguage: userLanguage,
getBackground: backgroundImage,
getFont: currentFont,
getTitleFont: currentTitleFont,
getTitleFontSyncGlobal: titleFontSyncGlobal,
getImageList: imageList,
getIsShowAvatar: isShowAvatar,
getDefiniteTime: definiteTime,
getWinMusic: isWinMusic,
} = storeToRefs(globalConfig)
const { getAlreadyPersonList: alreadyPersonList, getNotPersonList: notPersonList } = storeToRefs(personConfig)
@@ -32,6 +53,8 @@ export function useViewModel() {
const currentFontValue = ref(structuredClone(currentFont.value))
const currentTitleFontValue = ref(structuredClone(currentTitleFont.value))
const titleFontSyncGlobalValue = ref(structuredClone(titleFontSyncGlobal.value))
const definiteTimeValue = ref(structuredClone(definiteTime.value))
const isWinMusicValue = ref(structuredClone(isWinMusic.value))
const formData = ref({
rowCount: rowCountValue,
})
@@ -170,6 +193,12 @@ export function useViewModel() {
watch(isShowAvatarValue, () => {
globalConfig.setIsShowAvatar(isShowAvatarValue.value)
})
watch(definiteTimeValue, () => {
globalConfig.setDefiniteTime(definiteTimeValue.value)
})
watch(isWinMusicValue, () => {
globalConfig.setIsPlayWinMusic(isWinMusicValue.value)
})
onMounted(() => {
})
return {
@@ -203,5 +232,7 @@ export function useViewModel() {
resetPattern,
exportAllConfigData,
importAllConfigData,
definiteTimeValue,
isWinMusicValue,
}
}