{"id":13941612,"url":"https://github.com/renmingliang/vue-lottery","last_synced_at":"2025-07-20T04:32:15.469Z","repository":{"id":44979159,"uuid":"118115862","full_name":"renmingliang/vue-lottery","owner":"renmingliang","description":":art:  vue(2.x \\ 3.x) 抽奖以及截屏保存图片至本地","archived":false,"fork":false,"pushed_at":"2023-03-18T15:54:00.000Z","size":19879,"stargazers_count":118,"open_issues_count":0,"forks_count":51,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-27T10:36:16.586Z","etag":null,"topics":["axios","element-ui","lottery","mock","pinia","typescript","vue","vue3","vuex","webpack"],"latest_commit_sha":null,"homepage":"https://renmingliang.github.io/vue-lottery","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/renmingliang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-19T11:11:49.000Z","updated_at":"2024-11-07T01:31:47.000Z","dependencies_parsed_at":"2024-05-23T05:04:10.314Z","dependency_job_id":null,"html_url":"https://github.com/renmingliang/vue-lottery","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/renmingliang/vue-lottery","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renmingliang%2Fvue-lottery","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renmingliang%2Fvue-lottery/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renmingliang%2Fvue-lottery/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renmingliang%2Fvue-lottery/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/renmingliang","download_url":"https://codeload.github.com/renmingliang/vue-lottery/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/renmingliang%2Fvue-lottery/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266067267,"owners_count":23871324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["axios","element-ui","lottery","mock","pinia","typescript","vue","vue3","vuex","webpack"],"created_at":"2024-08-08T02:01:22.591Z","updated_at":"2025-07-20T04:32:12.314Z","avatar_url":"https://github.com/renmingliang.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# 简介\n\n\u003e 基于vue.js(3.x)抽奖项目，截屏保存每次抽奖图片至本地，附带背景音乐\n\n\u003e 技术栈：\n[vue3.x](https://v3.cn.vuejs.org/) + [pinia](https://pinia.vuejs.org/) + [vue-router4.x](https://router.vuejs.org/) + [element-plus](https://element-plus.org/) + [@vueuse/core](https://vueuse.org/) + axios + mockjs + html2canvas + nprogress + scss + typescript\n\n\u003e 基于vue.js(2.x)版本，可切换分支查看[feature-vue2](https://github.com/renmingliang/vue-lottery/tree/feature-vue2)；\n\n欢迎star or fork 关注！\n\n## 说明\n`注意`：本项目内使用 [node-sass](https://www.npmjs.com/package/node-sass)，由于该强依赖 [nodejs](https://nodejs.org/en/download/releases) 版本，具体可看 node-sass 指南；\n本项目内，安装 `node-sass@4.14` 版本，与之匹配 `node@14` 版本，请特别注意。\n如已安装 node 版本与 node-sass 不匹配，请重新安装node版本，或将 node-sass 替换成 dart-sass。\n\n### 示例地址\n\n\u003e [点击查看](https://renmingliang.github.io/vue-lottery)\n\n### 实现思路\n\n本项目主要有以下几个点需要`注意`：\n1. 为了保证数据安全，需要设置登录，在登录成功之后的前提下获取后台传递的数据，以及回传数据也需要验证是否已登录；\n2. 这里利用mockjs来模拟数据，考虑正式抽奖的数据都上千条，cookie和storage存储空间受限都不够用，依次考虑利用浏览器支持的indexDB来存储用户数据库，以及主要奖项和该奖项抽取的人数的；\n3. 每次抽奖完成的结果，须返回给后台存储数据，以保障前后台数据一致性（实现具体抽奖的逻辑功能，不受限，取决于前后台同事自己沟通结果，本示例前端实现抽取，在[src/views/lottery](src/views/lottery/hooks/useLottery.ts)文件内）；\n4. 记录单次抽奖人数，不论抽多少次，只要满足本轮奖项人数，即宣告本轮抽取结束，代码逻辑不以抽取多少次为依据；\n5. 同时每次抽中的用户数据需要三步处理：\n    \u003eA. 回传至后台；\n\n    \u003eB. 同步至本地indexDB，防止当前页刷新时丢失已抽中用户数据，再一次进入抽奖池；\n\n    \u003eC. 截取抽奖屏幕图，用于事后比对；\n6. 考虑抽奖现场肯定会加抽奖项的环节（不多说，参与过年会的都知道，没抽中的人肯定会叫喊老板现场再抽的），故可以在后台设置其他将，人数为空(若为空。前端会默认设置抽取99人，毕竟加抽的奖项人数，99人足够啦，)，或者更多，这里也可灵活变动；\n\n### 配置文件\n\n数据的构造，参照如下代码结构：\n```javascript\n// 抽奖数据\ndata: {\n  // 用户\n  userData: [\n    {\n      Company: '公司测1',\n      CompleteID: '1',\n      HeadImg: 'http://test.baoxianadmin.com/static/m/images/headImage/1.jpg',\n      Name: '测1',\n      Num: 'M1',\n      OpenID: '1',\n      Award: '0'\n    },\n    {\n      Company: '公司测13',\n      CompleteID: '13',\n      HeadImg: 'http://test.baoxianadmin.com/static/m/images/headImage/13.jpg',\n      Name: '测13',\n      Num: 'M13',\n      OpenID: '13',\n      Award: '0'\n    }\n  ],\n  // 奖项\n  type: [\n    {value: '9', label: '特等奖', number: '3'},\n    {value: '1', label: '一等奖', number: '5'},\n    {value: '2', label: '二等奖', number: '12'},\n    {value: '3', label: '三等奖', number: '20'},\n    {value: '4', label: '参与奖', number: '28'},\n    {value: '5', label: '其他', number: ''}\n  ]\n}\n```\n\n本项目配置文件位于[src/utils/config](src/utils/config.ts)，按照注释相应地修改对应项就好。\n\n```javascript\n\n// global config 注意: 所有接口均为mock测试，项目中需要自己替换\nconst config = {\n  // 1.登录页\n  login: {\n    // 登录请求地址\n    url: '/zt_lottery/login',\n    // 检测登陆状态\n    checkUrl: '/zt_lottery/check_login',\n    state: {\n      // 当前公司提示语\n      msg: '民太安集团年会抽奖系统',\n      form: {\n        username: 'mta2018',\n        trigger: 'blur',\n        show: true\n      }\n    }\n  },\n  // 2.加载数据页\n  onload: {\n    // 获取数据地址\n    url: '/zt_lottery/list_member',\n    // 参与限制人数\n    limit: 100\n  },\n  // 3.中奖活动页\n  lottery: {\n    // 回传中奖数据地址\n    url: '/zt_lottery/add',\n    state: {\n      // 样式\n      style: {\n        // 主背景图\n        bg: { // 在请求资源路径时，需要require\n          backgroundImage: `url(${require('../assets/images/background.png')})`,\n          backgroundRepeat: 'no-repeat',\n          backgroundSize: '100% 100%'\n        },\n        // 当前抽奖年\n        year: {\n          show: false,\n          img: require('../assets/images/2017.png')\n        }\n      },\n      // 是否需要下载抽奖截图\n      download: {\n        show: false,\n        delay: 800\n      },\n      // 滚动间隔\n      intervalTime: 50,\n      // 绑定键盘事件\n      keyBand: {\n        start: 'Enter',\n        stop: 'Space'\n      }\n    }\n  },\n  // 4.全局state状态\n  state: {\n    // indexDB名称\n    DBname: 'lottery2022',\n    // indexDB版本\n    DBver: '1',\n    // indexDB存储表名称\n    storeName: {\n      user: 'user', // 用户\n      award: 'type' // 奖项\n    },\n    // 背景音乐\n    music: {\n      show: false,\n      src: require('../assets/media/shiji.mp3')\n    },\n    // 参与规则\n    rule: {\n      show: true,\n      img: require('../assets/images/QR-code.jpg')\n    }\n  }\n}\n```\n\n## 功能\n\n1. 抽奖前，选择需要抽取的奖项\n2. 点击开始抽奖按钮(或Enter回车键)，数据滚动\n3. 点击抽取(或space空格键)结束滚动，显示中奖人员\n4. 再点击开始抽取进入第2步循环，若完成本轮抽取，则进入第1步选择抽取其他奖项\n\n## 截图\n\n一。界面截图：\n\n针对1920*1080大屏设计显示，当然也适配其他PC端，以下为该项目主要界面截图：\n\n![登录界面](screenshot/1.png)\n![数据加载界面](screenshot/2.gif)\n![抽奖界面](screenshot/3.gif)\n\n二。抽奖截屏：\n\n![截屏示例](screenshot/4.gif)\n\n自动保存的抽奖截图文件至本地思路：\n1. 实现的流程逻辑在[src/utils/screenshot](src/utils/screenshot.js)文件中；\n2. 由于浏览器browser不支持node.js的模块fs读写文件，因而本示例采用`html2canvas`来完成截图功能，具体的使用自行百度或谷歌；\n3. 截完屏，最主要的是需要自动保存至本地，利用a标签的download和herf属性可以实现，通过在结束时，自动调用click的事件来触发；\n4. 注意：可能在截屏功能下，出现没有将头像获取下来情况，经查阅资料发现，是由于头像采用的mockjs模拟的，而项目代码部署在另外一个服务器，因而出现跨越情况导致此情况出现，解决办法:前端在`html2canvas`中添加参数 ==\u003e 允许跨域：allowTaint: true，同时服务器需要允许跨越，即设置 [`CORS`](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)\n\n## 开发\n```\ngit clone https://github.com/renmingliang/vue-lottery.git\n```\n\n### 依赖安装\n```\nyarn install\n```\n\n### 开发调试\n```\nyarn serve\n```\n\n### 编译构建\n```\nyarn build\n```\n\n### eslint \u0026 fix\n```\nyarn lint\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenmingliang%2Fvue-lottery","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frenmingliang%2Fvue-lottery","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frenmingliang%2Fvue-lottery/lists"}