当前位置: 首页 > news >正文

微信小程序前后端开发快速入门(完结篇)

这篇是微信小程序前后端快速入门完结篇了,今天利用之前学习过的所有知识做一个新的项目「群登记助手v1.0」小程序。

整体技术架构:小程序原生前端+小程序云开发。

image.png
经历了前面教程的学习,大家有了一定的基础,所以本次分享重心主要是带着大家理清楚逻辑相关的云开发处理方案和之前未讲解过的重要组件,之前已经讲解过的重复知识就不会重新再讲解,需要大家利用之前已经学习过的知识来组合今天学习的新知识对接龙小程序进行整体的完善。

业务分析

流程分析

接龙小程序使用者角色上会有两种,分别是发起者和参与者。这个接龙是由发起者来让参与者接龙,所以他们两之间的使用逻辑是:

image.png
一共有以下七步,来完成整个接龙行为的闭环。

  1. 发起者 - 创建接龙活动
  2. 发起者 - 进入接龙列表
  3. 发起者 - 转发到微信群
  4. 参与者 - 点击程序卡片
  5. 参与者 - 进入活动详情
  6. 参与者 - 接龙信息填写
  7. 参与者 - 进入活动详情

界面如下:

image.png

数据库设计

首先数据库设计来看,我们需要三张表:

  1. 用户表(users),用于用户体系的基础搭建

image.png
2. 接龙活动表(solitaire),用于存放发起者接龙活动

image.png
3. 接龙信息表(solitaire_info),用于存放参与者接龙信息

image.png

实现路线图

难点部分会进行分析讲解,简单部分需自行实现(之前教过的知识点)

  1. 创建活动 -> 获取用户信息 -> 用户表插入用户数据 -> 活动表插入活动信息
  2. 转发活动 -> 通过联合查询出活动列表 -> 将接龙活动转发到群里
  3. 查询信息 -> 通过分享的活动ID查询详情 -> 跳转到填写信息
  4. 填写信息 -> 获取用户信息(同上)-> 信息表插入接龙信息 -> 更新活动参与人数 -> 发送订阅消息
  5. 回到详情 -> 刷新接龙信息列表(使用聚合查询)
  6. 其他功能 -> 导出表格

复杂查询

由于接龙信息和用户信息分别在两张表中实现,所以这里需要用到联表查询。这个时候就需用到小程序的聚合查询能力。

联表查询

如我们现在已经有一条活动数据了,那么现在数据库的数据结构应该是这样的:
用户表 users:

image.png
接龙表 solitaire:

image.png
然后使用 lookup 函数进行关联起来。
以下为属性含义

lookup({from: <要连接的集合名>,localField: <输入记录的要进行相等匹配的字段>,foreignField: <被连接集合的要进行相等匹配的字段>,as: <输出的数组字段名>
})

结合以上使用方式,我们使用下lookup连接查询

async queryLookupList(context, params) {let res = await db.collection('solitaire').aggregate().match({openid: context.OPENID}).lookup({from: 'users',localField: 'openid',foreignField: '_openid',as: 'users',}).sort({date: -1}).end()return res}

最后查询出来的结果是:

[{"_id": "cd045e756110ed09047443683dd70ecf","content": "312312","date": "2021-08-09 16:53","title": "12312","type": 1,"openid": "oyfiv5Z90bqbQ6BJ6A273eP68j-w","number": 0,"users": [{"_id": "8937eaa96110ea39039e900278a1529e","_openid": "oyfiv5Z90bqbQ6BJ6A273eP68j-w","date": "2021-08-09T08:41:29.878Z","userInfo": {"avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJ9VBHPzRxk4M7bc4xxwXOaw6DpciahEjzeZ4GP0UoSmiaqBMFQznROZlVG5ukvpv8dSXNzl34oaP7g/132","city": "Changsha","country": "China","gender": 1,"language": "zh_CN","nickName": "111陈宇明","province": "Hunan"}}]}]

由于在实际复杂业务中,聚合查询使用的比较多的,所以再次我们带大家来对聚合查询进行更深入的了解。

聚合查询

聚合是非常强大的数据分析工具,主要用于对记录进行批量处理,可以对记录进行按条件分组、跨集合联表等一系列批量而又复杂操作。类似于Excel整列整列跨字段的运算(如加、减、合并、比较等)、对内嵌的字段可以进行整列拆分、类型变换、组合等。

聚合查询 VS 普通查询

聚合aggregate和普通数据查询get是两套不同的体系,聚合更偏向于数据的复杂查询。聚合查询和普通数据查询都能对数据库进行查询,两个的很多方法都特别类似,我们可以通过对之前普通查询的理解来理解聚合查询的部分功能,具体查看以下表格对比。

image.png
在这里需要注意的是使用聚合查询之前需要先 aggregate() 发起一个聚合操作。以上是普通查询可以做到的,聚合查询也可以做到,接下来是普通查询做不到的。

聚合阶段

聚合阶段是聚合管理流水线作业的组成单元,是一个个功能节点,有的可以联表lookup、有的可以组合group、有的可以拆分unwind等等。每个聚合阶段可以使用表达式、操作符对输入文档进行计算综合、均值、拼接、分割、转换格式等操作,操作完成之后会输出给下一个阶段,直到end返回结果。

image.png

小技巧

在这里告诉大家一个小技巧,其实写查询的时候可以在数据库的高级操作区间先写好测试然后再放到函数中去使用,这样可以提高效率。

image.png
在这里不需要获取数据库对象,直接通过db就能使用,数据也不需要打印出来,只要使用了结束函数就可以了。

订阅消息

当发起者转发到群里之后,参与者就可以填写接龙信息,当接龙信息填写完成之后,可以在这里给到参与者发送一个订阅消息,告知参与者接龙成功。

这样设计有两个好处:

  1. 便于再次激活用户,多一个入口就多一些用户打开的概率。
  2. 更快捷的打开方式(提升1倍的效率)
  3. 正常打开路径:
  4. 下拉聊天界面进入小程序列表
  5. 点击接龙小程序
  6. 找到参与的接龙活动
  7. 找到具体接龙点击查看详情
  8. 订阅模版
  9. 进入服务通知列表
  10. 找到具体模版点击查看详情

那么如何给用户发送订阅消息呢?请接着往下看:

申请消息模版

第一步,先登录到后台,找到订阅消息菜单->申请订阅消息模版

image.png

第二步,进入订阅消息列表页面,点击选用按钮

image.png

第三步,进入选用模版库,通过关键词搜索进行查找,消息模版和小程序的类目有关,以“接龙”为例,小程序类目是「预约/报名,笔记」所以搜索到了这两个类目下的消息模版。

image.png

第四步,选择自己需要的模版,点击「选用」进入详情页面。模版有很多关键词,只需要勾选自己需要的关键词即可,然后填写下场景说明即可点击提交

image.png

第五步,填写完成后,会在我的模版看到刚才申请好的消息模版,复制模版ID即可,到时候然后切换到小程序端进行使用

image.png

获取订阅授权

第六步,找到小程序需要让用户授权的触发方法。如:需求是当用户填写完成接龙资料,让用户授权报名成功提醒,然后发一条报名成功的订阅消息,那么这个时候就需要找到填写信息的方法。如果只是单独先对这个功能进行学习,那么就可以在一个页面写个按钮,然后按钮绑定一个点击事件触发即可。

写在任意测试页面wxml

<button bindtap="onMsg" >测试订阅消息</button>

当前测试页面对应的js

wx.requestSubscribeMessage({tmplIds: ['模版ID'], success(res) {console.log(res)}})

第七步,用真机调试,模拟器不支持。点击之后界面会出现授权页面。

image.png

以下为我分别点击取消和允许的日志输出。用户可以支持一次调用最多可订阅3条消息。

image.png

然后我们再来看下 requestSubscribeMessage 文档中对返回体的解释

image.png

对于开发者来说,需要关心的就是是否用户允许来,所以我们需要通过以下方式获取结果,当结果是允许的时候我们插入就发送成功通知给到用户即可。当然我这里指的是用户添加完后发送添加成功通知的业务路径,如果不是需要当前动作完成后发送的话,那么就需要存储一条记录到数据库,等需要用到的时候再去做发送消息模版的动作。

onMsg() {wx.requestSubscribeMessage({tmplIds: ['模版ID'],success(res) {if(res.模版ID=='accept'){// 发送消息给到用户}}})}

发送模版消息

第七步,发送模版消息,新建一个发送模版消息的云函数 sendMessage ,然后打开 subscribeMessage. send 文档,可以看到这个方法支持云调用,也就是说官方已经帮开发者封装好了方法使用起来非常简单。

云调用是云开发提供的基于云函数使用小程序开放接口的能力

image.png

那么我们就用云调用方法来试试,首先在 sendMessage 的config.json文件配置权限

{"permissions": {"openapi": ["subscribeMessage.send"]}
}

然后在js中编写调用发送模版消息的方法,方法参数如下:

image.png

我把重要的参数用红色框框标记起来了,看下代码。

// 云函数入口文件
const cloud = require('wx-server-sdk')cloud.init()// 云函数入口函数
exports.main = async (event, context) => {const wxContext = cloud.getWXContext()const result = await cloud.openapi.subscribeMessage.send({"touser": wxContext.OPENID, // 发给自己直接从 getWXContext 获取"templateId":'模版ID',"page": '目标页面路径',"lang": 'zh_CN',"data": {"thing2": {"value": '报名接龙2021'},"phrase8": {"value": '报名成功'},"thing19": {"value": '详细点击查看=>'}},"miniprogramState": 'developer'})return result}

注意 data 这个参数需要回到小程序管理后台的消息订阅列表查看订阅模版的详情

image.png

这里需要注意每个不同的数据类型都有些限制条件详细可见文档,然后data参数需要和上面的模版内容一对一对应上,方法写完上传并部署即可。

第八步,调用模版消息。

onMsg() {wx.requestSubscribeMessage({tmplIds: ['模版ID'],success(res) {if (res.XXXXID == 'accept') {wx.cloud.callFunction({name: 'sendMessage'}).then(res => {console.log(res)})}}})}

调用成功后会在微信聊天页面的服务通知中收到模版消息提醒,点击即可进入小程序,效果如下:

image.png

导出表格

使用云函数使用Node.js的node-xlsx模块

安装模块

  1. 新建云函数 excel
  2. 右键云函数选择在外部终端窗口开打

image.png

  1. 输入命令
npm install node-xlsx
  1. 安装成功

image.png

  1. 文件结构

image.png

使用模块

  1. 导入模块
const xlsx = require('node-xlsx') 
  1. 准备数据
let row = ['姓名', '电话', '备注']; //表格的属性let allData = [] //表格内容// 添加表头allData.push(row)// 假数据,真实数据需要从小程序端传递过来或在云函数中云数据库查询出来allData.push(['陈宇明', '13148123123', ''])allData.push(['陈X明', '13148123123', '不知道'])
  1. 生成表格
// 生成表格var buffer = await xlsx.build([{name: 'mySheetName',data: allData}]);
  1. 最后生成完成之后还需要用到我们之前学习过的上传文件 uploadFile 上传到云存储中
 let cloudPath = `xlsx/${Math.floor(Math.random()*1000000000)}.xlsx`
//上传文件返回结果return await cloud.uploadFile({cloudPath: cloudPath,fileContent: buffer, //excel二进制文件})
  1. 调试一下

image.png

  1. 查看文件

image.png

  1. 通过复制下载链接,打开查看表格内容

image.png

在线查看文档

当获取到文件ID,在使用 getTempFileURL 用云文件 ID 换取真实链接,然后 downloadFile 下载文件资源到本地,通过 openDocument 新开页面打开文档。

openExcel(){wx.cloud.callFunction({name: "excel",data: {infos: {} //表格数据},complete: res => {wx.cloud.getTempFileURL({fileList: [res.result.fileID],success: res => {this.setData({tempFileURL: res.fileList[0].tempFileURL})console.log(this.data.tempFileURL)wx.downloadFile({url: this.data.tempFileURL,success: (res) => {const filePath = res.tempFilePathconsole.log(filePath)wx.openDocument({filePath: filePath,showMenu: true,success: res => {console.log(res)}})}})}})}})},

复制下载链接

当获取到文件ID,在使用 getTempFileURL 用云文件 ID 换取真实链接,然后 setClipboardData 设置系统剪贴板的内容。

 getExcelUrl() {wx.cloud.callFunction({name: "excel",data: {infos: {} //表格数据},complete: res => {wx.cloud.getTempFileURL({fileList: [res.result.fileID],success: res => {this.setData({tempFileURL: res.fileList[0].tempFileURL})wx.setClipboardData({ //复制到粘贴板data: this.data.tempFileURL,success(res) {wx.getClipboardData({success(res) {}})}})}})}})},

最后

这篇教程相比之前的备忘录教程更像是一道填空题,需要大家利用之前教程学习到的知识进行融合才能实现这个小程序,独立完成这个项目才是检验学习效果的最佳方式。

学习更多小程序云开发知识请关注CRMEB开源项目

相关文章:

微信小程序前后端开发快速入门(完结篇)

这篇是微信小程序前后端快速入门完结篇了&#xff0c;今天利用之前学习过的所有知识做一个新的项目「群登记助手v1.0」小程序。 整体技术架构&#xff1a;小程序原生前端小程序云开发。 经历了前面教程的学习&#xff0c;大家有了一定的基础&#xff0c;所以本次分享重心主要是…...

【Linux】进程间通信之消息队列

文章目录 消息队列的概念消息队列的出队特点消息队列函数接口获取消息队列向消息队列发送消息接收消息操作消息队列的接口 代码演示ipcs命令 消息队列的概念 消息队列提供进程间数据块传输的方法&#xff0c;传输的每一个数据块都认为是有类型的&#xff0c;不同的数据块是有优…...

一次Linux中的木马病毒解决经历(6379端口---newinit.sh)

病毒入侵解决方案 情景 最近几天一直CPU100%,也没有注意看到了以为正常的服务调用,直到腾讯给发了邮件警告说我的服务器正在入侵其他服务器的6379端口,我就是正常的使用不可能去入侵别人的系统的,这是违法的. 排查 既然入侵6379端口,就怀疑是通过我的Redis服务进入的我的系统…...

ProtoBuf

文章目录 1.认识 ProtoBuf2. 安装ProtoBuf3. 快速上手 ProtoBuf4. proto3 语法5. probuf 实战6. 总结 1.认识 ProtoBuf 在认识 啥是 ProtoBuf 之前我们先来 回顾一下 &#xff08;或 了解 一下 啥是 序列化&#xff09; 序列化概念回顾 : 图一 : 回顾 序列化 &#xff0c;下面…...

AJ-Captcha行为验证在vue中的使用

项目场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 项目场景&#xff1a;由原先的验证码校验升级为行为验证校验 使用方法 提示&#xff1a;参考文档&#xff1a; 参考文档&#xff1a;vue使用AJ-Captcha文档 gitee地址&#xff1a;AJ-Captcha &…...

Layui列表复选框根据条件禁用

// 禁用客服回访id有值的复选框res.data.forEach(function (item, i) {if (item.feedbackEmpId) {let index res.data[i][LAY_TABLE_INDEX];$(".layui-table tr[data-index"index"] input[typecheckbox]").prop(disabled,true);$(".layui-table tr[d…...

K8S核心组件etcd详解(下)

1 k8s如何使用etcd 在k8s中所有对象的manifest都需要保存到某个地方&#xff0c;这样他们的manifest在api server重启和失败的时候才不会丢失。 只有api server能访问etcd&#xff0c;其它组件只能间接访问etcd的好处是 增强乐观锁系统及验证系统的健壮性 方便后续存储的替换…...

【HarmonyOS】【DevEco Studio】ohpm安装失败该如何解决?

【关键词】 HarmonyOS、DevEco Studio、ohpm安装失败 【问题背景及解决方案】 最近遇到很多DevEco Studio安装ohpm失败的问题&#xff0c;下面给大家介绍几种出现的问题以及解决方案&#xff1a; 1、ohpm not set up&#xff0c;报错截图如下&#xff1a; ​ 解决方案&…...

STM32 cubemx CAN

接收用到的结构体如下&#xff1a;CAN概念&#xff1a; 全称Controller Area Network&#xff0c;是一种半双工&#xff0c;异步通讯。 物理层&#xff1a; 闭环&#xff1a;允许总线最长40m&#xff0c;最高速1Mbps&#xff0c;规定总线两端各有一个120Ω电阻&#xff0c;闭环…...

贴片电阻封装尺寸及焊盘尺寸

1、贴片电阻封装尺寸 有英制和公制之分&#xff0c;英制的单位是inch&#xff0c;公制的单位是m&#xff1b;&#xff08;m、cm、mm只是进制不同&#xff09; 通常说的都是英制&#xff0c;比如0603指的是inch单位下的0.06inch和0.03inch&#xff1b; 下图有inch和mm的对照、…...

软考笔记——9.软件工程

软件工程的基本原理&#xff1a;用分阶段的生命周期计划严格管理、坚持进行阶段评审、实现严格的产品控制、采用现代程序设计技术、结果应能清除的审查、开发小组的人员应少而精、承认不断改进软件工程事件的必要性。 软件工程的基本要素&#xff1a;方法、工具、过程 软件生…...

uniapp小程序实现上传图片功能,并显示上传进度

效果图&#xff1a; 实现方法&#xff1a; 一、通过uni.chooseMedia(OBJECT)方法&#xff0c;拍摄或从手机相册中选择图片或视频。 官方文档链接: https://uniapp.dcloud.net.cn/api/media/video.html#choosemedia uni.chooseMedia({count: 9,mediaType: [image,video],so…...

基于物理场的动态模式分解(piDMD)研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Docker部署rabbitmq遇到的问题 Stats in management UI are disabled on this node

1. Stats in management UI are disabled on this node #进入rabbitmq容器 docker exec -it {rabbitmq容器名称或者id} /bin/bash#进入容器后&#xff0c;cd到以下路径 cd /etc/rabbitmq/conf.d/#修改 management_agent.disable_metrics_collector false echo management_age…...

Python搭建http文件服务器实现手机电脑文件传输功能

第一种代码的界面如下&#xff1a;&#xff08;有缺点&#xff0c;中文乱码&#xff09; # !/usr/bin/env python3 # -*- coding:utf-8 _*-"""Simple HTTP Server With Upload. python -V3.6 This module builds on http.server by implementing the standard G…...

微信小程序实现拖拽的小球

目录 前言 js 获取微信小程序中获取系统信息 触摸移动事件的处理函数 触摸结束事件的处理函数 用于监听页面滚动事件 全局参数 html CSS 前言 小程序开发提供了丰富的API和事件处理函数&#xff0c;使得开发者可以方便地实现各种交互功能。其中&#xff0c;拖拽功能…...

uniapp的逆地理编码 和地理编码

1.先打开高德地图api找到那个 地理编码 2.封装好我们的请求 3.逆地理编码 和地理编码 都是固定的 记住自己封装的请求 就可以了 这个 是固定的 方式 下面这个是固定的 可以复制过去 getlocation就是uniapp提供的 获取经纬度 然后 下面的 就是高德地图提供的 方法 要想使用我…...

在Centos环境中搭建Nginx环境

一、Nginx概念简介 Nginx是一个轻量级的高性能HTTP反向代理服务器&#xff0c;同时它也是一个通用类型的代理服务器&#xff0c;支持绝大部分协议&#xff0c;如TCP、UDP、SMTP、HTTPS等。 Nginx与redis相同&#xff0c;都是基于多路复用模型构建出的产物&#xff0c;因此它与R…...

20W IP网络吸顶喇叭 POE供电吸顶喇叭

SV-29852T 20W IP网络吸顶喇叭产品简介 产品用途&#xff1a; ◆室内豪华型吸顶喇叭一体化网络音频解码扬声器&#xff0c;用于广播分区音频解码、声音还原作用 ◆应用场地如火车站、地铁、教堂、工厂、仓库、公园停车场等&#xff1b;室内使用效果均佳。 产品特点&#xff…...

React 之 Suspense和lazy

一. Suspense 参考链接&#xff1a;https://react.docschina.org/reference/react/Suspense suspense&#xff1a;n. 焦虑、悬念 <Suspense> 允许你显示一个退路方案&#xff08;fallback&#xff09;直到它的所有子组件完成加载。 <Suspense fallback{<Loadin…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist

现象&#xff1a; android studio报错&#xff1a; [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决&#xff1a; 不要动CMakeLists.…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

【Linux手册】探秘系统世界:从用户交互到硬件底层的全链路工作之旅

目录 前言 操作系统与驱动程序 是什么&#xff0c;为什么 怎么做 system call 用户操作接口 总结 前言 日常生活中&#xff0c;我们在使用电子设备时&#xff0c;我们所输入执行的每一条指令最终大多都会作用到硬件上&#xff0c;比如下载一款软件最终会下载到硬盘上&am…...

实战设计模式之模板方法模式

概述 模板方法模式定义了一个操作中的算法骨架&#xff0c;并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下&#xff0c;重新定义算法中的某些步骤。简单来说&#xff0c;就是在一个方法中定义了要执行的步骤顺序或算法框架&#xff0c;但允许子类…...

命令行关闭Windows防火墙

命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)​方法二:CMD命令…...