diff --git a/package.json b/package.json index 06e2c51..178a827 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,9 @@ "axios": "^1.6.1", "canvas-confetti": "^1.9.2", "dayjs": "^1.11.10", + "github-markdown-css": "^5.5.0", "localforage": "^1.10.0", + "markdown-it": "^14.0.0", "pinia": "^2.1.7", "pinia-plugin-persist": "^1.0.0", "sparticles": "^1.3.1", @@ -27,6 +29,7 @@ "three": "^0.160.0", "three-css3d": "^1.0.6", "vue": "^3.3.8", + "vue-dompurify-html": "^5.0.1", "vue-router": "^4.2.5", "vue-toast-notification": "^3", "vue3-colorpicker": "^2.2.3", @@ -39,6 +42,7 @@ "@tailwindcss/typography": "^0.5.10", "@testing-library/vue": "^8.0.0", "@types/canvas-confetti": "^1.6.4", + "@types/markdown-it": "^13.0.7", "@types/node": "^20.9.0", "@types/three": "^0.160.0", "@typescript-eslint/eslint-plugin": "^6.11.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e58e46f..1f1b270 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,9 +20,15 @@ dependencies: dayjs: specifier: ^1.11.10 version: 1.11.10 + github-markdown-css: + specifier: ^5.5.0 + version: 5.5.0 localforage: specifier: ^1.10.0 version: 1.10.0 + markdown-it: + specifier: ^14.0.0 + version: 14.0.0 pinia: specifier: ^2.1.7 version: 2.1.7(typescript@5.2.2)(vue@3.3.8) @@ -44,6 +50,9 @@ dependencies: vue: specifier: ^3.3.8 version: 3.3.8(typescript@5.2.2) + vue-dompurify-html: + specifier: ^5.0.1 + version: 5.0.1(vue@3.3.8) vue-router: specifier: ^4.2.5 version: 4.2.5(vue@3.3.8) @@ -76,6 +85,9 @@ devDependencies: '@types/canvas-confetti': specifier: ^1.6.4 version: 1.6.4 + '@types/markdown-it': + specifier: ^13.0.7 + version: 13.0.7 '@types/node': specifier: ^20.9.0 version: 20.9.0 @@ -742,6 +754,21 @@ packages: resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true + /@types/linkify-it@3.0.5: + resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} + dev: true + + /@types/markdown-it@13.0.7: + resolution: {integrity: sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==} + dependencies: + '@types/linkify-it': 3.0.5 + '@types/mdurl': 1.0.5 + dev: true + + /@types/mdurl@1.0.5: + resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} + dev: true + /@types/node@20.9.0: resolution: {integrity: sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==} dependencies: @@ -1413,7 +1440,6 @@ packages: /argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true /aria-query@5.1.3: resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} @@ -2163,6 +2189,10 @@ packages: domelementtype: 2.3.0 dev: true + /dompurify@3.0.8: + resolution: {integrity: sha512-b7uwreMYL2eZhrSCRC4ahLTeZcPZxSmYfmcQGXGkXiZSNW1X85v+SDM5KsWcpivIiUBH47Ji7NtyUdpLeF5JZQ==} + dev: false + /domutils@1.7.0: resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} dependencies: @@ -2229,7 +2259,6 @@ packages: /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: true /error-stack-parser-es@0.1.1: resolution: {integrity: sha512-g/9rfnvnagiNf+DRMHEVGuGuIBlCIMDFoTA616HaP2l9PlCjGjVhD98PNbVSJvmK4TttqT5mV5tInMhoFgi+aA==} @@ -2721,6 +2750,11 @@ packages: engines: {node: '>=0.10.0'} dev: true + /github-markdown-css@5.5.0: + resolution: {integrity: sha512-Ncp4putm+cGteDhtNYKGdchM4uiIm5tmQcAQx/eEYhuM0sOdjZYNQOauQTaodjDQjfw7whU99MijwC1M0FUY4w==} + engines: {node: '>=10'} + dev: false + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -3498,6 +3532,12 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + dependencies: + uc.micro: 2.0.0 + dev: false + /loader-runner@4.3.0: resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} engines: {node: '>=6.11.5'} @@ -3601,10 +3641,26 @@ packages: object-visit: 1.0.1 dev: true + /markdown-it@14.0.0: + resolution: {integrity: sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==} + hasBin: true + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.0.0 + dev: false + /mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} dev: true + /mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + dev: false + /merge-options@1.0.1: resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} engines: {node: '>=4'} @@ -4276,6 +4332,11 @@ packages: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: true + /punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + dev: false + /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -5113,6 +5174,10 @@ packages: engines: {node: '>=14.17'} hasBin: true + /uc.micro@2.0.0: + resolution: {integrity: sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==} + dev: false + /ufo@1.3.1: resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==} dev: true @@ -5531,6 +5596,15 @@ packages: dependencies: vue: 3.3.8(typescript@5.2.2) + /vue-dompurify-html@5.0.1(vue@3.3.8): + resolution: {integrity: sha512-8yoMbo7PX4vt01k0dcCHvP4tY0fOCLkQeMhXXRNmH7/muIUTkFOQNzkAtE0RmqgaF/unabvYnsnCu2CjIMgueg==} + peerDependencies: + vue: ^3.0.0 + dependencies: + dompurify: 3.0.8 + vue: 3.3.8(typescript@5.2.2) + dev: false + /vue-eslint-parser@9.3.2(eslint@8.53.0): resolution: {integrity: sha512-q7tWyCVaV9f8iQyIA5Mkj/S6AoJ9KBN8IeUSf3XEmBrOtxOZnfTg5s4KClbZBCK3GtnT/+RyCLZyDHuZwTuBjg==} engines: {node: ^14.17.0 || >=16.0.0} diff --git a/public/readme.md b/public/readme.md new file mode 100644 index 0000000..3d4d5f2 --- /dev/null +++ b/public/readme.md @@ -0,0 +1,31 @@ +# 操作说明 + +## 步骤 + +1. 首次进入,没有数据展示,可以选择使用默认数据进行使用,查看整体展示效果。推荐导入自己的数据来进行操作。步骤如下: + + a. 人员配置-人员名单-下载模板,下载数据模板并修改填入数据(请注意表头不可修改)。 + + b. 修改好后在同一个页面点击‘上传文件’,上传修改后的excel表格。 + +2. 进入奖品配置,修改自己的奖品信息。名称尽量短一点,方便展示;是否全员参加意指该项奖项是否从全体人员中抽取(已中奖的依然可以参与);获奖人数指该奖项要抽取的人数;已获奖人数不可编辑;已抽取被选中时指该奖项已使用,取消选择会重置该奖项,但不会重置已获奖的人;图片是在首页展示时的奖品图片(可在图片列表自己上传);左侧图标调整奖品顺序用。 + +完成上面两项已可以正常使用。 + +## 功能说明 + +1. 增加临时抽奖:抽奖页面的奖项列表有个‘+’号按钮,点击可临时增加抽奖,注意:一次只能增加一项临时抽奖,新增成功后当前奖项即设置为该临时奖项,抽取成功后返回正常奖项列表. +2. 音乐与图片列表,可自己上传文件进行使用,图片上传成功后就可以在奖项配置中进行选择图片展示,音乐上传成功后即加入了播放列表. +3. 音乐播放:使用鼠标左键点击是播放/暂停,使用鼠标右键点击是播放下一首. +4. 界面配置-图案设置中可使用鼠标点击自定义配置首页中的高亮图案. +5. 若不想在首页展示奖品列表,将界面配置中的'是否常显奖项列表'选中. +6. 首页点击按钮时按钮值不会立即更新,会等动画结束后才会更新为目标值,属于正常现象. + +## 快捷键 + +在抽奖页面设置了快捷键。 + +| 快捷键 | 说明 | +| --- | --- | +| Space | 进入抽奖/开始/抽取幸运儿/继续 | +| Esc | 取消 | diff --git a/src/hooks/useElement.ts b/src/hooks/useElement.ts index 33803e5..35c92d5 100644 --- a/src/hooks/useElement.ts +++ b/src/hooks/useElement.ts @@ -3,7 +3,7 @@ import { IPersonConfig } from '@/types/storeType' export const useElementStyle = (element: any, person: IPersonConfig, index: number, patternList: number[], patternColor: string, cardColor: string, cardSize: { width: number, height: number }, textSize: number, mod: 'default' | 'lucky'|'sphere' = 'default') => { if (patternList.includes(index+1)&&mod=='default') { - element.style.backgroundColor = rgba(patternColor, Math.random() * 0.5 + 0.5) + element.style.backgroundColor = rgba(patternColor, Math.random() * 0.2 + 0.8) } else if(mod=='sphere'||mod=='default') { element.style.backgroundColor = rgba(cardColor, Math.random() * 0.5 + 0.25) diff --git a/src/main.ts b/src/main.ts index 3713fd3..9e15246 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,8 +1,10 @@ import { createApp } from 'vue'; import './style.css'; +import './style/markdown.css' import './style/style.scss' import * as THREE from 'three'; import App from './App.vue'; +import VueDOMPurifyHTML from 'vue-dompurify-html' const app = createApp(App); // 全局svg组件 @@ -19,4 +21,4 @@ pinia.use(piniaPluginPersist); app.config.globalProperties.$THREE = THREE; //挂载到原型 app.component('svg-icon', svgIcon); -app.use(router).use(pinia).mount('#app'); +app.use(router).use(VueDOMPurifyHTML).use(pinia).mount('#app'); diff --git a/src/router/index.ts b/src/router/index.ts index 1d88356..5eb9e51 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -98,7 +98,16 @@ export const configRoutes={ } } ] - } + }, + { + path: '/log-lottery/config/readme', + name: 'Readme', + component: () => import('@/views/Config/Readme/index.vue'), + meta:{ + title: '操作说明', + icon: 'readme' + } + }, ] } const routes = [ diff --git a/src/store/prizeConfig.ts b/src/store/prizeConfig.ts index a6fc961..52ad2c3 100644 --- a/src/store/prizeConfig.ts +++ b/src/store/prizeConfig.ts @@ -83,15 +83,9 @@ return state.prizeConfig.prizeList; }, // 更新奖项数据 updatePrizeConfig(prizeConfigItem: IPrizeConfig) { - // const index = this.prizeConfig.prizeList.findIndex(item => item.id === prizeConfigItem.id); - // this.prizeConfig.prizeList[index] = prizeConfigItem; - // if(prizeConfigItem.isUsed&&index+1