瀏覽代碼

调整转盘、 国庆公告

zhengkaixin 9 月之前
父節點
當前提交
4ccc79035e

+ 8 - 0
apis/chargeProcess.js

@@ -76,6 +76,14 @@ export function stopCarCharging(data) {
 	})
 }
 
+export function getRateByRecordId(data) {
+	return request({
+		method: 'post',
+		data: data,
+		url: '/mobile/quickChargeActivity/getRateByRecordId'
+	})
+}
+
 export function useCoupon(data) {
 	return request({
 		method: 'post',

二進制
assets/img/temporary/national-2024-0.png


二進制
assets/img/temporary/national-2024-1.png


二進制
assets/img/temporary/national-2024-2.png


二進制
assets/img/temporary/national-2024-3.png


二進制
assets/img/temporary/national-2024-4.png


二進制
assets/img/temporary/national-2024-5.png


二進制
assets/img/temporary/national-2024-6.png


二進制
assets/img/temporary/national-2024-7.png


+ 676 - 0
components/lottery/index.vue

@@ -0,0 +1,676 @@
+<template>
+	<view class="main" >
+		<!-- <view class="title-container">
+			{{name}}
+		</view> -->
+		<view v-if="options.length>0" class="canvas-container">
+			<canvas canvas-id="canvas" id="canvas" :style="canvasStyle" />
+			
+		</view>
+		<image src="./national-2024-7.png"
+		style="width: 330px; height: 320px;z-index: 999; margin-top: -300px;"
+		></image>
+		<image src="./national-2024-6.png" @click="end"
+		style="width: 330px; height: 250px;    margin-top: -80px;"
+		></image>
+		<view class="show1" style="    position: relative;
+    top: -140px;
+    color: rgba(157, 58, 15, 1);
+    font-size: 28px;" >
+			{{name}}
+		</view>
+		<!-- <view v-if="showBtn" btn-container>
+			<button type="primary" :disabled="isLottery" @click="playReward">{{btnTitle}}</button>
+		</view> -->
+	</view>
+</template>
+<script>
+	var img2=require('./national-2024-2.png')
+	var img3=require('./national-2024-3.png')
+	var ctx = null;
+	export default {
+
+		props: {
+			// 弹窗内容 ,当 turnModalContent=【】时,默认弹窗内容为抽奖结果,并且不展示标题
+			turnModalContent: {
+				type: Array,
+			
+				default () {
+					return []
+				}
+			},
+			// 减速,值越小,减速效果越明显 turnReduceSpeed
+			turnReduceSpeed: {
+				type: Number,
+				default: 50
+			},
+			// 表示转速:表示再转多少圈再进行抽奖
+			turnCircle: {
+				type: Number,
+				default: 0
+			},
+			// 转盘名称
+			name: {
+				type: String,
+				default: "摇奖中..."
+			},
+			// 画布宽度
+			width: {
+				type: Number,
+				default: 100,
+
+			},
+			// 画布高度
+			height: {
+				type: Number,
+				default: 100
+			},
+			// 画布内字体大小
+			fontSize: {
+				type: Number,
+				default: 18
+			},
+			// 钩子函数,抽奖开始前执行,返回值为选项列表下标,若返回值为-1,则进行随机抽奖
+			setWinnerFn: {
+				type: Function,
+				default: null,
+			},
+			// // 钩子函数,抽奖开始前执行
+			// beforePlay: {
+			// 	type: Function,
+			// 	default: null,
+			// },
+			// // 钩子函数,抽奖结束后执行
+			// afterPlay: {
+			// 	type: Function,
+			// 	default: null,
+			// },
+			// 如果 true,则 使用组件默认的选项数据
+			isUseDefaultOptions: {
+				type: Boolean,
+				default: false
+			},
+			// 选项列表
+			data: {
+				type: Array,
+				default: []
+			},
+			// 是否要展示开始按钮
+			showBtn: {
+				type: Boolean,
+				default: false,
+			},
+			// 按钮文本
+			btnTitle: {
+				type: String,
+				default: "开始"
+			}
+		},
+		data() {
+			return {
+				img2:img2,
+				img3:img3,
+				options: [{
+						id: 0, // 唯一id
+						name: '水饺', // 名称
+						// "weight": 50, //  中奖权重,0-100
+						img: '', // 展示图片
+						color: "#f6e174" // 轮盘区域底色
+					},
+					{
+						id: 2,
+						name: '火锅',
+						img: '',
+						color: "#94494d"
+					},
+					{
+						id: 3,
+						name: '川菜',
+						img: '',
+						color: "#ffaa7f"
+					},
+					{
+						id: 4,
+						name: '麻辣烫',
+						img: '',
+						color: "#a48342"
+					},
+					{
+						id: 5,
+						name: '炸鸡汉堡',
+						img: '',
+						color: "#a25f81"
+					}
+					
+				],
+				isLottery: false, // 是否正在抽奖
+			};
+		},
+		computed: {
+			canvasStyle() {
+				return "width:" + this.width + "px;; height:" + this.height + "px;";
+			},
+
+		},
+		methods: {
+			end(){
+				if (this.isLottery) {
+					
+					uni.showToast({
+						title: "摇奖中...",
+						icon: "none"
+					})
+				}else{
+					this.$emit("end")
+				}
+			},
+			async playReward() {
+				if (this.isLottery) {
+					return
+				}
+				this.isLottery = true
+				let len = this.options.length
+				if (len == 0) {
+					return;
+				}
+				//console.log("playReward")
+				// if (this.beforePlay) {
+				// () => this.beforePlay()
+				// this.beforePlay()
+				this.$emit("beforePlay")
+				// }
+
+				let num = -1;
+				if (this.setWinnerFn) {
+					// 自定义抽奖结果
+					let res = () => this.setWinnerFn(this.options)
+					if (res != undefined && res >= 0) {
+						num = res
+					}
+					 
+				}
+
+				if (num < 0) {
+					// 进行权重抽奖
+					let optionIndex = this.lotteryWeight(this.options)
+					if (optionIndex != undefined || optionIndex >= 0) {
+						num = optionIndex
+					}
+				}
+				if (num < 0) {
+					// 没有自动抽奖结果 && 没有定义选项权重,则进行随机数抽奖
+					num = Math.floor(Math.random() * len)
+				}
+
+				const result = await this.roateCanvas(num)
+				//console.log("抽奖结果:", result.name)
+				this.name=result.name
+				this.isLottery = false
+				let title = ""
+				let content = result.name
+				if (this.turnModalContent.length > 0) {
+					// 若设置了 content ,则随机取一个 content 内容,并且 title 将展示为抽奖结果 
+					title = result.name
+					content = this.turnModalContent[Math.floor(Math.random() * this.turnModalContent.length)]
+				}
+				
+
+
+			},
+
+			initBtnCanvas() {
+				let angleTo = 0
+				let ctx = uni.createCanvasContext("canvasBtn", this);
+				// 6. 画中心点圆
+				// 圆中心点的坐标 x: 宽度的一半
+				let center_x = this.width / 2;
+				// 圆中心点的坐标 y: 高度的一半
+				let center_y = this.height / 2;
+
+				// 1. 先清除画布上在该矩形区域内的内容
+				ctx.clearRect(0, 0, this.width, this.height);
+
+				ctx.translate(center_x, center_y);
+
+				// 6. 画中心点圆
+				ctx.beginPath();
+				// ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
+				ctx.moveTo(0, -50); // 三角形顶点坐标
+				ctx.lineTo(-20, 10); // 左下角坐标
+				ctx.lineTo(20, 10); // 右下角坐标
+				ctx.setFillStyle("#ff0000");
+				ctx.fill();
+				ctx.draw();
+			},
+			initCanvas: function(ctx, angleTo) {
+
+				const len = this.options.length; //数组长度
+				if (len == 0) {
+					//console.log("options len == 0")
+					return;
+				}
+				if (!angleTo) {
+					angleTo = 0
+				}
+				// 圆中心点的坐标 x: 宽度的一半
+				let center_x = this.width / 2;
+				// 圆中心点的坐标 y: 高度的一半
+				let center_y = this.height / 2;
+				// 圆的弧度的总度数,2π表示画圆
+				let totalAngle = 2 * Math.PI;
+				// 平均一个选项占用的孤度数
+				let avgAngle = totalAngle / len;
+
+				let radius = center_x - 14;
+				let fontSize = this.getFontSize()
+
+				// 1. 先清除画布上在该矩形区域内的内容
+				ctx.clearRect(0, 0, this.width, this.height);
+
+				ctx.translate(center_x, center_y);
+				// 2. 设置画布内字体大小
+				ctx.setFontSize(fontSize);
+				ctx.setLineWidth(14);
+				ctx.save();
+
+				// 3. 画外圆
+				ctx.rotate(angleTo * Math.PI / 180);
+				var beginAngle = 2 * Math.PI / 360 * (-90);
+				// ctx.setStrokeStyle("#ffaa00");
+				ctx.setStrokeStyle("#ffffff");
+				ctx.arc(0, 0, radius - 3, 0, Math.PI * 2);
+				ctx.stroke();
+
+				// 4. 划分区域,并且填充颜色
+				ctx.setLineWidth(0.1);
+				beginAngle = 2 * Math.PI / 360 * (-90);
+				//绘制填充形状
+				for (var i = 0; i < len; i++) {
+					ctx.save();
+					ctx.beginPath();
+					ctx.moveTo(0, 0);
+					ctx.setStrokeStyle(this.options[i].color);
+					ctx.setFillStyle(this.options[i].color);
+
+					ctx.arc(0, 0, radius, beginAngle, beginAngle + avgAngle, false);
+					//ctx.stroke();
+					
+					beginAngle = beginAngle + avgAngle;
+					ctx.fill();
+					ctx.save();
+					
+					
+					 
+				}
+			
+				// 5. 绘制选项文字
+				beginAngle = 0; //avgAngle / 2;
+				for (var i = 0; i < len; i++) {
+					var ry = -(center_x / 2) - 25;
+					//绘制旋转文字
+					ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
+					ctx.setTextAlign("center");
+					ctx.setFillStyle("#9D3A0F");
+					ctx.fillText(this.options[i].name, 0, ry);
+					 
+				
+					  
+					ctx.restore();
+					beginAngle = beginAngle + avgAngle;
+				}
+				
+				 var img = new Image();  
+				// img.onload = function() {
+					
+					
+					beginAngle = 0; //avgAngle / 2;
+					for (var i = 0; i < len; i++) {
+						
+						ctx.save();
+						var ry = -(center_x / 2) - 25;
+						//绘制旋转文字
+						ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
+					
+						
+						if(this.options[i].id==1){
+							ctx.drawImage(this.img2, -17, -90,32,32);
+						}else{
+							ctx.drawImage(this.img3, -17, -90,32,32);
+						}
+						
+						
+						//  ctx.draw(true)
+						  
+						ctx.restore();
+						beginAngle = beginAngle + avgAngle;
+					}
+					//ctx.draw();	 
+					
+				// }
+				 
+				//  img.src=this.img3
+				  
+				
+				
+				
+				ctx.save();
+				// 6. 画中心点圆
+				ctx.beginPath();
+				ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
+				ctx.setFillStyle("#FFFFFF");
+				ctx.fill();
+				ctx.draw();
+			},
+			// 根据设置的权重进行抽奖
+			lotteryWeight(prizes) {
+				if (!prizes || prizes.length == 0) {
+					//console.log("奖品列表为空")
+					return -1
+				}
+				let winPrizesIndex = [] // 抽中的奖品下标,多个是因为如果存在多个奖品的权重一致的情况,则再进行随机抽奖
+				let winPrizeWeight = 0; // 抽中的奖品的权重
+
+				let round = Math.random() * 100; // 生成一个 0-100的随机数
+				//console.log("lotteryWeight 生成的 round:", round)
+				for (let index = 0; index < prizes.length; index++) {
+					let prize = prizes[index];
+					let weight = prize['weight']
+					if (!weight) {
+						// 没有设置权重,则跳过
+						//console.log("奖品 ", prize.name, " 未设置权重,则不参与抽奖")
+						continue
+					}
+					if (weight <= 0) {
+						// 如果奖品的权重设置<0,则表示不参与抽奖
+						//console.log("奖品 ", prize.name, " 不参与抽奖")
+						continue
+					}
+					if (round > weight) {
+						// 随机数超过了权重,则未抽中
+						continue
+					}
+					if (weight < winPrizeWeight) {
+						// 权重比之前抽中的还小,则跳过
+						//console.log("奖品 ", prize.name, "小于已经抽中的奖品", winPrizeWeight, " 不参与抽奖")
+						continue
+					}
+					if (weight == winPrizeWeight) {
+						// 本次抽中的奖品和已经抽中的奖品权重一致,则加入抽中列表
+						//console.log("再抽中奖品 ", prize.name, " 中奖")
+						winPrizesIndex.push(index)
+						continue
+					}
+					if (weight > winPrizeWeight) {
+						// 权重比之前抽中的还大,则重置抽中奖品
+						winPrizesIndex = [index]
+						winPrizeWeight = weight
+						//console.log("奖品 ", prize.name, " 中奖")
+						continue
+					}
+				}
+				if (winPrizesIndex.length <= 0) {
+					// 本次没有抽中奖品
+					//console.log("本次没有抽中奖品")
+					return -1
+				}
+				if (winPrizesIndex.length == 1) {
+					// 只抽中了一个奖品,这直接返回
+					let index = winPrizesIndex[0];
+					//console.log("奖品 ", prizes[index], " 抽中");
+					return index
+				}
+				if (winPrizesIndex.length > 1) {
+					// 抽中多个,则再进行随机抽奖
+					//console.log(" 抽中多个,则再进行随机抽奖");
+					let index = round % winPrizesIndex.length
+					index = Math.floor(index)
+					//console.log("再次抽中结果:", winPrizesIndex[index])
+					return winPrizesIndex[index]
+
+				}
+
+
+				//console.log("其他抽奖情况")
+				return -1
+
+			},
+			// 旋转画布,num 表示选项 options 的下标
+			roateCanvas(num) {
+				let len = this.options.length
+				let angle = 360 / len;
+				angle = num * angle + angle / 2;
+				angle = angle || 0;
+				angle = 360 - angle;
+				angle += 360 * 5;
+				if (this.turnCircle > 0) {
+					let turnCircle = this.turnCircle
+					// 最多只能转 10 圈
+					if (turnCircle > 10) {
+						turnCircle = 10
+					}
+					angle += 360 * turnCircle;
+				}
+				let that = this;
+				let count = 1;
+				// 减速,值越小,减速效果越明显 
+				let turnReduceSpeed = this.turnReduceSpeed
+				if (turnReduceSpeed == 0) {
+					turnReduceSpeed = 1
+				}
+				let baseStep = turnReduceSpeed;
+				// 起始滚动速度
+				let baseSpeed = 1;
+				let result = {}
+				return new Promise((resolve, reject) => {
+					let timer = setInterval(function() {
+						
+						that.initCanvas(that.ctx, count);
+						if (count == angle) {
+							clearInterval(timer);
+							result = that.options[num];
+							resolve(result)
+						}
+						count = count + baseStep * (((angle - count) / angle) > baseSpeed ? baseSpeed :
+							((angle -
+								count) / angle)) + 0.1;
+
+						if (angle - count < 0.5) {
+							count = angle;
+						}
+					}, 25);
+				});
+			},
+			getFontSize() {
+				let fontSize = this.fontSize
+				if (this.options.length > 10) {
+					if (this.fontSize >= 18) {
+						fontSize = this.fontSize - (this.options.length - 10)
+					}
+				}
+
+				return fontSize
+			},
+			// 生成随机颜色
+			genRandColor() {
+				// 生成随机的 RGB 值
+				var r = Math.floor(Math.random() * 256); // 0 到 255 之间的随机数
+				var g = Math.floor(Math.random() * 256);
+				var b = Math.floor(Math.random() * 256);
+
+				// 将 RGB 值转换为 Hex 颜色表示
+				var hexColor = "#" + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
+
+				return hexColor;
+			},
+			componentToHex(c) {
+				var hex = c.toString(16);
+				return hex.length === 1 ? "0" + hex : hex;
+			},
+			initOptions: function() {
+				let defaultOptions = this.options
+				if (this.isUseDefaultOptions) {
+					// 使用默认数据
+				} else {
+					this.options = this.data
+				}
+				// 所有默认的颜色
+				let allDefColorArr = defaultOptions.map(item => item.color);
+
+				// 找到最大的 id
+				let maxId = -Infinity;
+
+				this.options.forEach(item => {
+					if (!item.id) {
+						return
+					}
+					if (item.id > maxId) {
+						maxId = item.id;
+					}
+				});
+				// 填充 id,确保 id 唯一
+				var existIds = []
+				for (var i = 0; i < this.options.length; i++) {
+					let item = this.options[i]
+					if (item['id'] == undefined || item.id == 0 || existIds.includes(item.id)) {
+						// id 不存在,或者 id 重复了
+						this.options[i]['id'] = maxId + 1
+					}
+					existIds.push(this.options[i].id)
+					if (item['color'] == undefined || item.color == "") {
+
+					}
+				}
+				// 填充颜色,确保颜色唯一
+				let availableColor = JSON.parse(JSON.stringify(allDefColorArr)) // 可用颜色
+				let existColor = [] // 存在颜色
+				for (var i = 0; i < this.options.length; i++) {
+					let item = this.options[i]
+					if (item['color'] == undefined || item.color == "") {
+						continue
+					}
+					let color = item.color
+					existColor.push(color)
+					// 过滤掉已经用了的 color
+					availableColor = availableColor.filter(item => item !== color);
+
+				}
+				// 剩下的 allDefColorArr 都是可用的颜色
+				for (var i = 0; i < this.options.length; i++) {
+					let item = this.options[i]
+
+					if (item['color'] == undefined || item.color == "") {
+						if (availableColor.length == 0) {
+							// 没有可用颜色了,则随机生成一个
+							let color = ''
+							for (var j = 0; j < 100; j++) {
+								if (color != '') {
+									continue
+								}
+								let genColor = this.genRandColor()
+								if (!existColor.includes(genColor)) {
+									existColor.push(color)
+									color = genColor
+								}
+							}
+							this.options[i]['color'] = color
+							continue
+						}
+						const color = availableColor.shift();
+						existColor.push(color)
+						this.options[i].color = color
+					}
+
+
+				}
+			},
+			init() {
+				this.initOptions();
+				this.ctx = uni.createCanvasContext("canvas", this);
+				this.initCanvas(this.ctx, 0);
+				this.initBtnCanvas();
+				this.playReward()
+			}
+		},
+		// 初始化画布
+		mounted: function() {
+			//console.log("lottery mounted init......")
+			this.init()
+		}
+	}
+</script>
+<style scoped>
+	.main {
+		display: flex;
+		flex-direction: column;
+		justify-content: center;
+		align-items: center;
+	}
+
+	.title-container {
+		font-size: 25px;
+		margin-top: 120rpx;
+		margin-bottom: 40rpx;
+		z-index: 100;
+	}
+
+	.canvas-container {
+		position: relative;
+		width: fit-content;
+		height: fit-content;
+		z-index: 99;
+	}
+
+	.canvasBtn {
+		position: absolute;
+		top: 0%;
+	}
+
+	.canvas-btn {
+		position: absolute;
+		top: 50%;
+		left: 50%;
+		background-color: #ffffff;
+		transform: translate(-50%, -50%);
+		width: 110rpx;
+		height: 110rpx;
+		border-radius: 50%;
+		line-height: 110rpx;
+		text-align: center;
+		font-size: 45rpx;
+		text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
+		box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
+		text-decoration: none;
+	}
+
+
+	/* 	.canvas-btn::before {
+		content: "";
+		position: absolute;
+		top: -15px;
+		left: 50%;
+		transform: translateX(-50%);
+		width: 0;
+		height: 0;
+		border-left: 10px solid transparent;
+		border-right: 10px solid transparent;
+		border-bottom: 20px solid #ffffff;
+	} */
+
+	.canvas-btn.isLottery {
+		background-color: #CCCCCC;
+	}
+
+	/* 	.canvas-btn.isLottery {
+		pointer-events: none;
+		background: #CCCCCC;
+		color: #ccc;
+	} */
+
+	/* 	.canvas-btn.isLottery::before {
+		border-bottom-color: #CCCCCC;
+	}
+
+	.canvas-btn.isLottery::after {
+		border-bottom-color: #CCCCCC;
+	} */
+</style>

二進制
components/lottery/national-2024-2.png


二進制
components/lottery/national-2024-3.png


二進制
components/lottery/national-2024-5.png


二進制
components/lottery/national-2024-6.png


二進制
components/lottery/national-2024-7.png


+ 3 - 2
config/.env.dev.ud.js

@@ -2,7 +2,7 @@ const UNI_APP = {
 	ProjectName :"优电联盟",
 	BASE_URL: 'https://youdian.hbjp.com.cn/charging-station-server/',
 	//
-	//BASE_URL: 'https://charging.xiaoxinda.com/charging-station-test/',
+	BASE_URL: 'https://charging.xiaoxinda.com/charging-station-test/',
 
 	//BASE_URL: 'http://192.168.77.162:8081/charging-station/' ,
 	//PARK_URL: 'http://192.168.11.120:8082/charging-parking/' ,
@@ -12,6 +12,7 @@ const UNI_APP = {
 	SIMPLE_RUN:true,// 无视权限控制跳转页面   , 用于样式人员快速访问各种功能 ,快速测试等
 	defaultStation:["3865b3a3-13fd-461a-8145-ee9711df35a2","da6e714d-c5a8-4f76-8132-5f4a56677130"],
 	defaultStation:["e012f9fe-90a8-4a47-bb64-26ea139c3c05"],
+	 defaultStation:["3865b3a3-13fd-461a-8145-ee9711df35a2"],
 	//defaultStation:[],
 	openId:"zkxtest23",//zkx
 	gzUrl:"https://mp.weixin.qq.com/s/mCHz1nNvg0xAICiBeIyKRQ",
@@ -21,7 +22,7 @@ const UNI_APP = {
 
 	openId:"oSruR6YkhP7QDroLnZGxWis43Kn0",//zkx
 	//openId:"oSruR6dsG6wrbiQCwyftfgnp5690",//sz
-	//openId:"oK9Wr59rru-i3bm7dtTtxnkR-i4s",
+	openId:"oSruR6dZcmSM4ATuweZ5fjHGQsiA",//ys
 	//openId:"123",
 	//小鹏管家appid
 	//VUE_APP_WXAPPID:"wx7e70eb62a8459869",

+ 7 - 0
pages.json

@@ -957,6 +957,13 @@
         	{
         		"navigationBarTitleText" : ""
         	}
+        },
+        {
+        	"path" : "pages/temporary/national2024",
+        	"style" : 
+        	{
+        		"navigationBarTitleText" : ""
+        	}
         }
     ],
 	"globalStyle": {

+ 140 - 5
pages/searchPile/chargeProcess/dcCharging.vue

@@ -1,5 +1,21 @@
 <template>
-	<view>
+	<view>
+		<u-modal v-model="showlottery" class="showlottery"
+		 :show-title="false" 
+		 :show-confirm-button="false" >
+			<lottery class="lottery"
+			:width="lwidth"
+			 :height="lheight"
+			  :isUseDefaultOptions="false" 
+			  :data="dataLottery" 
+			    @beforePlay="beforePlay"
+			  @afterPlay="afterPlay"
+				@end="showlottery=false"
+			 :setWinnerFn="getWinnerFn">
+			</lottery>
+		</u-modal>
+
+		
 		<view v-if="chargingRecord.status==2" style="background-color: #fff; ">
 			<ujp-navbar title="充电结束">
 			</ujp-navbar>
@@ -702,6 +718,7 @@
 	import * as newsApi from '@/apis/news.js'
 	import * as echarts from "echarts";
 
+	import lottery from '@/components/lottery/index.vue';
 
 	import {
 		newDate,
@@ -709,9 +726,14 @@
 		hourDistanceArr,
 		daysDistance,minuteConversion
 	} from '@/utils'
-	export default {
+	export default {
+		components:{
+			lottery
+		},
 		data() {
-			return {
+			return {
+				showlottery:false,
+				
 				barstyle: {
 					backgroundColor: "#19be6b"
 				},
@@ -782,7 +804,50 @@
 				chargingTagUrl: false,
 				chargingTag: false,
 				personInfo: null,
-				myChart: null,
+				myChart: null,
+				
+				lwidth: 300,
+				lheight: 300,
+				
+				lotteryIndex:0,
+				dataLottery: [
+					{
+						id: 2,
+						name: '服务费5折',
+						num:50,
+						img: '',
+						color: "#f7e2c3"
+					},
+					{
+						id: 3,
+							name: '服务费6折',
+							num:60,
+						img: '',
+						color: "#fbf0df"
+					},
+					{
+						id: 4,
+							name: '服务费7折',
+							num:70,
+						img: '',
+						color: "#f7e2c3"
+					},
+					{
+						id: 5,
+						name: '服务费8折',
+						num:80,
+						img: '',
+						color: "#fbf0df"
+					},
+					{
+							id: 1, // 唯一id
+							num:0,
+							name: '服务费免单', // 名称
+							img: '', // 展示图片
+							color: "#fff" ,// 轮盘区域底色
+							
+						}
+				],
 			}
 		},
 		onLoad(op) {
@@ -869,6 +934,26 @@
 			}
 		},
 		methods: {
+			getWinnerFn() {
+				// 自定义抽奖结果 ,返回值为 options 奖品列表下标,若返回 -1,则会进行随机抽奖
+				return this.lotteryIndex
+			},
+			beforePlay(){
+				console.log("beforePlay....",this.lwidth)
+			},
+			afterPlay(result){
+				// uni.showModal({
+				// 	confirmText: "确定",
+				// 	showCancel: false,
+				// 	content: result.name,
+				// 	success: (res) => {
+				// 		if (res.confirm) {
+				// 			console.log('用户点击确定');
+				// 		}
+				// 	}
+				// })
+			
+			},
 			minuteConversion(a,b){
 				return minuteConversion(a,b)
 			},
@@ -1403,6 +1488,40 @@
 						title: error
 					})
 				})
+			},
+			
+			lotteryApi(){
+				API.getRateByRecordId({
+					recordId: this.chargingRecord.id
+				}).then((res) => {
+					
+					if(res.data.serviceDiscountRatio!=null){
+						
+						this.lotteryIndex=this.dataLottery.findIndex(item=>{
+							
+							console.log(res.data.serviceDiscountRatio,item.num,res.data.serviceDiscountRatio==item.num)
+							return res.data.serviceDiscountRatio==item.num
+						})
+						console.log(this.lotteryIndex)
+						if(this.lotteryIndex!=-1){
+							this.dataLottery[this.lotteryIndex].weight=100
+							
+							this.showlottery=true
+						}
+						
+					}else{
+					
+					}
+						this.confirm()
+					
+				}).catch(error => {
+				
+					uni.showToast({
+						title: error
+					})
+				
+				})
+				
 			},
 			submit() {
 				if (this.chargingRecord.status == 0 || this.chargingRecord.status == 1 || this.chargingRecord.status ==
@@ -1417,7 +1536,14 @@
 					success: res => {
 						if (res.confirm) {
 							//付钱  改为组件
-							this.confirm()
+							
+							if(this.chargingStation.quickChargeJoinActivity
+							&&this.chargingStation.quickChargeReduceResult){
+								this.lotteryApi()
+							}else{
+								//this.submitApi()
+								this.confirm()
+							}
 
 						} else if (res.cancel) {
 							//('用户点击取消');
@@ -2361,5 +2487,14 @@
 
 		 }
 		 
+	}
+	.showlottery{
+		/deep/.u-mode-center-box{
+			width: 330px !important;
+			background-color:unset;
+		}
+		/deep/.u-model{
+			background-color:unset;
+		}
 	}
 </style>

+ 649 - 0
pages/temporary/national2024.vue

@@ -0,0 +1,649 @@
+<template>
+	
+	<view class="all">
+	
+		<ujp-navbar title="国庆充电优惠活动" ></ujp-navbar>
+		<view class="InviteFriends" >
+			
+			<view class="text imgHead">
+				<img  src="@/assets/img/temporary/national-2024-1.png"></img>
+			</view>
+			<view class="text  national0">
+				<img  src="@/assets/img/temporary/national-2024-0.png"></img>
+			</view>
+			<view class="main">
+
+				<view class="suited">
+					<p class="title">活动时间 :</p>
+					<view class="content">
+						2024 年 10 月 1 日至 2024 年 10 月 31 日
+
+					</view>
+					
+					<p class="title">活动对象 :</p>
+					<view class="content">
+						优电联盟注册会员
+					
+					</view>
+
+					<p class="title">活动内容 :</p>
+					<view class="content">
+						
+						
+						<view class="p">1、凡在活动期间,前往活动场站充电的平台会员享受充电服务费 8.5 折优惠。</view>
+						<view class="p">2、凡在活动期间,快充且充电量达 30 度(含)以上均可享受一次抽奖机会(电费、停车费及占桩费据实结算)。</view>
+						<view class="p">	奖品如下:</view>
+					</view>
+					
+					
+					<view class="contentList">
+						<view class="item" v-for="(item,i) in list" :key="i"   >
+							<view class="item1" >
+								<view class="itemImg">
+									<img  v-if="item.num"  src="@/assets/img/temporary/national-2024-3.png"></img>
+									<img  v-else  src="@/assets/img/temporary/national-2024-2.png"></img>
+									
+								</view>
+								<view class="itemView">
+									<view class="itemName">{{item.name}}</view>
+									<view class="itemId">
+										
+										{{item.remark}}
+									</view>
+								</view>
+							</view>
+							<view class="item2"  v-if="item.num" >
+								{{(item.num)}}<span>折</span>
+							</view>
+							<view class="item2"  v-else >
+								免单
+							</view>
+						</view>
+					
+					</view>
+					<view class="remarks">
+					
+						
+						活动说明:<br/>
+						· 本活动以充电开始时间为准。<br/>
+						· 本次活动仅适用优电联盟平台会员,不包含快电、新电途用户。<br/>
+						· 本次活动最终解释权归湖北鹏育优电新能源科技有限公司所有<br/>
+					</view>
+					 
+				</view>
+
+			
+				
+				
+					
+					
+			</view>
+			
+		</view>
+		
+		<view class="text imgHead national4">
+			<img  src="@/assets/img/temporary/national-2024-4.png"></img>
+			
+			
+		</view>
+	</view>
+</template>
+
+<script>
+	
+
+
+	export default {
+		components: {
+		
+		},
+		data() {
+			return {
+				list:[
+					{
+						id:"3865b3a3-13fd-461a-8145-ee9711df35a2",
+						name:"服务费免单券",
+						num:0,
+						remark:"每日限 3 单"
+					},
+					{
+						id:"3c554cea-f522-4281-b582-d761510ed91e",
+						name:"服务费5折券",
+						num:5,
+						remark:"每日限 10 单"
+					},
+					{
+						id:"ef59b220-965f-4e9a-a087-4b52bbbcfb7f",
+						name:"服务费6折券",
+						num:6,
+						remark:"不限次数"
+					},
+					{
+						id:"8ab96b30-8102-476e-b166-78dc930838c2",
+						name:"服务费7折券",
+						num:7,
+						remark:"不限次数"
+					},
+					{
+						id:"5e71de75-d30e-4db3-9b3e-1fb2587d8f42",
+						name:"服务费8折券",
+						num:8,
+						remark:"不限次数"
+					}
+				]
+
+			}
+		},
+		onLoad(op) {
+			
+			
+		},
+		onReady() {
+			
+			
+		},
+		onShow() {
+
+			
+
+		},
+		methods: {
+			gotoStation(id){
+				uni.navigateTo({
+					url:"/pages/searchPile/stationAndPile/stationDetails?id="+id
+				})
+			}
+		}
+	}
+</script>
+<style>
+	page {
+		background: #b92d27;
+	}
+</style>
+<style lang="scss" scoped>
+	@import "@/_theme.scss";
+
+	.all {
+		@include themeify {
+			font-size: themed('font-size1');
+		}
+	}
+	 .imgHead {
+		img {
+		 			width: 100%;
+				} 
+	 }
+	
+	
+	// .imgHead {
+	// 	padding-top: 72rpx;
+	// 	display: flex;
+	// 	flex-direction: column;
+	// 	align-items: center;
+
+	// 	.imgHead1 {
+	// 		img {
+	// 			height: 24px;
+	// 		}
+
+	// 		display: flex;
+	// 		justify-content: center;
+	// 		align-items: center;
+	// 	}
+
+	// 	.imgHead2 {
+
+	// 		display: flex;
+
+	// 		img {
+	// 			width: 100%;
+	// 			height: 40px;
+	// 		}
+
+	// 		margin-top: 16px;
+	// 	}
+	// }
+	.contentList{
+		.item{
+			border: 1px solid rgba(232, 229, 225, 1);
+			border-radius: 8px;
+			display: flex;
+			    align-items: center;
+			    justify-content: space-between;
+				margin-bottom: 16rpx;
+				padding: 16rpx 24rpx;
+			.item1{
+				display: flex;
+				    align-items: center;
+				    justify-content: space-between;
+				.itemImg{
+					margin-right: 16rpx;
+					img{
+						width: 80rpx;
+						height: 80rpx;
+					}
+					
+				}
+				.itemName{
+					font-weight: bold;
+					color: rgba(16, 16, 16, 1);
+					font-size: 36rpx;
+				}
+				.itemId{
+					color: #96A2B4 ;
+					font-size: 24rpx;
+					    display: flex;
+						align-items: center;
+					    margin-top: 3px;
+					img{
+						width: 32rpx;
+						height: 32rpx;
+						margin-right: 2px;
+					}
+				}
+			}
+			.item2{
+				color: #FF6B00 ;
+				font-size: 72rpx;
+				font-weight: bold;
+				span{
+					font-weight: 400;
+					font-size: 28rpx;
+					margin-left: 8rpx;
+				}
+
+			}
+		}
+	}
+	.national0{
+		position: absolute;
+		top: 130rpx;
+		    width: 100%;
+			
+		    display: flex;
+		    justify-content: center;
+		img{
+			width: 666rpx;
+			height: 100rpx;
+		}
+	}
+	.national4{
+		    margin-top: -280rpx;
+		
+	}
+	.main {
+		position: relative;
+		top: -90rpx;
+		padding: 22rpx 24rpx 10rpx;
+
+		.text {
+			color: rgba(255, 255, 255, 100);
+
+		
+
+			/*		   font-size: 18px;*/
+			text-align: justify;
+			text-indent: 36px;
+
+
+		}
+
+		.suited {
+			background-color: #fff;
+			//background: linear-gradient(180deg, rgba(189,255,224,1) 0%,rgba(255,255,255,1) 14%);
+		//	background: linear-gradient(180deg, rgba(255, 224, 223, 1) 0%, rgba(255, 255, 255, 1) 14%);
+			//background: linear-gradient(180deg, rgba(214,226,255,1) 0%,rgba(255,255,255,1) 14%);
+			margin-top: 40rpx;
+			padding: 40rpx 32rpx;
+			border-radius: 20px;
+
+			.title {
+				/*height: 18px;*/
+				color: rgba(16, 16, 16, 100);
+
+
+
+				font-size: 32rpx;
+				font-weight: 600;
+			}
+			.remarks{
+				color: rgba(188, 188, 188, 1);
+				font-size: 22rpx;
+				margin-top: 40rpx;
+			}
+			.content {
+				.p{
+					margin: 12rpx 0;
+				}
+				margin: 16rpx 0 40rpx ;
+				//font-weight: 550;
+				color: #333333 ;
+				
+				font-size: 28rpx;
+				span{
+					color: #ec4f27;
+				}
+				p {
+					margin: 8rpx 0;
+				}
+			}
+		}
+		.application-table {
+			.nezhaImgView{
+				text-align: center;
+				margin-bottom: 24rpx;
+				img{
+					width: 100%;
+				}
+			}
+			background-color: #fff;
+			border-radius: 16px;
+			margin-top: 24px;
+			padding: 24rpx 36rpx;
+			padding-top:8px;
+		}
+
+		.application-form {
+			//background: linear-gradient(180deg, rgba(214,226,255,1) 0%,rgba(255,255,255,1) 14%);
+			color:#333333;
+			background-color: #fff;
+			border-radius: 16px;
+			margin-top: 24px;
+			padding: 24px;
+			.titlespan{
+				font-weight: bold;
+				color: rgba(16, 16, 16, 1);
+			}
+			.title{
+				color: rgba(16, 16, 16, 1);
+				font-size: 36rpx;
+				font-weight: bold;
+				margin-bottom: 24rpx
+			}
+			
+			.u-input {
+				border-radius: 50px;
+				background-color: rgba(232, 236, 234, 100);
+				margin-top: 12px;
+
+			}
+
+			/deep/.uni-input-input {
+				margin: 20px;
+			}
+
+			/deep/.u-input__right-icon {
+				margin-right: 10px;
+			}
+
+			p {
+				font-size: 18px;
+
+				@include themeify {
+
+					line-height: themed('font-size4');
+					height: themed('font-size4');
+				}
+
+				/*		  				  height: 18px;
+							  line-height: 18px;*/
+				color: rgba(16, 16, 16, 100);
+				/*		  				  font-size: 18px;*/
+			}
+
+			.tel,
+			.place,
+			.type,
+			.want {
+				//margin-top: 24px;
+			}
+
+			.textarea {
+				width: 72.2vw;
+				height: 140px;
+				border-radius: 22px;
+				background-color: rgba(232, 236, 234, 100);
+				margin-top: 12px;
+				overflow-y: scroll;
+
+				@include themeify {
+					font-size: themed('font-size2');
+					line-height: themed('font-size2');
+				}
+
+				.uni-textarea-placeholder {
+					padding: 12px 20px;
+
+					@include themeify {
+						font-size: themed('font-size2');
+						line-height: themed('font-size2');
+					}
+				}
+
+				/deep/.uni-textarea-textarea {
+					width: 90%;
+					padding: 10px 20px;
+
+				}
+
+				/deep/.u-input__right-icon {
+					display: none;
+				}
+			}
+		}
+
+		.type {
+			.checkbox {
+				margin-top: 12px;
+
+				/deep/.u-checkbox {
+					width: 50% !important;
+					margin-top: 4px;
+				}
+			}
+
+		}
+
+		.want {
+			/deep/.u-checkbox {
+				margin-top: 8px;
+			}
+		}
+
+		.hint {
+			margin-top: 12px;
+
+			@include themeify {
+				font-size: themed('font-size2');
+				line-height: themed('font-size5');
+			}
+
+			/*
+			font-size: 14px;
+			line-height: 20px;
+			*/
+			text-align: center;
+
+			.tel-num {
+				color: #9FC7FF;
+			}
+		}
+
+		/deep/.u-btn {
+			border-radius: 50px;
+			margin-top: 40rpx;
+		}
+	}
+
+	.InviteFriends {
+		//background-image: linear-gradient(0deg, #a2e9c9, #01b963);
+	
+		background: #b92d27;
+
+	}
+
+
+
+	.opacityClass {
+		opacity: 0.2;
+	}
+
+	// 底部
+	.bottomView {
+		border-radius: 50px;
+		color: rgba(0, 185, 98, 100);
+
+		// width: 100%;
+		// height: 64px;
+		// text-align: center;
+		// background-color: #fff;
+		.button {
+			//width: 90%;
+			border-radius: 50px;
+			// background-color: #fff;
+			color: #fff;
+			font-size: 16px;
+			background: linear-gradient(90deg, rgba(255, 98, 0, 1) 0%, rgba(255, 150, 0, 1) 100%);
+			//border: 1px solid rgba(0, 163, 86, 1);
+		}
+
+		// 	button::after {
+		// 		border: rgba(0, 185, 98, 100);
+		// 	}
+	}
+
+	.carAuth {
+		border-radius: 12px;
+		background-color: rgba(255, 255, 255, 1);
+		border: 2px dashed rgba(187, 187, 187, 1);
+		//height: 400rpx;
+		width: 100%;
+		overflow: hidden;
+		text-align: center;
+
+		.carAuthImg {
+			margin-top: 10px;
+			margin-bottom: 10px;
+			width: 510rpx;
+			height: 360rpx;
+		}
+
+		.carAuthIcon {
+			position: absolute;
+			background: #6e7175;
+			width: 44px;
+			height: 44px;
+			border-radius: 50px;
+			/* left: 200px; */
+			/* top: 200px; */
+			margin: 160rpx 230rpx;
+			z-index: 99;
+			display: flex;
+			justify-content: center;
+
+		}
+	}
+
+	// .car-type{
+	// 	    display: flex;
+	// 	    flex-direction: row;
+	// 		margin: 0 40rpx;
+	// 		flex-wrap: wrap;
+	// }
+	.want {
+		.wantView {
+			display: flex;
+		}
+
+		button {
+			width: 45%;
+			color: rgba(51, 51, 51, 1);
+			background-color: rgba(232, 236, 234, 1);
+
+		}
+
+		button::after {
+			border: none;
+		}
+
+		.wantBtn {
+			background-color: #fff;
+			border: 2px solid #00B962;
+		}
+
+		.wanttpis {
+			position: relative;
+			top: -100rpx;
+			left: 180rpx;
+			z-index: 99;
+			background: #00B962;
+			padding: 2px 3px;
+			font-size: 10px;
+			color: #fff;
+			border-radius: 4px;
+
+		}
+	}
+
+	.carTempBlInput {
+		display: flex;
+		align-items: center;
+		font-size: 16px;
+		min-height: 44px;
+		padding: 4px 16px;
+		border-radius: 20px;
+		background: #e9ecea;
+		color: #808080
+	}
+	
+	.table {
+		table {
+			color:#010101 ;
+			border-spacing:0;
+			font-size: 32rpx;
+			
+			.th {
+				
+
+				background-color: #f2efef;
+				text-align: center;
+				color:	#101010;
+				font-weight: bold;
+				td{
+					border: 1px solid   #dbdbdb;
+					padding: 12rpx 0;
+					height: 96rpx;
+
+				}
+			}
+	
+			.td1 {
+				text-align: start;
+			//	background-color: rgba(243, 245, 247, 1);
+				width: 132rpx;
+				text-align: center;
+
+				border-left: 1px solid   #dbdbdb;
+				border-right: 1px solid   #dbdbdb;
+				
+			}
+			.td3 {
+				text-align: start;
+				//background-color: rgba(243, 245, 247, 1);
+				//width: 100rpx;
+			
+				border-left: 1px solid   #dbdbdb;
+				border-right: 1px solid   #dbdbdb;
+			}
+	
+			td {
+				//text-align: center;
+				border-bottom: 1px solid   #dbdbdb;
+				//width: 160rpx;
+			}
+		}
+	
+	
+	}
+</style>

+ 22 - 0
uni_modules/ljs-turntable/changelog.md

@@ -0,0 +1,22 @@
+## 2.0.1(2023-04-06)
+修复版本显示错误,修复配置说明。
+## 1.1.6(2023-03-03)
+更新文档。
+## 1.1.5(2023-03-03)
+更新文档。
+## 1.1.4(2021-09-13)
+优化份数bug。
+## 1.1.3(2021-09-13)
+优化说明。
+## 1.1.2(2021-09-13)
+优化文字显示,优化占比为36,每份站10度。
+## 1.1.1(2021-09-10)
+修复已知问题。
+## 1.1.0(2021-09-10)
+修复微信小程序和app两端无法使用的bug。
+## 1.0.2(2021-06-28)
+优化说明文档。
+## 1.0.1(2021-06-28)
+优化显示bug,优化说明。
+## 1.0.0(2021-06-28)
+转盘抽奖。支持自定义盘面选项,灵活配置占比及奖品。当前版本1.0.0。

二進制
uni_modules/ljs-turntable/components/ljs-turntable/images/ico_close.png


+ 184 - 0
uni_modules/ljs-turntable/components/ljs-turntable/index.js

@@ -0,0 +1,184 @@
+const powerMax = 200; // 最大力量值
+const powerMin = Math.floor(powerMax/2) + 1; // 最小力量值
+const decline = powerMax/10000; // 衰退
+export default {
+	data() {
+		return {
+			truntableData: [], // 转盘数据
+			color: ["#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff","#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff","#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff","#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff","#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff","#014EB5","#A800FF","#e82edb","#B5454C","#443bff","#e8a425","#ff7aab","#e84b1e","#552ce2","#e8861e","#d441ff","#9c7aff"],
+			timerRun: false, // 工具是否已开始
+			transform: null, 
+			allPower: [], // 力量集合
+		}
+	},
+	props: {
+		list: Array, // 转盘基础数据。基础数据参照‘list参数’
+		show: Boolean, // 显示组件:默认不显示
+		// 每次转完是否默认回起始位置
+		startPosition: {
+			type: Boolean,
+			default: false
+		},
+		// 是否启用概率算法,默认按照扇形面积占比的大小出奖。开启概率算法,需要同时设置startPosition为true,否则会出现异常。
+		probabilityTag: {
+			type: Boolean,
+			default: false
+		},
+	},
+	mounted() {
+		this.init();
+		
+	},
+	methods: {
+		// 隐藏组件
+		close(){
+			if(this.timerRun){
+				uni.showToast({
+					title: '请耐心等待',
+					duration: 1500,
+					icon: "none"
+				});
+				return
+			}
+			this.$emit("turntableState", false);
+		},
+		// 点击开始按钮
+		go(){
+			if(this.timerRun){
+				uni.showToast({
+					title: '请耐心等待',
+					duration: 1500,
+					icon: "none"
+				});
+				return
+			}
+			this.timerRun = true;
+			let power = 0;
+			if (this.probabilityTag) {
+				power = this.allPower[Math.floor((Math.random()*this.allPower.length))]; //随机获取一个力量值 - 有概率
+			} else {
+				power = this.rand(powerMin, powerMax); //随机获取一个力量值 - 无概率
+			}
+			let jiaodu = 0; // 旋转的角度
+			let timer = setInterval(()=>{
+				if(Number(power.toFixed(4)) <= 0){
+					clearInterval(timer);
+					this.getData(jiaodu%360);
+				}
+				jiaodu += power;
+				// #ifdef H5
+				document.getElementById("rotateBoard").style.transform = 'rotate('+ jiaodu +'deg)';
+				// #endif
+				// #ifdef MP-WEIXIN || APP-PLUS
+				this.transform = 'rotate('+ jiaodu +'deg)'
+				// #endif
+				
+				power = (power - power*decline) < decline?0:power - power*decline;
+				// console.log(power)
+			}, 10)
+		},
+		// 获取[m, n]的随机数
+		rand(m, n)  {
+		    return Math.ceil(Math.random() * (n-m+1) + m-1)
+		},
+		// 按照概率获取力量的中奖数据集合
+		getPowerResult() {
+			const allPower = [];
+			for(let i = powerMin; i <= powerMax; i++){
+				allPower.push(i);
+			}
+			this.allPower = this.getModeResult(allPower);
+		},
+		// 获取模拟结果
+		getModeResult(allPower){
+			const powerPrizes = [];
+			const tempJs = powerMax - powerMin + 1;
+			allPower.forEach((item) => {
+				let power = item; //随机获取一个力量值
+				let jiaodu = 0; // 旋转的角度
+				while (Number(power.toFixed(4)) > 0) {
+					jiaodu += power;				
+					power = (power - power*decline) < decline?0:power - power*decline;
+				}
+				const deg = 360 - jiaodu%360;
+				let prize = null;
+				let nums = this.list.length;
+				for(let i = 0; i < nums; i++){
+					if(this.list[i].start <= deg && deg < this.list[i].start + this.list[i].prop*10){
+						if (this.list[i].result.length/tempJs < this.list[i].probability) {
+							this.list[i].result.push(item);
+							powerPrizes.push(item);
+						}
+						break;
+					}
+				}
+			});
+			// 不够的进行补入
+			let nums = this.list.length;
+			for(let i = 0; i < nums; i++){
+				if (this.list[i].result.length/tempJs < this.list[i].probability) {
+					const n = Number((Number((this.list[i].probability - this.list[i].result.length/tempJs).toFixed(2)) * tempJs).toFixed(0));
+					for(let j = 0; j < n; j++){
+						this.list[i].result.push(this.list[i].result[0]);
+						powerPrizes.push(this.list[i].result[0]);
+					}
+				}
+			}
+			return powerPrizes;
+		},
+		// 通过旋转得角度,获取当前指向得奖品
+		getData(deg){
+			deg = 360 - deg;
+			let prize = null;
+			let nums = this.list.length;
+			for(let i = 0; i < nums; i++){
+				if(this.list[i].start <= deg && deg < this.list[i].start + this.list[i].prop*10){
+					prize = this.list[i];
+					
+					this.$emit("getPrize", prize.state, prize.id, prize.name)
+					this.timerRun = false;
+					if (this.startPosition) {
+						this.initJiaodu();
+					}
+					// this.BASE.msg(prize.name, 2000);
+					break;
+				}
+			}
+		},
+		// 重置角度
+		initJiaodu(){
+			const jiaodu = 0;
+			setTimeout(() => {
+				// #ifdef H5
+				document.getElementById("rotateBoard").style.transform = 'rotate('+ jiaodu +'deg)';
+				// #endif
+				// #ifdef MP-WEIXIN || APP-PLUS
+				this.transform = 'rotate('+ jiaodu +'deg)'
+				// #endif
+			}, 10);
+		},
+		init(){
+			let tempStart = 0;
+			let tempScale = 0;
+			this.list.forEach((item, i)=>{
+				item["result"] = []; // 中奖的力量集合
+				item["scale"] = item.prop*10 - 90; // 所占弧度的度数
+				item["scaleText"] = tempScale + (90 + (item.prop*10 - 90))/2; // 文字的回旋角度
+				item["sin"] = Math.sin(Math.PI*2*item.scaleText/360)*160; // 正弦
+				item["cos"] = Math.cos(Math.PI*2*item.scaleText/360)*160; // 余弦
+				tempScale = tempScale + 90 + (item.prop*10 - 90);
+				if(i !== 0){
+					tempStart = tempStart + this.list[i - 1].prop*10;
+				}
+				item["start"] = tempStart;
+			});
+			this.truntableData = this.list;
+			
+			// 按照概率获取力量的中奖数据集合
+			if (this.probabilityTag) {
+				this.getPowerResult();
+			}
+			this.go()
+		},
+	}
+}

+ 33 - 0
uni_modules/ljs-turntable/components/ljs-turntable/ljs-turntable.vue

@@ -0,0 +1,33 @@
+<template>
+	<view class="ljs-turntable" v-if="show">
+		<view class="close" @click="close">
+			<image class="ico" :src="require('./images/ico_close.png')"></image>
+		</view>
+		<view class="box">
+		</view>
+		<view class="box2">
+		</view>
+		<view class="but" >
+		</view>
+		<view class="rotateBoard" id="rotateBoard" ref="rotateBoard" :style="transform !== null?'transform:'+ transform:''">
+			<view v-for="(item, i) in truntableData" :key="i" class="sector" 
+				:style="{'transform': `rotate(${item.start}deg) skewY(${item.scale}deg)`, 'background': color[i]}">
+			</view>
+			<view class="name" v-for="(item, i) in truntableData" :key="`t${i}`"
+			:style="{'transform': `rotate(${item.scaleText}deg)`, 'left': (310 + item.sin) + 'rpx', 'top': (160 - item.cos) +'rpx'}"
+			>{{item.name}}
+			<img    src="@/assets/img/temporary/national-2024-2.png"></img>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+  import index from './index.js'
+  export default index
+</script>
+
+<style lang="scss" scoped>
+	@import "./style.scss"
+</style>

文件差異過大導致無法顯示
+ 38 - 0
uni_modules/ljs-turntable/components/ljs-turntable/style.scss


+ 80 - 0
uni_modules/ljs-turntable/package.json

@@ -0,0 +1,80 @@
+{
+  "id": "ljs-turntable",
+  "displayName": "轮盘 大转盘 幸运 多端支持 抽奖 概率 ljs-turntable",
+  "version": "2.0.1",
+  "description": "轮盘 大转盘 幸运 多端支持 抽奖 概率 ljs-turntable",
+  "keywords": [
+    "轮盘",
+    "大转盘",
+    "幸运",
+    "抽奖",
+    "概率"
+],
+  "repository": "",
+"engines": {
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "插件不采集任何数据",
+      "permissions": "无"
+    },
+    "npmurl": "",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "u"
+        }
+      }
+    }
+  }
+}

+ 146 - 0
uni_modules/ljs-turntable/readme.md

@@ -0,0 +1,146 @@
+# 方便您的同时,请五星、收藏,让好的东西照亮更多深渊中负重前行的代码人。
+# 创作不易,在您方便之际,赞赏作者,我们会更有动力继续下去。
+
+# 简介
+转盘抽奖。支持自定义盘面选项,灵活配置占比及奖品。
+
+# 平台兼容性
+全平台兼容。
+# 快速开始
+### 使用 uni_modules 安装(推荐)
+使用 uni_modules 方式安装组件库,可以直接通过插件市场导入,通过右键菜单快速更新组件,不需要引用、注册,直接在页面中使用 ljs-turntable 组件。
+
+### 参数
+
+参数  | 类型| 必填项 | 默认值 | 说明
+---- | ----- | ------ | ------  | :------ 
+show  | Boolean | √ | | 是否显示。
+list  | Array  | √ | | 转盘基础数据。基础数据参照‘list参数’。
+startPosition | Boolean | × | true | 每次转完是否默认回起始位置。
+probabilityTag | Boolean | × | false | 是否启用概率算法,默认按照扇形面积占比的大小出奖。开启概率算法,需要同时设置startPosition为true,否则会出现异常。
+
+
+###### list 参数:
+
+参数  | 类型| 解释
+---- | ----- | ------ 
+name | String | 奖品名称。
+prop | Int | (必填)奖品占比。说明: 比例总共被分解成36份。此数值,设置为1,代表占1份区域,最小为1,最大不得超过12,最少3个区域。所有奖品选项,占比和需为36。否则无法绘制。
+probability | Number | 概率,所有项和必须等于1。
+state| Boolean | (必填)是否中奖。
+id| String | (必填)奖品唯一标识。
+
+### 方法
+
+参数  | 类型| 解释
+---- | ----- | ------ 
+@getPrize| 回调函数| 抽奖结束返回function(state, id, prizeName)。state:是否中奖, id:中奖ID, prizeName:奖品名称。
+@turntableState| 关闭按钮回调函数| 修改转盘的展示状态。
+
+
+### 快速应用
+```
+<template>
+	<view class="content">
+		<view class="openBut" @click="open()">打开转盘</view>
+		<ljs-turntable
+			:show="ljs_turntable_show"
+			@getPrize="getPrize"
+			@turntableState="turntableState"
+			:probabilityTag="true"
+			:list="list"/>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				ljs_turntable_show: false,
+				list: [],
+			}
+		},
+		onLoad() {
+			// 最少3个选项
+			// 最大值:12份,
+			// 最小值:1份,
+			// 每份10度
+			this.list = [
+				{
+					name: "Iphone 13",
+					prop: 2,
+					probability: 0.01, // 概率,所有项和必须等于1。
+					state: true, // 是否中奖
+					id: 1
+				},
+				{
+					name: "谢谢参与",
+					prop: 5,
+					probability: 0.27,
+					state: false, // 是否中奖
+					id: 5
+				},
+				{
+					name: "10个积分",
+					prop: 12,
+					probability: 0.3,
+					state: true, // 是否中奖
+					id: 3
+				},
+				{
+					name: "蓝牙耳机",
+					prop: 5,
+					probability: 0.02,
+					state: false, // 是否中奖
+					id: 5
+				},
+				{
+					name: "66个积分",
+					prop: 4,
+					probability: 0.1,
+					state: true, // 是否中奖
+					id: 4
+				},
+				{
+					name: "精美大礼包",
+					prop: 8,
+					probability: 0.3,
+					state: false, // 是否中奖
+					id: 5
+				},
+			];
+		},
+		methods: {
+			// 打开转盘
+			open(){
+				this.ljs_turntable_show = true;
+			},
+			// 回调,修改转盘的展示状态
+			turntableState(val){
+				this.ljs_turntable_show = val;
+			},
+			// 回调,转盘结果
+			getPrize(state, id, prizeName){
+				console.log(state, id, prizeName)
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.openBut{
+		margin: 20upx;
+		background-color: #007AFF;
+		color: #FFF;
+		width: 200upx;
+		height: 60upx;
+		line-height: 60upx;
+		text-align: center;
+		border-radius: 10upx;
+	}
+</style>
+
+```
+
+# 贡献代码
+龙九山。有任何问题,请在平台留言,在手头宽裕得情况下,我会尽快修复问题。

部分文件因文件數量過多而無法顯示