微信小程序(uni-app)中使用便捷式蓝牙打印机(完整代码)

<!-- 蓝牙打印页面 -->
<template>
	<view style="height: 100vh; display: flex; flex-direction: column">
		<view style="flex: 1; overflow-y: auto; padding-bottom: 20rpx">
			<button class="button" hover-class="hover" @click="startSearch" :loading="isScanning">
				搜索蓝牙设备
			</button>
			<text class=".td">(Android8.0+系统需开启定位)</text>
			<view v-if="list.length > 0" style="text-align: center">
				<view style="font-size: 18px">蓝牙设备列表</view>
				<view style="color: #666; font-size: 10px">点击连接蓝牙设备</view>
			</view>
			<view v-if="deviceinfo.deviceId" class="linkcss">蓝牙设备已连接:{{ deviceinfo.name }}</view>
			<scroll-view class="device_list" scroll-y scroll-with-animation>
				<view :class="item.deviceId === deviceinfo.deviceId ? 'sign_step' : ''" v-for="item in list"
					:data-title="item.deviceId" :data-name="item.name" :data-advertisData="item.advertisServiceUUIDs"
					:key="item.deviceId" @click="bindViewTap" class="item" hover-class="item_hover">
					<view>
						<view style="font-size: 16px">{{ item.name }}</view>
						<view style="font-size: 12px">{{ item.deviceId }}</view>
						<view style="font-size: 10px; color: #666">信号强度: {{ item.RSSI }}dBm
						</view>
					</view>
				</view>
			</scroll-view>
		</view>
		<view class="btncss">
			<u-button :disabled="!deviceinfo.deviceId||printing" :custom-style="{ width: '200rpx' }" type="primary"
				@click="submitPrinte" :loading="printing">打 印</u-button>
		</view>
	</view>
</template>

<script>
	function inArray(arr, key, val) {
		for (let i = 0; i < arr.length; i++) {
			if (arr[i][key] === val) {
				return i;
			}
		}
		return -1;
	}

	// ArrayBuffer转16进度字符串示例
	function ab2hex(buffer) {
		var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function(bit) {
			return ("00" + bit.toString(16)).slice(-2);
		});
		return hexArr.join("");
	}

	function convertToGrayscale(data) {
		let g = 0;
		for (let i = 0; i < data.length; i += 4) {
			g = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11;
			data[i] = g;
			data[i + 1] = g;
			data[i + 2] = g;
		}
		return data;
	}

	function setPixel(data, offset, value) {
		data[offset] = value;
		data[offset + 1] = value;
		data[offset + 2] = value;
	}

	function adjustPixel(data, offset, value) {
		data[offset] += value;
	}

	// 彩色图转成单色图
	function convertToMonoImage(width, height, data, shake) {
		let g = 0;
		let e = 0;

		for (let i = 0; i < data.length; i += 4) {
			data[i] = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11;
		}

		for (let y = 0; y < height; y++) {
			for (let x = 0; x < width; x++) {
				let dataOffset = (width * y + x) * 4;
				g = data[dataOffset];
				if (g >= 150) {
					// 灰色转黑白的阈值, 可以调整打印效果
					e = g - 255;
					setPixel(data, dataOffset, 255);
				} else {
					e = g;
					setPixel(data, dataOffset, 0);
				}

				if (!shake) continue;

				if (x < width - 1 && y < height - 1) {
					//右边像素处理
					data[(width * y + x + 1) * 4] += (7 * e) / 16;
					//下
					data[(width * (y + 1) + x) * 4] += (5 * e) / 16;
					//右下
					data[(width * (y + 1) + x + 1) * 4] += e / 16;
					//左下
					if (x > 0) {
						data[(width * (y + 1) + x - 1) * 4] += (3 * e) / 16;
					}
				} else if (x == width - 1 && y < height - 1) {
					//下方像素处理
					data[(width * (y + 1) + x) * 4] += (5 * e) / 16;
				} else if (x < width - 1 && y == height - 1) {
					//右边像素处理
					data[(width * y + x + 1) * 4] += (7 * e) / 16;
				}
			}
		}
		return data;
	}
	import esc from "./utils/esc.js";
	import tsc from "./utils/tsc.js";
	import encode from "./utils/encoding.js";
	import {
		get_tem_data
	} from "./printe_template.js";
	import {
		getEdPrintDTODetail
	} from "@/api/index.js";
	export default {
		data() {
			return {
				printing: false,
				imageSrc: "./wechat.jpg",
				jpgSrc: "./wechat.jpg",
				canvasWidth: 100,
				canvasHeight: 100,
				looptime: 0,
				currentTime: 1,
				lastData: 0,
				oneTimeData: 0,
				buffSize: [],
				buffIndex: 0, //发送字节数下标
				printNum: [],
				printNumIndex: 0,
				printerNum: 1,
				currentPrint: 1,
				isLabelSend: false,
				isQuery: false,
				jpgWidth: 200,
				jpgHeight: 200,
				list: [],
				services: [],
				serviceId: 0,
				writeCharacter: false,
				readCharacter: false,
				notifyCharacter: false,
				isScanning: false,
				isReceiptSend: false,
				detail: {},
				type: [],
				detaillist: [],
				eb_detail: {},
				longitude: "",
				latitude: "",
				eb_id: "",
			};
		},
		onLoad: async function(option) {
			this.eb_id = option.id;
			console.log('@@@@@@@@@@@onLoad', option)
			this.get_loc();
		},
		computed: {
			deviceinfo() {
				console.log('computed', this.BLEInformation)
				return this.BLEInformation;
			},
		},
		onShow() {
			var list = [];
			var numList = [];
			var j = 0;
			for (var i = 20; i < 200; i += 10) {
				list[j] = i;
				j++;
			}
			for (var i = 1; i < 10; i++) {
				numList[i - 1] = i;
			}
			this.buffSize = list;
			this.oneTimeData = list[0];
			this.printNum = numList;
			this.printerNum = numList[0];
		},
		methods: {
			closeBluetoothAdapter() {
				wx.closeBluetoothAdapter({
					success(res) {
						console.log('closeBluetoothAdapter', res)
					}
				})
			},
			get_loc() {
				wx.showLoading({
					title: "正在获取经纬度",
					icon: "loading",
				});
				var that = this;
				uni.getLocation({
					type: "wgs84",
					success(res) {
						wx.hideLoading();
						getApp().globalData.location = res;
						console.log("getLocation", res);
						that.latitude = res.latitude;
						that.longitude = res.longitude;
						that.get_EdPrintDTODetail();
					},
					fail() {
						wx.hideLoading();
						that.$tip.toast("获取不到经纬度接口,但支持导出/打印单证");
						that.get_EdPrintDTODetail();
					},
				});
			},
			gettype(val) {
				let type = "";
				if (val.indexOf("DB") !== -1) {
					type = "transfer";
				}
				if (val.indexOf("HS") !== -1) {
					type = "recovery";
				}
				return type;
			},
			getindex(val) {
				return Number(val.replace(/[^\d]/g, ""));
			},
			async get_EdPrintDTODetail() {
				this.printing = true
				wx.showLoading({
					title: "正在获取数据",
					icon: "loading",
				});
				const that = this
				const {
					data
				} = await getEdPrintDTODetail({
					bizNo: this.eb_id,
					longitude: this.longitude,
					latitude: this.latitude,
				}).finally((e) => {
					console.log('getEdPrintDTODetail', e)
					that.$u.toast(e)
				});
				wx.hideLoading();
				if (data.code === 200) {
					this.type = [];
					this.detaillist = [];
					this.eb_detail = data.data;
					data.data.printCategoryPaperList.forEach((m) => {
						let skuNameall = [];
						let realNumall = 0;
						let badBoxNumall = 0;
						let stainedBoxNumall = 0;
						const item_type = this.gettype(m.category);
						const item_index = this.getindex(m.category) - 1;
						const t_data = get_tem_data(item_type, item_index);
						this.type.push(item_type);
						let sku_detail = data.data[m.dataPrefix];
						console.log("sku_detail", m, sku_detail);
						sku_detail?.boxDetailPrintList?.forEach((m) => {
							skuNameall = [...skuNameall, m.skuName];
							realNumall += m.realNum;
							badBoxNumall += m.badBoxNum;
							stainedBoxNumall += m.stainedBoxNum;
						});
						sku_detail = {
							...data.data[m.dataPrefix],
							skuNameall: skuNameall.join("、"),
							realNumall,
							stainedBoxNumall,
							badBoxNumall,
							agentReceiveNo: sku_detail?.agentReceiveNo || "",
						};
						const item = {
							detail: sku_detail, // 数据
							t_detail: t_data, // 模板数据
						};
						this.detaillist.push(item);
						console.log("this.detaillist", this.detaillist);
					});
					if (!this.deviceinfo.deviceId) { // 如果没有设备id就要去搜索设备
						this.startSearch();
					} else { // 有设备id需要验证下连接
						wx.showLoading({
							title: "正在连接蓝牙设备",
							icon: "loading",
						});
						wx.createBLEConnection({
							deviceId: that.BLEInformation.deviceId,
							success: function(res) {
								console.log("连接成功", res, that.BLEInformation);
								// that.BLEInformation.deviceId = e.currentTarget.dataset.title;
								// that.BLEInformation.name = e.currentTarget.dataset.name;
								// console.log("createBLEConnection", res, e, that.BLEInformation);
								wx.hideLoading();
								that.getSeviceId();
							},
							fail: function(e) {
								wx.hideLoading();
								that.$u.toast('设备已断开')
								that.BLEInformation.platform = ''
								that.BLEInformation.deviceId = ''
								that.BLEInformation.writeCharaterId = ''
								that.BLEInformation.writeServiceId = ''
								that.BLEInformation.notifyCharaterId = ''
								that.BLEInformation.notifyServiceId = ''
								that.BLEInformation.readCharaterId = ''
								that.BLEInformation.readServiceId = ''
								that.$forceUpdate()
								that.startSearch();
							},
							complete: function(e) {
								console.log(e);
							},
						});
					}
				} else {
					this.printing = false
					this.$u.toast(data.message);
					setTimeout(function() {
						uni.navigateBack(-1);
					}, 1500);
				}
			},
			receiptTest() {
				//票据打印方法 ,t_data:模板数据
				const that = this;
				var canvasWidth = this.canvasWidth;
				var canvasHeight = this.canvasHeight;
				var command = esc.jpPrinter.createNew();
				command.init(); //初始化打印机
				command.setSelectJustification(1);
				command.setCharacterSize(0);
				command.setText("公司");
				command.setPrint(); //打印并换行
				that.prepareSend(command.getData()); //准备发送数据
			},
			startSearch() {
				var that = this;
				that.closeBluetoothAdapter()
				wx.openBluetoothAdapter({
					success: function(res) {
						wx.getBluetoothAdapterState({
							success: function(res) {
								console.log("openBluetoothAdapter success", res);
								if (res.available) {
									if (res.discovering) {
										// wx.stopBluetoothDevicesDiscovery({
										// 	success: function(res) {
										// 		console.log(res)
										// 	}
										// })
									} else {
										// that.startBluetoothDevicesDiscovery()
										that.getBluetoothDevices();
									}
									// that.checkPemission()
								} else {
									wx.showModal({
										title: "提示",
										content: "本机蓝牙不可用",
										showCancel: false,
									});
								}
							},
						});
					},
					fail: function(res) {
						// if (res.errCode === 10001) {
						//   wx.onBluetoothAdapterStateChange(function (res) {
						//     console.log('onBluetoothAdapterStateChange', res)
						//     if (res.available) {
						//       this.startBluetoothDevicesDiscovery()
						//     }
						//   })
						// }
						console.log(res);
						wx.showModal({
							title: "提示",
							content: "蓝牙初始化失败,请到设置打开蓝牙",
							showCancel: false,
						});
					},
				});
			},
			checkPemission() {
				var that = this;
				var platform = that.BLEInformation.platform;
				if (platform == "ios") {
					that.globalData.platform = "ios";
					that.getBluetoothDevices();
				} else if (platform == "android") {
					that.globalData.platform = "android";
					console.log(
						that
						.getSystem()
						.substring(
							that.getSystem().length - (that.getSystem().length - 8),
							that.getSystem().length - (that.getSystem().length - 8) + 1
						)
					);
					if (
						that
						.getSystem()
						.substring(
							that.getSystem().length - (that.getSystem().length - 8),
							that.getSystem().length - (that.getSystem().length - 8) + 1
						) > 5
					) {
						wx.getSetting({
							success: function(res) {
								console.log(res);
								if (!res.authSetting["scope.userLocation"]) {
									wx.authorize({
										scope: "scope.userLocation",
										complete: function(res) {
											that.getBluetoothDevices();
										},
									});
								} else {
									that.getBluetoothDevices();
								}
							},
						});
					}
				}
			},
			getBluetoothDevices() {
				var that = this;
				console.log("start search");
				wx.showLoading({
					title: "正在搜索",
					icon: "loading",
				});
				that.isScanning = true;
				wx.startBluetoothDevicesDiscovery({
					allowDuplicatesKey: false,
					success: function(res) {
						console.log(res);
						setTimeout(function() {
							wx.getBluetoothDevices({
								success: function(res) {
									console.log("###getBluetoothDevices", res);
									var devices = [];
									var num = 0;
									for (var i = 0; i < res.devices.length; ++i) {
										if (res.devices[i].name != "未知设备") {
											devices[num] = res.devices[i];
											num++;
										}
									}
									that.list = devices;
									that.isScanning = false;
									that.printing = false
									wx.hideLoading();
									wx.stopPullDownRefresh();
									wx.stopBluetoothDevicesDiscovery({
										success: function(res) {
											console.log("停止搜索蓝牙");
										},
									});
								},
							});
						}, 5000);
					},
				});
			},
			bindViewTap(e) {
				console.log("bindViewTap", e);
				var that = this;
				wx.stopBluetoothDevicesDiscovery({
					success: function(res) {
						console.log(res);
					},
				});
				that.serviceId = 0;
				that.writeCharacter = false;
				that.readCharacter = false;
				that.notifyCharacter = false;
				console.log(e);
				wx.showLoading({
					title: "正在连接",
				});
				wx.createBLEConnection({
					deviceId: e.currentTarget.dataset.title,
					success: function(res) {
						console.log("连接成功", res, e, that.BLEInformation);
						that.BLEInformation.deviceId = e.currentTarget.dataset.title;
						that.BLEInformation.name = e.currentTarget.dataset.name;
						console.log("createBLEConnection", res, e, that.BLEInformation);
						that.getSeviceId();
					},
					fail: function(e) {
						wx.showModal({
							title: "提示",
							content: "连接失败",
							showCancel: false,
						});
						console.log("连接失败", e);
						wx.hideLoading();
						that.closeBluetoothAdapter()
					},
					complete: function(e) {
						console.log(e);
					},
				});
			},
			getSeviceId() {
				var that = this;
				var platform = that.BLEInformation.platform;
				console.log(that.BLEInformation.deviceId);
				wx.getBLEDeviceServices({
					deviceId: that.BLEInformation.deviceId,
					success: function(res) {
						console.log("getSeviceId", res);
						// var realId = ''
						// if (platform == 'android') {
						//   // for(var i=0;i<res.services.length;++i){
						//   // var item = res.services[i].uuid
						//   // if (item == "0000FEE7-0000-1000-8000-00805F9B34FB"){
						//   realId = "0000FEE7-0000-1000-8000-00805F9B34FB"
						//   //       break;
						//   //     }
						//   // }
						// } else if (platform == 'ios') {
						//   // for(var i=0;i<res.services.length;++i){
						//   // var item = res.services[i].uuid
						//   // if (item == "49535343-FE7D-4AE5-8FA9-9FAFD205E455"){
						//   realId = "49535343-FE7D-4AE5-8FA9-9FAFD205E455"
						//   // break
						//   // }
						//   // }
						// }
						// that.BLEInformation.serviceId = realId
						that.services = res.services;
						that.getCharacteristics();
					},
					fail: function(e) {
						console.log(e);
					},
					complete: function(e) {
						console.log(e);
					},
				});
			},
			getCharacteristics() {
				var that = this;
				var list = that.services;
				var num = that.serviceId;
				var write = that.writeCharacter;
				var read = that.readCharacter;
				var notify = that.notifyCharacter;
				wx.getBLEDeviceCharacteristics({
					deviceId: that.BLEInformation.deviceId,
					serviceId: list[num].uuid,
					success: function(res) {
						console.log("getCharacteristics", res);
						for (var i = 0; i < res.characteristics.length; ++i) {
							var properties = res.characteristics[i].properties;
							var item = res.characteristics[i].uuid;
							if (!notify) {
								if (properties.notify) {
									that.BLEInformation.notifyCharaterId = item;
									that.BLEInformation.notifyServiceId = list[num].uuid;
									notify = true;
								}
							}
							if (!write) {
								if (properties.write) {
									that.BLEInformation.writeCharaterId = item;
									that.BLEInformation.writeServiceId = list[num].uuid;
									write = true;
								}
							}
							if (!read) {
								if (properties.read) {
									that.BLEInformation.readCharaterId = item;
									that.BLEInformation.readServiceId = list[num].uuid;
									read = true;
								}
							}
						}
						if (!write || !notify || !read) {
							num++;
							that.writeCharacter = write;
							that.readCharacter = read;
							that.notifyCharacter = notify;
							that.serviceId = num;
							if (num == list.length) {
								wx.showModal({
									title: "提示",
									content: "找不到该读写的特征值",
									showCancel: false,
								});
							} else {
								that.getCharacteristics();
							}
						} else {
							that.openControl();
						}
					},
					fail: function(e) {
						console.log(e);
					},
					complete: function(e) {
						console.log("write:" + that.BLEInformation.writeCharaterId);
						console.log("read:" + that.BLEInformation.readCharaterId);
						console.log("notify:" + that.BLEInformation.notifyCharaterId);
					},
				});
			},
			openControl() {
				// 连接成功后打印
				console.log(this.BLEInformation);
				wx.hideLoading();
				const that = this;
				wx.showModal({
					title: "提示",
					content: "蓝牙设备连接成功,是否确认打印",
					success(res) {
						if (res.confirm) {
							that.submitPrinte();
						} else if (res.cancel) {
							that.printing = false
						}
					},
				});
			},
			submitPrinte() {
				console.log("this.detaillist", this.detaillist);
				// if (this.eb_detail) {
				this.receiptTest();
				// } else {
				// 	this.get_loc()
				// }
			},
			prepareSend(buff) {
				//准备发送,根据每次发送字节数来处理分包数量
				//console.log(buff)
				var that = this;
				var time = this.oneTimeData;
				var looptime = parseInt(buff.length / time);
				var lastData = parseInt(buff.length % time);
				//console.log(looptime + "---" + lastData)
				that.looptime = looptime + 1;
				that.lastData = lastData;
				that.currentTime = 1;
				that.Send(buff);
			},
			Send(buff) {
				this.printing = true
				//分包发送
				var that = this;
				var currentTime = this.currentTime;
				var loopTime = this.looptime;
				var lastData = this.lastData;
				var onTimeData = this.oneTimeData;
				var printNum = this.printerNum;
				var currentPrint = this.currentPrint;
				var buf;
				var dataView;
				if (currentTime < loopTime) {
					buf = new ArrayBuffer(onTimeData);
					dataView = new DataView(buf);
					for (var i = 0; i < onTimeData; ++i) {
						dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i]);
					}
				} else {
					buf = new ArrayBuffer(lastData);
					dataView = new DataView(buf);
					for (var i = 0; i < lastData; ++i) {
						dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i]);
					}
				}
				console.log(
					"第" + currentTime + "次发送数据大小为:" + buf.byteLength,
					this.BLEInformation
				);
				setTimeout(() => {
					wx.writeBLECharacteristicValue({
						deviceId: this.BLEInformation.deviceId,
						serviceId: this.BLEInformation.writeServiceId,
						characteristicId: this.BLEInformation.writeCharaterId,
						value: buf,
						success: function(res) {
							if (currentTime <= loopTime) {
								// wx.showLoading({
								//   title: '传输中...',
								// })
							} else {
								wx.showToast({
									title: "已打印第" + currentPrint + "张成功",
								});
							}
							//console.log(res)
						},
						fail: function(e) {
							console.log("失败原因", e);
							if ([10003, 10006, 10000, 10001, 10002].includes(e.errCode)) {
								wx.showToast({
									title: "打印失败,蓝牙已断开连接",
									icon: "none",
								});
								that.closeBluetoothAdapter()
								that.BLEInformation.platform = ''
								that.BLEInformation.deviceId = ''
								that.BLEInformation.writeCharaterId = ''
								that.BLEInformation.writeServiceId = ''
								that.BLEInformation.notifyCharaterId = ''
								that.BLEInformation.notifyServiceId = ''
								that.BLEInformation.readCharaterId = ''
								that.BLEInformation.readServiceId = ''
								that.$forceUpdate()
							} else {
								wx.showToast({
									title: "打印失败",
									icon: "none",
								});
							}
							that.printing = false
							//console.log(e)
						},
						complete: function() {
							currentTime++;
							if (currentTime <= loopTime) {
								that.currentTime = currentTime;
								that.Send(buff);
							} else {
								if (currentPrint == printNum) {
									console.log('that.looptime', that.looptime)
									const num = that.looptime
									setTimeout(() => {
										that.printing = false
									}, num * 80)
									that.looptime = 0;
									that.lastData = 0;
									that.currentTime = 1;
									that.isReceiptSend = false;
									that.currentPrint = 1;

								} else {
									currentPrint++;
									that.currentPrint = currentPrint;
									that.currentTime = 1;
									that.Send(buff);
								}
							}
						},
					});
				}, 50);
			},
		},
	};
</script>

<style scoped lang="scss">
	.btncss {
		background-color: white;
		padding-inline: 20rpx;
		width: 100%;
		padding-top: 30rpx;
		padding-bottom: 50rpx;
		box-shadow: 2px 2px 4px 4px rgba(223, 223, 223, 0.5);
		z-index: 9999;
	}

	.linkcss {
		border: 2px solid #54bec2;
		padding: 10px;
		margin: 10px;
	}

	.button {
		margin-top: 20px;
		margin-bottom: 20px;
		width: 70%;
		background-color: #54bec2;
		color: white;
		border-radius: 98rpx;
		background: bg_red;
	}

	/* 按下变颜色 */
	.hover {
		background: #dcdcdc;
	}

	.device_list {
		height: auto;
		margin-left: 20rpx;
		margin-right: 20rpx;
		margin-top: 10px;
		margin-bottom: 20px;
		/* border: 1px solid #EEE; */
		width: auto;
	}

	.td {
		display: flex;
		align-items: center;
		justify-content: center;
		margin-top: 10px;
	}

	/* .item {
    padding-top: 10px;
    padding-bottom: 10px;
     height: 130rpx;
     width: 100%;
} */
	.item {
		display: block;
		background-color: white;
		border-radius: 18rpx;
		margin-bottom: 16rpx;
		padding: 8px;
	}

	.item_hover {
		background-color: rgba(0, 0, 0, 0.1);
	}

	.block {
		display: block;
		color: #ffffff;
		padding: 5px;
	}

	.button::after {
		border-width: 0px;
	}

	.sign_step>view::after {
		// 对钩的三角行底色
		position: absolute;
		right: 0;
		top: 0;
		width: 0;
		height: 0;
		content: "";
		border: 16px solid;
		border-color: #70cad3 #70cad3 transparent transparent;
		border-bottom-right-radius: 2px;
	}

	.sign_step {
		position: relative;
		border: 2px solid #54bec2;
	}

	.sign_step>view::before {
		// 对钩样式
		position: absolute;
		right: 2px;
		top: 4px;
		z-index: 1;
		width: 10px;
		height: 5px;
		content: "";
		background: transparent;
		border: 2px solid white;
		border-top: none;
		border-right: none;
		-webkit-transform: rotate(-55deg);
		-ms-transform: rotate(-55deg);
		transform: rotate(-55deg);
	}

	/* pages/bleConnect/bleConnect.wxss */
</style>
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值