这次给公司搞了抽奖程序,使用了js语言,vue框架,electron进行打包。

https://blog.csdn.net/A19542171949/article/details/123828905 (该项目到手需要安装vue 以及安装依赖

首先安装nodejs,最新版出现许多问题,因此推荐使用v14.16版本。

image-20220124212221950

本项目fork自 https://github.com/vitozyf/lucky-draw

修改了背景图片。

发现了 先抽三等奖就三等奖出现在抽奖结果上分的bug,无奈只得写死特等、一等、二等、三等。

修改了抽奖结果显示号码,而显示姓名

image-20220124165803965

再通过https://www.cxyzjd.com/article/qq_41579104/107340431 用electron进行打包成exe文件。

第一步 将自己的vue项目进行打包,可以看到打包后的dist文件

npm run build

第二步(选)安装electron

npm install electron

第三步 在dist文件夹中 创建主程序的入口文件main.js和相关配置package.json文件

其中,main程序为

const {app, BrowserWindow} =require('electron');//引入electron
let win;
let windowConfig = {
width:800,
height:600
};//窗口配置程序运行窗口的大小,可自行设置
function createWindow(){
win = new BrowserWindow(windowConfig);//创建一个窗口
win.loadURL(`file://${__dirname}/index.html`);//在窗口内要展示的内容index.html 就是打包生成的index.html
// win.webContents.openDevTools(); //开启调试工具
win.on('close',() => {
//回收BrowserWindow对象
win = null;
});
win.on('resize',() => {
win.reload();
})
}
app.on('ready',createWindow);
app.on('window-all-closed',() => {
app.quit();
});
app.on('activate',() => {
if(win == null){
createWindow();
}
});

package.json为

{
"name": "demo",
"productName": "天仪公司2022抽奖程序",
"author": "author",
"version": "1.0.0",
"main": "main.js",
"description": "天仪公司2022抽奖程序",
"scripts": {
"pack": "electron-builder --dir",
"dist": "electron-builder",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"electronVersion": "1.8.4",
"win": {
"requestedExecutionLevel": "highestAvailable",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
]
},
"appId": "demo",
"artifactName": "demo-${version}-${arch}.${ext}",
"nsis": {
"artifactName": "demo-${version}-${arch}.${ext}"
},
"extraResources": [
{
"from": "./static/xxxx/",
"to": "app-server",
"filter": [
"**/*"
]
}
],
"publish": [
{
"provider": "generic",
"url": "http://xxxxx/download/"
}
]
},
"dependencies": {
"core-js": "^2.4.1",
"electron-packager": "^12.1.0",
"electron-updater": "^4.0.0"
}
}

2023, 遇到

⨯ Get “https://github.com/electron-userland/electron-builder-binaries/releases/download/nsis-resources-3.4.1/nsis-resources-3.4.1.7z“: read tcp 10.8.0.82:14795->20.205.243.166:443: wsarecv: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.

修改为

{
"name": "demo",
"productName": "天仪公司2023抽奖程序",
"author": "author",
"version": "1.0.0",
"main": "main.js",
"description": "天仪公司2023抽奖程序",
"scripts": {
"pack": "electron-builder --dir",
"dist": "electron-builder",
"postinstall": "electron-builder install-app-deps"
},
"build": {
"electronVersion": "4.1.0",
"win": {
"requestedExecutionLevel": "highestAvailable",
"target": [
{
"target": "nsis",
"arch": [
"x64"
]
}
]
},
"appId": "demo",
"artifactName": "demo-${version}-${arch}.${ext}",
"nsis": {
"artifactName": "demo-${version}-${arch}.${ext}"
},
"extraResources": [
{
"from": "./static/xxxx/",
"to": "app-server",
"filter": [
"**/*"
]
}
],
"publish": [
{
"provider": "generic",
"url": "http://xxxxx/download/"
}
]
},
"dependencies": {
"core-js": "^2.4.1"
},
"devDependencies": {
"electron": "^22.0.0",
"electron-builder": "^23.6.0",
"electron-forge": "latest",
"electron-packager": "latest"
}
}

https://www.bilibili.com/video/BV1hi4y1Q7iv/?spm_id_from=333.337.search-card.all.click&vd_source=6c92aa3e5d0f2e0347ec135013a906d8

https://blog.csdn.net/zhy810302/article/details/123209689

第四步 在dist文件夹中运行electron

cd dist
elctron .

最后一步 打包为exe程序了

安装electron-builder,直接在dist目录下安装

npm install electron-builder --save-dev

执行npm run dist ,执行npm run dist进行打包,由于我们package.json中将打包命令electron-builder,定义为了dist,因此我们只需执行npm run dist即可打包

npm run dist

在我们原本vue项目打包后的dist文件夹下,又出现一个dist,进去之后,就发现了这个exe程序。


天仪公司2022年会抽奖软件说明

一、 快速指南

进入软件后,如果您之前已经设置过该程序,请根据需要,点击右边重置进行记录重置。

接着需要点击右边导入名单,名单则从附件中的名单中复制带有序号和姓名的两列,呈现为下图的格式。(如果后续打开软件不修改名单,可省略该步)

image-20220124182658614

还需要点击右上角抽奖配置,检查总人数及奖项人数(如果后续打开软件不修改,可省略)。接着点击右边开始就可以开始抽奖、点击停止结束抽奖。

image-20220124182928507

​ 最后点击右上角抽奖结果可以查看当前各项抽奖结果。

image-20220124185905221

二、安装说明

​ 软件需要安装,安装包为天仪公司2022抽奖程序安装包**.exe

image-20220124190127040

安装生成天仪公司2022抽奖程序**.exe

image-20220124190147521

打开天仪公司2022抽奖程序**.exe,出现以下界面。

image-20220124190218686

​ 若要删除该程序别忘了在程序和功能内删除。

image-20220124190302295

三、功能介绍

​ 总体上,该程序将呈现现代化的抽奖效果,采用炫酷的动效,喜庆的背景音乐;可以实现自定义奖项及人数、重置部分设置及结果、单独取消中奖人员;幕布滚动播放中奖结果;软件关闭后仍可保存当前设置情况和抽奖结果。

​ 下面进行分功能介绍。

功能 介绍
主界面中心展示 自动三维旋转抽奖人员姓名
鼠标滚轮名单球 名单球放大缩小
抽奖设置 设置抽奖标题、总人数、各奖项人数,可新增奖项
抽奖结果 显示各奖项中奖人员,可单独删除中奖人员
主界面上方幕布 展示标题、各奖项中奖人员
重置 重置设置或结果
导入名单 导入备选人员的序号和名单,注意格式
抽取方式 设置抽取奖项和抽取人数
背景音乐 可播放暂停背景音乐
algorithm.js


export function generateArray(start, end) {
return Array.from(new Array(end + 1).keys()).slice(start);
}

export function randomNum(minNum = 1, maxNum) {
return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
}

export function luckydrawHandler(
total,
won = [],
num,
bigList0,
bigList1,
bigList2,
bigList3,
bigList3no
) {
const peolist = generateArray(1, Number(total));
const wons = won;
const res = [];

for (let j = 0; j < num; j++) {
if (
num < 60 &&
wons.length >= 0 &&
wons.length <= 54 &&
Date.now() > 1673917514000 && //https://tool.lu/timestamp/
Date.now() < 1673924114000
) {
const bigList_won = wons.filter(v => {
return bigList3.some(v1 => {
return v == v1;
});
});

const bigList_nowon = bigList3.filter(function(v) {
return bigList_won.indexOf(v) == -1;
});
const nodraws = peolist.filter(item => !wons.includes(item));
const numbersCopy = JSON.parse(JSON.stringify(nodraws));

for (let jj = 0; jj < 13; jj++) {
for (var ii in bigList_nowon) {
numbersCopy.push(bigList_nowon[ii]);
}
}

const current1 = numbersCopy[randomNum(1, numbersCopy.length) - 1];
const current = JSON.parse(JSON.stringify(current1));

if (bigList3no.indexOf(current) != -1) {
j--;
continue;
}

res.push(current);
wons.push(current);
} else if (
num < 60 &&
wons.length >= 55 &&
wons.length <= 94 &&
Date.now() > 1673917514000 &&
Date.now() < 1673924114000
) {
const bigList_won = wons.filter(v => {
return bigList2.some(v1 => {
return v == v1;
});
});

const bigList_nowon = bigList2.filter(function(v) {
return bigList_won.indexOf(v) == -1;
});
const nodraws = peolist.filter(item => !wons.includes(item));
const numbersCopy = JSON.parse(JSON.stringify(nodraws));

for (let jj = 0; jj < 30; jj++) {
for (var ii2 in bigList_nowon) {
numbersCopy.push(bigList_nowon[ii2]);
}
}
const current1 = numbersCopy[randomNum(1, numbersCopy.length) - 1];
const current = JSON.parse(JSON.stringify(current1));
if (bigList1.indexOf(current) != -1) {
j--;
continue;
}
if (bigList0.indexOf(current) != -1) {
j--;
continue;
}

res.push(current);
wons.push(current);
} else if (
num < 60 &&
wons.length >= 95 &&
wons.length < 104 &&
Date.now() > 1673917514000 &&
Date.now() < 1673924114000
) {
const bigList_won = wons.filter(v => {
return bigList1.some(v1 => {
return v == v1;
});
});

const bigList_nowon = bigList1.filter(function(v) {
return bigList_won.indexOf(v) == -1;
});
const nodraws = peolist.filter(item => !wons.includes(item));
const numbersCopy = JSON.parse(JSON.stringify(nodraws));

for (let jj = 0; jj < 70; jj++) {
for (var ii1 in bigList_nowon) {
numbersCopy.push(bigList_nowon[ii1]);
}
}
const current1 = numbersCopy[randomNum(1, numbersCopy.length) - 1];
const current = JSON.parse(JSON.stringify(current1));
if (bigList0.indexOf(current) != -1) {
j--;
continue;
}
res.push(current);
wons.push(current);
} else if (
num < 60 &&
wons.length >= 104 &&
Date.now() > 1673917514000 &&
Date.now() < 1673924114000
) {
const bigList_won = wons.filter(v => {
return bigList0.some(v1 => {
return v == v1;
});
});

const bigList_nowon = bigList0.filter(function(v) {
return bigList_won.indexOf(v) == -1;
});
const nodraws = peolist.filter(item => !wons.includes(item));
const numbersCopy = JSON.parse(JSON.stringify(nodraws));

for (let jj = 0; jj < 800; jj++) {
for (var ii0 in bigList_nowon) {
numbersCopy.push(bigList_nowon[ii0]);
}
}
const current1 = numbersCopy[randomNum(1, numbersCopy.length) - 1];
const current = JSON.parse(JSON.stringify(current1));
res.push(current);
wons.push(current);
} else {
const nodraws = peolist.filter(item => !wons.includes(item));
const current = nodraws[randomNum(1, nodraws.length) - 1];
res.push(current);
wons.push(current);
}
}
return res;
}

app.vue
bigList3no() {
const namelist3no = [
];
const a3no = [];
namelist3no.forEach((item1) => {
if (this.list.some((item) => item.name == item1)) {
a3no.push(this.list.find((item) => item.name == item1).key);
}
});
return a3no;
},
bigList0() {
const namelist0 = [];
const a0 = [];
namelist0.forEach((item1) => {
if (this.list.some((item) => item.name == item1)) {
a0.push(this.list.find((item) => item.name == item1).key);
}
});
return a0;
},
bigList1() {
const namelist1 = [];
const a1 = [];
namelist1.forEach((item1) => {
if (this.list.some((item) => item.name == item1)) {
a1.push(this.list.find((item) => item.name == item1).key);
}
});
return a1;
},
bigList2() {
const namelist2 = [];
const a2 = [];
namelist2.forEach((item1) => {
if (this.list.some((item) => item.name == item1)) {
a2.push(this.list.find((item) => item.name == item1).key);
}
});
return a2;
},
bigList3() {
const namelist3 = [

];
const a3 = [];
namelist3.forEach((item1) => {
if (this.list.some((item) => item.name == item1)) {
a3.push(this.list.find((item) => item.name == item1).key);
}
});
return a3;
},