写在前面
中小企业低价值活动抽奖可用,高价值抽奖不要用!!!
雷区:
1.因为需要通过前端操作数据接口,可能导致权限不受控
2.数据都是通过前端接口操作,不安全!!!
正确的方式应该接入后端,数据在后端处理
环境
平台:钉钉宜搭
表单
大致页面如下,编号及链接代码自动生成
自定义页面
转盘参考插件jQuery抽奖转盘(原创)
链接携带参数prize,取抽奖编号
判断prize是否存在
if (!this.utils.router.getQuery("prize")) {
this.dialog("活动准备中...")
return
}
获取表单数据
let response = await this.getPrize(this.utils.router.getQuery("prize"))
let prizeData = response.content.data[0].formData
export async function getPrize(id) {
let url = new URL(BASE_API + "searchFormDatas.json")
let params = {
formUuid: formUuid,
searchFieldJson: JSON.stringify({
textField_lqq8tffj: id,
}),
currentPage: 1,
pageSize: 100
}
Object.keys(params).forEach(key => {
url.searchParams.set(key, params[key])
})
const response = await fetch(url);
const json = await response.json();
if (json.success == true && json.content.data.length > 0) {
return json
}
}
整理奖品数据
let formData = []
let prizeName = prizeData.textField_lqq71rf9
prizeData.tableField_lqq71rfa.forEach(item => {
if (item.numberField_lqq71rfd > 0) {
formData.push({
"id": item.numberField_lqq71rfc,
"name": item.textField_lqq71rfb,
"image": `${location.origin}` + JSON.parse(item.imageField_lqq71rfe)[0].url,
"rank": item.numberField_lqq71rfc,
"quantity": item.numberField_lqq71rfd
})
}
})
let userPrize = ""
prizeData.tableField_lqqg9v5z.forEach(item => {
if (!_.isEmpty(item)) {
if (!_.isEmpty(item.employeeField_lqqg9v60_id)) {
if (this.utils.getLoginUserId() == item.employeeField_lqqg9v60_id[0]) {
userPrize = item.textField_lqqg9v61
}
}
}
})
处理各种参与状态
if (!_.isEmpty(userPrize)) {
this.utils.dialog({
title: '已参加过抽奖',
content: this.utils.getLoginUserName() + ',您已参加过抽奖,奖品为\"' + userPrize + "\",奖品请等待统一分发", // 如需换行可传入 HTML/JSX 来实现
onOk: () => { }
});
return
}
let prizeType = prizeData.selectField_lqq7alb8
let userList = prizeData.employeeField_lqq86hwl_id
let refresh = true
this.setState({ formData, refresh })
switch (prizeType) {
case "准备中":
this.dialog("活动准备中...")
return;
case "进行中":
break;
case "已结束":
this.dialog("活动已结束...")
return;
default:
break;
}
if (userList.indexOf(this.utils.getLoginUserId()) == -1) {
this.dialog("不属于本次活动参与者...")
return
}
引入jQuery及转盘插件
import("https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js").then(async res => {
(function (jQuery) {
//插件下载到本地后直接将turntable.js复制过来
//部分参数稍作改动,以适应奖品数量
let minCSRadius = 240 //外圆半径
let minISRadius = 220 //内圆半径
let minCSWidth = 22 //外圆宽度
let minISWidth = (minCSRadius - minCSWidth / 2 - minISRadius) * 2 //内圆宽度
let minSectorRadius = (minISRadius - minISWidth / 2) / 2 //转盘半径
let minSectorWidth = minSectorRadius * 2 //转盘宽度
let minCIRadius = minCSRadius - minCSWidth / 2 //装饰圈半径
let minOrnamentRadius = 11 //装饰点半径
let namePosition = [0, -170, 150]
let imgPosition = [-40, -40 - 130]
let imgSize = 80
if (num > 7) {
let ratio = Math.sqrt(1 + (num - 7) / 7)
minCSRadius *= ratio
minISRadius *= ratio
minCSWidth *= ratio
minISWidth *= ratio
minSectorRadius *= ratio
minSectorWidth *= ratio
minCIRadius *= ratio
minOrnamentRadius *= ratio
namePosition[1] *= ratio
namePosition[2] /= ratio
imgSize /= ratio
imgPosition[0] = -imgSize / 2
imgPosition[1] = namePosition[1] + 20 * ratio
}
}(jQuery))
jQuery("#prize_name").html(prizeName)
jQuery("#prize_name").css({ "text-align": "center", "font-size": "20px" })
let choujiang = await this.getImg("抽奖")
this.setState({ "choujiang": choujiang })
this.initPrize()
// setInterval(() => {
// if (this.state.refresh) {
// this.refreshPrize()
// }
// }, 1000);
//根据需要看是不是需要刷新最新奖品数据
})
ctx.translate作为单独方法调用
加载转盘
export function initPrize() {
let _this = this
let formData = this.state.formData
let wheelSurf
let totla = formData.reduce((prev, cur) => prev + cur["quantity"], 0)
formData.forEach(data => {
data.percent = (data.quantity / totla) * 100
})
// 初始化装盘数据 正常情况下应该由后台返回
var initData = {
"success": true,
"list": formData
}
// 计算分配获奖概率(前提所有奖品概率相加100%)
async function getGift() {
var percent = Math.random() * 100
var totalPercent = 0
for (var i = 0, l = initData.list.length; i < l; i++) {
totalPercent += initData.list[i].percent
if (percent <= totalPercent) {
let response = await _this.getPrize(_this.utils.router.getQuery("prize"))
let prizeData = response.content.data[0].formData
let formInstId = response.content.data[0].formInstId
let chose = false //限制抽检按钮
let isChose = false //限制多页面导致多次抽奖
prizeData.tableField_lqqg9v5z.forEach(item => {
if (!_.isEmpty(item)) {
item.employeeField_lqqg9v60 = item.employeeField_lqqg9v60_id
if (item.employeeField_lqqg9v60_id.indexOf(_this.utils.getLoginUserId()) > -1) {
isChose = true
chose = true
}
}
})
if (!isChose) {
for (let j = 0; j < prizeData.tableField_lqq71rfa.length; j++) {
if (prizeData.tableField_lqq71rfa[j].numberField_lqq71rfc == initData.list[i].id && prizeData.tableField_lqq71rfa[j].numberField_lqq71rfd > 0) {
prizeData.tableField_lqq71rfa[j].numberField_lqq71rfd -= 1
prizeData.tableField_lqqg9v5z.push({
employeeField_lqqg9v60: [_this.utils.getLoginUserId()],
textField_lqqg9v61: initData.list[i].name,
dateField_lqqg9v62: new Date().getTime()
})
console.log(prizeData)
let params = {
formInstId: formInstId,
updateFormDataJson: JSON.stringify({
tableField_lqq71rfa: prizeData.tableField_lqq71rfa,
tableField_lqqg9v5z: prizeData.tableField_lqqg9v5z
}),
useLatestVersion: "y"
}
let response = await _this.updateForm(params)
if (response) {
chose = true
}
}
}
}
return [initData.list[i], chose, isChose]
}
}
}
var list = {}
var angel = 360 / initData.list.length
// 格式化成插件需要的奖品列表格式
for (var i = 0, l = initData.list.length; i < l; i++) {
list[initData.list[i].rank] = {
id: initData.list[i].id,
name: initData.list[i].name,
image: initData.list[i].image
}
}
// 查看奖品列表格式
wheelSurf = jQuery('#myCanvas').WheelSurf({
list: list, // 奖品 列表,(必填)
outerCircle: {
color: '#df1e15' // 外圈颜色(可选)
},
innerCircle: {
color: '#f4ad26' // 里圈颜色(可选)
},
dots: ['#fbf0a9', '#fbb936'], // 装饰点颜色(可选)
disk: ['#ffb933', '#ffe8b5', '#ffb933', '#ffd57c', '#ffb933', '#ffe8b5', '#ffd57c'], //中心奖盘的颜色,默认7彩(可选)
title: {
color: '#5c1e08',
font: '19px Arial'
} // 奖品标题样式(可选)
})
jQuery("#start").attr({ src: this.state.choujiang })
// 初始化转盘
wheelSurf.translate()//TODO:这里有变动
wheelSurf.init()
// 抽奖
var throttle = true;
jQuery("#start").on('click', async function () {
if (!throttle) {
return false;
}
var [winData, chose, isChose] = await getGift() // 正常情况下获奖信息应该由后台返回
jQuery("#message").html('')
if (!_this.state.refresh) {
return false;
}
throttle = false;
_this.setState({ refresh: false })
var count = 0
// 计算奖品角度
for (const key in list) {
if (list.hasOwnProperty(key)) {
if (winData.id == list[key].id) {
break;
}
count++
}
}
// 转盘抽奖,
wheelSurf.lottery((count * angel + angel / 2), function () {
if (isChose) {
_this.utils.dialog({
title: "已经参加过本次抽奖",
content: "已经参加过本次抽奖,请勿重复抽奖", // 如需换行可传入 HTML/JSX 来实现
footerActions: ['ok'],
onOk: () => { }
});
jQuery("#start").css("filter", "grayscale(100%)")
} else {
if (chose) {
_this.utils.dialog({
title: "抽奖结束",
content: "恭喜抽中奖品\"" + winData.name + "\",奖品请等待统一分发", // 如需换行可传入 HTML/JSX 来实现
footerActions: ['ok'],
onOk: () => { }
});
jQuery("#start").css("filter", "grayscale(100%)")
} else {
_this.dialog("奖品异常,再抽一次吧")
_this.setState({ refresh: true })
throttle = true;
}
}
})
})
}
其他需要自己写的代码:
1.图片获取
2.转盘刷新(按需)
3.更新表单数据