From f04d2ac5332905b12820353a4d5fa42509e041a0 Mon Sep 17 00:00:00 2001
From: lefengyang <lefengyang@tencent.com>
Date: Fri, 14 Aug 2026 23:56:01 +0800
Subject: [PATCH] 去掉无用文件

---
 /dev/null                                |  624 --------------------------------------------------------
 ledApp/pages.json                        |    7 
 ledApp/pages/addTemplate/addTemplate.vue |    7 
 3 files changed, 0 insertions(+), 638 deletions(-)

diff --git a/ledApp/pages.json b/ledApp/pages.json
index 1be60ba..b04e9a6 100644
--- a/ledApp/pages.json
+++ b/ledApp/pages.json
@@ -66,13 +66,6 @@
 			}
 		},
 		{
-			"path": "pages/animation/animation",
-			"style": {
-				"navigationBarTitleText": "编辑动画",
-				"orientation": "landscape"
-			}
-		},
-		{
 			"path": "pages/register/register",
 			"style": {
 				"navigationBarTitleText": ""
diff --git a/ledApp/pages/addDevice/addDevice0.vue b/ledApp/pages/addDevice/addDevice0.vue
deleted file mode 100644
index 65f8b60..0000000
--- a/ledApp/pages/addDevice/addDevice0.vue
+++ /dev/null
@@ -1,487 +0,0 @@
-<template>
-	<view>
-		<uv-navbar title="添加设备" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="#3B74EE"
-			titleStyle="color:#fff"></uv-navbar>
-
-		<view class="page_bg">
-			<view class="searching_ico" @click="getBluetoothDevices">
-				<image src="/static/img/ico_1.png" mode="widthFix"></image>
-			</view>
-
-			<view class="searching_text">
-				<view class="name">
-					搜索中
-				</view>
-				<view class="text">
-					持续自动搜索中...
-				</view>
-			</view>
-		</view>
-
-		<view class="bluetooth" v-if="bluetoothList.length != 0">
-			<view class="bluetooth_title">
-				<image class="ico" src="/static/img/ico_2.png" mode="widthFix"></image>
-				<text>已找到设备</text>
-			</view>
-			<view class="bluetooth_list">
-				<view class="item" v-for="(item,index) in bluetoothList" :key="index">
-					<image class="ph" src="/static/img/ph_1.png" mode="aspectFill"></image>
-					<view class="info">
-						<view class="name">
-							{{item.device.name}}
-						</view>
-						<view class="btn">
-							<uv-button type="primary" shape="circle" text="连接" size="small"
-								@click="createBLEConnection(item.device.address)"></uv-button>
-
-						</view>
-
-					</view>
-				</view>
-			</view>
-		</view>
-
-	</view>
-</template>
-
-<script>
-	import {
-		BleLib
-	} from '@/uni_modules/android-ble'
-	var lib = new BleLib()
-
-	export default {
-		data() {
-			return {
-				searchIng: true,
-				bluetoothList: [],
-				deviceId: '', //设备id
-				serviceId: '', //服务uuid
-				characteristicId: '', //特征uuid
-				characteristicId1: '',
-				characteristicId2: '',
-				characteristicId3: '',
-				bluetooth: false
-			}
-		},
-		onLoad() {
-
-		},
-		onShow() {
-			this.bluetooth = lib.isEnabled();
-			if (this.bluetooth) {
-				console.log('蓝牙开启', this.bluetooth)
-				this.getBluetoothDevices()
-			} else {
-				console.log('蓝牙关闭', this.bluetooth)
-			}
-		},
-		onUnload() {
-			//lib.close();
-		},
-		methods: {
-			// 蓝牙扫描
-			getBluetoothDevices() {
-				console.log('蓝牙扫描----')
-				const that = this
-				var isconnect = lib.isConnected();
-				console.log('蓝牙是否连接----',isconnect)
-				if(isconnect){
-					console.log('蓝牙是否连接----',isconnect)
-					var device = lib.getConnectMac();
-					console.log('device----',device)
-				}
-				lib.startScanBleDevice(15000, function(res) {
-					if (res.data.device.name === 'CH9140BLE2U') {
-						that.bluetoothList.push(res.data);
-						console.log(res.data)
-					}
-				})
-			},
-			// 连接蓝牙
-			createBLEConnection(address) {
-				console.log('address-----',address)
-				const that = this
-				const isconnect = lib.isConnected();
-				console.log('蓝牙是否连接----',isconnect)
-				// if(isconnect){
-				// 	const device = lib.getConnectMac();
-				// 	console.log('获取已连接设备id----',device)
-				// 	that.commandCHEC()
-				// }
-				// else{
-					lib.connect(address, false, function(res) {
-						console.log('连接', res)
-						// type==0 表示连接成功
-						if (res.type == 0) {
-							// 扫描蓝牙与特征值
-							lib.scanServices(function(resSevice) {
-								console.log('特征值--------', resSevice)
-								that.characteristicId1 = resSevice.data[2].characteristics[0].uuid;
-								that.characteristicId2 = resSevice.data[2].characteristics[1].uuid;
-								that.characteristicId3 = resSevice.data[2].characteristics[2].uuid;
-								that.onNotityReadBleData()
-								setTimeout(() => {
-									console.log("延迟执行这段代码");
-									that.setBaud()
-									//that.commandCHEC()
-								}, 2000);
-							});
-							// lib.setMtu(512, function(resMtu) {
-							// 	console.log('设置mtu(仅安卓)', resMtu)
-							// })
-							
-
-						} else {
-							if(res.message == 'bluetooth is connected'){
-								//that.commandCHEC()
-							}
-							else{
-								uni.showToast({
-									title: '蓝牙连接失败',
-									duration: 2000,
-									icon: 'none'
-								});
-							}
-						}
-					})
-				// }
-			},
-			// 开启服务消息通知
-			onNotityReadBleData() {
-				const that = this
-				console.log(that.characteristicId1)
-				lib.onNotityReadBleData(lib.getSericUUID(),
-					that.characteristicId1,
-					true,
-					function(res) {
-						console.log('开启服务消息通知', res.data)
-						
-						uni.$uv.debounce(that.extractEncryptedIDWithCheck(res.data), 2000)
-					}
-				)
-			},
-			// 构建指令数据
-			commandCHEC() {
-				//555555555555555555557e41434845430095977e
-				// 构建指令数据
-				const startBytes = new Array(10).fill(0x55); // 10个启动字节
-				const frameHeader = 0x7E; // 帧头
-				const packageType = 0x41; // 包类型
-				const command = [0x43, 0x48, 0x45, 0x43]; // "CHEC"的ASCII码
-				const reserved = 0x00; // 保留字节
-
-				// 组合数据
-				const data = [
-					...startBytes,
-					frameHeader,
-					packageType,
-					...command,
-					reserved
-				];
-
-				// 计算CRC校验码(从包头段开始计算)
-				const crc = this.calcCRC16(data.slice(11));
-
-				// 添加CRC和帧尾
-				data.push((crc >> 8) & 0xFF); // CRC高8位
-				data.push(crc & 0xFF); // CRC低8位
-				data.push(frameHeader); // 帧尾
-
-				setTimeout(() => {
-					this.writeDataToBle(data)
-				}, 2000);
-			},
-			// 设置波特率
-			setBaud() {
-				var that = this
-				var d = "06000900009600000801009F"
-				lib.writeStringDataToBle(
-					lib.getSericUUID(),
-					that.characteristicId2,
-					d,
-					function(res) {
-						console.log('设置波特率', res)
-						that.commandCHEC()
-					}
-				)
-			},
-			
-			// 发送写入指令
-			writeDataToBle(b) {
-				var that = this
-				lib.writeDataToBle(
-					lib.getSericUUID(),
-					that.characteristicId2,
-					b,
-					function(res) {
-						console.log('发送16进制数组', res)
-						
-					}
-				)
-			},
-			writeStringDataToBle() {
-				var that = this
-				var d = "555555555555555555557e41434845430095977e"
-				lib.writeStringDataToBle(
-					lib.getSericUUID(),
-					that.characteristicId2,
-					d,
-					function(res) {
-						console.log('发送16进制字符数据', res)
-					}
-				)
-			},
-			// 16进制数据转二位数据
-			hexStringToArrayBuffer(hexStr) {
-				const bytes = new Uint8Array(hexStr.match(/.{2}/g).map(byte => parseInt(byte, 16)));
-				return bytes.buffer;
-			},
-			// 二位数据转16进制数据
-			ab2hex(buffer) {
-				const hexArr = Array.prototype.map.call(
-					new Uint8Array(buffer),
-					function(bit) {
-						return ('00' + bit.toString(16)).slice(-2)
-					}
-				)
-				return hexArr.join('')
-			},
-			calcCRC16(data) {
-				// 创建查表
-				const table = this.buildCRC16Table();
-				let crc = 0;
-
-				// 计算CRC
-				for (let i = 0; i < data.length; i++) {
-					crc = ((crc << 8) & 0xFF00) ^ table[((crc >> 8) ^ data[i]) & 0xFF];
-				}
-
-				return crc & 0xFFFF;
-			},
-			buildCRC16Table() {
-				const table = new Array(256);
-				const poly = 0x1021; // CRC-CCITT多项式
-
-				for (let i = 0; i < 256; i++) {
-					let nData = i << 8;
-					let nAccum = 0;
-
-					for (let j = 0; j < 8; j++) {
-						if ((nData ^ nAccum) & 0x8000) {
-							nAccum = (nAccum << 1) ^ poly;
-						} else {
-							nAccum <<= 1;
-						}
-						nData <<= 1;
-					}
-					table[i] = nAccum & 0xFFFF;
-				}
-				return table;
-			},
-			// 判断返回数据是否正确 并提取加密id
-			extractEncryptedIDWithCheck(buffer) {
-				const hexArr = Array.prototype.map.call(
-					new Uint8Array(buffer),
-					function(bit) {
-						return ('00' + bit.toString(16)).slice(-2)
-					}
-				)
-				const responseHex = hexArr.join('').slice(20)
-				console.log('responseHex---',responseHex)
-				// 1. 提取返回标志位置(第11字节,即下标:30~31)
-				const returnFlagHex = responseHex.substring(12, 14).toUpperCase();
-				console.log('returnFlagHex---',returnFlagHex)
-				if (returnFlagHex === "30") {
-					// 正常,提取加密ID(从下标 32 开始,取 40 位
-					const encryptedID = responseHex.substring(14, 55).toUpperCase();
-					console.log('encryptedID---',encryptedID)
-					uni.showToast({
-						title: encryptedID,
-						duration: 2000,
-						icon: 'none'
-					});
-				} else if (returnFlagHex === "31") {
-					// 异常,无加密ID
-					uni.showToast({
-						title: '智能壳工作异常,返回标志0x31',
-						duration: 2000,
-						icon: 'none'
-					});
-					lib.close();
-				} else {
-					// 未知标志
-					uni.showToast({
-						title: '智能壳工作异常,未知返回标志',
-						duration: 2000,
-						icon: 'none'
-					});
-					lib.close();
-				}
-			},
-			// 解密函数
-			decryptSmartShellID(encryptedHex) {
-				if (encryptedHex.length !== 40) {
-					console.error('加密ID长度必须为40个十六进制字符(20字节)');
-					return null;
-				}
-
-				const key = [
-					0x14, 0x15, 0x0A, 0x0C, 0x24, 0x01, 0x0B, 0x13, 0x44, 0x02,
-					0x0F, 0x00, 0x0E, 0x0D, 0x47, 0x2A, 0x5E, 0x32, 0x32, 0x11
-				];
-
-				const decrypted = [];
-
-				for (let i = 0; i < 20; i++) {
-					const byteHex = encryptedHex.substr(i * 2, 2);
-					const encryptedByte = parseInt(byteHex, 16);
-					const decryptedByte = (encryptedByte - key[i] + 256) % 256;
-					decrypted.push(decryptedByte.toString(16).padStart(2, '0').toUpperCase());
-				}
-
-				return decrypted.join(' ');
-			},
-			// 加密函数
-			encryptSmartShellID(originalHex) {
-				if (originalHex.length !== 40) {
-					console.error('原始ID长度必须为40位十六进制字符串(20字节)');
-					return null;
-				}
-
-				// 加密密钥(20 字节)
-				const key = [
-					0x14, 0x15, 0x0A, 0x0C, 0x24, 0x01, 0x0B, 0x13, 0x44, 0x02,
-					0x0F, 0x00, 0x0E, 0x0D, 0x47, 0x2A, 0x5E, 0x32, 0x32, 0x11
-				];
-
-				const encrypted = [];
-
-				for (let i = 0; i < 20; i++) {
-					const byteHex = originalHex.substr(i * 2, 2);
-					const originalByte = parseInt(byteHex, 16);
-					const encryptedByte = (originalByte + key[i]) % 256; // 忽略进位
-					encrypted.push(encryptedByte.toString(16).padStart(2, '0').toUpperCase());
-				}
-
-				return encrypted.join('');
-			}
-
-
-
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.bluetooth {
-		padding: 0 30rpx;
-
-		.bluetooth_list {
-			.item {
-				background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-				box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-				border-radius: 20rpx;
-				border: 2rpx solid #FFFFFF;
-				padding: 22rpx;
-				display: flex;
-				align-items: stretch;
-				justify-content: space-between;
-				margin-top: 24rpx;
-
-				.ph {
-					display: block;
-					flex-shrink: 0;
-					width: 230rpx;
-					height: 170rpx;
-					border-radius: 20rpx;
-					margin-right: 24rpx;
-				}
-
-				.info {
-					width: 100%;
-					display: flex;
-					flex-direction: column;
-					justify-content: space-between;
-
-					.name {
-						font-weight: 500;
-						font-size: 27rpx;
-						color: #000000;
-						line-height: 50rpx;
-					}
-
-					.btn {
-						width: 160rpx;
-						margin-top: 10rpx;
-					}
-				}
-			}
-		}
-
-		.bluetooth_title {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			margin-top: 20rpx;
-
-			text {
-				display: block;
-				width: 100%;
-				font-weight: 500;
-				font-size: 34rpx;
-				color: rgba(0, 0, 0, 0.7);
-				line-height: 38rpx;
-			}
-
-			.ico {
-				flex-shrink: 0;
-				width: 40rpx;
-				margin-right: 10rpx;
-			}
-		}
-	}
-
-	.searching_text {
-		text-align: center;
-		background: url('/static/img/bg_3.png') no-repeat center top;
-		background-size: 100% auto;
-		box-sizing: border-box;
-		padding-top: 140rpx;
-		margin-top: -100rpx;
-		height: 300rpx;
-
-		.name {
-			font-weight: 500;
-			font-size: 36rpx;
-			color: #000000;
-			line-height: 34rpx;
-		}
-
-		.text {
-			font-size: 26rpx;
-			color: rgba(0, 0, 0, 0.5);
-			line-height: 34rpx;
-			margin-top: 30rpx;
-		}
-	}
-
-	.searching_ico {
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		padding-top: 100rpx;
-	}
-
-	.page_bg {
-		width: 100%;
-		background: linear-gradient(3deg, #72E5FF 0%, #3B74EE 98%, #3B74EE 100%);
-	}
-
-	.page_bg1 {
-		width: 100%;
-		min-height: calc(100vh - var(--window-bottom));
-		background: url('/static/img/bg_2.jpg') no-repeat center top;
-		background-size: 100% auto;
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/addTemplate/addTemplate copy 1.vue b/ledApp/pages/addTemplate/addTemplate copy 1.vue
deleted file mode 100644
index d90c1a9..0000000
--- a/ledApp/pages/addTemplate/addTemplate copy 1.vue
+++ /dev/null
@@ -1,548 +0,0 @@
-<template>
-	<view class="page_bg">
-		<uv-navbar title="新增模版" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="rgba(0,0,0,0)"
-			titleStyle="color:#fff"></uv-navbar>
-
-		<view class="temp">
-			<view class="temp_item">
-				<view class="title">
-					模版名称
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入名称" border="none" v-model="tempName" fontSize="27rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					封面图片
-				</view>
-				<view class="item item_pic">
-					<uv-upload :fileList="fileList1" name="1" :maxCount="1" width="200rpx" height="200rpx"
-						:previewFullImage="false" @afterRead="afterRead" @delete="deletePic">
-					</uv-upload>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					屏幕规格
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="specVal" placement="column" @change="changeSpec">
-						<uv-radio class="spec_radio" v-for="(item, index) in specList" :key="index" :label="item.name"
-							:name="item.name">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画方式
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="modeVal" placement="column" @change="changeMode">
-						<uv-radio class="spec_radio" v-for="(item, index) in modeList" :key="index" :label="item.name"
-							:name="item.val">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-
-			<view class="temp_item">
-				<view class="title">
-					动画帧数
-				</view>
-				<view class="item" @click="clickTotal">
-					<uv-input placeholder="请输入" readonly border="none" v-model="total" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画速度
-				</view>
-				<view class="item" @click="clickSpeed">
-					<uv-input placeholder="请输入" readonly border="none" v-model="speed" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<!-- <view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					循环次数
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入" readonly border="none" v-model="cycle" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view> -->
-
-			<view class="temp_item1" v-for="(item,index) in total" :key="index">
-				<view class="title">
-					动画第{{item}}帧
-				</view>
-				<view class="item">
-					<uv-button text="编辑" @click="clickGoAnim(index)" shape="circle" size="small"
-						color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)"></uv-button>
-				</view>
-			</view>
-
-		</view>
-
-
-		<!-- <view class="temp_btn" @click="clickGoAnim">
-			编辑动画
-		</view> -->
-
-		<view class="footer_none"></view>
-		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle"
-				@click="clickTempleteAdd()"></uv-button>
-			<uv-button text="测试" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle"
-				style="margin-top: 30rpx;" @click="clickTempleteAdd2()"></uv-button>
-		</view>
-
-		<!-- 动画帧数 -->
-		<uv-picker ref="pickerTotal" :columns="columnsTotal" @confirm="confirmTotal"></uv-picker>
-
-		<!-- 动画速度 -->
-		<uv-picker ref="pickerSpeed" :columns="columnsSpeed" @confirm="confirmSpeed"></uv-picker>
-
-
-	</view>
-</template>
-
-<script>
-	import {
-		templeteAdd
-	} from '@/api/api.js'
-	export default {
-		data() {
-			return {
-				tempName: '',
-				pic: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				specWidth: 24,
-				specHeight: 12,
-				modeList: [{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-						28, 29, 30
-					]
-				],
-				total: 1, //动画总帧数
-				columnsSpeed: [
-					[10, 20, 30, 40, 50, 60, 70, 80, 90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1, //第几帧
-				fpsIds: [],
-
-				baseURL: '',
-				fileList1: [],
-				animationData: [],
-				fpsTotal: 1
-			}
-		},
-		onLoad() {
-			this.baseURL = uni.$uv.http.config.baseURL
-		},
-		onShow() {
-			console.log('------onShow')
-			//const fpsParams = uni.getStorageSync('fpsParams');
-			// if (fpsParams) {
-			// 	console.log('收到回传参数:', fpsParams);
-			// 	this.fpsData[fpsParams.fpsIndex] = fpsParams.data;
-			// 	uni.removeStorageSync('fpsParams');
-			// }
-			const that = this
-			uni.getStorage({
-				key: 'fpsParams',
-				success: (res) => {
-					console.log('获取成功:', res.data);
-					that.fpsData[res.data.fpsIndex] = res.data.data;
-				},
-				fail: (err) => {
-					console.error('获取失败:', err);
-				}
-			});
-		},
-		methods: {
-			// 屏幕规格
-			changeSpec(e) {
-				const ratio = e.split('*');
-				this.specHeight = Number(ratio[0]);
-				this.specWidth = Number(ratio[1]);
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			// 生成一帧动画其他帧数据
-			generateFrames(data, frameCount = 24) {
-				const cols = this.specWidth; // 每行 24 个
-				const rows = this.specHeight; // 共 12 行
-				const frames = [];
-				// 拆分成 12 行
-				let grid = [];
-				for (let r = 0; r < rows; r++) {
-					grid.push(data.slice(r * cols, (r + 1) * cols));
-				}
-				// 生成帧
-				for (let f = 0; f < frameCount; f++) {
-					let frame = [];
-					// 每行左移 f 次
-					for (let r = 0; r < rows; r++) {
-						let row = grid[r].slice(); // 拷贝一行
-						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
-						frame = frame.concat(shifted);
-					}
-					frames.push(frame);
-				}
-				return frames;
-			},
-			clickTempleteAdd2() {
-
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-
-				templeteAdd({
-					name: '',
-					userId: uni.getStorageSync('userId'),
-					screen: '', //屏幕
-					fpsTotal: '', //总帧数
-					speed: '', //速度
-					pic: '',
-					fpsData: ''
-				}).then(res => {
-					console.log('添加动画模版', res)
-					uni.hideLoading();
-					uni.navigateBack({
-						delta: 1
-					});
-				})
-
-			},
-			clickTempleteAdd() {
-				if (!this.tempName) {
-					uni.showToast({
-						title: '请输入模版名称',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fileList1.length == 0) {
-					uni.showToast({
-						title: '请上传封面图片',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fpsData.length == 0) {
-					uni.showToast({
-						title: '请编辑动画帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				//console.log('fpsData------------', this.fpsData)
-				// 循环校验每一帧是否完整
-				// let missingIndex = -1;
-				// for (let i = 0; i < this.total; i++) {
-				// 	if (this.fpsData[i] === null || this.fpsData[i] === undefined) {
-				// 		missingIndex = i;
-				// 		break;
-				// 	}
-				// }
-				// if (missingIndex !== -1) {
-				// 	uni.showToast({
-				// 		title: '请编辑第' + (missingIndex + 1) + '帧',
-				// 		duration: 2000,
-				// 		icon: 'none'
-				// 	});
-				// 	return;
-				// }
-
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-				// 动画方式
-				if (this.modeVal == 0) { //一帧动画
-					let frames = this.generateFrames(this.fpsData[0], 24);
-					const parsedData = frames.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = 24
-				} else if (this.modeVal == 1) {
-					const parsedData = this.fpsData.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = this.total
-				}
-
-				// setTimeout(() => {
-
-				// }, 1000)
-				const addData = {
-					name: this.tempName,
-					userId: uni.getStorageSync('userId'),
-					screen: this.specVal, //屏幕
-					fpsTotal: this.fpsTotal, //总帧数
-					speed: this.speed, //速度
-					pic: this.fileList1[0].url,
-					fpsData: JSON.stringify(this.animationData)
-				}
-				console.log('addData-----', addData)
-				templeteAdd(addData).then(res => {
-					console.log('添加动画模版', res)
-					uni.hideLoading();
-					if (res.code == 200) {
-						uni.navigateBack({
-							delta: 1
-						});
-					} else {
-						uni.showToast({
-							title: res.msg,
-							duration: 1500,
-							icon: 'none',
-							mask: true
-						});
-					}
-				})
-
-			},
-			clickSpeed() {
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal() {
-				if (this.total != 1) {
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-				// this.fpsData = []
-				// for (let i = 0; i < this.total; i++) {
-				// 	this.fpsData.push(null);
-				// }
-				this.adjustFpsData()
-				console.log('fpsData------------', this.fpsData)
-			},
-			changeMode(e) {
-				this.fpsData = []
-				if (e == 0) {
-					this.total = 1
-				} else {
-					this.total = 2
-				}
-				this.adjustFpsData()
-			},
-			clickGoAnim(index) {
-				uni.navigateTo({
-					url: '/pages/animation/animation?fps=' + index
-				})
-			},
-			adjustFpsData() {
-				// 如果 fpsData 太长 → 截取
-				if (this.fpsData.length > this.total) {
-					this.fpsData = this.fpsData.slice(0, this.total);
-				}
-				// 如果 fpsData 太短 → 补齐 null
-				else if (this.fpsData.length < this.total) {
-					const missing = this.total - this.fpsData.length;
-					this.fpsData = this.fpsData.concat(new Array(missing).fill(null));
-				}
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log('event---', event)
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					this.avatar = result
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: this.baseURL + '/common/uploadFileByAnny', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						success: (res) => {
-							console.log('图片-----', JSON.parse(res.data).fileName)
-							setTimeout(() => {
-								resolve(JSON.parse(res.data).fileName)
-							}, 1000)
-						}
-					});
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.footer_none {
-		height: 200rpx;
-	}
-
-	.footer_btn {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-	}
-
-	.temp_btn {
-		position: fixed;
-		left: 30rpx;
-		bottom: 60rpx;
-		right: 30rpx;
-		box-sizing: border-box;
-		height: 96rpx;
-		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
-		border-radius: 385rpx 385rpx 385rpx 385rpx;
-		font-size: 30rpx;
-		color: #FFFFFF;
-		line-height: 96rpx;
-		text-align: center;
-	}
-
-	.spec_radio {
-		margin-top: 30rpx;
-
-		&:first-child {
-			margin-top: 10rpx;
-		}
-	}
-
-	.temp {
-		padding: 0 30rpx;
-
-		.temp_item1 {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-
-			}
-
-			.item {}
-		}
-
-		.temp_item {
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-			}
-
-			.item {
-				margin-top: 20rpx;
-
-				&.item_pic {
-					margin-top: 25rpx;
-				}
-			}
-		}
-	}
-
-	.page_bg {
-		width: 100%;
-		min-height: calc(100vh - var(--window-bottom));
-		background: url('/static/img/bg_2.jpg') no-repeat center top;
-		background-size: 100% auto;
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/addTemplate/addTemplate copy 2.vue b/ledApp/pages/addTemplate/addTemplate copy 2.vue
deleted file mode 100644
index d90c1a9..0000000
--- a/ledApp/pages/addTemplate/addTemplate copy 2.vue
+++ /dev/null
@@ -1,548 +0,0 @@
-<template>
-	<view class="page_bg">
-		<uv-navbar title="新增模版" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="rgba(0,0,0,0)"
-			titleStyle="color:#fff"></uv-navbar>
-
-		<view class="temp">
-			<view class="temp_item">
-				<view class="title">
-					模版名称
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入名称" border="none" v-model="tempName" fontSize="27rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					封面图片
-				</view>
-				<view class="item item_pic">
-					<uv-upload :fileList="fileList1" name="1" :maxCount="1" width="200rpx" height="200rpx"
-						:previewFullImage="false" @afterRead="afterRead" @delete="deletePic">
-					</uv-upload>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					屏幕规格
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="specVal" placement="column" @change="changeSpec">
-						<uv-radio class="spec_radio" v-for="(item, index) in specList" :key="index" :label="item.name"
-							:name="item.name">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画方式
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="modeVal" placement="column" @change="changeMode">
-						<uv-radio class="spec_radio" v-for="(item, index) in modeList" :key="index" :label="item.name"
-							:name="item.val">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-
-			<view class="temp_item">
-				<view class="title">
-					动画帧数
-				</view>
-				<view class="item" @click="clickTotal">
-					<uv-input placeholder="请输入" readonly border="none" v-model="total" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画速度
-				</view>
-				<view class="item" @click="clickSpeed">
-					<uv-input placeholder="请输入" readonly border="none" v-model="speed" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<!-- <view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					循环次数
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入" readonly border="none" v-model="cycle" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view> -->
-
-			<view class="temp_item1" v-for="(item,index) in total" :key="index">
-				<view class="title">
-					动画第{{item}}帧
-				</view>
-				<view class="item">
-					<uv-button text="编辑" @click="clickGoAnim(index)" shape="circle" size="small"
-						color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)"></uv-button>
-				</view>
-			</view>
-
-		</view>
-
-
-		<!-- <view class="temp_btn" @click="clickGoAnim">
-			编辑动画
-		</view> -->
-
-		<view class="footer_none"></view>
-		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle"
-				@click="clickTempleteAdd()"></uv-button>
-			<uv-button text="测试" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle"
-				style="margin-top: 30rpx;" @click="clickTempleteAdd2()"></uv-button>
-		</view>
-
-		<!-- 动画帧数 -->
-		<uv-picker ref="pickerTotal" :columns="columnsTotal" @confirm="confirmTotal"></uv-picker>
-
-		<!-- 动画速度 -->
-		<uv-picker ref="pickerSpeed" :columns="columnsSpeed" @confirm="confirmSpeed"></uv-picker>
-
-
-	</view>
-</template>
-
-<script>
-	import {
-		templeteAdd
-	} from '@/api/api.js'
-	export default {
-		data() {
-			return {
-				tempName: '',
-				pic: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				specWidth: 24,
-				specHeight: 12,
-				modeList: [{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-						28, 29, 30
-					]
-				],
-				total: 1, //动画总帧数
-				columnsSpeed: [
-					[10, 20, 30, 40, 50, 60, 70, 80, 90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1, //第几帧
-				fpsIds: [],
-
-				baseURL: '',
-				fileList1: [],
-				animationData: [],
-				fpsTotal: 1
-			}
-		},
-		onLoad() {
-			this.baseURL = uni.$uv.http.config.baseURL
-		},
-		onShow() {
-			console.log('------onShow')
-			//const fpsParams = uni.getStorageSync('fpsParams');
-			// if (fpsParams) {
-			// 	console.log('收到回传参数:', fpsParams);
-			// 	this.fpsData[fpsParams.fpsIndex] = fpsParams.data;
-			// 	uni.removeStorageSync('fpsParams');
-			// }
-			const that = this
-			uni.getStorage({
-				key: 'fpsParams',
-				success: (res) => {
-					console.log('获取成功:', res.data);
-					that.fpsData[res.data.fpsIndex] = res.data.data;
-				},
-				fail: (err) => {
-					console.error('获取失败:', err);
-				}
-			});
-		},
-		methods: {
-			// 屏幕规格
-			changeSpec(e) {
-				const ratio = e.split('*');
-				this.specHeight = Number(ratio[0]);
-				this.specWidth = Number(ratio[1]);
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			// 生成一帧动画其他帧数据
-			generateFrames(data, frameCount = 24) {
-				const cols = this.specWidth; // 每行 24 个
-				const rows = this.specHeight; // 共 12 行
-				const frames = [];
-				// 拆分成 12 行
-				let grid = [];
-				for (let r = 0; r < rows; r++) {
-					grid.push(data.slice(r * cols, (r + 1) * cols));
-				}
-				// 生成帧
-				for (let f = 0; f < frameCount; f++) {
-					let frame = [];
-					// 每行左移 f 次
-					for (let r = 0; r < rows; r++) {
-						let row = grid[r].slice(); // 拷贝一行
-						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
-						frame = frame.concat(shifted);
-					}
-					frames.push(frame);
-				}
-				return frames;
-			},
-			clickTempleteAdd2() {
-
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-
-				templeteAdd({
-					name: '',
-					userId: uni.getStorageSync('userId'),
-					screen: '', //屏幕
-					fpsTotal: '', //总帧数
-					speed: '', //速度
-					pic: '',
-					fpsData: ''
-				}).then(res => {
-					console.log('添加动画模版', res)
-					uni.hideLoading();
-					uni.navigateBack({
-						delta: 1
-					});
-				})
-
-			},
-			clickTempleteAdd() {
-				if (!this.tempName) {
-					uni.showToast({
-						title: '请输入模版名称',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fileList1.length == 0) {
-					uni.showToast({
-						title: '请上传封面图片',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fpsData.length == 0) {
-					uni.showToast({
-						title: '请编辑动画帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				//console.log('fpsData------------', this.fpsData)
-				// 循环校验每一帧是否完整
-				// let missingIndex = -1;
-				// for (let i = 0; i < this.total; i++) {
-				// 	if (this.fpsData[i] === null || this.fpsData[i] === undefined) {
-				// 		missingIndex = i;
-				// 		break;
-				// 	}
-				// }
-				// if (missingIndex !== -1) {
-				// 	uni.showToast({
-				// 		title: '请编辑第' + (missingIndex + 1) + '帧',
-				// 		duration: 2000,
-				// 		icon: 'none'
-				// 	});
-				// 	return;
-				// }
-
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-				// 动画方式
-				if (this.modeVal == 0) { //一帧动画
-					let frames = this.generateFrames(this.fpsData[0], 24);
-					const parsedData = frames.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = 24
-				} else if (this.modeVal == 1) {
-					const parsedData = this.fpsData.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = this.total
-				}
-
-				// setTimeout(() => {
-
-				// }, 1000)
-				const addData = {
-					name: this.tempName,
-					userId: uni.getStorageSync('userId'),
-					screen: this.specVal, //屏幕
-					fpsTotal: this.fpsTotal, //总帧数
-					speed: this.speed, //速度
-					pic: this.fileList1[0].url,
-					fpsData: JSON.stringify(this.animationData)
-				}
-				console.log('addData-----', addData)
-				templeteAdd(addData).then(res => {
-					console.log('添加动画模版', res)
-					uni.hideLoading();
-					if (res.code == 200) {
-						uni.navigateBack({
-							delta: 1
-						});
-					} else {
-						uni.showToast({
-							title: res.msg,
-							duration: 1500,
-							icon: 'none',
-							mask: true
-						});
-					}
-				})
-
-			},
-			clickSpeed() {
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal() {
-				if (this.total != 1) {
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-				// this.fpsData = []
-				// for (let i = 0; i < this.total; i++) {
-				// 	this.fpsData.push(null);
-				// }
-				this.adjustFpsData()
-				console.log('fpsData------------', this.fpsData)
-			},
-			changeMode(e) {
-				this.fpsData = []
-				if (e == 0) {
-					this.total = 1
-				} else {
-					this.total = 2
-				}
-				this.adjustFpsData()
-			},
-			clickGoAnim(index) {
-				uni.navigateTo({
-					url: '/pages/animation/animation?fps=' + index
-				})
-			},
-			adjustFpsData() {
-				// 如果 fpsData 太长 → 截取
-				if (this.fpsData.length > this.total) {
-					this.fpsData = this.fpsData.slice(0, this.total);
-				}
-				// 如果 fpsData 太短 → 补齐 null
-				else if (this.fpsData.length < this.total) {
-					const missing = this.total - this.fpsData.length;
-					this.fpsData = this.fpsData.concat(new Array(missing).fill(null));
-				}
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log('event---', event)
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					this.avatar = result
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: this.baseURL + '/common/uploadFileByAnny', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						success: (res) => {
-							console.log('图片-----', JSON.parse(res.data).fileName)
-							setTimeout(() => {
-								resolve(JSON.parse(res.data).fileName)
-							}, 1000)
-						}
-					});
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.footer_none {
-		height: 200rpx;
-	}
-
-	.footer_btn {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-	}
-
-	.temp_btn {
-		position: fixed;
-		left: 30rpx;
-		bottom: 60rpx;
-		right: 30rpx;
-		box-sizing: border-box;
-		height: 96rpx;
-		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
-		border-radius: 385rpx 385rpx 385rpx 385rpx;
-		font-size: 30rpx;
-		color: #FFFFFF;
-		line-height: 96rpx;
-		text-align: center;
-	}
-
-	.spec_radio {
-		margin-top: 30rpx;
-
-		&:first-child {
-			margin-top: 10rpx;
-		}
-	}
-
-	.temp {
-		padding: 0 30rpx;
-
-		.temp_item1 {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-
-			}
-
-			.item {}
-		}
-
-		.temp_item {
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-			}
-
-			.item {
-				margin-top: 20rpx;
-
-				&.item_pic {
-					margin-top: 25rpx;
-				}
-			}
-		}
-	}
-
-	.page_bg {
-		width: 100%;
-		min-height: calc(100vh - var(--window-bottom));
-		background: url('/static/img/bg_2.jpg') no-repeat center top;
-		background-size: 100% auto;
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/addTemplate/addTemplate copy 3.vue b/ledApp/pages/addTemplate/addTemplate copy 3.vue
deleted file mode 100644
index dc6ca6d..0000000
--- a/ledApp/pages/addTemplate/addTemplate copy 3.vue
+++ /dev/null
@@ -1,1056 +0,0 @@
-<template>
-	<view class="page_bg">
-		
-		<uv-navbar :title="titleName" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="rgba(0,0,0,0)" titleStyle="color:#fff"></uv-navbar>
-		
-		<view class="temp">
-			<view class="temp_item">
-				<view class="title">
-					模版名称
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入名称" border="none" v-model="tempName" fontSize="27rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					封面图片
-				</view>
-				<view class="item item_pic">
-					<uv-upload :fileList="fileList1" name="1" :maxCount="1" width="200rpx" height="200rpx"
-						:previewFullImage="false" @afterRead="afterRead" @delete="deletePic">
-						<!-- <image v-if="fileList1.length != 0"
-							:src="baseURL + fileList1[0]?.url" 
-							mode="aspectFill" 
-							style="width: 200rpx;height: 200rpx;"
-						></image>
-						<view class="item_pic_btn" v-else>
-							<uv-icon name="camera-fill" color="#ccc" size="60rpx"></uv-icon>
-						</view> -->
-					</uv-upload>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					屏幕规格
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="specVal" placement="column" @change="changeSpec">
-						<uv-radio class="spec_radio" v-for="(item, index) in specList" :key="index" :label="item.name"
-							:name="item.name">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画方式
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="modeVal" placement="column" @change="changeMode">
-						<uv-radio class="spec_radio" v-for="(item, index) in modeList" :key="index" :label="item.name"
-							:name="item.val">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-
-			<view class="temp_item">
-				<view class="title">
-					动画帧数
-				</view>
-				<view class="item" @click="clickTotal">
-					<uv-input placeholder="请输入" readonly border="none" v-model="total" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画速度
-				</view>
-				<view class="item" @click="clickSpeed">
-					<uv-input placeholder="请输入" readonly border="none" v-model="speed" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<!-- <view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					循环次数
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入" readonly border="none" v-model="cycle" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view> -->
-			<view class="temp_item1" v-for="(item,index) in total" :key="index">
-				<view class="title">
-					动画第{{item}}帧
-				</view>
-				<view class="item">
-					<uv-button text="编辑" @click="popupAnimationOpen(index)" shape="circle" size="small" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)"></uv-button>
-				</view>
-			</view>
-		</view>
-
-		<view class="footer_none"></view>
-		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" @click="clickTempleteAdd()"></uv-button>
-		</view>
-
-		<!-- 动画帧数 -->
-		<uv-picker ref="pickerTotal" :columns="columnsTotal" @confirm="confirmTotal"></uv-picker>
-
-		<!-- 动画速度 -->
-		<uv-picker ref="pickerSpeed" :columns="columnsSpeed" @confirm="confirmSpeed"></uv-picker>
-		
-		<!-- 动画弹出框 -->
-		<uv-popup ref="popupAnimation" mode="center" @change="changeAnimation" :safeAreaInsetTop="false" :safeAreaInsetBottom="false" :zoom="false" duration="0">
-			<view class="animation_pixel">
-				<view class="back_btn" @click="popupAnimationClose">
-					<uv-icon name="arrow-leftward" color="#333" size="30"></uv-icon>
-				</view>
-				<!-- 动画按钮 -->
-				<view class="controls">
-					<uv-button type="primary" :plain="true" text="分辨率" @click="changeRatio()"></uv-button>
-					<uv-button type="primary" :plain="true" text="颜色" @click="changeColor()"></uv-button>
-					<uv-button type="primary" :plain="true" text="添加文字" @click="addText()"></uv-button>
-					<uv-button type="primary" :plain="true" text="清除" @click="clear()"></uv-button>
-					<uv-button type="primary" :plain="true" text="保存" @click="clickSaveData"></uv-button>
-				</view>
-				
-				<!-- 文字生成图形 -->
-				<canvas canvas-id="myCanvas" id="myCanvas" class="canvas" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
-
-				<view class="pixel_grid" @touchstart.prevent="handleTouchStart" @touchmove.prevent="handleTouchMove"
-					@touchend.prevent="handleTouchEnd" @touchcancel.prevent="handleTouchEnd" 
-					:style="{
-						gridTemplateRows: `repeat(${height}, 1fr)`,
-						gridTemplateColumns: `repeat(${width}, 1fr)`
-					}">
-					<view class="pixel_cell" v-for="(cell, cellIndex) in pixelData" :key="cellIndex">
-						<view class="pixel_cell_item" :style="{ backgroundColor: cell }"></view>
-					</view>
-				</view>
-			</view>
-		</uv-popup>
-		
-		<!-- 分辨率 -->
-		<uv-picker ref="pickerRatio" :columns="columnsRatio" @confirm="confirmRatio"></uv-picker>
-		
-		<!-- 颜色 -->
-		<uv-popup ref="pickerColor" mode="bottom" round="10" :closeable="true">
-			<view class="color_list">
-				<view class="color_item" v-for="(item, index) in colorList" :class="{ hover: color === item }" :key="index" :style="{ backgroundColor: item }" @click="clickColor(item)"></view>
-			</view>
-		</uv-popup>
-		
-	</view>
-</template>
-
-<script>
-	import {
-		templeteAdd,
-		templeteInfo,
-		templeteEdit
-	} from '@/api/api.js'
-	let ctx = null
-	export default {
-		data() {
-			return {
-				tempName: '',
-				pic: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				specWidth: 24,
-				specHeight: 12,
-				modeList: [{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-						28, 29, 30
-					]
-				],
-				total: 1, //动画总帧数
-				columnsSpeed: [
-					[10, 20, 30, 40, 50, 60, 70, 80, 90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1, //第几帧
-				fpsIds: [],
-
-				baseURL: '',
-				fileList1: [],
-				animationData: [],
-				fpsTotal: 1,
-				
-				
-				
-				// 模版动画
-				pixelData: [],
-				canvasData: [],
-				canvasWidth: 240,
-				canvasHeight: 120,
-				width: 24,
-				height: 12,
-				color: '#FF0000',
-				gridRect: null, // 存储像素网格的位置信息
-				lastCell: null, // 防止重复绘制
-				columnsRatio: [
-					['12*24', '16*32', '24*48', '32*64', '40*80']
-				],
-				// columnsRatio: [
-				// 	['12*24']
-				// ],
-				colorList: [
-					'#FF0000',
-					'#00FF00',
-					'#0000FF',
-					'#FFFF00',
-					'#FFA500',
-					'#800080',
-					'#00FFFF',
-					'#FFC0CB'
-				],
-				fpsIndex: 0,
-				fpsList: [],
-				tId: '',
-				tempInfo:{},
-				titleName: '新增模版'
-				
-			}
-		},
-		onLoad(opt) {
-			this.baseURL = uni.$uv.http.config.baseURL
-			if(opt.id){
-				this.tId = opt.id
-				this.getTempleteInfo()
-				this.titleName = '编辑模版'
-			}
-			else{
-				this.titleName = '新增模版'
-			}
-		},
-		onShow() {
-			
-		},
-		onHide() {
-			this.$refs.popupAnimation.close();
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		onUnload() {
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		methods: {
-			// 获取编辑详情
-			getTempleteInfo(){
-				templeteInfo(this.tId).then(res=>{
-					console.log('获取编辑详情-------',res)
-					if(res.code == 200){
-						this.tempInfo = res.data
-						this.tempName = this.tempInfo.name
-						this.fileList1.push({
-							url: this.baseURL + this.tempInfo.pic
-						})
-						
-						this.specVal = this.tempInfo.screen
-						this.modeVal = this.tempInfo.mode
-						
-						this.total = this.tempInfo.cycle
-						this.fpsTotal = this.tempInfo.fpsTotal
-						this.speed = this.tempInfo.speed
-						
-						this.fpsList = JSON.parse(this.tempInfo.fpsList)
-						
-					}
-					else{
-						uni.showToast({
-							title: res.msg,
-							duration: 2000,
-							icon: 'none'
-						});
-					}
-				})
-			},
-			// 添加模版提交接口
-			clickTempleteAdd() {
-				
-				if (!this.tempName) {
-					uni.showToast({
-						title: '请输入模版名称',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fileList1.length == 0) {
-					uni.showToast({
-						title: '请上传封面图片',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				
-				if (this.fpsList.length == 0) {
-					uni.showToast({
-						title: '请编辑动画帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				} else {
-					for (let i = 0; i < this.fpsList.length; i++) {
-					    if (this.fpsList[i] === null) {
-							uni.showToast({
-								title: `请编辑第 ${i+1} 个动画帧`,
-								duration: 2000,
-								icon: 'none'
-							});
-							return
-					    }
-					}
-				}
-				console.log('this.fpsList=========',this.fpsList)
-				
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-				
-				
-				// 遍历二维数组
-				this.fpsData = this.fpsList.map(inner =>
-				  inner.map(item => {
-				    if (item === "") {
-				      return "000000"; // 空的改成000000
-				    } else if (item.includes("#")) {
-				      return item.replace("#", ""); // 去掉#
-				    } else {
-				      return item; // 保持原样
-				    }
-				  })
-				);
-				
-				console.log('this.fpsData=========',this.fpsData)
-				
-				// 动画方式
-				if (this.modeVal == 0) { //一帧动画
-					let frames = this.generateFrames(this.fpsData[0], 24);
-					const parsedData = frames.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = 24
-				} else if (this.modeVal == 1) {
-					console.log('modeVal--------1')
-					const parsedData = this.fpsData.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					console.log('modeVal--------1',parsedData)
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = this.total
-				}
-				console.log('animationData--------', this.animationData)
-				
-				// 判断this.fileList1[0].url里是否有 this.baseURL
-				if (this.fileList1[0].url.includes(this.baseURL)) {
-					this.fileList1[0].url = this.fileList1[0].url.replace(this.baseURL, "");
-				}
-				
-				console.log('url----',this.fileList1[0].url);
-				
-				// 判断如果有id就编辑
-				if(this.tId){
-					const putData = {
-						id: this.tId,
-						name: this.tempName,
-						userId: uni.getStorageSync('userId'),
-						screen: this.specVal, //屏幕
-						mode: this.modeVal,
-						cycle: this.total,
-						fpsTotal: this.fpsTotal, //总帧数
-						speed: this.speed, //速度
-						pic: this.fileList1[0].url,
-						fpsData: JSON.stringify(this.animationData),
-						fpsList: JSON.stringify(this.fpsList)
-					}
-					console.log('putData-----', putData)
-					templeteEdit(putData).then(res => {
-						console.log('编辑动画模版', res)
-						uni.hideLoading();
-						if (res.code == 200) {
-							uni.navigateBack({
-								delta: 1
-							});
-						} else {
-							uni.showToast({
-								title: res.msg,
-								duration: 1500,
-								icon: 'none',
-								mask: true
-							});
-						}
-					})
-				}
-				else{
-					const addData = {
-						name: this.tempName,
-						userId: uni.getStorageSync('userId'),
-						screen: this.specVal, //屏幕
-						mode: this.modeVal,
-						cycle: this.total,
-						fpsTotal: this.fpsTotal, //总帧数
-						speed: this.speed, //速度
-						pic: this.fileList1[0].url,
-						fpsData: JSON.stringify(this.animationData),
-						fpsList: JSON.stringify(this.fpsList)
-					}
-					console.log('addData-----', addData)
-					templeteAdd(addData).then(res => {
-						console.log('添加动画模版', res)
-						uni.hideLoading();
-						if (res.code == 200) {
-							uni.navigateBack({
-								delta: 1
-							});
-						} else {
-							uni.showToast({
-								title: res.msg,
-								duration: 1500,
-								icon: 'none',
-								mask: true
-							});
-						}
-					})
-				}
-				
-			},
-			// 保存动画
-			clickSaveData() {
-				
-				this.fpsList[this.fpsIndex] = this.pixelData;
-				
-				
-				
-				
-				this.$refs.popupAnimation.close();
-			},
-			changeColor() {
-				this.$refs.pickerColor.open();
-			},
-			clickColor(item) {
-				console.log('confirmColor---', item);
-				this.color = item;
-				this.$refs.pickerColor.close();
-			},
-			changeRatio() {
-				this.$refs.pickerRatio.open();
-			},
-			// 分辨率
-			confirmRatio(e) {
-				console.log('confirmRatio---', e.value[0]);
-				const ratio = e.value[0].split('*');
-				console.log('ratio---', ratio[0]);
-				this.height = Number(ratio[0]);
-				this.width = Number(ratio[1]);
-				this.canvasWidth = this.width * 10;
-				this.canvasHeight = this.height * 10;
-				// 重新初始化一维数组
-				this.pixelData = new Array(this.height * this.width).fill('')
-				console.log('pixelData---', this.pixelData);
-			},
-			// 预先获取像素网格的位置信息
-			getGridRect(cb) {
-				if (this.gridRect) {
-					cb(this.gridRect)
-				} else {
-					uni.createSelectorQuery().in(this).select('.pixel_grid').boundingClientRect(rect => {
-						this.gridRect = rect
-						cb(rect)
-					}).exec()
-				}
-			},
-			// 计算触摸点对应的格子
-			getCellByTouch(touch, cb) {
-				this.getGridRect(rect => {
-					if (!rect) return
-					const x = touch.clientX - rect.left
-					const y = touch.clientY - rect.top
-					const cellWidth = rect.width / this.width
-					const cellHeight = rect.height / this.height
-					const colIndex = Math.floor(x / cellWidth)
-					const rowIndex = Math.floor(y / cellHeight)
-					if (
-						colIndex >= 0 && colIndex < this.width &&
-						rowIndex >= 0 && rowIndex < this.height
-					) {
-						cb({
-							rowIndex,
-							colIndex
-						})
-					}
-				})
-			},
-			handleTouchStart(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-			
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					this.lastCell = cell
-					this.handleClick(cell.rowIndex, cell.colIndex)
-				})
-			},
-			handleTouchMove(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-			
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					// 只在格子变化时才触发
-					if (!this.lastCell || this.lastCell.rowIndex !== cell.rowIndex || this.lastCell.colIndex !==
-						cell.colIndex) {
-						this.lastCell = cell
-						this.handleClick(cell.rowIndex, cell.colIndex)
-					}
-				})
-			},
-			handleTouchEnd() {
-				this.lastCell = null
-			},
-			handleClick(rowIndex, colIndex) {
-				console.log(rowIndex, colIndex)
-				// 计算一维数组的索引
-				const index = rowIndex * this.width + colIndex
-				// 如果当前像素有颜色,则清除;如果没有颜色,则添加当前选择的颜色
-				const currentColor = this.pixelData[index]
-				const newColor = currentColor ? '' : this.color
-				this.$set(this.pixelData, index, newColor)
-			},
-			clear() {
-				ctx && ctx.clearRect(0, 0, 1000, 1000)
-				// 将所有像素点设置为空字符串
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 模版动画弹出框
-			changeAnimation(e){
-				//console.log('打开关闭模版动画弹窗触发---',e)
-				if(e.show){
-					if (typeof plus !== 'undefined') {
-						plus.screen.lockOrientation('landscape-primary')
-					}
-				}
-				else{
-					if (typeof plus !== 'undefined') {
-						plus.screen.lockOrientation('portrait')
-					}
-				}
-			},
-			// 打开模版动画
-			popupAnimationOpen(index){
-				this.$refs.popupAnimation.open();
-				this.fpsIndex = index
-				
-				if(this.fpsList[this.fpsIndex] == null){
-					console.log('第一次编辑-----null')
-					this.pixelData = new Array(this.height * this.width).fill('')
-				}else{
-					console.log('已编辑过-----')
-					this.pixelData = this.fpsList[this.fpsIndex]
-				}
-			},
-			// 关闭模版动画
-			popupAnimationClose(){
-				this.$refs.popupAnimation.close();
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 屏幕规格
-			changeSpec(e) {
-				const ratio = e.split('*');
-				this.specHeight = Number(ratio[0]);
-				this.specWidth = Number(ratio[1]);
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			// 生成一帧动画其他帧数据
-			generateFrames(data, frameCount = 24) {
-				const cols = this.specWidth; // 每行 24 个
-				const rows = this.specHeight; // 共 12 行
-				const frames = [];
-				// 拆分成 12 行
-				let grid = [];
-				for (let r = 0; r < rows; r++) {
-					grid.push(data.slice(r * cols, (r + 1) * cols));
-				}
-				// 生成帧
-				for (let f = 0; f < frameCount; f++) {
-					let frame = [];
-					// 每行左移 f 次
-					for (let r = 0; r < rows; r++) {
-						let row = grid[r].slice(); // 拷贝一行
-						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
-						frame = frame.concat(shifted);
-					}
-					frames.push(frame);
-				}
-				return frames;
-			},
-			
-			clickSpeed() {
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal() {
-				if (this.total != 1) {
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-				this.adjustFpsData()
-			},
-			changeMode(e) {
-				this.fpsList = []
-				this.fpsData = []
-				if (e == 0) {
-					this.total = 1
-				} else {
-					this.total = 2
-				}
-				this.adjustFpsData()
-			},
-			adjustFpsData() {
-				// 如果 fpsData 太长 → 截取
-				if (this.fpsList.length > this.total) {
-					this.fpsList = this.fpsList.slice(0, this.total);
-				}
-				// 如果 fpsData 太短 → 补齐 null
-				else if (this.fpsList.length < this.total) {
-					const missing = this.total - this.fpsList.length;
-					this.fpsList = this.fpsList.concat(new Array(missing).fill(null));
-				}
-				
-				// 如果 fpsList 太长 → 截取
-				if (this.fpsData.length > this.total) {
-					this.fpsData = this.fpsData.slice(0, this.total);
-				}
-				// 如果 fpsList 太短 → 补齐 null
-				else if (this.fpsData.length < this.total) {
-					const missing = this.total - this.fpsData.length;
-					this.fpsData = this.fpsData.concat(new Array(missing).fill(null));
-				}
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log('event---', event)
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					this.avatar = result
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: this.baseURL + '/common/uploadFileByAnny', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						success: (res) => {
-							console.log('图片-----', JSON.parse(res.data))
-							setTimeout(() => {
-								resolve(JSON.parse(res.data).fileName)
-							}, 1000)
-						}
-					});
-				})
-			},
-			// 生成点阵数据
-			generateDotMatrix(char) {
-				return new Promise((resolve, reject) => {
-			
-					// 使用 uni-app 的 canvas context
-					ctx = uni.createCanvasContext('myCanvas', this);
-			
-					// 设置字体样式
-					ctx.setFontSize(this.canvasHeight * 0.9);
-					ctx.setFillStyle('#000')
-					ctx.setTextAlign('center')
-					ctx.setTextBaseline('middle')
-					// 绘制文字
-					// 计算文字位置
-					// 水平居中
-					const x = this.canvasWidth / 2;
-					// 垂直居中,稍微向上偏移一点
-					const y = this.canvasHeight / 2;
-			
-					// 绘制文字
-					ctx.fillText(char, x, y);
-			
-					// 绘制到画布
-					ctx.draw(false, () => {
-						// 获取画布数据
-						uni.canvasGetImageData({
-							canvasId: 'myCanvas',
-							x: 0,
-							y: 0,
-							width: this.canvasWidth,
-							height: this.canvasHeight,
-							success: (res) => {
-								console.log(res)
-								const imageData = res.data;
-								// 生成一维数组
-								const pixelArray = new Array(this.height * this.width).fill('')
-			
-								// 计算每个格子的像素大小
-								const cellWidth = this.canvasWidth / this.width;
-								const cellHeight = this.canvasHeight / this.height;
-			
-								// 生成一维数组
-								for (let y = 0; y < this.height; y++) {
-									for (let x = 0; x < this.width; x++) {
-										let blackPixels = 0;
-										let totalPixels = 0;
-			
-										// 对每个格子进行采样
-										for (let py = 0; py < cellHeight; py++) {
-											for (let px = 0; px < cellWidth; px++) {
-												const pixelY = Math.floor(y * cellHeight + py);
-												const pixelX = Math.floor(x * cellWidth + px);
-			
-												const idx = (pixelY * this.canvasWidth + pixelX) * 4;
-												const r = imageData[idx];
-												const g = imageData[idx + 1];
-												const b = imageData[idx + 2];
-												const a = imageData[idx + 3];
-			
-												// 计算亮度
-												const brightness = 0.3 * r + 0.59 * g + 0.11 * b;
-			
-												// 如果亮度小于阈值且透明度大于阈值,则认为是黑色
-												if (brightness < 128 && a > 128) {
-													blackPixels++;
-												}
-												totalPixels++;
-											}
-										}
-			
-										// 如果黑色像素占比超过阈值,则设置为当前选择的颜色
-										const isBlack = blackPixels / totalPixels > 0.3;
-										const arrayIndex = y * this.width + x;
-										pixelArray[arrayIndex] = isBlack ? this.color : ''; // 改为颜色值或空字符串
-									}
-								}
-			
-								resolve(pixelArray);
-							},
-							fail: (err) => {
-								reject(err);
-							}
-						});
-					});
-				});
-			},
-			
-			// 修改添加文字方法
-			async addText() {
-				uni.showModal({
-					title: '添加文字',
-					content: '',
-					editable: true,
-					placeholderText: '请输入文字',
-					success: async (res) => {
-						if (res.confirm) {
-							const text = res.content;
-							if (text.length > 0) {
-								try {
-									// 生成点阵数据
-									const dotMatrix = await this.generateDotMatrix(text);
-									console.log('点阵数据:', dotMatrix);
-									this.pixelData = dotMatrix
-								} catch (error) {
-									console.error('生成点阵失败:', error);
-									uni.showToast({
-										title: '生成点阵失败',
-										icon: 'none'
-									});
-								}
-							} else {
-								uni.showToast({
-									title: '请输入文字',
-									icon: 'none'
-								});
-							}
-						}
-					}
-				});
-			},
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	page {
-	  -webkit-text-size-adjust: 100%;
-	  text-size-adjust: 100%;
-	}
-	.item_pic_btn{
-		width: 200rpx;
-		height: 200rpx;
-		background: #eee;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		margin-bottom: 15rpx;
-	}
-	.color_list {
-		width: 100%;
-		display: flex;
-		justify-content: center;
-		flex-wrap: wrap;
-		gap: 30rpx;
-		box-sizing: border-box;
-		padding: 50rpx;
-	
-		.color_item {
-			width: 30rpx;
-			height: 30rpx;
-			border-radius: 5rpx;
-		}
-	}
-	
-	.controls {
-		position: absolute;
-		bottom: 10px;
-		left: 50px;
-		display: flex;
-		gap: 20px;
-		z-index: 9;
-	}
-	.animation_pixel{
-		width: 100vw;
-		height: 100vh;
-		position: relative;
-		.back_btn{
-			position: absolute;
-			left: 30px;
-			top: 20px;
-			z-index: 9999;
-		}
-		.canvas {
-			margin: 100rpx auto 0;
-			background: #ccc;
-			position: absolute;
-			z-index: 1;
-			left: -9999px;
-			top: -9999px;
-		}
-		.pixel_grid {
-			position: fixed;
-			left: 0;
-			top: var(--status-bar-height);
-			right: 0;
-			bottom: 0;
-			display: grid;
-			gap: 1px;
-			box-sizing: border-box;
-			background: #eee;
-			touch-action: none;
-			-webkit-touch-callout: none;
-			-webkit-user-select: none;
-			user-select: none;
-		
-			.pixel_cell {
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				box-sizing: border-box;
-				background: #fff;
-		
-				.pixel_cell_item {
-					width: 50%;
-					height: 50%;
-					aspect-ratio: 1/1;
-					font-size: 10rpx;
-				}
-			}
-		}
-		
-	}
-	// -------------
-	.footer_none {
-		height: 200rpx;
-	}
-
-	.footer_btn {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-	}
-	.footer_btn2 {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
-	}
-
-	.temp_btn {
-		position: fixed;
-		left: 30rpx;
-		bottom: 60rpx;
-		right: 30rpx;
-		box-sizing: border-box;
-		height: 96rpx;
-		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
-		border-radius: 385rpx 385rpx 385rpx 385rpx;
-		font-size: 30rpx;
-		color: #FFFFFF;
-		line-height: 96rpx;
-		text-align: center;
-	}
-
-	.spec_radio {
-		margin-top: 30rpx;
-
-		&:first-child {
-			margin-top: 10rpx;
-		}
-	}
-
-	.temp {
-		padding: 0 30rpx;
-
-		.temp_item1 {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-
-			}
-
-			.item {}
-		}
-
-		.temp_item {
-			display: flex;
-			align-items: flex-start;
-			justify-content: flex-start;
-			flex-direction: column;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-			}
-
-			.item {
-				margin-top: 20rpx;
-				width: 100%;
-				&.item_pic {
-					margin-top: 25rpx;
-				}
-			}
-		}
-	}
-
-	.page_bg {
-		width: 100%;
-		min-height: calc(100vh - var(--window-bottom));
-		background: url('/static/img/bg_2.jpg') no-repeat center top;
-		background-size: 100% auto;
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/addTemplate/addTemplate copy 4.vue b/ledApp/pages/addTemplate/addTemplate copy 4.vue
deleted file mode 100644
index dc6ca6d..0000000
--- a/ledApp/pages/addTemplate/addTemplate copy 4.vue
+++ /dev/null
@@ -1,1056 +0,0 @@
-<template>
-	<view class="page_bg">
-		
-		<uv-navbar :title="titleName" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="rgba(0,0,0,0)" titleStyle="color:#fff"></uv-navbar>
-		
-		<view class="temp">
-			<view class="temp_item">
-				<view class="title">
-					模版名称
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入名称" border="none" v-model="tempName" fontSize="27rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					封面图片
-				</view>
-				<view class="item item_pic">
-					<uv-upload :fileList="fileList1" name="1" :maxCount="1" width="200rpx" height="200rpx"
-						:previewFullImage="false" @afterRead="afterRead" @delete="deletePic">
-						<!-- <image v-if="fileList1.length != 0"
-							:src="baseURL + fileList1[0]?.url" 
-							mode="aspectFill" 
-							style="width: 200rpx;height: 200rpx;"
-						></image>
-						<view class="item_pic_btn" v-else>
-							<uv-icon name="camera-fill" color="#ccc" size="60rpx"></uv-icon>
-						</view> -->
-					</uv-upload>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					屏幕规格
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="specVal" placement="column" @change="changeSpec">
-						<uv-radio class="spec_radio" v-for="(item, index) in specList" :key="index" :label="item.name"
-							:name="item.name">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画方式
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="modeVal" placement="column" @change="changeMode">
-						<uv-radio class="spec_radio" v-for="(item, index) in modeList" :key="index" :label="item.name"
-							:name="item.val">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-
-			<view class="temp_item">
-				<view class="title">
-					动画帧数
-				</view>
-				<view class="item" @click="clickTotal">
-					<uv-input placeholder="请输入" readonly border="none" v-model="total" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画速度
-				</view>
-				<view class="item" @click="clickSpeed">
-					<uv-input placeholder="请输入" readonly border="none" v-model="speed" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx"
-						customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<!-- <view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					循环次数
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入" readonly border="none" v-model="cycle" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view> -->
-			<view class="temp_item1" v-for="(item,index) in total" :key="index">
-				<view class="title">
-					动画第{{item}}帧
-				</view>
-				<view class="item">
-					<uv-button text="编辑" @click="popupAnimationOpen(index)" shape="circle" size="small" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)"></uv-button>
-				</view>
-			</view>
-		</view>
-
-		<view class="footer_none"></view>
-		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" @click="clickTempleteAdd()"></uv-button>
-		</view>
-
-		<!-- 动画帧数 -->
-		<uv-picker ref="pickerTotal" :columns="columnsTotal" @confirm="confirmTotal"></uv-picker>
-
-		<!-- 动画速度 -->
-		<uv-picker ref="pickerSpeed" :columns="columnsSpeed" @confirm="confirmSpeed"></uv-picker>
-		
-		<!-- 动画弹出框 -->
-		<uv-popup ref="popupAnimation" mode="center" @change="changeAnimation" :safeAreaInsetTop="false" :safeAreaInsetBottom="false" :zoom="false" duration="0">
-			<view class="animation_pixel">
-				<view class="back_btn" @click="popupAnimationClose">
-					<uv-icon name="arrow-leftward" color="#333" size="30"></uv-icon>
-				</view>
-				<!-- 动画按钮 -->
-				<view class="controls">
-					<uv-button type="primary" :plain="true" text="分辨率" @click="changeRatio()"></uv-button>
-					<uv-button type="primary" :plain="true" text="颜色" @click="changeColor()"></uv-button>
-					<uv-button type="primary" :plain="true" text="添加文字" @click="addText()"></uv-button>
-					<uv-button type="primary" :plain="true" text="清除" @click="clear()"></uv-button>
-					<uv-button type="primary" :plain="true" text="保存" @click="clickSaveData"></uv-button>
-				</view>
-				
-				<!-- 文字生成图形 -->
-				<canvas canvas-id="myCanvas" id="myCanvas" class="canvas" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
-
-				<view class="pixel_grid" @touchstart.prevent="handleTouchStart" @touchmove.prevent="handleTouchMove"
-					@touchend.prevent="handleTouchEnd" @touchcancel.prevent="handleTouchEnd" 
-					:style="{
-						gridTemplateRows: `repeat(${height}, 1fr)`,
-						gridTemplateColumns: `repeat(${width}, 1fr)`
-					}">
-					<view class="pixel_cell" v-for="(cell, cellIndex) in pixelData" :key="cellIndex">
-						<view class="pixel_cell_item" :style="{ backgroundColor: cell }"></view>
-					</view>
-				</view>
-			</view>
-		</uv-popup>
-		
-		<!-- 分辨率 -->
-		<uv-picker ref="pickerRatio" :columns="columnsRatio" @confirm="confirmRatio"></uv-picker>
-		
-		<!-- 颜色 -->
-		<uv-popup ref="pickerColor" mode="bottom" round="10" :closeable="true">
-			<view class="color_list">
-				<view class="color_item" v-for="(item, index) in colorList" :class="{ hover: color === item }" :key="index" :style="{ backgroundColor: item }" @click="clickColor(item)"></view>
-			</view>
-		</uv-popup>
-		
-	</view>
-</template>
-
-<script>
-	import {
-		templeteAdd,
-		templeteInfo,
-		templeteEdit
-	} from '@/api/api.js'
-	let ctx = null
-	export default {
-		data() {
-			return {
-				tempName: '',
-				pic: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				specWidth: 24,
-				specHeight: 12,
-				modeList: [{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-						28, 29, 30
-					]
-				],
-				total: 1, //动画总帧数
-				columnsSpeed: [
-					[10, 20, 30, 40, 50, 60, 70, 80, 90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1, //第几帧
-				fpsIds: [],
-
-				baseURL: '',
-				fileList1: [],
-				animationData: [],
-				fpsTotal: 1,
-				
-				
-				
-				// 模版动画
-				pixelData: [],
-				canvasData: [],
-				canvasWidth: 240,
-				canvasHeight: 120,
-				width: 24,
-				height: 12,
-				color: '#FF0000',
-				gridRect: null, // 存储像素网格的位置信息
-				lastCell: null, // 防止重复绘制
-				columnsRatio: [
-					['12*24', '16*32', '24*48', '32*64', '40*80']
-				],
-				// columnsRatio: [
-				// 	['12*24']
-				// ],
-				colorList: [
-					'#FF0000',
-					'#00FF00',
-					'#0000FF',
-					'#FFFF00',
-					'#FFA500',
-					'#800080',
-					'#00FFFF',
-					'#FFC0CB'
-				],
-				fpsIndex: 0,
-				fpsList: [],
-				tId: '',
-				tempInfo:{},
-				titleName: '新增模版'
-				
-			}
-		},
-		onLoad(opt) {
-			this.baseURL = uni.$uv.http.config.baseURL
-			if(opt.id){
-				this.tId = opt.id
-				this.getTempleteInfo()
-				this.titleName = '编辑模版'
-			}
-			else{
-				this.titleName = '新增模版'
-			}
-		},
-		onShow() {
-			
-		},
-		onHide() {
-			this.$refs.popupAnimation.close();
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		onUnload() {
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		methods: {
-			// 获取编辑详情
-			getTempleteInfo(){
-				templeteInfo(this.tId).then(res=>{
-					console.log('获取编辑详情-------',res)
-					if(res.code == 200){
-						this.tempInfo = res.data
-						this.tempName = this.tempInfo.name
-						this.fileList1.push({
-							url: this.baseURL + this.tempInfo.pic
-						})
-						
-						this.specVal = this.tempInfo.screen
-						this.modeVal = this.tempInfo.mode
-						
-						this.total = this.tempInfo.cycle
-						this.fpsTotal = this.tempInfo.fpsTotal
-						this.speed = this.tempInfo.speed
-						
-						this.fpsList = JSON.parse(this.tempInfo.fpsList)
-						
-					}
-					else{
-						uni.showToast({
-							title: res.msg,
-							duration: 2000,
-							icon: 'none'
-						});
-					}
-				})
-			},
-			// 添加模版提交接口
-			clickTempleteAdd() {
-				
-				if (!this.tempName) {
-					uni.showToast({
-						title: '请输入模版名称',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if (this.fileList1.length == 0) {
-					uni.showToast({
-						title: '请上传封面图片',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				
-				if (this.fpsList.length == 0) {
-					uni.showToast({
-						title: '请编辑动画帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				} else {
-					for (let i = 0; i < this.fpsList.length; i++) {
-					    if (this.fpsList[i] === null) {
-							uni.showToast({
-								title: `请编辑第 ${i+1} 个动画帧`,
-								duration: 2000,
-								icon: 'none'
-							});
-							return
-					    }
-					}
-				}
-				console.log('this.fpsList=========',this.fpsList)
-				
-				uni.showLoading({
-					title: '添加中',
-					mask: true
-				});
-				
-				
-				// 遍历二维数组
-				this.fpsData = this.fpsList.map(inner =>
-				  inner.map(item => {
-				    if (item === "") {
-				      return "000000"; // 空的改成000000
-				    } else if (item.includes("#")) {
-				      return item.replace("#", ""); // 去掉#
-				    } else {
-				      return item; // 保持原样
-				    }
-				  })
-				);
-				
-				console.log('this.fpsData=========',this.fpsData)
-				
-				// 动画方式
-				if (this.modeVal == 0) { //一帧动画
-					let frames = this.generateFrames(this.fpsData[0], 24);
-					const parsedData = frames.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = 24
-				} else if (this.modeVal == 1) {
-					console.log('modeVal--------1')
-					const parsedData = this.fpsData.map(item => {
-						return this.toSnakeData(item, this.specWidth)
-					});
-					console.log('modeVal--------1',parsedData)
-					this.animationData = parsedData.map(item => {
-						return this.mergeRowsToString(item)
-					});
-					this.fpsTotal = this.total
-				}
-				console.log('animationData--------', this.animationData)
-				
-				// 判断this.fileList1[0].url里是否有 this.baseURL
-				if (this.fileList1[0].url.includes(this.baseURL)) {
-					this.fileList1[0].url = this.fileList1[0].url.replace(this.baseURL, "");
-				}
-				
-				console.log('url----',this.fileList1[0].url);
-				
-				// 判断如果有id就编辑
-				if(this.tId){
-					const putData = {
-						id: this.tId,
-						name: this.tempName,
-						userId: uni.getStorageSync('userId'),
-						screen: this.specVal, //屏幕
-						mode: this.modeVal,
-						cycle: this.total,
-						fpsTotal: this.fpsTotal, //总帧数
-						speed: this.speed, //速度
-						pic: this.fileList1[0].url,
-						fpsData: JSON.stringify(this.animationData),
-						fpsList: JSON.stringify(this.fpsList)
-					}
-					console.log('putData-----', putData)
-					templeteEdit(putData).then(res => {
-						console.log('编辑动画模版', res)
-						uni.hideLoading();
-						if (res.code == 200) {
-							uni.navigateBack({
-								delta: 1
-							});
-						} else {
-							uni.showToast({
-								title: res.msg,
-								duration: 1500,
-								icon: 'none',
-								mask: true
-							});
-						}
-					})
-				}
-				else{
-					const addData = {
-						name: this.tempName,
-						userId: uni.getStorageSync('userId'),
-						screen: this.specVal, //屏幕
-						mode: this.modeVal,
-						cycle: this.total,
-						fpsTotal: this.fpsTotal, //总帧数
-						speed: this.speed, //速度
-						pic: this.fileList1[0].url,
-						fpsData: JSON.stringify(this.animationData),
-						fpsList: JSON.stringify(this.fpsList)
-					}
-					console.log('addData-----', addData)
-					templeteAdd(addData).then(res => {
-						console.log('添加动画模版', res)
-						uni.hideLoading();
-						if (res.code == 200) {
-							uni.navigateBack({
-								delta: 1
-							});
-						} else {
-							uni.showToast({
-								title: res.msg,
-								duration: 1500,
-								icon: 'none',
-								mask: true
-							});
-						}
-					})
-				}
-				
-			},
-			// 保存动画
-			clickSaveData() {
-				
-				this.fpsList[this.fpsIndex] = this.pixelData;
-				
-				
-				
-				
-				this.$refs.popupAnimation.close();
-			},
-			changeColor() {
-				this.$refs.pickerColor.open();
-			},
-			clickColor(item) {
-				console.log('confirmColor---', item);
-				this.color = item;
-				this.$refs.pickerColor.close();
-			},
-			changeRatio() {
-				this.$refs.pickerRatio.open();
-			},
-			// 分辨率
-			confirmRatio(e) {
-				console.log('confirmRatio---', e.value[0]);
-				const ratio = e.value[0].split('*');
-				console.log('ratio---', ratio[0]);
-				this.height = Number(ratio[0]);
-				this.width = Number(ratio[1]);
-				this.canvasWidth = this.width * 10;
-				this.canvasHeight = this.height * 10;
-				// 重新初始化一维数组
-				this.pixelData = new Array(this.height * this.width).fill('')
-				console.log('pixelData---', this.pixelData);
-			},
-			// 预先获取像素网格的位置信息
-			getGridRect(cb) {
-				if (this.gridRect) {
-					cb(this.gridRect)
-				} else {
-					uni.createSelectorQuery().in(this).select('.pixel_grid').boundingClientRect(rect => {
-						this.gridRect = rect
-						cb(rect)
-					}).exec()
-				}
-			},
-			// 计算触摸点对应的格子
-			getCellByTouch(touch, cb) {
-				this.getGridRect(rect => {
-					if (!rect) return
-					const x = touch.clientX - rect.left
-					const y = touch.clientY - rect.top
-					const cellWidth = rect.width / this.width
-					const cellHeight = rect.height / this.height
-					const colIndex = Math.floor(x / cellWidth)
-					const rowIndex = Math.floor(y / cellHeight)
-					if (
-						colIndex >= 0 && colIndex < this.width &&
-						rowIndex >= 0 && rowIndex < this.height
-					) {
-						cb({
-							rowIndex,
-							colIndex
-						})
-					}
-				})
-			},
-			handleTouchStart(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-			
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					this.lastCell = cell
-					this.handleClick(cell.rowIndex, cell.colIndex)
-				})
-			},
-			handleTouchMove(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-			
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					// 只在格子变化时才触发
-					if (!this.lastCell || this.lastCell.rowIndex !== cell.rowIndex || this.lastCell.colIndex !==
-						cell.colIndex) {
-						this.lastCell = cell
-						this.handleClick(cell.rowIndex, cell.colIndex)
-					}
-				})
-			},
-			handleTouchEnd() {
-				this.lastCell = null
-			},
-			handleClick(rowIndex, colIndex) {
-				console.log(rowIndex, colIndex)
-				// 计算一维数组的索引
-				const index = rowIndex * this.width + colIndex
-				// 如果当前像素有颜色,则清除;如果没有颜色,则添加当前选择的颜色
-				const currentColor = this.pixelData[index]
-				const newColor = currentColor ? '' : this.color
-				this.$set(this.pixelData, index, newColor)
-			},
-			clear() {
-				ctx && ctx.clearRect(0, 0, 1000, 1000)
-				// 将所有像素点设置为空字符串
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 模版动画弹出框
-			changeAnimation(e){
-				//console.log('打开关闭模版动画弹窗触发---',e)
-				if(e.show){
-					if (typeof plus !== 'undefined') {
-						plus.screen.lockOrientation('landscape-primary')
-					}
-				}
-				else{
-					if (typeof plus !== 'undefined') {
-						plus.screen.lockOrientation('portrait')
-					}
-				}
-			},
-			// 打开模版动画
-			popupAnimationOpen(index){
-				this.$refs.popupAnimation.open();
-				this.fpsIndex = index
-				
-				if(this.fpsList[this.fpsIndex] == null){
-					console.log('第一次编辑-----null')
-					this.pixelData = new Array(this.height * this.width).fill('')
-				}else{
-					console.log('已编辑过-----')
-					this.pixelData = this.fpsList[this.fpsIndex]
-				}
-			},
-			// 关闭模版动画
-			popupAnimationClose(){
-				this.$refs.popupAnimation.close();
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 屏幕规格
-			changeSpec(e) {
-				const ratio = e.split('*');
-				this.specHeight = Number(ratio[0]);
-				this.specWidth = Number(ratio[1]);
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			// 生成一帧动画其他帧数据
-			generateFrames(data, frameCount = 24) {
-				const cols = this.specWidth; // 每行 24 个
-				const rows = this.specHeight; // 共 12 行
-				const frames = [];
-				// 拆分成 12 行
-				let grid = [];
-				for (let r = 0; r < rows; r++) {
-					grid.push(data.slice(r * cols, (r + 1) * cols));
-				}
-				// 生成帧
-				for (let f = 0; f < frameCount; f++) {
-					let frame = [];
-					// 每行左移 f 次
-					for (let r = 0; r < rows; r++) {
-						let row = grid[r].slice(); // 拷贝一行
-						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
-						frame = frame.concat(shifted);
-					}
-					frames.push(frame);
-				}
-				return frames;
-			},
-			
-			clickSpeed() {
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal() {
-				if (this.total != 1) {
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-				this.adjustFpsData()
-			},
-			changeMode(e) {
-				this.fpsList = []
-				this.fpsData = []
-				if (e == 0) {
-					this.total = 1
-				} else {
-					this.total = 2
-				}
-				this.adjustFpsData()
-			},
-			adjustFpsData() {
-				// 如果 fpsData 太长 → 截取
-				if (this.fpsList.length > this.total) {
-					this.fpsList = this.fpsList.slice(0, this.total);
-				}
-				// 如果 fpsData 太短 → 补齐 null
-				else if (this.fpsList.length < this.total) {
-					const missing = this.total - this.fpsList.length;
-					this.fpsList = this.fpsList.concat(new Array(missing).fill(null));
-				}
-				
-				// 如果 fpsList 太长 → 截取
-				if (this.fpsData.length > this.total) {
-					this.fpsData = this.fpsData.slice(0, this.total);
-				}
-				// 如果 fpsList 太短 → 补齐 null
-				else if (this.fpsData.length < this.total) {
-					const missing = this.total - this.fpsData.length;
-					this.fpsData = this.fpsData.concat(new Array(missing).fill(null));
-				}
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log('event---', event)
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					this.avatar = result
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: this.baseURL + '/common/uploadFileByAnny', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						success: (res) => {
-							console.log('图片-----', JSON.parse(res.data))
-							setTimeout(() => {
-								resolve(JSON.parse(res.data).fileName)
-							}, 1000)
-						}
-					});
-				})
-			},
-			// 生成点阵数据
-			generateDotMatrix(char) {
-				return new Promise((resolve, reject) => {
-			
-					// 使用 uni-app 的 canvas context
-					ctx = uni.createCanvasContext('myCanvas', this);
-			
-					// 设置字体样式
-					ctx.setFontSize(this.canvasHeight * 0.9);
-					ctx.setFillStyle('#000')
-					ctx.setTextAlign('center')
-					ctx.setTextBaseline('middle')
-					// 绘制文字
-					// 计算文字位置
-					// 水平居中
-					const x = this.canvasWidth / 2;
-					// 垂直居中,稍微向上偏移一点
-					const y = this.canvasHeight / 2;
-			
-					// 绘制文字
-					ctx.fillText(char, x, y);
-			
-					// 绘制到画布
-					ctx.draw(false, () => {
-						// 获取画布数据
-						uni.canvasGetImageData({
-							canvasId: 'myCanvas',
-							x: 0,
-							y: 0,
-							width: this.canvasWidth,
-							height: this.canvasHeight,
-							success: (res) => {
-								console.log(res)
-								const imageData = res.data;
-								// 生成一维数组
-								const pixelArray = new Array(this.height * this.width).fill('')
-			
-								// 计算每个格子的像素大小
-								const cellWidth = this.canvasWidth / this.width;
-								const cellHeight = this.canvasHeight / this.height;
-			
-								// 生成一维数组
-								for (let y = 0; y < this.height; y++) {
-									for (let x = 0; x < this.width; x++) {
-										let blackPixels = 0;
-										let totalPixels = 0;
-			
-										// 对每个格子进行采样
-										for (let py = 0; py < cellHeight; py++) {
-											for (let px = 0; px < cellWidth; px++) {
-												const pixelY = Math.floor(y * cellHeight + py);
-												const pixelX = Math.floor(x * cellWidth + px);
-			
-												const idx = (pixelY * this.canvasWidth + pixelX) * 4;
-												const r = imageData[idx];
-												const g = imageData[idx + 1];
-												const b = imageData[idx + 2];
-												const a = imageData[idx + 3];
-			
-												// 计算亮度
-												const brightness = 0.3 * r + 0.59 * g + 0.11 * b;
-			
-												// 如果亮度小于阈值且透明度大于阈值,则认为是黑色
-												if (brightness < 128 && a > 128) {
-													blackPixels++;
-												}
-												totalPixels++;
-											}
-										}
-			
-										// 如果黑色像素占比超过阈值,则设置为当前选择的颜色
-										const isBlack = blackPixels / totalPixels > 0.3;
-										const arrayIndex = y * this.width + x;
-										pixelArray[arrayIndex] = isBlack ? this.color : ''; // 改为颜色值或空字符串
-									}
-								}
-			
-								resolve(pixelArray);
-							},
-							fail: (err) => {
-								reject(err);
-							}
-						});
-					});
-				});
-			},
-			
-			// 修改添加文字方法
-			async addText() {
-				uni.showModal({
-					title: '添加文字',
-					content: '',
-					editable: true,
-					placeholderText: '请输入文字',
-					success: async (res) => {
-						if (res.confirm) {
-							const text = res.content;
-							if (text.length > 0) {
-								try {
-									// 生成点阵数据
-									const dotMatrix = await this.generateDotMatrix(text);
-									console.log('点阵数据:', dotMatrix);
-									this.pixelData = dotMatrix
-								} catch (error) {
-									console.error('生成点阵失败:', error);
-									uni.showToast({
-										title: '生成点阵失败',
-										icon: 'none'
-									});
-								}
-							} else {
-								uni.showToast({
-									title: '请输入文字',
-									icon: 'none'
-								});
-							}
-						}
-					}
-				});
-			},
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	page {
-	  -webkit-text-size-adjust: 100%;
-	  text-size-adjust: 100%;
-	}
-	.item_pic_btn{
-		width: 200rpx;
-		height: 200rpx;
-		background: #eee;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		margin-bottom: 15rpx;
-	}
-	.color_list {
-		width: 100%;
-		display: flex;
-		justify-content: center;
-		flex-wrap: wrap;
-		gap: 30rpx;
-		box-sizing: border-box;
-		padding: 50rpx;
-	
-		.color_item {
-			width: 30rpx;
-			height: 30rpx;
-			border-radius: 5rpx;
-		}
-	}
-	
-	.controls {
-		position: absolute;
-		bottom: 10px;
-		left: 50px;
-		display: flex;
-		gap: 20px;
-		z-index: 9;
-	}
-	.animation_pixel{
-		width: 100vw;
-		height: 100vh;
-		position: relative;
-		.back_btn{
-			position: absolute;
-			left: 30px;
-			top: 20px;
-			z-index: 9999;
-		}
-		.canvas {
-			margin: 100rpx auto 0;
-			background: #ccc;
-			position: absolute;
-			z-index: 1;
-			left: -9999px;
-			top: -9999px;
-		}
-		.pixel_grid {
-			position: fixed;
-			left: 0;
-			top: var(--status-bar-height);
-			right: 0;
-			bottom: 0;
-			display: grid;
-			gap: 1px;
-			box-sizing: border-box;
-			background: #eee;
-			touch-action: none;
-			-webkit-touch-callout: none;
-			-webkit-user-select: none;
-			user-select: none;
-		
-			.pixel_cell {
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				box-sizing: border-box;
-				background: #fff;
-		
-				.pixel_cell_item {
-					width: 50%;
-					height: 50%;
-					aspect-ratio: 1/1;
-					font-size: 10rpx;
-				}
-			}
-		}
-		
-	}
-	// -------------
-	.footer_none {
-		height: 200rpx;
-	}
-
-	.footer_btn {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-	}
-	.footer_btn2 {
-		position: fixed;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
-	}
-
-	.temp_btn {
-		position: fixed;
-		left: 30rpx;
-		bottom: 60rpx;
-		right: 30rpx;
-		box-sizing: border-box;
-		height: 96rpx;
-		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
-		border-radius: 385rpx 385rpx 385rpx 385rpx;
-		font-size: 30rpx;
-		color: #FFFFFF;
-		line-height: 96rpx;
-		text-align: center;
-	}
-
-	.spec_radio {
-		margin-top: 30rpx;
-
-		&:first-child {
-			margin-top: 10rpx;
-		}
-	}
-
-	.temp {
-		padding: 0 30rpx;
-
-		.temp_item1 {
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-
-			}
-
-			.item {}
-		}
-
-		.temp_item {
-			display: flex;
-			align-items: flex-start;
-			justify-content: flex-start;
-			flex-direction: column;
-			background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0.5) 100%);
-			box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67, 147, 248, 0.1), -8rpx -8rpx 23rpx 0rpx rgba(255, 255, 255, 0.4);
-			border-radius: 23rpx 23rpx 23rpx 23rpx;
-			border: 2rpx solid #FFFFFF;
-			padding: 30rpx;
-			box-sizing: border-box;
-			margin-top: 24rpx;
-
-			.title {
-				flex-shrink: 0;
-				font-size: 30rpx;
-				color: rgba(0, 0, 0, 0.9);
-				line-height: 40rpx;
-			}
-
-			.item {
-				margin-top: 20rpx;
-				width: 100%;
-				&.item_pic {
-					margin-top: 25rpx;
-				}
-			}
-		}
-	}
-
-	.page_bg {
-		width: 100%;
-		min-height: calc(100vh - var(--window-bottom));
-		background: url('/static/img/bg_2.jpg') no-repeat center top;
-		background-size: 100% auto;
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/addTemplate/addTemplate copy.vue b/ledApp/pages/addTemplate/addTemplate copy.vue
deleted file mode 100644
index 5778ff6..0000000
--- a/ledApp/pages/addTemplate/addTemplate copy.vue
+++ /dev/null
@@ -1,348 +0,0 @@
-<template>
-	<view class="page_bg">
-		<uv-navbar title="新增模版" :autoBack="true" :placeholder="true" leftIconColor="#fff" bgColor="rgba(0,0,0,0)" titleStyle="color:#fff"></uv-navbar>
-		
-		<view class="temp">
-			<view class="temp_item">
-				<view class="title">
-					模版名称
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入名称" border="none" v-model="tempName" fontSize="27rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					屏幕规格
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="specVal" placement="column">
-						<uv-radio 
-							class="spec_radio"
-							v-for="(item, index) in specList" 
-							:key="index" 
-							:label="item.name" 
-							:name="item.name">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-			<view class="temp_item">
-				<view class="title">
-					动画方式
-				</view>
-				<view class="item">
-					<uv-radio-group v-model="modeVal" placement="column"  @change="changeMode">
-						<uv-radio 
-							class="spec_radio"
-							v-for="(item, index) in modeList" 
-							:key="index" 
-							:label="item.name" 
-							:name="item.val">
-						</uv-radio>
-					</uv-radio-group>
-				</view>
-			</view>
-
-			<view class="temp_item">
-				<view class="title">
-					动画帧数
-				</view>
-				<view class="item" @click="clickTotal">
-					<uv-input placeholder="请输入" readonly border="none" v-model="total" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					动画速度
-				</view>
-				<view class="item" @click="clickSpeed">
-					<uv-input placeholder="请输入" readonly border="none" v-model="speed" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view>
-			<!-- <view class="temp_item" v-if="modeVal == 1">
-				<view class="title">
-					循环次数
-				</view>
-				<view class="item">
-					<uv-input placeholder="请输入" readonly border="none" v-model="cycle" suffixIcon="arrow-right"
-						suffixIconStyle="color: #bbb" fontSize="26rpx" customStyle="background: #ECEFF6;padding:18rpx 20rpx;border-radius: 10rpx;"></uv-input>
-				</view>
-			</view> -->
-			
-			<view class="temp_item1" v-for="(item,index) in total" :key="index">
-				<view class="title">
-					动画第{{item}}帧
-				</view>
-				<view class="item">
-					<uv-button text="编辑" @click="clickGoAnim(item)" shape="circle" size="small" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)"></uv-button>
-				</view>
-			</view>
-
-		</view>
-		
-		
-		<!-- <view class="temp_btn" @click="clickGoAnim">
-			编辑动画
-		</view> -->
-		
-		<view class="footer_none"></view>
-		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" @click="clickTempleteAdd()"></uv-button>
-		</view>
-		
-		<!-- 动画帧数 -->
-		<uv-picker ref="pickerTotal" :columns="columnsTotal" @confirm="confirmTotal"></uv-picker>
-		
-		<!-- 动画速度 -->
-		<uv-picker ref="pickerSpeed" :columns="columnsSpeed" @confirm="confirmSpeed"></uv-picker>
-		
-	</view>
-</template>
-
-<script>
-	import { templeteAdd } from '@/api/api.js'
-	export default {
-		data() {
-			return {
-				tempName: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				modeList: [
-					{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2,3,4,5,6,7,8,9]
-				],
-				total: 1,
-				columnsSpeed: [
-					[10,20,30,40,50,60,70,80,90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1,
-				fpsIds: []
-			}
-		},
-		onLoad() {
-
-		},
-		onShow() {
-			console.log('------onShow')
-			const fpsParams = uni.getStorageSync('fpsParams');
-			// if (fpsParams) {
-			// 	console.log('收到回传参数:', fpsParams);
-			// 	this.fpsIndex = fpsParams.fpsIndex+1
-			// 	this.fpsData[fpsParams.fpsIndex] = fpsParams.data;
-			// 	this.fpsIds.push(fpsParams.fpsIndex)
-			// 	console.log(this.fpsIndex, this.fpsData);
-			// 	uni.removeStorageSync('fpsParams'); // 清理掉
-			// }
-			if (fpsParams) {
-			    console.log('收到回传参数:', fpsParams);
-			    // 用 splice 代替下标赋值
-				this.fpsIndex = fpsParams.fpsIndex+1
-			    this.fpsData.splice(fpsParams.fpsIndex, 1, fpsParams.data);
-				
-			    if (!this.fpsIds.includes(fpsParams.fpsIndex + 1)) {
-					this.fpsIds.push(fpsParams.fpsIndex + 1);
-			    }
-			    console.log(this.fpsIndex, this.fpsData);
-			    uni.removeStorageSync('fpsParams'); // 清理掉
-			}
-		},
-		methods: {
-			clickTempleteAdd(){
-				if(!this.tempName){
-					uni.showToast({
-						title: '请输入模版名称',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				if(this.fpsIds.length == 0){
-					uni.showToast({
-						title: '请编辑动画帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				let totalArr = new Array(this.total).fill(0).map((_, i) => i + 1);
-				let diffBA = totalArr.filter(v => !this.fpsIds.includes(v));
-				console.log(totalArr, diffBA)
-				if(diffBA.length != 0){
-					uni.showToast({
-						title: '请编辑第'+ Math.min(...diffBA) +'帧',
-						duration: 2000,
-						icon: 'none'
-					});
-					return
-				}
-				
-				templeteAdd({
-					name: this.tempName,
-					userId: uni.getStorageSync('userId'),
-					screen: this.specVal, //屏幕
-					fpsTotal: this.total, //总帧数
-					speed: this.speed, //速度
-					
-					fpsData: JSON.stringify(this.fpsData)
-				}).then(res=>{
-					console.log('添加动画模版',res)
-					uni.showToast({
-						title: res.msg,
-						duration: 2000,
-						icon: 'none'
-					});
-					if(res.code == 200){
-						uni.navigateBack({
-							delta: 1
-						});
-					}
-				})
-			},
-			clickSpeed(){
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal(){
-				if(this.total != 1){
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-			},
-			changeMode(e){
-				if(e == 0){
-					this.total = 1
-				}
-				else{
-					this.total = 2
-				}
-				this.fpsIndex = 1
-				this.fpsData = []
-			},
-			clickGoAnim(index){
-				console.log(this.fpsIndex, index)
-				// if(this.fpsIndex > index){
-				// 	uni.showToast({
-				// 		title: '请先编辑第'+this.fpsIndex+'帧',
-				// 		duration: 2000,
-				// 		icon: 'none'
-				// 	});
-				// 	return
-				// }
-				uni.navigateTo({
-					url: '/pages/animation/animation?fps='+index
-				})
-			}
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-.footer_none{
-	height: 200rpx;
-}
-.footer_btn{
-	position: fixed;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	background: #fff;
-	padding:30rpx 40rpx;
-}
-.temp_btn{
-	position: fixed;
-	left: 30rpx;
-	bottom: 60rpx;
-	right: 30rpx;
-	box-sizing: border-box;
-	height: 96rpx;
-	background: linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%);
-	border-radius: 385rpx 385rpx 385rpx 385rpx;
-	font-size: 30rpx;
-	color: #FFFFFF;
-	line-height: 96rpx;
-	text-align: center;
-}
-.spec_radio{
-	margin-top: 30rpx;
-	&:first-child{
-		margin-top: 10rpx;
-	}
-}
-.temp{
-	padding:0 30rpx;
-	.temp_item1{
-		display: flex;
-		align-items: center;
-		justify-content: space-between;
-		background: linear-gradient( 180deg, #FFFFFF 0%, rgba(255,255,255,0.5) 100%);
-		box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67,147,248,0.1), -8rpx -8rpx 23rpx 0rpx rgba(255,255,255,0.4);
-		border-radius: 23rpx 23rpx 23rpx 23rpx;
-		border: 2rpx solid #FFFFFF;
-		padding:30rpx;
-		box-sizing: border-box;
-		margin-top: 24rpx;
-		.title{
-			flex-shrink: 0;
-			font-size: 30rpx;
-			color: rgba(0,0,0,0.9);
-			line-height: 40rpx;
-			
-		}
-		.item{
-			
-		}
-	}
-	.temp_item{
-		background: linear-gradient( 180deg, #FFFFFF 0%, rgba(255,255,255,0.5) 100%);
-		box-shadow: 8rpx 8rpx 23rpx 0rpx rgba(67,147,248,0.1), -8rpx -8rpx 23rpx 0rpx rgba(255,255,255,0.4);
-		border-radius: 23rpx 23rpx 23rpx 23rpx;
-		border: 2rpx solid #FFFFFF;
-		padding:30rpx;
-		box-sizing: border-box;
-		margin-top: 24rpx;
-		.title{
-			flex-shrink: 0;
-			font-size: 30rpx;
-			color: rgba(0,0,0,0.9);
-			line-height: 40rpx;
-		}
-		.item{
-			margin-top: 15rpx;
-		}
-	}
-}
-.page_bg{
-	width: 100%;
-	min-height: calc(100vh - var(--window-bottom));
-	background:url('/static/img/bg_2.jpg') no-repeat center top;
-	background-size: 100% auto;
-}
-</style>
diff --git a/ledApp/pages/addTemplate/addTemplate.vue b/ledApp/pages/addTemplate/addTemplate.vue
index 0a208de..ba8ff1d 100644
--- a/ledApp/pages/addTemplate/addTemplate.vue
+++ b/ledApp/pages/addTemplate/addTemplate.vue
@@ -264,13 +264,6 @@
 			}
 		},
 		methods: {
-			// 跳转到编辑动画页面
-			goToAnimaiton(index){
-				this.fpsIndex = index
-				uni.navigateTo({
-				  url: '/pages/animation/animation?index='+index
-				})
-			},
 			// 获取编辑详情
 			getTempleteInfo(){
 				templeteInfo(this.tId).then(res=>{
diff --git a/ledApp/pages/animation/animation copy.vue b/ledApp/pages/animation/animation copy.vue
deleted file mode 100644
index 15ccbff..0000000
--- a/ledApp/pages/animation/animation copy.vue
+++ /dev/null
@@ -1,533 +0,0 @@
-<template>
-	<view>
-		<!-- <uv-navbar title="动画编辑" :autoBack="true" bgColor="rgba(0,0,0,0)" :placeholder="false"></uv-navbar> -->
-		<view class="back_btn" @click="clickBack">
-			<uv-icon name="arrow-leftward" color="#333" size="26rpx"></uv-icon>
-		</view>
-		<view class="controls">
-			<uv-button type="primary" :plain="true" text="分辨率" @click="changeRatio()"></uv-button>
-			<uv-button type="primary" :plain="true" text="颜色" @click="changeColor()"></uv-button>
-
-			<uv-button type="primary" :plain="true" text="添加文字" @click="addText()"></uv-button>
-			<uv-button type="primary" :plain="true" text="清除" @click="clear()"></uv-button>
-
-			<uv-button type="primary" :plain="true" text="保存" @click="clickSaveData"></uv-button>
-		</view>
-
-		<!-- 文字生成图形 -->
-		<canvas canvas-id="myCanvas" id="myCanvas" class="canvas" :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
-
-		<!-- 修改像素网格显示 -->
-		<!-- <view class="pixel-grid" @touchstart.prevent="handleTouchStart" @touchmove.prevent="handleTouchMove">
-			<view class="pixel-row" v-for="(row, rowIndex) in Math.ceil(pixelData.length / width)" :key="rowIndex">
-				<view class="pixel-cell" v-for="(item, colIndex) in width" :key="colIndex">
-					<view v-if="pixelData[rowIndex * width + colIndex]" class="pixel-cell-item" :style="{ backgroundColor: pixelData[rowIndex * width + colIndex] }">
-						{{rowIndex,colIndex}}
-					</view>
-				</view>
-			</view>
-		</view> -->
-
-		<view class="pixel_grid" @touchstart.prevent="handleTouchStart" @touchmove.prevent="handleTouchMove"
-			@touchend.prevent="handleTouchEnd" @touchcancel.prevent="handleTouchEnd" 
-			:style="{
-				gridTemplateRows: `repeat(${height}, 1fr)`,
-				gridTemplateColumns: `repeat(${width}, 1fr)`
-			}">
-			<view class="pixel_cell" v-for="(cell, cellIndex) in pixelData" :key="cellIndex">
-				<view class="pixel_cell_item" :style="{ backgroundColor: cell }">
-
-				</view>
-			</view>
-		</view>
-
-		<!-- 分辨率 -->
-		<uv-picker ref="pickerRatio" :columns="columnsRatio" @confirm="confirmRatio"></uv-picker>
-
-		<!-- 颜色 -->
-		<uv-popup ref="pickerColor" mode="bottom" round="10" :closeable="true">
-			<view class="color_list">
-				<view class="color_item" v-for="(item, index) in colorList" :class="{ hover: color === item }"
-					:key="index" :style="{ backgroundColor: item }" @click="clickColor(item)"></view>
-			</view>
-		</uv-popup>
-
-		<!-- <uv-pick-color ref="pickerColor" @confirm="confirm"></uv-pick-color> -->
-
-	</view>
-</template>
-
-<script>
-	let ctx = null
-
-	export default {
-		data() {
-			return {
-				pixelData: [],
-				canvasData: [],
-				canvasWidth: 240,
-				canvasHeight: 120,
-				width: 24,
-				height: 12,
-				color: '#FF0000',
-				gridRect: null, // 存储像素网格的位置信息
-				lastCell: null, // 防止重复绘制
-				columnsRatio: [
-					['12*24', '16*32', '24*48', '32*64', '40*80']
-				],
-				// columnsRatio: [
-				// 	['12*24']
-				// ],
-				colorList: [
-					'#FF0000',
-					'#00FF00',
-					'#0000FF',
-					'#FFFF00',
-					'#FFA500',
-					'#800080',
-					'#00FFFF',
-					'#FFC0CB'
-				],
-				fpsIndex: 0
-			}
-		},
-		onLoad(opt) {
-			// App端强制横屏
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('landscape-primary')
-			}
-			if (opt.fps) {
-				this.fpsIndex = opt.fps
-			}
-
-		},
-		onShow() {
-			// 改为一维数组初始化
-			this.pixelData = new Array(this.height * this.width).fill('')
-		},
-		onHide() {
-			console.log('离开页面恢复竖屏------onHide')
-			// 离开页面恢复竖屏
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		onUnload() {
-			console.log('离开页面恢复竖屏------onUnload')
-			// 离开页面恢复竖屏
-			if (typeof plus !== 'undefined') {
-				plus.screen.lockOrientation('portrait')
-			}
-		},
-		methods: {
-			clickBack() {
-				uni.navigateBack({
-					delta: 1
-				});
-			},
-			clickSaveData() {
-				const parsed = this.pixelData.map(item => {
-					if (item) {
-						return item.replace("#", "");
-					} else {
-						return "000000";
-					}
-				});
-				console.log('parsed-------------', parsed.join(''))
-				//const snakeRows = this.toSnakeData(parsed, this.width)
-				//console.log('snakeRows-------------', snakeRows)
-				//const snakeString = this.mergeRowsToString(snakeRows)
-				//console.log('snakeString-------------', snakeString)
-
-				// uni.setStorageSync('fpsParams', {
-				// 	shouldRefresh: true,
-				// 	fpsIndex: Number(this.fpsIndex),
-				// 	//data: snakeString
-				// 	data: parsed
-				// });
-
-				uni.setStorage({
-					key: 'fpsParams',
-					data: {
-						shouldRefresh: true,
-						fpsIndex: Number(this.fpsIndex),
-						data: parsed
-					},
-					success: () => {
-						console.log('存储成功');
-						uni.navigateBack({
-							delta: 1,
-						});
-					},
-					fail: (err) => {
-						console.error('存储失败:', err);
-					}
-				});
-
-				
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			getData() {
-				uni.switchTab({
-					url: '/pages/template/template',
-					success() {
-						console.log('跳转成功');
-					},
-					fail(err) {
-						console.error('跳转失败:', err);
-					}
-				});
-			},
-			changeColor() {
-				this.$refs.pickerColor.open();
-			},
-			clickColor(item) {
-				console.log('confirmColor---', item);
-				this.color = item;
-				this.$refs.pickerColor.close();
-			},
-			changeRatio() {
-				this.$refs.pickerRatio.open();
-			},
-			// 分辨率
-			confirmRatio(e) {
-				console.log('confirmRatio---', e.value[0]);
-				const ratio = e.value[0].split('*');
-				console.log('ratio---', ratio[0]);
-				this.height = Number(ratio[0]);
-				this.width = Number(ratio[1]);
-				this.canvasWidth = this.width * 10;
-				this.canvasHeight = this.height * 10;
-				// 重新初始化一维数组
-				this.pixelData = new Array(this.height * this.width).fill('')
-				console.log('pixelData---', this.pixelData);
-			},
-			// 预先获取像素网格的位置信息
-			getGridRect(cb) {
-				if (this.gridRect) {
-					cb(this.gridRect)
-				} else {
-					uni.createSelectorQuery().in(this).select('.pixel_grid').boundingClientRect(rect => {
-						this.gridRect = rect
-						cb(rect)
-					}).exec()
-				}
-			},
-			// 计算触摸点对应的格子
-			getCellByTouch(touch, cb) {
-				this.getGridRect(rect => {
-					if (!rect) return
-					const x = touch.clientX - rect.left
-					const y = touch.clientY - rect.top
-					const cellWidth = rect.width / this.width
-					const cellHeight = rect.height / this.height
-					const colIndex = Math.floor(x / cellWidth)
-					const rowIndex = Math.floor(y / cellHeight)
-					if (
-						colIndex >= 0 && colIndex < this.width &&
-						rowIndex >= 0 && rowIndex < this.height
-					) {
-						cb({
-							rowIndex,
-							colIndex
-						})
-					}
-				})
-			},
-			handleTouchStart(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					this.lastCell = cell
-					this.handleClick(cell.rowIndex, cell.colIndex)
-				})
-			},
-			handleTouchMove(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					// 只在格子变化时才触发
-					if (!this.lastCell || this.lastCell.rowIndex !== cell.rowIndex || this.lastCell.colIndex !==
-						cell.colIndex) {
-						this.lastCell = cell
-						this.handleClick(cell.rowIndex, cell.colIndex)
-					}
-				})
-			},
-			handleTouchEnd() {
-				this.lastCell = null
-			},
-			handleClick(rowIndex, colIndex) {
-				console.log(rowIndex, colIndex)
-				// 计算一维数组的索引
-				const index = rowIndex * this.width + colIndex
-				// 如果当前像素有颜色,则清除;如果没有颜色,则添加当前选择的颜色
-				const currentColor = this.pixelData[index]
-				const newColor = currentColor ? '' : this.color
-				this.$set(this.pixelData, index, newColor)
-			},
-			clear() {
-				ctx && ctx.clearRect(0, 0, 1000, 1000)
-				// 将所有像素点设置为空字符串
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 生成点阵数据
-			generateDotMatrix(char) {
-				return new Promise((resolve, reject) => {
-
-					// 使用 uni-app 的 canvas context
-					ctx = uni.createCanvasContext('myCanvas', this);
-
-					// 设置字体样式
-					ctx.setFontSize(this.canvasHeight * 0.9);
-					ctx.setFillStyle('#000')
-					ctx.setTextAlign('center')
-					ctx.setTextBaseline('middle')
-					// 绘制文字
-					// 计算文字位置
-					// 水平居中
-					const x = this.canvasWidth / 2;
-					// 垂直居中,稍微向上偏移一点
-					const y = this.canvasHeight / 2;
-
-					// 绘制文字
-					ctx.fillText(char, x, y);
-
-					// 绘制到画布
-					ctx.draw(false, () => {
-						// 获取画布数据
-						uni.canvasGetImageData({
-							canvasId: 'myCanvas',
-							x: 0,
-							y: 0,
-							width: this.canvasWidth,
-							height: this.canvasHeight,
-							success: (res) => {
-								console.log(res)
-								const imageData = res.data;
-								// 生成一维数组
-								const pixelArray = new Array(this.height * this.width).fill('')
-
-								// 计算每个格子的像素大小
-								const cellWidth = this.canvasWidth / this.width;
-								const cellHeight = this.canvasHeight / this.height;
-
-								// 生成一维数组
-								for (let y = 0; y < this.height; y++) {
-									for (let x = 0; x < this.width; x++) {
-										let blackPixels = 0;
-										let totalPixels = 0;
-
-										// 对每个格子进行采样
-										for (let py = 0; py < cellHeight; py++) {
-											for (let px = 0; px < cellWidth; px++) {
-												const pixelY = Math.floor(y * cellHeight + py);
-												const pixelX = Math.floor(x * cellWidth + px);
-
-												const idx = (pixelY * this.canvasWidth +
-													pixelX) * 4;
-												const r = imageData[idx];
-												const g = imageData[idx + 1];
-												const b = imageData[idx + 2];
-												const a = imageData[idx + 3];
-
-												// 计算亮度
-												const brightness = 0.3 * r + 0.59 * g + 0.11 *
-													b;
-
-												// 如果亮度小于阈值且透明度大于阈值,则认为是黑色
-												if (brightness < 128 && a > 128) {
-													blackPixels++;
-												}
-												totalPixels++;
-											}
-										}
-
-										// 如果黑色像素占比超过阈值,则设置为当前选择的颜色
-										const isBlack = blackPixels / totalPixels > 0.3;
-										const arrayIndex = y * this.width + x;
-										pixelArray[arrayIndex] = isBlack ? this.color :
-											''; // 改为颜色值或空字符串
-									}
-								}
-
-								resolve(pixelArray);
-							},
-							fail: (err) => {
-								reject(err);
-							}
-						});
-					});
-				});
-			},
-
-			// 修改添加文字方法
-			async addText() {
-				uni.showModal({
-					title: '添加文字',
-					content: '',
-					editable: true,
-					placeholderText: '请输入文字',
-					success: async (res) => {
-						if (res.confirm) {
-							const text = res.content;
-							if (text.length > 0) {
-								try {
-									// 生成点阵数据
-									const dotMatrix = await this.generateDotMatrix(text);
-									console.log('点阵数据:', dotMatrix);
-									this.pixelData = dotMatrix
-								} catch (error) {
-									console.error('生成点阵失败:', error);
-									uni.showToast({
-										title: '生成点阵失败',
-										icon: 'none'
-									});
-								}
-							} else {
-								uni.showToast({
-									title: '请输入文字',
-									icon: 'none'
-								});
-							}
-						}
-					}
-				});
-			},
-			
-			
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-	.back_btn {
-		position: fixed;
-		left: 10rpx;
-		top: 26rpx;
-		z-index: 9999;
-	}
-
-	.pixel_grid {
-		position: fixed;
-		left: 0;
-		top: var(--status-bar-height);
-		right: 0;
-		bottom: 0;
-		display: grid;
-		gap: 1px;
-		box-sizing: border-box;
-		background: #eee;
-		touch-action: none;
-		-webkit-touch-callout: none;
-		-webkit-user-select: none;
-		user-select: none;
-
-		.pixel_cell {
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			box-sizing: border-box;
-			background: #fff;
-
-			.pixel_cell_item {
-				width: 50%;
-				height: 50%;
-				aspect-ratio: 1/1;
-				font-size: 10rpx;
-			}
-		}
-	}
-
-	.color_list {
-		width: 100%;
-		display: flex;
-		justify-content: center;
-		flex-wrap: wrap;
-		gap: 30rpx;
-		box-sizing: border-box;
-		padding: 50rpx;
-
-		.color_item {
-			width: 30rpx;
-			height: 30rpx;
-			border-radius: 5rpx;
-		}
-	}
-
-	.controls {
-		position: absolute;
-		bottom: 15rpx;
-		left: 20rpx;
-		display: flex;
-		gap: 20rpx;
-		z-index: 9;
-	}
-
-	.canvas {
-		margin: 100rpx auto 0;
-		background: #ccc;
-		position: absolute;
-		z-index: 1;
-		left: -9999px;
-		top: -9999px;
-	}
-
-	.pixel-grid {
-		position: fixed;
-		left: 0;
-		top: 0;
-		right: 0;
-		bottom: 0;
-		display: flex;
-		flex-direction: column;
-		z-index: 8;
-		background: #fff;
-		touch-action: none;
-		-webkit-touch-callout: none;
-		-webkit-user-select: none;
-		user-select: none;
-
-		.pixel-row {
-			display: flex;
-			flex: 1;
-
-			.pixel-cell {
-				flex: 1;
-				display: flex;
-				justify-content: center;
-				align-items: center;
-				border: 1rpx solid #eee;
-				box-sizing: border-box;
-
-				.pixel-cell-item {
-					width: 50%;
-					aspect-ratio: 1/1;
-					color: #333 !important;
-					;
-					font-size: 10rpx;
-				}
-			}
-		}
-	}
-</style>
\ No newline at end of file
diff --git a/ledApp/pages/animation/animation.vue b/ledApp/pages/animation/animation.vue
deleted file mode 100644
index 280e105..0000000
--- a/ledApp/pages/animation/animation.vue
+++ /dev/null
@@ -1,624 +0,0 @@
-<template>
-	<view>
-		<view class="animation_pixel">
-			<view class="back_btn" @click="popupAnimationClose">
-				<uv-icon name="arrow-leftward" color="#333" size="30"></uv-icon>
-			</view>
-			<!-- 动画按钮 -->
-			<view class="controls">
-				<uv-button type="primary" :plain="true" text="分辨率" @click="changeRatio()"></uv-button>
-				<uv-button type="primary" :plain="true" text="颜色" @click="changeColor()"></uv-button>
-				<uv-button type="primary" :plain="true" text="添加文字" @click="addText()"></uv-button>
-				<uv-button type="primary" :plain="true" text="清除" @click="clear()"></uv-button>
-				<uv-button type="primary" :plain="true" text="保存" @click="clickSaveData"></uv-button>
-			</view>
-
-			<!-- 文字生成图形 -->
-			<canvas canvas-id="myCanvas" id="myCanvas" class="canvas"
-				:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"></canvas>
-
-			<view class="pixel_grid" @touchstart.prevent="handleTouchStart" @touchmove.prevent="handleTouchMove"
-				@touchend.prevent="handleTouchEnd" @touchcancel.prevent="handleTouchEnd" :style="{
-					gridTemplateRows: `repeat(${height}, 1fr)`,
-					gridTemplateColumns: `repeat(${width}, 1fr)`
-				}">
-				<view class="pixel_cell" v-for="(cell, cellIndex) in pixelData" :key="cellIndex">
-					<view class="pixel_cell_item" :style="{ backgroundColor: cell }"></view>
-				</view>
-			</view>
-		</view>
-
-		<!-- 分辨率 -->
-		<uv-picker ref="pickerRatio" :columns="columnsRatio" @confirm="confirmRatio"></uv-picker>
-
-		<!-- 颜色 -->
-		<uv-popup ref="pickerColor" mode="bottom" round="10" :closeable="true">
-			<view class="color_list">
-				<view class="color_item" v-for="(item, index) in colorList" :class="{ hover: color === item }"
-					:key="index" :style="{ backgroundColor: item }" @click="clickColor(item)"></view>
-			</view>
-		</uv-popup>
-
-	</view>
-</template>
-
-<script>
-	let ctx = null
-	export default {
-		data() {
-			return {
-				tempName: '',
-				pic: '',
-				specList: [{
-					name: '12*24'
-				}, {
-					name: '16*24'
-				}, {
-					name: '18*24'
-				}],
-				specVal: '12*24',
-				specWidth: 24,
-				specHeight: 12,
-				modeList: [{
-						name: '单个动画帧',
-						val: 0
-					},
-					{
-						name: '动画帧切换',
-						val: 1
-					}
-				],
-				modeVal: 0,
-				columnsTotal: [
-					[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
-						28, 29, 30
-					]
-				],
-				total: 1, //动画总帧数
-				columnsSpeed: [
-					[10, 20, 30, 40, 50, 60, 70, 80, 90]
-				],
-				speed: 10,
-				cycle: 1,
-				fpsData: [],
-				fpsIndex: 1, //第几帧
-				fpsIds: [],
-
-				baseURL: '',
-				fileList1: [],
-				animationData: [],
-				fpsTotal: 1,
-
-
-
-				// 模版动画
-				pixelData: [],
-				canvasData: [],
-				canvasWidth: 240,
-				canvasHeight: 120,
-				width: 24,
-				height: 12,
-				color: '#FF0000',
-				gridRect: null, // 存储像素网格的位置信息
-				lastCell: null, // 防止重复绘制
-				columnsRatio: [
-					['12*24', '16*32', '24*48', '32*64', '40*80']
-				],
-				// columnsRatio: [
-				// 	['12*24']
-				// ],
-				colorList: [
-					'#FF0000',
-					'#00FF00',
-					'#0000FF',
-					'#FFFF00',
-					'#FFA500',
-					'#800080',
-					'#00FFFF',
-					'#FFC0CB'
-				],
-				fpsIndex: 0,
-				fpsList: [],
-				tId: '',
-				tempInfo: {},
-				titleName: '新增模版',
-				
-
-			}
-		},
-		onLoad(opt) {
-			this.baseURL = uni.$uv.http.config.baseURL
-			if (opt.index) {
-				this.fpsIndex = opt.index
-				console.log('fpsIndex--', this.fpsIndex)
-			}
-		},
-		onShow() {
-			this.pixelData = new Array(this.height * this.width).fill('')
-		},
-		onHide() {
-			
-		},
-		onUnload() {
-			
-		},
-		methods: {
-			// 保存动画
-			clickSaveData() {
-				this.fpsList[this.fpsIndex] = this.pixelData;
-				this.$refs.popupAnimation.close();
-			},
-			changeColor() {
-				this.$refs.pickerColor.open();
-			},
-			clickColor(item) {
-				console.log('confirmColor---', item);
-				this.color = item;
-				this.$refs.pickerColor.close();
-			},
-			changeRatio() {
-				this.$refs.pickerRatio.open();
-			},
-			// 分辨率
-			confirmRatio(e) {
-				console.log('confirmRatio---', e.value[0]);
-				const ratio = e.value[0].split('*');
-				console.log('ratio---', ratio[0]);
-				this.height = Number(ratio[0]);
-				this.width = Number(ratio[1]);
-				this.canvasWidth = this.width * 10;
-				this.canvasHeight = this.height * 10;
-				// 重新初始化一维数组
-				this.pixelData = new Array(this.height * this.width).fill('')
-				console.log('pixelData---', this.pixelData);
-			},
-			// 预先获取像素网格的位置信息
-			getGridRect(cb) {
-				if (this.gridRect) {
-					cb(this.gridRect)
-				} else {
-					uni.createSelectorQuery().in(this).select('.pixel_grid').boundingClientRect(rect => {
-						this.gridRect = rect
-						cb(rect)
-					}).exec()
-				}
-			},
-			// 计算触摸点对应的格子
-			getCellByTouch(touch, cb) {
-				this.getGridRect(rect => {
-					if (!rect) return
-					const x = touch.clientX - rect.left
-					const y = touch.clientY - rect.top
-					const cellWidth = rect.width / this.width
-					const cellHeight = rect.height / this.height
-					const colIndex = Math.floor(x / cellWidth)
-					const rowIndex = Math.floor(y / cellHeight)
-					if (
-						colIndex >= 0 && colIndex < this.width &&
-						rowIndex >= 0 && rowIndex < this.height
-					) {
-						cb({
-							rowIndex,
-							colIndex
-						})
-					}
-				})
-			},
-			handleTouchStart(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					this.lastCell = cell
-					this.handleClick(cell.rowIndex, cell.colIndex)
-				})
-			},
-			handleTouchMove(e) {
-				// 阻止默认行为
-				e.preventDefault && e.preventDefault();
-
-				if (!e.touches.length) return
-				this.getCellByTouch(e.touches[0], cell => {
-					// 只在格子变化时才触发
-					if (!this.lastCell || this.lastCell.rowIndex !== cell.rowIndex || this.lastCell.colIndex !==
-						cell.colIndex) {
-						this.lastCell = cell
-						this.handleClick(cell.rowIndex, cell.colIndex)
-					}
-				})
-			},
-			handleTouchEnd() {
-				this.lastCell = null
-			},
-			handleClick(rowIndex, colIndex) {
-				console.log(rowIndex, colIndex)
-				// 计算一维数组的索引
-				const index = rowIndex * this.width + colIndex
-				// 如果当前像素有颜色,则清除;如果没有颜色,则添加当前选择的颜色
-				const currentColor = this.pixelData[index]
-				const newColor = currentColor ? '' : this.color
-				this.$set(this.pixelData, index, newColor)
-			},
-			clear() {
-				ctx && ctx.clearRect(0, 0, 1000, 1000)
-				// 将所有像素点设置为空字符串
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 模版动画弹出框
-			changeAnimation(e) {
-				//console.log('打开关闭模版动画弹窗触发---',e)
-				// ios设备不支持弹出框横屏切换
-				// if(e.show){
-				// 	if (typeof plus !== 'undefined') {
-				// 		plus.screen.lockOrientation('landscape-primary')
-				// 	}
-				// }
-				// else{
-				// 	if (typeof plus !== 'undefined') {
-				// 		plus.screen.lockOrientation('portrait')
-				// 	}
-				// }
-			},
-			// 打开模版动画
-			popupAnimationOpen(index) {
-				this.fpsIndex = index
-				if (this.fpsList[this.fpsIndex] == null) {
-					console.log('第一次编辑-----null')
-					this.pixelData = new Array(this.height * this.width).fill('')
-				} else {
-					console.log('已编辑过-----')
-					this.pixelData = this.fpsList[this.fpsIndex]
-				}
-			},
-			// 关闭模版动画
-			popupAnimationClose() {
-				this.$refs.popupAnimation.close();
-				this.pixelData = new Array(this.height * this.width).fill('')
-			},
-			// 屏幕规格
-			changeSpec(e) {
-				const ratio = e.split('*');
-				this.specHeight = Number(ratio[0]);
-				this.specWidth = Number(ratio[1]);
-			},
-			// 偶数行数据反转
-			toSnakeData(pixelData, cols = 24) {
-				const rows = []
-				for (let i = 0; i < pixelData.length; i += cols) {
-					let row = pixelData.slice(i, i + cols)
-					if ((rows.length + 1) % 2 === 0) {
-						row.reverse() // 偶数行反转
-					}
-					rows.push(row)
-				}
-				return rows
-			},
-			// 二维数组转字符串
-			mergeRowsToString(rows) {
-				const rowStrings = rows.map(r => r.join('')) // 每行合并
-				return rowStrings.join('') // 所有行合并
-			},
-			// 生成一帧动画其他帧数据
-			generateFrames(data, frameCount = 12) {
-				const cols = this.specWidth; // 每行 24 个
-				const rows = this.specHeight; // 共 12 行
-				const frames = [];
-				// 拆分成 12 行
-				let grid = [];
-				for (let r = 0; r < rows; r++) {
-					grid.push(data.slice(r * cols, (r + 1) * cols));
-				}
-				// 生成帧
-				for (let f = 0; f < frameCount; f++) {
-					let frame = [];
-					// 每行左移 f 次
-					for (let r = 0; r < rows; r++) {
-						let row = grid[r].slice(); // 拷贝一行
-						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
-						frame = frame.concat(shifted);
-					}
-					frames.push(frame);
-				}
-				return frames;
-			},
-
-			clickSpeed() {
-				this.$refs.pickerSpeed.open();
-			},
-			confirmSpeed(e) {
-				console.log('confirmSpeed', e.value[0]);
-				this.speed = e.value[0]
-			},
-			clickTotal() {
-				if (this.total != 1) {
-					this.$refs.pickerTotal.open();
-				}
-			},
-			confirmTotal(e) {
-				console.log('confirmTotal', e.value[0]);
-				this.total = e.value[0]
-				this.adjustFpsData()
-			},
-			changeMode(e) {
-				this.fpsList = []
-				this.fpsData = []
-				if (e == 0) {
-					this.total = 1
-				} else {
-					this.total = 2
-				}
-				this.adjustFpsData()
-			},
-			adjustFpsData() {
-				// 如果 fpsData 太长 → 截取
-				if (this.fpsList.length > this.total) {
-					this.fpsList = this.fpsList.slice(0, this.total);
-				}
-				// 如果 fpsData 太短 → 补齐 null
-				else if (this.fpsList.length < this.total) {
-					const missing = this.total - this.fpsList.length;
-					this.fpsList = this.fpsList.concat(new Array(missing).fill(null));
-				}
-
-				// 如果 fpsList 太长 → 截取
-				if (this.fpsData.length > this.total) {
-					this.fpsData = this.fpsData.slice(0, this.total);
-				}
-				// 如果 fpsList 太短 → 补齐 null
-				else if (this.fpsData.length < this.total) {
-					const missing = this.total - this.fpsData.length;
-					this.fpsData = this.fpsData.concat(new Array(missing).fill(null));
-				}
-			},
-			// 删除图片
-			deletePic(event) {
-				this[`fileList${event.name}`].splice(event.index, 1)
-			},
-			// 新增图片
-			async afterRead(event) {
-				console.log('event---', event)
-				// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
-				let lists = [].concat(event.file)
-				let fileListLen = this[`fileList${event.name}`].length
-				lists.map((item) => {
-					this[`fileList${event.name}`].push({
-						...item,
-						status: 'uploading',
-						message: '上传中'
-					})
-				})
-				for (let i = 0; i < lists.length; i++) {
-					const result = await this.uploadFilePromise(lists[i].url)
-					this.avatar = result
-					let item = this[`fileList${event.name}`][fileListLen]
-					this[`fileList${event.name}`].splice(fileListLen, 1, Object.assign(item, {
-						status: 'success',
-						message: '',
-						url: result
-					}))
-					fileListLen++
-				}
-			},
-			uploadFilePromise(url) {
-				return new Promise((resolve, reject) => {
-					let a = uni.uploadFile({
-						url: this.baseURL + '/common/uploadFileByAnny', // 仅为示例,非真实的接口地址
-						filePath: url,
-						name: 'file',
-						success: (res) => {
-							console.log('图片-----', JSON.parse(res.data))
-							setTimeout(() => {
-								resolve(JSON.parse(res.data).fileName)
-							}, 1000)
-						}
-					});
-				})
-			},
-			// 生成点阵数据
-			generateDotMatrix(char) {
-				return new Promise((resolve, reject) => {
-
-					// 使用 uni-app 的 canvas context
-					ctx = uni.createCanvasContext('myCanvas', this);
-
-					// 设置字体样式
-					ctx.setFontSize(this.canvasHeight * 0.9);
-					ctx.setFillStyle('#000')
-					ctx.setTextAlign('center')
-					ctx.setTextBaseline('middle')
-					// 绘制文字
-					// 计算文字位置
-					// 水平居中
-					const x = this.canvasWidth / 2;
-					// 垂直居中,稍微向上偏移一点
-					const y = this.canvasHeight / 2;
-
-					// 绘制文字
-					ctx.fillText(char, x, y);
-
-					// 绘制到画布
-					ctx.draw(false, () => {
-						// 获取画布数据
-						uni.canvasGetImageData({
-							canvasId: 'myCanvas',
-							x: 0,
-							y: 0,
-							width: this.canvasWidth,
-							height: this.canvasHeight,
-							success: (res) => {
-								console.log(res)
-								const imageData = res.data;
-								// 生成一维数组
-								const pixelArray = new Array(this.height * this.width).fill('')
-
-								// 计算每个格子的像素大小
-								const cellWidth = this.canvasWidth / this.width;
-								const cellHeight = this.canvasHeight / this.height;
-
-								// 生成一维数组
-								for (let y = 0; y < this.height; y++) {
-									for (let x = 0; x < this.width; x++) {
-										let blackPixels = 0;
-										let totalPixels = 0;
-
-										// 对每个格子进行采样
-										for (let py = 0; py < cellHeight; py++) {
-											for (let px = 0; px < cellWidth; px++) {
-												const pixelY = Math.floor(y * cellHeight + py);
-												const pixelX = Math.floor(x * cellWidth + px);
-
-												const idx = (pixelY * this.canvasWidth +
-													pixelX) * 4;
-												const r = imageData[idx];
-												const g = imageData[idx + 1];
-												const b = imageData[idx + 2];
-												const a = imageData[idx + 3];
-
-												// 计算亮度
-												const brightness = 0.3 * r + 0.59 * g + 0.11 *
-													b;
-
-												// 如果亮度小于阈值且透明度大于阈值,则认为是黑色
-												if (brightness < 128 && a > 128) {
-													blackPixels++;
-												}
-												totalPixels++;
-											}
-										}
-
-										// 如果黑色像素占比超过阈值,则设置为当前选择的颜色
-										const isBlack = blackPixels / totalPixels > 0.3;
-										const arrayIndex = y * this.width + x;
-										pixelArray[arrayIndex] = isBlack ? this.color :
-										''; // 改为颜色值或空字符串
-									}
-								}
-
-								resolve(pixelArray);
-							},
-							fail: (err) => {
-								reject(err);
-							}
-						});
-					});
-				});
-			},
-
-			// 修改添加文字方法
-			async addText() {
-				uni.showModal({
-					title: '添加文字',
-					content: '',
-					editable: true,
-					placeholderText: '请输入文字',
-					success: async (res) => {
-						if (res.confirm) {
-							const text = res.content;
-							if (text.length > 0) {
-								try {
-									// 生成点阵数据
-									const dotMatrix = await this.generateDotMatrix(text);
-									console.log('点阵数据:', dotMatrix);
-									this.pixelData = dotMatrix
-								} catch (error) {
-									console.error('生成点阵失败:', error);
-									uni.showToast({
-										title: '生成点阵失败',
-										icon: 'none'
-									});
-								}
-							} else {
-								uni.showToast({
-									title: '请输入文字',
-									icon: 'none'
-								});
-							}
-						}
-					}
-				});
-			},
-		}
-	}
-</script>
-
-<style lang="scss" scoped>
-.color_list {
-	width: 100%;
-	display: flex;
-	justify-content: center;
-	flex-wrap: wrap;
-	gap: 30rpx;
-	box-sizing: border-box;
-	padding: 50rpx;
-
-	.color_item {
-		width: 30rpx;
-		height: 30rpx;
-		border-radius: 5rpx;
-	}
-}
-
-.controls {
-	position: absolute;
-	bottom: 10px;
-	left: 50px;
-	display: flex;
-	gap: 20px;
-	z-index: 9;
-}
-
-.animation_pixel {
-	width: 100vw;
-	height: 100vh;
-	position: relative;
-
-	.back_btn {
-		position: absolute;
-		left: 30px;
-		top: 20px;
-		z-index: 9999;
-	}
-
-	.canvas {
-		margin: 100rpx auto 0;
-		background: #ccc;
-		position: absolute;
-		z-index: 1;
-		left: -9999px;
-		top: -9999px;
-	}
-
-	.pixel_grid {
-		position: fixed;
-		left: 0;
-		top: var(--status-bar-height);
-		right: 0;
-		bottom: 0;
-		display: grid;
-		gap: 1px;
-		box-sizing: border-box;
-		background: #eee;
-		touch-action: none;
-		-webkit-touch-callout: none;
-		-webkit-user-select: none;
-		user-select: none;
-
-		.pixel_cell {
-			display: flex;
-			align-items: center;
-			justify-content: center;
-			box-sizing: border-box;
-			background: #fff;
-
-			.pixel_cell_item {
-				width: 50%;
-				height: 50%;
-				aspect-ratio: 1/1;
-				font-size: 10rpx;
-			}
-		}
-	}
-
-}
-</style>
\ No newline at end of file

--
Gitblit v1.10.0