wzx hace 1 año
commit
f272822057

+ 51 - 0
poly/App.uvue

@@ -0,0 +1,51 @@
+<script lang="uts">
+	let firstBackTime = 0
+	export default {
+		onLaunch: function () {
+			console.log('App Launch')
+		},
+		onShow: function () {
+			console.log('App Show')
+		},
+		onHide: function () {
+			console.log('App Hide')
+		},
+		// #ifdef APP-ANDROID
+		onLastPageBackPress: function () {
+			console.log('App LastPageBackPress')
+			if (firstBackTime == 0) {
+				uni.showToast({
+					title: '再按一次退出应用',
+					position: 'bottom',
+				})
+				firstBackTime = Date.now()
+				setTimeout(() => {
+					firstBackTime = 0
+				}, 2000)
+			} else if (Date.now() - firstBackTime < 2000) {
+				firstBackTime = Date.now()
+				uni.exit()
+			}
+		},
+		// #endif
+		onExit: function () {
+			console.log('App Exit')
+		},
+	}
+</script>
+
+<style>
+	/*每个页面公共css */
+	
+	page {
+		background-color: #237bd8;
+	}
+	
+	.uni-row {
+		flex-direction: row;
+	}
+
+	.uni-column {
+		flex-direction: column;
+	}
+</style>

+ 7 - 0
poly/common/api.js

@@ -0,0 +1,7 @@
+export const apiServer = 'https://colormaprun.com/api/baoli/';
+
+// 获取赛事统计数据
+export const apiGetStatistics = apiServer + 'getStatistics';
+
+// 获取赛事上传的图片
+export const apiGetUploadPic = apiServer + 'getUploadPic';

+ 307 - 0
poly/common/tools.js

@@ -0,0 +1,307 @@
+var tools = {
+	// 秒数转换成时分秒
+	convertSecondsToHMS(seconds) {
+		var hours = Math.floor(seconds / 3600);
+		var minutes = Math.floor((seconds % 3600) / 60);
+		var remainingSeconds = seconds % 60;
+		// return hours + ":" + minutes + ":" + remainingSeconds;
+		return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${remainingSeconds.toString().padStart(2, '0')}`;
+	},
+
+	// 计算(中英文混合)字符串长度
+	calStrLen(str) {
+		var length = 0;
+		for (var i = 0; i < str.length; i++) {
+			// 将字符转换为 Unicode 编码
+			var charCode = str.charCodeAt(i);
+			if (charCode >= 0 && charCode <= 128) {
+				length++;
+			} else {
+				length += 2;
+			}
+		}
+
+		return length;
+	},
+
+	// 集合对象去重
+	unique(arr, field) {
+		var map = {};
+		var res = [];
+		for (var i = 0; i < arr.length; i++) {
+			if (!map[arr[i][field]]) {
+				map[arr[i][field]] = 1;
+				res.push(arr[i]);
+			}
+		}
+		return res;
+	},
+
+	// 正则取出html标签
+	repalceHtml(str) {
+		var dd = str.replace(/<\/?.+?>/g, "");
+		var dds = dd.replace(/ /g, ""); //dds为得到后的内容
+		return dds;
+	},
+
+	// 判断身份证号    
+	isSfz(idcard) {
+		var id =
+			/^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$/
+		if (idcard === '') {
+			uni.showToast({
+				title: '请输入身份证号',
+				icon: 'none'
+			})
+		} else if (!id.test(idcard)) {
+			uni.showToast({
+				title: '身份证号格式不正确!',
+				icon: 'none'
+			})
+			return false
+		} else {
+			return false
+		}
+	},
+
+	// 判断是否是手机号   
+	isPhone(val) {
+		var patrn = /^(((1[3456789][0-9]{1})|(15[0-9]{1}))+\d{8})$/
+		if (!patrn.test(val) || val === '') {
+			uni.showToast({
+				title: '手机号格式不正确',
+				icon: 'none'
+			})
+			return false
+		} else {
+			return true
+		}
+	},
+
+	// 判断邮箱
+	isEmail(email) {
+		if (email.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)
+			return true;
+		else
+			return false;
+	},
+
+	//获取随机数
+	getSuiji() {
+		var Range = Max - Min;
+		var Rand = Math.random();
+		return (Min + Math.round(Rand * Range));
+	},
+
+	//计算多长时间前
+	getDateDiff(dateTimeStamp) {
+		var minute = 1000 * 60;
+		var hour = minute * 60;
+		var day = hour * 24;
+		var halfamonth = day * 15;
+		var month = day * 30;
+		var year = day * 365;
+		var now = new Date().getTime();
+		var diffValue = now - dateTimeStamp;
+		if (diffValue < 0) {
+			return;
+		}
+		var yearC = diffValue / year;
+		var monthC = diffValue / month;
+		var weekC = diffValue / (7 * day);
+		var dayC = diffValue / day;
+		var hourC = diffValue / hour;
+		var minC = diffValue / minute;
+		if (yearC >= 1) {
+			result = "" + parseInt(yearC) + "年前";
+		}
+		if (monthC >= 1) {
+			result = "" + parseInt(monthC) + "月前";
+		} else if (weekC >= 1) {
+			result = "" + parseInt(weekC) + "周前";
+		} else if (dayC >= 1) {
+			result = "" + parseInt(dayC) + "天前";
+		} else if (hourC >= 1) {
+			result = "" + parseInt(hourC) + "小时前";
+		} else if (minC >= 1) {
+			result = "" + parseInt(minC) + "分钟前";
+		} else
+			result = "刚刚";
+		return result;
+	},
+
+	// 时间戳转时间
+	timestampToTime(timestamp, i) {
+		var date = new Date(timestamp); //时间戳为10位需*1000,时间戳为13位的话不需乘1000
+		// console.log(date, timestamp)
+		var Y = date.getFullYear() + '-';
+		var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) + '-';
+		var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + ' ';
+		var h = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()) + ':';
+		var m = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()) + ':';
+		var s = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds());
+		if (i == 1) {
+			return Y + M + D;
+		}
+		return Y + M + D + h + m + s;
+	},
+
+	// 是否是汉字
+	isHanzi(str) {
+		let reg = /\p{Unified_Ideograph}/ug;
+		return reg.test(str);
+	},
+
+	// 是否是字母数字
+	isStringAndNumber(str) {
+		let regNumber = new RegExp(/^[0-9A-Za-z]+$/);
+		return regNumber.test(str)
+	},
+
+	// var arr3 = [30,10,111,35,1899,50,45];
+	// 集合排序  元素数字
+	listSort(list) {
+		arr3.sort(function(a, b) {
+			return a - b;
+		})
+	},
+
+	// var arr5 = [{id:10},{id:5},{id:6},{id:9},{id:2},{id:3}];
+	// 元素  对象
+	listObjectSort(arr) {
+		arr.sort(function(a, b) {
+			return a.id - b.id
+		})
+		return arr;
+	},
+
+	/*
+	 * 忽略大小写判断字符串是否相同
+	 * @param str1
+	 * @param str2
+	 * @returns {Boolean}
+	 */
+	isEqualsIgnorecase: function(str1, str2) {
+		if (str1.toUpperCase() == str2.toUpperCase()) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	 * 判断是否是数字
+	 * @param value
+	 * @returns {Boolean}
+	 */
+	isNum: function(value) {
+		if (value != null && value.length > 0 && isNaN(value) == false) {
+			return true;
+		} else {
+			return false;
+		}
+	},
+
+	/**
+	 * 判断是否是中文
+	 * @param str
+	 * @returns {Boolean}
+	 */
+	isChine: function(str) {
+		var reg = /^([u4E00-u9FA5]|[uFE30-uFFA0])*$/;
+		if (reg.test(str)) {
+			return false;
+		}
+		return true;
+	},
+
+	/*验证是否为图片*/
+	tmCheckImage: function(fileName) {
+		return /(gif|jpg|jpeg|png|GIF|JPG|PNG)$/ig.test(fileName);
+	},
+
+	/*验证是否为视频*/
+	tmCheckVideo: function(fileName) {
+		return /(mp4|mp3|flv|wav)$/ig.test(fileName);
+	},
+
+	/**
+	 * 去除字符串两边的空格
+	 * @param str
+	 * @returns {number|Number}
+	 * 调用方法:var str = utils.trim("abcd")
+	 */
+	trim: function(str) {
+		String.prototype.trim = function() {
+			return str.replace(/(^\s*)|(\s*$)/g, "");
+		}
+	},
+
+	// 判断密码是否符合 至少6位,包括大小写字母、数字、特殊字符
+	isPassword(val) {
+		var reg = /^(?![0-9]+$)(?![a-z]+$)(?![A-Z]+$)(?!([^(0-9a-zA-Z)])+$)^.{8,16}$/;
+		if (val === '') {
+			uni.showToast({
+				title: '请输入密码',
+				icon: 'none'
+			})
+		} else if (!reg.test(val)) {
+			uni.showToast({
+				title: '至少6位,包括大小写字母、数字、特殊字符',
+				icon: 'none'
+			})
+			return false
+		} else {
+			return true
+		}
+	},
+
+	// 电话匿名
+	noPassByMobile(str) {
+		if (null != str && str != undefined) {
+			var pat = /(\d{3})\d*(\d{4})/;
+			return str.replace(pat, '$1****$2');
+		} else {
+			return "";
+		}
+	},
+
+	// 获取两点间的距离
+	//进行经纬度转换为距离的计算
+	Rad(d) {
+		return d * Math.PI / 180.0; //经纬度转换成三角函数中度分表形式。
+	},
+
+	/*
+	 计算距离,参数分别为第一点的纬度,经度;第二点的纬度,经度
+	 默认单位km
+	*/
+	getMapDistance(lat1, lat2, lng1, lng2) {
+		lat1 = lat1 || 0;
+		lng1 = lng1 || 0;
+		lat2 = lat2 || 0;
+		lng2 = lng2 || 0;
+
+		var rad1 = lat1 * Math.PI / 180.0;
+		var rad2 = lat2 * Math.PI / 180.0;
+		var a = rad1 - rad2;
+		var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
+		var r = 6378137;
+		var distance = r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) *
+			Math.pow(Math.sin(b / 2), 2)));
+		console.log(lat1, lng1, lat2, lng2);
+		console.log(distance);
+		return Math.round(distance) / 1000;
+	},
+
+	// 预览图片
+	yulanImg(item) {
+		let arr = [item]
+		uni.previewImage({
+			urls: arr,
+		});
+	},
+
+}
+
+export default tools;

+ 20 - 0
poly/index.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="UTF-8" />
+		<script>
+			var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
+				CSS.supports('top: constant(a)'))
+			document.write(
+				'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
+				(coverSupport ? ', viewport-fit=cover' : '') + '" />')
+		</script>
+		<title></title>
+		<!--preload-links-->
+		<!--app-context-->
+	</head>
+	<body>
+		<div id="app"><!--app-html--></div>
+		<script type="module" src="/main"></script>
+	</body>
+</html>

+ 9 - 0
poly/main.uts

@@ -0,0 +1,9 @@
+import App from './App.uvue'
+
+import { createSSRApp } from 'vue'
+export function createApp() {
+	const app = createSSRApp(App)
+	return {
+		app
+	}
+}

+ 55 - 0
poly/manifest.json

@@ -0,0 +1,55 @@
+{
+    "name" : "mobile_h5",
+    "appid" : "__UNI__DE74995",
+    "description" : "",
+    "versionName" : "1.0.0",
+    "versionCode" : "100",
+    "uni-app-x" : {},
+    /* 快应用特有相关 */
+    "quickapp" : {},
+    /* 小程序特有相关 */
+    "mp-weixin" : {
+        "appid" : "",
+        "setting" : {
+            "urlCheck" : false
+        },
+        "usingComponents" : true
+    },
+    "mp-alipay" : {
+        "usingComponents" : true
+    },
+    "mp-baidu" : {
+        "usingComponents" : true
+    },
+    "mp-toutiao" : {
+        "usingComponents" : true
+    },
+    "uniStatistics" : {
+        "enable" : false
+    },
+    "vueVersion" : "3",
+    "app" : {
+        "distribute" : {
+            "icons" : {
+                "android" : {
+                    "hdpi" : "",
+                    "xhdpi" : "",
+                    "xxhdpi" : "",
+                    "xxxhdpi" : ""
+                }
+            }
+        }
+    },
+    "h5" : {
+        "title" : "保利",
+        "optimization" : {
+            "treeShaking" : {
+                "enable" : true
+            }
+        },
+        "router" : {
+            "base" : "/poly/",
+            "mode" : "hash"
+        }
+    }
+}

+ 48 - 0
poly/pages.json

@@ -0,0 +1,48 @@
+{
+	"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+		{
+			"path": "pages/index/index",
+			"style": {
+				"navigationBarTitleText": "首页"
+			}
+		},
+		{
+			"path": "pages/challenge/index",
+			"style": {
+				"navigationBarTitleText": "挑战结果"
+			}
+		},
+		{
+			"path": "pages/challenge/success",
+			"style": {
+				"navigationBarTitleText": "挑战成功"
+			}
+		},
+		{
+			"path": "pages/challenge/exit",
+			"style": {
+				"navigationBarTitleText": "退出比赛"
+			}
+		},
+		{
+			"path": "pages/originality/index",
+			"style": {
+				"navigationBarTitleText": "文创信息"
+			}
+		},
+		{
+			"path": "pages/led/index",
+			"style": {
+				"navigationBarTitleText": "LED显示屏"
+			}
+		}
+	],
+	"globalStyle": {
+		"navigationStyle": "custom",
+		"navigationBarTextStyle": "black",
+		"navigationBarTitleText": "保利",
+		"navigationBarBackgroundColor": "#F8F8F8",
+		"backgroundColor": "#F8F8F8"
+	},
+	"uniIdRouter": {}
+}

+ 82 - 0
poly/pages/challenge/exit.uvue

@@ -0,0 +1,82 @@
+<template>
+	<view class="body">
+		<view class="content">
+			<view class="top">
+				<image class="logo" mode="aspectFit" src="/static/logo.png"></image>
+				<image class="right-logo" mode="aspectFit" src="/static/40.png"></image>
+			</view>
+			<view class="main">
+				<view class="exit_game"></view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+			}
+		},
+		computed: {
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+		},
+		methods: {
+		}
+	}
+</script>
+
+<style>
+	.body {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.content {
+		width: 390px;
+		/* margin: 0 auto; */
+	}
+
+	.top {
+		width: 100%;
+		height: 10vh;
+		padding: 0 36px;
+		/* padding: 36px 36px 0 36px; */
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.logo {
+		width: 91.5px;
+		height: 26px;
+	}
+
+	.right-logo {
+		width: 37.5px;
+		height: 26px;
+	}
+
+	.main {
+		width: 100%;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.exit_game {
+		width: 70%;
+		height: 90vh;
+		/* height: 650px; */
+		margin-top: -30px;
+		margin-left: 20px;
+		background-image: url("/static/challenge/exit_game.webp");
+		background-repeat: no-repeat;
+		background-position-x: center;
+		background-position-y: center;
+		background-size: contain;
+	}
+</style>

+ 42 - 0
poly/pages/challenge/index.uvue

@@ -0,0 +1,42 @@
+<template>
+	<view></view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+			}
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+			// console.log(event);
+			const queryString = this.objectToQueryString(event);
+			// console.log(queryString);
+			const status = event["status"] ?? ""
+			
+			if (status == 'success') {	// 挑战成功
+				uni.reLaunch({
+					url: '/pages/challenge/success?' + queryString
+				});
+			}
+			else if (status == 'ok' || status == 'fail') {	// 挑战完成/挑战失败
+				uni.reLaunch({
+					url: '/pages/challenge/exit'
+				});
+			}
+			else {
+				this.showErr();
+			}
+		},
+		methods: {
+			showErr() {
+				uni.showToast({
+					title: '参数错误'
+				});
+			},
+			objectToQueryString(obj) {
+				return Object.keys(obj).map(k => k + '=' + obj[k]).join('&');
+			}
+		}
+	}
+</script>

+ 246 - 0
poly/pages/challenge/success.uvue

@@ -0,0 +1,246 @@
+<template>
+	<view class="body">
+		<view class="content">
+			<view class="top">
+				<image class="logo" mode="aspectFit" src="/static/logo.png"></image>
+				<image class="right-logo" mode="aspectFit" src="/static/40.png"></image>
+			</view>
+			<view class="main">
+				<view class="main-content">
+					<view class="rank">
+						<view class="statistic">
+							<text class="statistic-title">总用时:</text>
+							<view class="statistic-right">
+								<text class="statistic-value">{{durationMin}}</text><text
+									class="statistic-unit">min</text>
+							</view>
+						</view>
+						<view class="statistic">
+							<text class="statistic-title">总里程:</text>
+							<view class="statistic-right">
+								<text class="statistic-value">{{distanceKm}}</text><text
+									class="statistic-unit">Km</text>
+							</view>
+						</view>
+						<view class="statistic">
+							<text class="statistic-title">脑力值:</text>
+							<view class="statistic-right">
+								<text class="statistic-value">{{accuracy}}</text><text class="statistic-unit">%</text>
+							</view>
+						</view>
+					</view>
+					<text class="name">{{nameSub}}</text>
+				</view>
+			</view>
+			<!-- <view class="bottom">
+				<view class="bottom-left">
+					<image src="../../static/medal.webp" class="medal" mode="aspectFit"></image>
+					<text class="medal_count">x{{syscount}}</text>
+				</view>
+				<view class="bottom-right">
+					<text class="bottom-text">提示:</text>
+					<text class="bottom-text">可以在“成就”中查看详细数据</text>
+				</view>
+			</view> -->
+		</view>
+	</view>
+</template>
+
+<script>
+	import tools from '../../common/tools';
+
+	export default {
+		data() {
+			return {
+				status: "",		// success: 挑战成功, ok: 挑战完成(没在规定时间完成,但打了所有点), fail: 挑战结束
+				name: "",		// 用户名
+				duration: 0,	// 总用时,秒
+				distance: 0,	// 总里程,米
+				cal: 0,			// 卡路里,卡 int
+				accuracy: 0,	// 脑力值百分比
+				syscount: 0		// 点数
+			}
+		},
+		computed: {
+			nameSub() {
+				const maxlen = 8;
+				const nameLen = tools.calStrLen(this.name);
+				console.log('nameLen', nameLen);
+				if (nameLen <= 6) {
+					return '选手: ' + this.name;
+				}
+				// else if (nameLen >= maxlen) {
+				// 	return this.name.substring(0,maxlen-1) + '...';
+				// }
+				else {
+					return this.name;
+				}
+			},
+			durationMin() {
+				return Math.round(this.duration * 10 / 60) / 10;
+			},
+			distanceKm() {
+				return Math.round(this.distance * 10 / 1000) / 10;
+			}
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+			console.log('[challenge result] onLoad');
+			this.status = event["status"] ?? "";
+			this.name = event["name"] ?? "";
+			this.duration = event["duration"] ?? 0;
+			this.distance = event["distance"] ?? 0;
+			this.cal = event["cal"] ?? 0;
+			this.accuracy = event["accuracy"] ?? 0;
+			this.syscount = event["syscount"] ?? 0;
+		},
+		methods: {
+		}
+	}
+</script>
+
+<style>
+	.body {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.content {
+		width: 390px;
+		/* margin: 0 auto; */
+	}
+
+	.top {
+		width: 100%;
+		height: 10vh;
+		padding: 0 36px;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.logo {
+		width: 91.5px;
+		height: 26px;
+	}
+
+	.right-logo {
+		width: 37.5px;
+		height: 26px;
+	}
+
+	.main {
+		width: 100%;
+		height: 90vh;
+		flex-direction: column;
+		justify-content: flex-start;
+	}
+
+	.main-content {
+		height: 570px;
+		margin-top: 20px;
+		background-image: url("/static/challenge/success_bg.webp");
+		background-repeat: no-repeat;
+		background-position-x: center;
+		background-position-y: center;
+		background-size: contain;
+	}
+
+	.rank {
+		width: 292px;
+		margin-left: 43px;
+		margin-top: 386px;
+	}
+
+	.name {
+		width: 125px;
+		/* 确保文本在一行内显示 */
+		white-space: nowrap;
+		/* 超出容器部分的文本隐藏起来 */
+		overflow: hidden;
+		/* 使用省略号表示被截断的文本 */
+		/* text-overflow: ellipsis; */
+		text-align: center;
+		margin-left: 103px;
+		margin-top: 19px;
+		font-family: Source Han Sans CN;
+		font-weight: 500;
+		font-size: 18px;
+		color: #ffffff;
+	}
+
+	.statistic {
+		height: 38.8px;
+		flex-direction: row;
+		align-items: center;
+		justify-content: space-between;
+	}
+
+	.statistic-right {
+		flex-direction: row;
+		align-items: baseline;
+	}
+
+	.statistic-title {
+		font-family: Source Han Sans CN;
+		font-weight: 500;
+		font-size: 23px;
+		color: #ffffff;
+	}
+
+	.statistic-value {
+		font-family: Source Han Sans CN;
+		font-weight: 700;
+		font-size: 28px;
+		color: #ffffff;
+		font-weight: bold;
+	}
+
+	.statistic-unit {
+		font-family: Source Han Sans CN;
+		font-size: 20px;
+		color: #ffffff;
+		padding-left: 5px;
+	}
+
+	.bottom {
+		width: 100%;
+		flex-direction: row;
+		justify-content: space-between;
+		padding: 30px 30px 30px 30px;
+	}
+
+	.bottom-left {
+		flex-direction: row;
+		justify-content: flex-start;
+	}
+
+	.bottom-right {
+		width: 116px;
+		flex-direction: column;
+		justify-content: center;
+	}
+
+	/*.medal {
+		width: 78px;
+		height: 81px;
+		margin-right: 10px;
+	}
+
+	.medal_count {
+		font-family: Source Han Sans CN;
+		font-weight: 900;
+		color: #ffee29;
+		font-size: 50px;
+		margin-top: 10px;
+	}
+
+	.bottom-text {
+		line-height: normal;
+		font-family: Source Han Sans CN;
+		font-weight: 500;
+		font-size: 12px;
+		color: #ffffff;
+	} */
+</style>

+ 16 - 0
poly/pages/index/index.uvue

@@ -0,0 +1,16 @@
+<template>
+	<view></view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+			}
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+		},
+		methods: {
+		}
+	}
+</script>

+ 248 - 0
poly/pages/led/index - 副本.uvue

@@ -0,0 +1,248 @@
+<template>
+	<view class="body">
+		<view class="content bg-led02">
+			<view class="pic-container">
+				<!-- <image class="pic" mode="aspectFill" :src="imageSrc"></image> -->
+				<swiper class="swiper" autoplay circular :current="picCurIndex" :interval="picInterval" :duration="picDuration" @change="swiperChange">
+					<swiper-item v-for="(image, index) in picList" :key="index">
+						<image class="pic" mode="aspectFit" :src="image"></image>
+					</swiper-item>
+				</swiper>
+			</view>
+			<view class="distance-container">
+				<view class="total-time">总用时: {{durationStr}}</view>
+				<view class="total-distance">{{distanceKm}}KM</view>
+			</view>
+			<image class="mascot" mode="aspectFit" src="/static/led/mascot.png"></image>
+			<image class="lpzg" mode="aspectFit" src="/static/lpzg.png"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import tools from '../../common/tools';
+	import { apiGetStatistics, apiGetUploadPic } from '../../common/api';
+
+	export default {
+		data() {
+			return {
+				actIdArrStr: "175,176,177,178",
+				SumDuration: 0,
+				SumDistance: 0,
+				picCount: 0,
+				picList: [''],
+				picInterval: 3000,	// 自动切换时间间隔
+				picDuration: 500,	// 滑动动画时长
+				picCurIndex: 0,		// swiper当前所在滑块的 index
+				intervalSta: 0,
+				// imageSrc: '',
+			}
+		},
+		computed: {
+			durationStr() {
+				return tools.convertSecondsToHMS(this.SumDuration);
+			},
+			distanceKm() {
+				if (this.SumDistance < 1000000)
+					return Math.round(this.SumDistance * 10 / 1000) / 10;
+				else
+					return Math.round(this.SumDistance / 1000);
+			}
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+			// this.SumDuration = 1622;
+			// this.SumDistance = 999050;
+			// this.SumDistance = 999949;
+			// this.SumDistance = 2066869;
+			// this.imageSrc = "/static/led/pic2.jpg";
+
+			this.getStatistics();
+			this.getUploadPic();
+			
+			this.intervalSta = setInterval(this.getStatistics, 1000);
+		},
+		onUnload() {
+			console.log("onUnload");
+			clearInterval(this.intervalSta);
+		},
+		methods: {
+			getStatistics() {
+				uni.request({
+					url: apiGetStatistics,
+					header: {
+						"Content-Type": "application/x-www-form-urlencoded",
+					},
+					method: "POST",
+					data: {
+						actIdArrStr: this.actIdArrStr
+					},
+					success: (res) => {
+						// console.log("getStatistics", res)
+						const data = res.data.data;
+						this.SumDuration = data.SumDuration;
+						this.SumDistance = data.SumDistance;
+					},
+					fail: (err) => {
+						console.log("getStatistics err", err)
+					},
+				});
+			},
+			getUploadPic() {
+				uni.request({
+					url: apiGetUploadPic,
+					header: {
+						"Content-Type": "application/x-www-form-urlencoded",
+					},
+					method: "POST",
+					data: {
+						actIdArrStr: this.actIdArrStr
+					},
+					success: (res) => {
+						// console.log("getUploadPic", res);
+						const data = res.data.data;
+						const newCount = data.List.length;
+						console.log("newCount", newCount);
+						if (newCount > 0) {
+							this.picList.length = 0;	// 清空数组
+							for	(let i=0; i<newCount; i++) {
+								let picUrl = data.Domain + data.List[i];
+								// console.log("picUrl: " + picUrl);
+								this.picList.push(picUrl);
+							}
+							this.picCurIndex = this.picCount - 1;
+							console.log("重定位 index", this.picCurIndex);
+						}
+						this.picCount = newCount;
+						if (this.picCount == 0) {
+							setTimeout(this.getUploadPic, 1000);
+						} else if (this.picCount == 1) {
+							// swiper在只有1张图片的情况下不会触发 @change事件,需要在这里再次获取图片数据
+							setTimeout(this.getUploadPic, this.picInterval);
+						} 
+						// console.log("picList", this.picList);
+					},
+					fail: (err) => {
+						console.log("getUploadPic err", err);
+						setTimeout(this.getUploadPic, 3000);
+					},
+				});
+			},
+			//当前轮播索引
+			swiperChange(e) {
+				console.log("pic index: " +  e.detail.current);
+				const curIndex = e.detail.current;
+				// 播放完最后一张图片后重新获取图片数据
+				if (curIndex == this.picCount - 1) {
+					console.log("播放完毕,重新获取图片数据...");
+					// this.picCurIndex = curIndex;
+					this.getUploadPic();
+				}
+			},
+			//点击轮播
+			swiperClick(e) {
+				console.log('点击轮播', e);
+			},
+			animationfinish() {
+				console.log('animationfinish');
+			}
+		}
+	}
+</script>
+
+<style>
+	.body {
+		/* width: 100%; */
+		/* height: 100vh; */
+		width: 1920px;
+		height: 1440px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.content {
+		width: 100%;
+		height: 100%;
+		flex-direction: row;
+		align-items: flex-start;
+		/* justify-content: flex-start; */
+	}
+
+	.bg-led01 {
+		background-image: url("/static/led/led01.webp");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.bg-led02 {
+		background-image: url("/static/led/led02.webp");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.pic-container {
+		width: 1300px;
+		height: 850px;
+		margin-left: 76px;
+		margin-top: 303px;
+		background: url("/static/led/pic_border.png");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.swiper {
+		height: 850px;
+		mask-image: url('/static/led/pic_mask.png');
+		mask-size: 1298px;
+		mask-repeat: no-repeat;
+	}
+	
+	.pic {
+		margin: 3px;
+		width: 1300px;
+		height: 840px;
+		/* mask-image: url('/static/led/pic_mask.png');
+		mask-size: 1293px;
+		mask-repeat: no-repeat; */
+	}
+
+	.distance-container {
+		align-items: center;
+		justify-content: space-around;
+		width: 695px;
+		height: 296px;
+		margin-left: -253px;
+		margin-top: 946px;
+		background: url("/static/led/distance_bg.png") no-repeat;
+		background-size: cover;
+	}
+
+	.total-time {
+		font-family: 'Arial Black';
+		font-size: 36px;
+		color: #ffffff;
+		margin-left: 250px;
+		line-height: 50px;
+	}
+
+	.total-distance {
+		font-family: 'Arial';
+		font-size: 200px;
+		transform: scaleX(0.8);
+		color: #ffffff;
+		line-height: 180px;
+	}
+
+	.mascot {
+		height: 468px;
+		margin-left: -495px;
+		margin-top: 486px;
+	}
+
+	.lpzg {
+		width: 468px;
+		margin-left: -1540px;
+		margin-top: 1072px;
+	}
+</style>

+ 347 - 0
poly/pages/led/index.uvue

@@ -0,0 +1,347 @@
+<template>
+	<view class="body">
+
+		<view v-if="pageType == 1" class="content bg-led01">
+			<view class="distance-container-1">
+				<view class="total-time-1">总用时: {{durationStr}}</view>
+				<view class="total-distance-1">{{distanceKm}}KM</view>
+			</view>
+			<image class="run" mode="aspectFit" src="/static/led/run.gif"></image>
+		</view>
+
+		<view v-if="pageType == 2" class="content bg-led02">
+			<view class="pic-container">
+				<!-- <image class="pic" mode="aspectFill" :src="imageSrc"></image> -->
+				<swiper class="swiper" autoplay circular :current="picCurIndex" :interval="picInterval"
+					:duration="picDuration" @change="swiperChange">
+					<swiper-item v-for="(image, index) in picList" :key="index">
+						<image class="pic-bg" :src="image"></image>
+						<image class="pic" mode="aspectFit" :src="image"></image>
+					</swiper-item>
+				</swiper>
+			</view>
+			<view class="distance-container-2">
+				<view class="total-time-2">总用时: {{durationStr}}</view>
+				<view class="total-distance-2">{{distanceKm}}KM</view>
+			</view>
+			<image class="mascot" mode="aspectFit" src="/static/led/mascot.png"></image>
+			<image class="lpzg" mode="aspectFit" src="/static/lpzg.png"></image>
+		</view>
+	</view>
+</template>
+
+<script>
+	import tools from '../../common/tools';
+	import { apiGetStatistics, apiGetUploadPic } from '../../common/api';
+
+	export default {
+		data() {
+			return {
+				testMode: 0, // 测试模式  0:否 1:是
+				testDuration: 0,
+				testDistance: 0,
+				pageAutoChange: 0, // 有照片是否自动切换背景 0:否 1:是
+				pageType: 1, // 1: 无照片  2: 有照片
+				actIdArrStr: "",
+				SumDuration: 0,
+				SumDistance: 0,
+				picCount: 0,
+				picList: [],
+				picInterval: 3000,	// 自动切换时间间隔
+				picDuration: 500,	// 滑动动画时长
+				picCurIndex: 0,		// swiper当前所在滑块的 index
+				intervalSta: 0,
+				// imageSrc: '',
+			}
+		},
+		computed: {
+			durationStr() {
+				return tools.convertSecondsToHMS(this.SumDuration);
+			},
+			distanceKm() {
+				if (this.SumDistance < 1000000)
+					return Math.round(this.SumDistance * 10 / 1000) / 10;
+				else
+					return Math.round(this.SumDistance / 1000);
+			}
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+			// this.SumDuration = 1622;
+			// this.SumDistance = 999050;
+			// this.SumDistance = 999949;
+			// this.SumDistance = 2066869;
+			// this.imageSrc = "/static/led/pic2.jpg";
+
+			this.testMode = event["test"] ?? 0;
+			this.pageAutoChange = event["pac"] ?? 0;
+			this.pageType = event["page"] ?? 1;
+			this.actIdArrStr = event["act"] ?? "175,176,177,178";
+
+			this.getUploadPic();
+			this.getStatistics();
+
+			this.intervalSta = setInterval(this.getStatistics, 1000);
+		},
+		onUnload() {
+			console.log("onUnload");
+			clearInterval(this.intervalSta);
+		},
+		methods: {
+			getStatistics() {
+				if (this.testMode == 1) {
+					this.testDuration += 1;
+					this.testDistance += 100;
+					this.SumDuration = this.testDuration;
+					this.SumDistance = this.testDistance;
+					return;
+				}
+				
+				uni.request({
+					url: apiGetStatistics,
+					header: {
+						"Content-Type": "application/x-www-form-urlencoded",
+					},
+					method: "POST",
+					data: {
+						actIdArrStr: this.actIdArrStr
+					},
+					success: (res) => {
+						// console.log("getStatistics", res)
+						const data = res.data.data;
+						this.SumDuration = data.SumDuration;
+						this.SumDistance = data.SumDistance;
+					},
+					fail: (err) => {
+						console.log("getStatistics err", err)
+					},
+				});
+			},
+			getUploadPic() {
+				uni.request({
+					url: apiGetUploadPic,
+					header: {
+						"Content-Type": "application/x-www-form-urlencoded",
+					},
+					method: "POST",
+					data: {
+						actIdArrStr: this.actIdArrStr
+					},
+					success: (res) => {
+						// console.log("getUploadPic", res);
+						const data = res.data.data;
+						const newCount = data.List.length;
+						console.log("获取到的图片数量:", newCount);
+
+						if (newCount > 0) {
+							if (this.pageAutoChange == 1) {
+								this.pageType = 2;
+							}
+							/* this.picList.length = 0;	// 清空数组
+							for (let i = 0; i < newCount; i++) {
+								let picUrl = data.Domain + data.List[i];
+								// console.log("picUrl: " + picUrl);
+								this.picList.push(picUrl);
+							}
+							if (this.picCount > 0) {
+								this.picCurIndex = this.picCount - 1;
+								console.log("重定位 index", this.picCurIndex);
+							} */
+						} else {
+							if (this.pageAutoChange == 1) {
+								if (this.picCount == 0)
+									this.pageType = 1;
+								else
+									this.pageType = 2;
+							}
+						}
+
+						if (newCount > this.picCount) { // 有新图片
+							console.log("有 " + (newCount - this.picCount) + " 张新图片");
+							// 将新增的图片追加到图片队列
+							for (let i = this.picCount; i < newCount; i++) {
+								let picUrl = data.Domain + data.List[i];
+								console.log("[" + i + "] picUrl: " + picUrl);
+								this.picList.push(picUrl);
+							}
+							if (this.picCount > 0) {
+								this.picCurIndex = this.picCount;
+								console.log("重定位 index", this.picCurIndex);
+							}
+							
+							this.picCount = newCount;
+						}
+						
+						if (this.picCount == 0) {
+							// console.log('this.picCount == 0');
+							setTimeout(this.getUploadPic, 1000);
+						}
+						else if (this.picCount == 1) {
+							// console.log('this.picCount == 1');
+							// swiper在只有1张图片的情况下不会触发 @change事件,需要在这里再次获取图片数据
+							setTimeout(this.getUploadPic, this.picInterval);
+						}
+						// console.log("picList", this.picList);
+					},
+					fail: (err) => {
+						console.log("getUploadPic err", err);
+						setTimeout(this.getUploadPic, 3000);
+					},
+				});
+			},
+			//当前轮播索引
+			swiperChange(e) {
+				console.log("pic index: " + e.detail.current);
+				const curIndex = e.detail.current;
+				// 播放完最后一张图片后重新获取图片数据
+				if (curIndex == this.picCount - 1) {
+					console.log("播放完毕,重新获取图片数据...");
+					// this.picCurIndex = curIndex;
+					this.getUploadPic();
+				}
+			},
+			//点击轮播
+			swiperClick(e) {
+				console.log('点击轮播', e);
+			},
+			animationfinish() {
+				console.log('animationfinish');
+			}
+		}
+	}
+</script>
+
+<style>
+	.body {
+		/* width: 100%; */
+		/* height: 100vh; */
+		width: 1920px;
+		height: 1440px;
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: center;
+	}
+
+	.content {
+		width: 100%;
+		height: 100%;
+		flex-direction: row;
+		align-items: flex-start;
+		/* justify-content: flex-start; */
+	}
+
+	.bg-led01 {
+		background-image: url("/static/led/led01.webp");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.bg-led02 {
+		background-image: url("/static/led/led02.webp");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.pic-container {
+		width: 1300px;
+		height: 850px;
+		margin-left: 76px;
+		margin-top: 303px;
+		background: url("/static/led/pic_border.png");
+		background-repeat: no-repeat;
+		background-size: contain;
+	}
+
+	.swiper {
+		height: 852px;
+		mask-image: url('/static/led/pic_mask.png');
+		mask-size: 1298px;
+		mask-repeat: no-repeat;
+	}
+
+	.pic {
+		margin: 3px;
+		width: 1300px;
+		height: 840px;
+	}
+
+	.pic-bg {
+		position: absolute;
+		margin: -10px;
+		width: 1320px;
+		height: 860px;
+		filter: blur(15px);
+	}
+
+	.distance-container-1 {
+		align-items: center;
+		justify-content: space-around;
+		width: 1070px;
+		height: 450px;
+		margin-left: 766px;
+		margin-top: 850px;
+	}
+
+	.total-time-1 {
+		font-family: 'Arial Black';
+		font-size: 50px;
+		color: #ffffff;
+		margin-left: 390px;
+		line-height: 100px;
+		margin-top: 6px;
+	}
+
+	.total-distance-1 {
+		font-family: 'Arial';
+		font-size: 330px;
+		transform: scaleX(0.8);
+		color: #ffffff;
+		line-height: 330px;
+	}
+
+	.distance-container-2 {
+		align-items: center;
+		justify-content: space-around;
+		width: 695px;
+		height: 296px;
+		margin-left: -253px;
+		margin-top: 946px;
+		background: url("/static/led/distance_bg.png") no-repeat;
+		background-size: cover;
+	}
+
+	.total-time-2 {
+		font-family: 'Arial Black';
+		font-size: 36px;
+		color: #ffffff;
+		margin-left: 250px;
+		line-height: 50px;
+	}
+
+	.total-distance-2 {
+		font-family: 'Arial';
+		font-size: 200px;
+		transform: scaleX(0.8);
+		color: #ffffff;
+		line-height: 180px;
+	}
+
+	.run {
+		width: 520px;
+		height: 520px;
+		margin-left: -880px;
+		margin-top: 356px;
+	}
+
+	.mascot {
+		height: 468px;
+		margin-left: -495px;
+		margin-top: 486px;
+	}
+
+	.lpzg {
+		width: 468px;
+		margin-left: -1540px;
+		margin-top: 1072px;
+	}
+</style>

+ 97 - 0
poly/pages/originality/index.uvue

@@ -0,0 +1,97 @@
+<template>
+	<view class="body">
+		<view class="content">
+			<view class="top">
+				<image class="logo" src="/static/logo.webp"></image>
+			</view>
+			<view class="main">
+				<text class="main-text">id: {{id}}</text>
+				<text class="main-text">isPlan: {{isPlan}}</text>
+				<text class="main-text">isSuccess: {{isSuccess}}</text>
+				<text class="main-text">isStart: {{isStart}}</text>
+				<text class="main-text">isFinish: {{isFinish}}</text>
+				<text class="main-text">isPreload: {{isPreload}}</text>
+				<text class="main-text">token: {{token}}</text>
+				<text class="main-text">pagetype: {{pagetype}}</text>
+				<button class="btnClose" @click="btnClose">关闭</button>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				token: "",
+				id: 0,				// 检查点ID
+				isPlan: false,		// 是否为自定义规划路线点
+				isSuccess: false,	// 是否打点成功
+				isStart: false,		// 是否为开始点
+				isFinish: false,	// 是否为结束点
+				isPreload: false,	// 是否为预加载
+			}
+		},
+		computed: {
+		},
+		onLoad(event) { // 类型非必填,可自动推导
+			console.log('[originality index] onLoad');
+			this.token = event["token"] ?? "";
+			this.id = event["id"] ?? 0;
+			this.isPlan = event["isPlan"] ?? false;
+			this.isSuccess = event["isSuccess"] ?? false;
+			this.isStart = event["isStart"] ?? false;
+			this.isFinish = event["isFinish"] ?? false;
+			this.isPreload = event["isPreload"] ?? false;
+		},
+		methods: {
+			btnClose() {
+				window.location.href = "action://close";
+			}
+		}
+	}
+</script>
+
+<style>
+	.body {
+		display: flex;
+		flex-direction: column;
+		align-items: center;
+		justify-content: flex-start;
+	}
+
+	.content {
+		width: 390px;
+		/* margin: 0 auto; */
+	}
+
+	.top {
+		width: 100%;
+		padding: 36px 36px 0 36px;
+		flex-direction: row;
+		justify-content: space-between;
+	}
+
+	.logo {
+		width: 135.66px;
+		height: 26.95px;
+	}
+
+	.main {
+		width: 100%;
+		margin-top: 30px;
+		margin-left: 30px;
+		flex-direction: column;
+		align-items: flex-start;
+		justify-content: center;
+	}
+
+	.main-text {
+		color: #ffffff;
+	}
+	
+	.btnClose {
+		margin-top: 30px;
+	}
+	
+</style>

BIN
poly/static/40.png


BIN
poly/static/challenge/exit_game.webp


BIN
poly/static/challenge/rank_bg.png


BIN
poly/static/challenge/success_bg.webp


BIN
poly/static/challenge/success_bg2.webp


BIN
poly/static/led/distance_bg.png


BIN
poly/static/led/led01.webp


BIN
poly/static/led/led02.webp


BIN
poly/static/led/mascot.png


BIN
poly/static/led/pic_border.png


BIN
poly/static/led/pic_mask.png


BIN
poly/static/led/run.gif


BIN
poly/static/logo.png


BIN
poly/static/lpzg.png


+ 76 - 0
poly/uni.scss

@@ -0,0 +1,76 @@
+/**
+ * 这里是uni-app内置的常用样式变量
+ *
+ * uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
+ * 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
+ *
+ */
+
+/**
+ * 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
+ *
+ * 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
+ */
+
+/* 颜色变量 */
+
+/* 行为相关颜色 */
+$uni-color-primary: #007aff;
+$uni-color-success: #4cd964;
+$uni-color-warning: #f0ad4e;
+$uni-color-error: #dd524d;
+
+/* 文字基本颜色 */
+$uni-text-color:#333;//基本色
+$uni-text-color-inverse:#fff;//反色
+$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
+$uni-text-color-placeholder: #808080;
+$uni-text-color-disable:#c0c0c0;
+
+/* 背景颜色 */
+$uni-bg-color:#ffffff;
+$uni-bg-color-grey:#f8f8f8;
+$uni-bg-color-hover:#f1f1f1;//点击状态颜色
+$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
+
+/* 边框颜色 */
+$uni-border-color:#c8c7cc;
+
+/* 尺寸变量 */
+
+/* 文字尺寸 */
+$uni-font-size-sm:12px;
+$uni-font-size-base:14px;
+$uni-font-size-lg:16px;
+
+/* 图片尺寸 */
+$uni-img-size-sm:20px;
+$uni-img-size-base:26px;
+$uni-img-size-lg:40px;
+
+/* Border Radius */
+$uni-border-radius-sm: 2px;
+$uni-border-radius-base: 3px;
+$uni-border-radius-lg: 6px;
+$uni-border-radius-circle: 50%;
+
+/* 水平间距 */
+$uni-spacing-row-sm: 5px;
+$uni-spacing-row-base: 10px;
+$uni-spacing-row-lg: 15px;
+
+/* 垂直间距 */
+$uni-spacing-col-sm: 4px;
+$uni-spacing-col-base: 8px;
+$uni-spacing-col-lg: 12px;
+
+/* 透明度 */
+$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
+
+/* 文章场景相关 */
+$uni-color-title: #2C405A; // 文章标题颜色
+$uni-font-size-title:20px;
+$uni-color-subtitle: #555555; // 二级标题颜色
+$uni-font-size-subtitle:26px;
+$uni-color-paragraph: #3F536E; // 文章段落颜色
+$uni-font-size-paragraph:15px;