From 4729566b5611e77245b2c30ca8ccfa5539687448 Mon Sep 17 00:00:00 2001 From: log1997 <2694233102@qq.com> Date: Thu, 4 Dec 2025 20:40:06 +0800 Subject: [PATCH] =?UTF-8?q?feat(prize-config):=20=E5=BC=95=E5=85=A5?= =?UTF-8?q?=E6=8B=96=E6=8B=BD=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=A5=96=E5=93=81=E9=85=8D=E7=BD=AE=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 `vue-draggable-plus` 和 `lodash-es` 依赖以支持列表拖拽排序 - 使用 `cloneDeep` 深拷贝奖品列表,避免直接修改原始数据 - 移除原有的手动排序逻辑(上下移动按钮),改用可视化拖拽方式 - 调整 UI 布局和样式,增强用户体验与可操作性 - 在 Demo 页面中添加 draggable 示例用于验证功能实现 --- package.json | 3 + pnpm-lock.yaml | 39 +++++++++ src/views/Config/Prize/PrizeConfig.vue | 73 +++++++---------- src/views/Config/Prize/usePrizeConfig.ts | 100 +++++++++++++++++++++++ src/views/Demo/index.vue | 35 ++++++++ 5 files changed, 207 insertions(+), 43 deletions(-) create mode 100644 src/views/Config/Prize/usePrizeConfig.ts diff --git a/package.json b/package.json index ebddfa4..8087e55 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "dexie": "^4.2.1", "github-markdown-css": "^5.8.0", "localforage": "^1.10.0", + "lodash-es": "^4.17.21", "lucide-vue-next": "^0.555.0", "markdown-it": "^14.1.0", "pinia": "^3.0.3", @@ -34,6 +35,7 @@ "uuid": "^13.0.0", "vue": "^3.5.13", "vue-dompurify-html": "^5.2.0", + "vue-draggable-plus": "^0.6.0", "vue-i18n": "^11.1.12", "vue-router": "^4.5.0", "vue-toast-notification": "^3", @@ -51,6 +53,7 @@ "@tailwindcss/vite": "^4.1.13", "@testing-library/vue": "^8.1.0", "@types/canvas-confetti": "^1.6.4", + "@types/lodash-es": "^4.17.12", "@types/markdown-it": "^14.1.2", "@types/node": "^24.5.2", "@types/three": "^0.166.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 720248a..bd00353 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,6 +32,9 @@ importers: localforage: specifier: ^1.10.0 version: 1.10.0 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 lucide-vue-next: specifier: ^0.555.0 version: 0.555.0(vue@3.5.13(typescript@5.5.3)) @@ -62,6 +65,9 @@ importers: vue-dompurify-html: specifier: ^5.2.0 version: 5.2.0(vue@3.5.13(typescript@5.5.3)) + vue-draggable-plus: + specifier: ^0.6.0 + version: 0.6.0(@types/sortablejs@1.15.9) vue-i18n: specifier: ^11.1.12 version: 11.1.12(vue@3.5.13(typescript@5.5.3)) @@ -108,6 +114,9 @@ importers: '@types/canvas-confetti': specifier: ^1.6.4 version: 1.6.4 + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 '@types/markdown-it': specifier: ^14.1.2 version: 14.1.2 @@ -1728,6 +1737,12 @@ packages: '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} + '@types/markdown-it@14.1.2': resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} @@ -1746,6 +1761,9 @@ packages: '@types/node@24.5.2': resolution: {integrity: sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ==} + '@types/sortablejs@1.15.9': + resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==} + '@types/stats.js@0.17.3': resolution: {integrity: sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==} @@ -5407,6 +5425,15 @@ packages: peerDependencies: vue: ^3.0.0 + vue-draggable-plus@0.6.0: + resolution: {integrity: sha512-G5TSfHrt9tX9EjdG49InoFJbt2NYk0h3kgjgKxkFWr3ulIUays0oFObr5KZ8qzD4+QnhtALiRwIqY6qul4egqw==} + peerDependencies: + '@types/sortablejs': ^1.15.0 + '@vue/composition-api': '*' + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue-eslint-parser@10.2.0: resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -7211,6 +7238,12 @@ snapshots: '@types/linkify-it@5.0.0': {} + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.21 + + '@types/lodash@4.17.21': {} + '@types/markdown-it@14.1.2': dependencies: '@types/linkify-it': 5.0.0 @@ -7232,6 +7265,8 @@ snapshots: dependencies: undici-types: 7.12.0 + '@types/sortablejs@1.15.9': {} + '@types/stats.js@0.17.3': {} '@types/svgo@2.6.4': @@ -11307,6 +11342,10 @@ snapshots: dompurify: 3.2.1 vue: 3.5.13(typescript@5.5.3) + vue-draggable-plus@0.6.0(@types/sortablejs@1.15.9): + dependencies: + '@types/sortablejs': 1.15.9 + vue-eslint-parser@10.2.0(eslint@9.15.0(jiti@2.5.1)): dependencies: debug: 4.4.3 diff --git a/src/views/Config/Prize/PrizeConfig.vue b/src/views/Config/Prize/PrizeConfig.vue index ee3c7b9..fde2b20 100644 --- a/src/views/Config/Prize/PrizeConfig.vue +++ b/src/views/Config/Prize/PrizeConfig.vue @@ -1,8 +1,11 @@ @@ -176,27 +169,20 @@ watch(() => prizeList.value, (val: IPrizeConfig[]) => { - - + + ([]) + + const prizeList = ref(cloneDeep(localPrizeList.value)) + const selectedPrize = ref() + + function selectPrize(item: IPrizeConfig) { + selectedPrize.value = item + selectedPrize.value.isUsedCount = 0 + selectedPrize.value.isUsed = false + + if (selectedPrize.value.separateCount.countList.length > 1) { + return + } + selectedPrize.value.separateCount = { + enable: true, + countList: [ + { + id: '0', + count: item.count, + isUsedCount: 0, + }, + ], + } + } + + function changePrizeStatus(item: IPrizeConfig) { + item.isUsed ? item.isUsedCount = 0 : item.isUsedCount = item.count + item.separateCount.countList = [] + item.isUsed = !item.isUsed + } + + function changePrizePerson(item: IPrizeConfig) { + let indexPrize = -1 + for (let i = 0; i < prizeList.value.length; i++) { + if (prizeList.value[i].id === item.id) { + indexPrize = i + break + } + } + if (indexPrize > -1) { + prizeList.value[indexPrize].separateCount.countList = [] + prizeList.value[indexPrize].isUsed ? prizeList.value[indexPrize].isUsedCount = prizeList.value[indexPrize].count : prizeList.value[indexPrize].isUsedCount = 0 + } + } + function submitData(value: any) { + selectedPrize.value!.separateCount.countList = value + selectedPrize.value = null + } + + async function getImageDbStore() { + const keys = await imageDbStore.keys() + if (keys.length > 0) { + imageDbStore.iterate((value, key) => { + imgList.value.push({ + key, + value, + }) + }) + } + } + + function delItem(item: IPrizeConfig) { + prizeConfig.deletePrizeConfig(item.id) + } + onMounted(() => { + getImageDbStore() + }) + watch(() => prizeList.value, (val: IPrizeConfig[]) => { + console.log('prizeList', val) + prizeConfig.setPrizeConfig(val) + }, { deep: true }) + + return { + currentPrize, + + } +} diff --git a/src/views/Demo/index.vue b/src/views/Demo/index.vue index 1f7529b..a0acc4b 100644 --- a/src/views/Demo/index.vue +++ b/src/views/Demo/index.vue @@ -1,6 +1,26 @@