【微信小程序】启动项目

一、团队开发准备

1.1 申请权限

团队开发小程序时一般不再使用个人的 AppID,而使用企业 AppID 时做为开发人员需要先申请权限,权限可以分成两种:

  • 开发者权限:提供给开发者使用(程序员)

    • 提供开发者的微信号
    • 获取企业(团队)AppID
  • 体验者权限:提供给测试、产品、客户等

    • 提供体验者的微信号
    • 扫码申请,由管理员审核通过
1.2 开发环境

小程序原始的一套开发环境比较基础,小程序项目的规模变大后将不易管理,需要有针对性的对开发环境进行调整 ,主要有3个方面:

1. 优化目录结构

将涉及业务的代码独立到单独的目录当中,非业务的文件和目录直接放在根目录中,调整后小程序运行会报错,需要修改 project.config.json 中的配置项:

{"setting": {"packNpmManually": true,"packNpmRelationList": [{"miniprogramNpmDistDir": "业务代码所在目录","packageJsonPath": "package.json的路径"}]},"miniprogramRoot": "业务代码所在目录"
}

2. 启用 less/sass

通过 less/sass 可以更好的管理 css 样式,通过 project.config.json 可以启用对 less/sass 的支持。

{"setting": {"useCompilerPlugins": ["sass"]}
}

然后将 .wxss 文件后缀改换成 .scss 即可。

3. 配置 VS Code(了解)

小程序开发者工具的代码编辑器功能相较 VS Code 是有些不足的(其实小程序开发者工具是基于 VS Code 开发的),因此为了提高代码编写的效率,编写小程序代码时使用 VS Code 调试小程序仍然用小程序开发者工具。

安装用于小程序开发的一些插件:

  • WXML - Language Service 小程序代码语法高亮和提示

    {"minapp-vscode.wxmlFormatter": "prettier","minapp-vscode.prettier": {"useTabs": false,"tabWidth": 2,"printWidth": 80,"singleQuote": false},"[wxml]": {"editor.defaultFormatter": "qiu8310.minapp-vscode"},"minapp-vscode.formatMaxLineCharacters": 80,
    }
    
  • Prettier - Code Formatter 格式化代码

  • … 其它

二、享+生活

享+社区是一个生活类的小程序项目,主要服务于小区业主,为其提供生活家电报修、访客门禁通行的的功能,该项目主要包含房屋管理、报修管理、访客管理、用户管理、通知管理等功能模块,技术栈以原生小程序技术为主配合了 Vant 组件库。

2.1 启动项目
2.1.1 拉取代码

享+社区小程序项目静态页面已经完成,我们的任务是联调接口处理业务逻辑,以下是代码仓库地址:

# gitee 仓库
git clone -b template https://gitee.com/lotjol/enjoy-plus.git

通过 git clone 拉取代码时默认会将远仓库地址指向了我的的仓库,会导致同学们 push 代码时失败,如果在企业中的情况下,需要联系负责人将你添加为团队开发者获取权限。

2.1.2 运行小程序

使用小程序开发者工具导入【享+生活】的代码,注意由于我没有给大家添加开发者权限,因此不能使用我的 AppID 开发小程序,大家要换成个人 AppID!

接下来通过 VS Code 打开【享+生活】的代码,打开命令行终端安装项目的依赖:

npm install

最后使用小程序开发者工具构建 npm

重点注意的是 project.config.js 中的几个配置:

{"miniprogramRoot": "miniprogram/","setting": {"useCompilerPlugins": ["sass"],"packNpmManually": true,"packNpmRelationList": [{"packageJsonPath": "./package.json","miniprogramNpmDistDir": "./miniprogram"}],}
}
  • miniprogramRoot 项目的根目录为 miniprogram
  • setting.useCompilerPlugins 启用了 sass 支持
  • packNpmRelationList 指定了 npm 构建时所需的 package.json 的位置以及构建后代码的生成位置
2.2 基础封装

在小程序项目的开发过程中将一些通用的功能逻辑封装成方法能够提高开发的效率。

2.2.1 消息反馈

将所有通用的工具方法封装到 utils/utils.js 中:

// utils/utils.js
const utils = {/*** 用户消息反馈* @param {string} title 文字提示的内容*/toast(title = '数据加载失败...') {wx.showToast({title,mask: true,icon: 'none',})}
}
// 模块导出
export default utils

除了将封装的模块正常导出外,还可以挂载到全局对象 wx 上,这样在使用的时候会更方便一些。

// 在 app.js 中导入 utils.js
import utils from './utils/utils.js'// 挂载到全局对象 wx
wx.utils = utilsApp({// ...
})
2.2.2 网络请求

小程序 API wx.request 不支持返回 Promise、拦截器等功能,需要开发者进行二次封装,也可以使用第三方的封装好的模块。

npm install wechat-http

注:安装完成后还必须要构建 npm后才可以使用。

接下来介绍 wechat-http 模块的使用,其用法与 axios 类似:

  • http.baseURL 配置接口基础路径
  • http.getGET 方法发起请求
  • http.postPOST 方法发起请求
  • http.putPUT 方法发起请求
  • http.deleteDELETE 方法发起请求
  • http.intercept 配置请求和响应拦截器
  • http 本身做为函数调用也能用于发起网络请求

新建 utils/http.js 文件

// 导入 http 模块
import http from 'wechat-http'
// 基础路径,同时需添加合法请求域名
http.baseURL = 'https://live-api.itheima.net'// 响应拦截器,返回核心数据 data
http.intercept.response = ({ data }) => {return data
}// 普通的模块导出
export default http

以全局对象方式调用时需要在入口中执行 utils/http.js

// 导入 uitls/http.js
import http from './utils/http.js'// 挂载到全局对象
wx.http = httpApp({// ...
})

【享+生活】接口文档地址

2.3 公告管理

公告管理主要有两部的业务逻辑需要处理:一是获取公告列表,二是查看公告的详情。

2.3.1 公告列表

在首页面调用接口获取公告列表数据,每次只会返回 3 条数据,不需要处理分页。

接口文档地址

参考代码如下所示:

Page({onLoad() {// 获取公告列表数据this.getNotices()},// 调用公告列表接口async getNotices() {// 请求接口const {code, data: notices} = await wx.http.get('/announcement')// 渲染数据this.setData({notices})}
})

模板中渲染数据:

<view class="notices-body"><navigatorwx:for="{{notices}}"wx:key="id"hover-class="none"url="/pages/notify/index"class="notice"><view class="notice-title">{{item.title}}</view><view class="notice-brief">{{item.content}}</view><view class="notice-date">{{item.createdAt}}</view></navigator>
</view>
2.3.2 公告详情

点击公告列表后将公告的ID通过地址参数传递到公告详情页面,在 onLoad 生命周期中读取到公告 ID,然后调用接口获取公告详情的数据。

接口文档地址

参考代码如下所示:

Page({data: {noticeDetail: {}},onLoad({id}) {// 获取公告详情数据this.getNoticeDetail(id)},// 调用公告详情接口async getNoticeDetail(id) {// 检测 id 是否存在if(typeof id === undefined) return// 调用接接口const {code, data: noticeDetail} = await wx.http.get('/announcement/' + id)// 渲染数据this.setData({noticeDetail})}
})

在模板中渲染数据:

<scroll-view enhanced show-scrollbar="{{false}}" scroll-y><view class="notify-meta"><view class="title">{{noticeDetail.title}}</view><view class="extra"><view class="author">{{noticeDetail.creatorName}}</view><view class="datetime">{{noticeDetail.createdAt}}</view></view></view><view class="notify-content"><rich-text nodes="{{noticeDetail.content}}"></rich-text></view>
</scroll-view>

在小程序中无法直接解析富文本中包含的 HTML 标签,必须通过内置的小程序组件 rich-text 才能解析富文件,其用法是将富文件的内容赋值给 nodes 属性即可:

<!-- rich-text 使用示例 -->
<rich-text nodes="{{'<h1>这里的 h1 标签可以被小程序解析</h1>'}}"></rich-text>
2.4 用户管理

用户管理主要包含登录检测、短信验证码、登录&注册、头像和昵称的功能。

2.4.1. 登录检测

在项目中大部分的页面要用户必须是登录状态才能被访问,将检测登录的逻辑封装到一个组件(authorization)当中,只要在页面中应用这个组件就能实现用户登录状态检测的功能了。

  1. 在根目录中创建 components 文件夹用来存放全局的组件,然后通过小程序开发者工具创建一个名为 authorization 的组件(步骤略)

  2. 接下来全局来注册这个组件,保证任何页面中都可以直接应用 authorization 组件:

    {"usingComponents": {"authorization": "/components/authorization/index"},
    }
    
  3. 到用户信息页面中应用 authorization 使用做为页面根节点

    <authorization><view class="profile">...</view>
    </authorization>
    
  4. 读取本地存储的 token 数据,用于判断是否曾登录过

    // app.js
    App({onLaunch() {// 读取本地存储的 token 数据this.getToken()},getToken() {// 将 token 数据记到应用实例中this.token = wx.getStorageSync('token')}
    })
    

    注:当前未实现登录的功能,因此读取到的 token 数据为 undefined

  5. 检测登录状态,要求未登录时不显示页面中的内容且跳转到登录页面

    <!-- /components/authorization/index.wxml -->
    <slot wx:if="{{isLogin}}"></slot>
    
    // components/auth/auth.js
    Component({data: {isLogin: false},lifetimes: {attached() {// 获取登录凭证,判断用户是否已登录const app = getApp()// 转换成布尔类型const isLogin = Boolean(app.token)// 更新页面数据this.setData({ isLogin })// 如果未登录,跳转到登录页if (isLogin === false) {// 关闭当前页面,跳转到登录页wx.redirectTo({url: '/pages/login/index',})}}},
    })
    
2.4.2 短信验证码

短信验证倒计时的交互使用了 Vant 的组件 van–count-down

  • time 指定倒计时时长
  • bind:change 监听时间的变化
  • use-slot 启用插槽(自定义倒计时内容)

van-count-down 组件的应用示例:

<van-count-down use-slot time="{{ 60 * 1000 }}" bind:change="countDownChange"><text>{{timeData.seconds}}秒后重新获取</text>
</van-count-down>
Page({// 监听时间的变化countDownChange(ev) {this.setData({// 倒计时当前的时间值timeData: ev.detail,})},
})
  1. 结合项目来使用 van-count-down 组件,当用户点击了获取验证码按钮后再启用倒计时组件,通过数据 countDownVisible 进行控制:

    Page({data: {// 初始状态不启用倒计时组件countDownVisible: false},getSMSCode() {// 点击后启用倒计时组件this.set({countDownVisible: true})}
    })
    
    <text bind:tap="getSMSCode" wx:if="{{!countDownVisible}}">获取验证码</text>
    <van-count-down wx:else use-slot time="{{ 60 * 1000 }}" bind:change="countDownChange"><text>{{timeData.seconds}}秒后重新获取</text>
    </van-count-down>
    

    另外还要处理倒计时结束后的状态,此时需要将倒计时组件关闭:

    Page({countDownChange(ev) {this.setData({timeData: ev.detail,// 倒时结束时关闭组件countDownVisible: ev.detail.minutes === 1 || ev.detail.seconds > 0,})},
    })
    
  2. 验证表单数据(手机号码)

    安装并构建表单验证码插件 wechat-validate

    # 安装 wechat-validate
    npm install wechat-validate
    

    将插件导入到项目中:

    • behaviors 将插件注入到页面中
    • rules 由插件提供的属性,用来定义数据验证的规则(类似于 Element UI)
    • validate 由插件提供的方法,根据 rules 的规则来对数据进行验证
    // 导入表单验证插件
    import wxValidate from 'wechat-validate'
    Page({data: {mobile: ''},// 将插件注入到页面实例中behaviors: [wxValidate],rules: {mobile: [{required: true, message: '请填写手机号码!'},{pattern: /^1[3-8]\d{9}$/, message: '请填写正确的手机号码!'}]},// 获取短信验证码async getSMSCode() {// 获取验证结果const {valid, message} = this.validate('mobile')// 如果验证不合法则不再执行后面的逻辑if(!valid) return wx.utils.toast(message)// 显示倒计时组件this.setData({countDownVisible: true})},
    })
    

    用户填写的手机号 mobile 通过简易双向数据绑定来获取:

    <van-field maxlength="{{ 11 }}" model:value="{{mobile}}" />
    
  3. 调用接口将手机号发送给服务端

    接口文档地址

    参考代码如下所示:

    Page({// 获取短信验证码async getSMSCode() {// 获取验证结果const {valid, message} = this.validate('mobile')// 如果验证不合法则不再执行后面的逻辑if(!valid) return wx.utils.toast(message)// 显示倒计时组件this.setData({countDownVisible: true})// 调用接口获取验证码const {code, data} = await wx.http.get('/code', {mobile: this.data.mobile})// 检测验证码是否发送成功if(code !== 10000) return wx.utils.toast('发送失败,稍后重试!')},
    })
    

    注:在生产环境中短信验证码不会通过接口返回,只能以短信的形式发送到用户的手机上,在课程中的发开发环境可以通过接口获取短信验证码。

2.4.3 登录&注册

调用接口把获取的手机号码和验证码发送给服务端,登录和注册功能是合二为一的,后端会检测手机号是否已注册过,如果注册了则执行登录的操作,否则执行注册的操作。

接口文档地址

  1. 在调用接口前需要对验证码的数据进行验证码:

    <van-field model:value="{{code}}" />
    
    Page({data: {mobile: '',code: ''},rules: {// ...code: [{required: true, message: '请填写验证码!'},{pattern: /^\d{6}$/, message: '请填写正确的验证码!'}]}
    })
    

    监听用户点击登录按钮,然后调用接口:

    Page({// ...// 提交表单数据,完成登录/注册的功能async submitForm() {// 验证数据是否合法if(!this.validate()) return// 调用登录接口const {code, data} = await wx.http.post('/login', {mobile: this.data.mobile,code: this.data.code})// 验证是否登录成功if(code !== 10000) return wx.utils.toast('登录失败,稍后重试!')}
    })
    
  2. 记录登录状态,将 token 存入本地存储

    // app.js
    App({// ...setToken(key, token) {// 将 token 记录在应用实例中   this[key] = token// 将 token 存入本地wx.setStorageSync(key, token)}
    })
    
    // pages/login/index.js
    const app = getApp()
    Page({// ...// 提交表单数据,完成登录/注册的功能async submitForm() {// 验证数据是否合法if(!this.validate()) return// 调用登录接口const {code, data} = await wx.http.post('/login', {mobile: this.data.mobile,code: this.data.code})// 验证是否登录成功if(code !== 10000) return wx.utils.toast('登录失败,稍后重试!')// 记录登录状态app.setToken('token', data.token)app.setToken('refreshToken', data.refreshToken)}
    })
    
  3. 地址重定向,登录成功后跳回到原来的页面

    authoirzation 组件检测登录时获取当前页面栈实例,并在跳转到登录页面时在 URL 地址上拼凑参数:

    // /components/authorization/index.js
    Component({// ...lifetimes: {attached() {// 获取登录状态const isLogin = !!getApp().token// 变更登录状态this.setData({ isLogin })// 获取页面栈const pageStack = getCurrentPages()// 获取页面路径const currentPage = pageStack.pop()// 未登录的情况下跳转到登录页面if (!isLogin) {wx.redirectTo({url: '/pages/login/index?redirectURL=/' + currentPage.route,})}},},
    })
    

    在登录成功后获取地址的参数(一个页面的路径),重定向到原来的页面

    // pages/login/index.js
    const app = getApp()
    Page({// ...onLoad({redirectURL}) {// 获取地址参数this.redirectURL = redirectURL},// 提交表单数据,完成登录/注册的功能async submitForm() {// 验证数据是否合法if(!this.validate()) return// 调用登录接口const {code, data} = await wx.http.post('/login', {mobile: this.data.mobile,code: this.data.code})// 验证是否登录成功if(code !== 10000) return wx.utils.toast('登录失败,稍后重试!')// 记录登录状态app.setToken('token', data.token)app.setToken('refreshToken', data.refreshToken)// 重定向wx.redirectTo({url: this.redirectURL})}
    })
    
2.4.4 头像和昵称

配置请求拦截器将用户的登录状态通过自定义的头信息 Authorization 随接口调用时一起发送到服务端。

// utils/http.js
// 导入 wechat-http 模块
import http from 'wechat-http'
// 配置接口基础路径
http.baseURL = 'https://live-api.itheima.net'
// 配置请求拦截器
http.intercept.request = function (options) {// 扩展头信息const defaultHeader = {}// 身份认证defaultHeader.Authorization = 'Bearer ' + getApp().token// 与默认头信息合并options.header = Object.assign({}, defaultHeader, options.header)// 处理后的请求参数return options
}
// ...

注:传递 token 时需要拼凑字符串前缀 "Bearer "

  1. 获取用户信息

    调用接口获取当前用户的信息,此时还是一个新用户,所以用户昵称和头像数据都是不存在。

    接口文档地址

    参考示例代码:

    // 获取应用实例
    const app = getApp()
    Page({onLoad() {// 用户未登录时不必请求app.token && this.getUserProfile()},async getUserProfile() {// 调用接口获取昵称和头像const {code, data: {avatar, nickName}} = await wx.http.get('/userInfo')// 检测接口是否正常返回结果if(code !== 10000) return wx.utils.toast()// 渲染数据this.setData({avatar, nickName})},
    })
    

    渲染接口返回的数据:

    <view class="profile">  <view class="profile-base"><image class="avatar" src="{{avatar}}"></image><text class="nickname">{{nickName || '微信用户'}}</text><navigator hover-class="none" class="link" url="/pages/profile/index">去完善信息<text class="enjoy-icon icon-arrow"></text></navigator></view>...
    </view>
    
  2. 更新用户昵称

    接口文档地址

    获取用户填写的昵称后调用接口提交数据:

    <!-- pages/profile/index.wxml -->
    <!-- 需要检测登录状态 -->
    <authorization><view class="profile">...<van-fieldcenterlabel="昵称"input-align="right"bind:blur="getUserNickname"type="nickname"value="{{nickName}}"placeholder="请输入昵称"/></view>
    </authorization>
    // pages/profile/index.js
    Page({// 获取用户昵称getUserNickname(ev) {// 更新昵称this.updateNickname(ev.detail.value)},// 更新昵称接口async updateNickname(nickName) {if(nickName === '') return// 调用接口更新用户昵称const {code} = await wx.http.put('/userInfo', {nickName})// 检测接口是否调用成功if(code !== 10000) return wx.utils.toast('更新昵称失败!')},
    })
    

    在此可以通过页面实例来更新 pages/my/index.wxml 的昵称:

    // pages/profile/index.js
    const pageStack = getCurrentPages()
    Page({// 获取用户昵称getUserNickname(ev) {// 更新昵称this.updateNickname(ev.detail.value)},// 更新昵称接口async updateNickname(nickName) {if(nickName === '') return// 调用接口更新用户昵称const {code} = await wx.http.put('/userInfo', {nickName})// 检测接口是否调用成功if(code !== 10000) return wx.utils.toast('更新昵称失败!')// 借助于页面栈实例来更新 pages/my/index.wxml 中的昵称pageStack[0].setData({nickName})},
    })
    
  3. 更新用户头像

    接口文档地址

    获取用户选择的头像地址,通过 wx.uploadFile 将图片上传到服务端,wx.uploadFile 的基本语法:

    • url 上传接口地址
    • filePath 待上传文件的临时路径(该路径只能用于小程序内部)
    • name 接口接收上传文件的数据名称(由后端指定)
    • formData 除上传文件外的其它数据
    • header 自定义头信息
    • success 上传成功的回调函数
    • fail 上传失败后的回调函数
    • complete 上传完成时的回调(无论成功或失败)

    注:该 API 不支持返回 Promise,调用该 API 时,需要提前在小程序管理后台添加服务器域名。

    参考示例代码如下所示:

    <!-- pages/profile/index.wxml -->
    <authorization><view class="profile"><van-cell center title="头像"><van-icon slot="right-icon" name="arrow" size="16" color="#c3c3c5" /><buttonclass="button"size="mini"hover-class="none"bind:chooseavatar="getUserAvatar"open-type="chooseAvatar"><image class="avatar" src="{{avatar}}"></image></button></van-cell>...</view>
    </authorization>
    
    // pages/profile/index.js
    const pageStack = getCurrentPages()
    Page({// 获取用户头像getUserAvatar(ev) {// 更新用户头像this.updateAvatar(ev.detail.avatarUrl)},// 更新用户头像updateAvatar(avatar) {// 调用 API 上传文件wx.uploadFile({// 接口地址url: wx.http.baseURL + '/upload',// 待上传的文件路径filePath: avatar,name: 'file',header: {// 用户登录状态Authorization: 'Bearer ' + getApp().token},formData: {type: 'avatar'},success: (result) => {// 处理返回的数据const data = JSON.parse(result.data)// 检测接口是否调用成功if(data.code !== 10000) return wx.utils.toast('上传头像失败!')// 借助于页面栈实例来更新 pages/my/index.wxml 中的头像pageStack[0].setData({avatar: data.data.url})}})}
    })
    

    上述代码中通过 wx.http.baseURL 获取接口服务器地址,通过应用实例获取 token

  4. 默认头像和昵称

    通过应用实例来跨页面共享数据,将在 pages/my/index.wxml 获取的数据存入应用实例中:

    // pages/my/index.js
    Page({// ...async getUserProfile() {// ...// 将头像和昵称存到应用实例中app.userProfile = {avatar, nickName}},
    })
    

    pages/profile/index.wxml 中读取应用实例中的数据

    // pages/profile/index.js
    Page({onLoad() {// 获取实例const app = getApp()// 将头像和昵称渲染到页面中this.setData({...app.userProfile})},// ...async updateNickname(nickName) {// ...// 同步数据到应用实例中const app = getApp()app.userProfile.nickName = nickName},// ...updateAvatar(avatar) {// ...// 同步更新数据到应用实例中const app = getApp()app.userProfile.avatar = data.data.url}
    })
    

    在更新头像和昵称后记得将最新的数据同步到应用实例中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/12597.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

政企学习考试系统(源码+文档+部署+讲解)

本文将深入解析“政企学习考试系统”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 本项目名称为政企学习考试系统&#xff0c;是一款面向政企用户的在线学习与考试平台。该系统旨在为用户提供便捷、高效的学习和考核服务&a…

Jmeter基础篇(22)服务器性能监测工具Nmon的使用

一、前言 我们在日常做压测的过程中&#xff0c;不仅仅需要监控TPS&#xff0c;响应时间&#xff0c;报错率等这些系统基础性能数据&#xff0c;还需要对服务器的性能&#xff08;如CPU、磁盘、内存、网络IO等&#xff09;做监控&#xff0c;以求对系统运行过程中的硬件性能有…

三级等保安全解决方案,实施方案,整改方案(Word,PPT等相关资料学习)

信息系统进行三级等保的主要原因在于保障信息安全&#xff0c;维护国家安全和公共利益。三级等保是我国根据相关法律法规制定的信息安全等级保护制度中的一部分&#xff0c;旨在确保信息系统的完整性、可用性和保密性。通过三级等保&#xff0c;信息系统可以得到一系列的安全保…

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件

Springboot 使用EasyExcel导出含图片并设置样式的Excel文件 Excel导出系列目录&#xff1a;★★★★尤其注意&#xff1a;引入依赖创建导出模板类逻辑处理controllerservice 导出效果总结 Excel导出系列目录&#xff1a; 【Springboot 使用EasyExcel导出Excel文件】 【Springb…

老破机器硬盘要坏,转移虚拟机里的打字平台过程全记录

我有一台老破机器&#xff0c;说破其实没多破&#xff0c;但是老应该是有几年了&#xff0c;这机器一开始一直放在领导办公室不让人用&#xff0c;后来因为单位整体搬迁&#xff0c;我跟领导讨了来&#xff0c;win10的系统&#xff0c;我装了个虚拟机好像是15的版本&#xff0c…

光流法与直接法在SLAM中的应用

本文总结视觉SLAM中常用的光流法与直接法 1、Lucas-Kanade光流法 相机所拍摄到的图像随相机视角的变化而变化&#xff0c;这种变化也可以理解为图像中像素的反向移动。“光流”&#xff08;Optical Flow&#xff09;是指通过分析连续图像帧来估计场景中像素或特征点的运动的技…

VPN相关学习笔记

目录 VPN IPSec AH ESP IKE 工作流程 SSL SSL协议 握手协议 记录协议 警告协议 非对称密钥协商过程 SSL VPN工作 两种技术对比 VPN 介绍&#xff1a;VPN创建了一个专用隧道&#xff0c;用于安全地传输数据。Internet协议安全&#xff08;IPSec&#xff09;和安全套…

通过条件访问策略增强企业的安全性

在当今的数字时代&#xff0c;保护组织的数据比以往任何时候都更加重要&#xff0c;实现这一目标的一种方法是实施条件访问策略。这些策略有助于管理谁可以访问组织的网络&#xff0c;确保只有经过授权的人员才能通过&#xff0c;它们可以充当组织数据的保安&#xff0c;只让符…

二叉树搜索树(上)

二叉树搜索树&#xff08;上&#xff09; 概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一颗空树&#xff0c;或者是具有以下性质的二叉树: • 若它的左子树不为空&#xff0c;则左子树上所有结点的值都⼩于等于根结点的值 • 若它的右子树不为空&#xff0c;则右子树…

人群计数制作私有数据集教程-----自用

一、人群计数的数据集包括两部分&#xff1a;图像部分和标签部分 1.公开数据集格式 标签部分主要包括每个人头的坐标点&#xff1a;&#xff08;x, y&#xff09;&#xff1b; 常见的标签格式例如&#xff1a;ShanghaiTech数据集中的格式&#xff0c;用mat文件存储每个人头的坐…

SpringBoot项目快速打包成jar项目与部署

上文中,tomcat配置完成了。接下来我们需要将我们的项目打包部署至tomcat服务器。 传统的Web应用进行打包部署时,通常会打成War包的形式,然后将War包部署到Tomcat等服务器中,而SpringBoot应用使用的是嵌入式Servlet容器,也就是说,SpringBoot应用默认是以jar包形式进行打包…

【YOLOv8图像分类】YOLOv8图像分类源代码

前言 此程序是使用YOLOv8训练自己的图像并测试。Yolo系列模型可以说是比较特殊的模型&#xff0c;因为不像其他公开网络ResNet、GoogLeNet等等&#xff0c;可以自己构建和更改层。Yolo只能整体调用这个网络&#xff0c;这个可能是让初学者比较头疼的问题&#xff0c;就是看不到…

【干货】金融数据分析:风险评估中的数据分析

风险评估中的数据分析 金融风险评估因是金融行业的核心任务之一&#xff0c;也是保障金融稳定和机构可持续发展的关键。在当今数字化时代&#xff0c;数据分析已经成为金融风险评估的有力武器&#xff0c;能够帮助我们拨开复杂现象的迷雾&#xff0c;洞察风险的本质。 金融风…

【Hadoop】【hdfs】【大数据技术基础】实验三 HDFS Java API编程实践

实验三&#xff1a; HDFS Java API编程实践 实验题目 HDFS Java API编程实践 实验目的 熟悉HDFS操作常用的Java API。 实验平台 操作系统&#xff1a;Linux Hadoop版本&#xff1a;2.6.0或以上版本 JDK版本&#xff1a;1.6或以上版本 Java IDE&#xff1a;Eclipse 实验…

第R3周:RNN-心脏病预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** &#x1f37a; 要求&#xff1a; 找到并处理第8周的程序问题&#xff08;本文给出了答案&#xff09;了解循环神经网络&#xff08…

数据结构 ——— 链式二叉树oj题:将链式二叉树的前序遍历存放在数组中

题目要求 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历 手搓一个链式二叉树 代码演示&#xff1a; // 数据类型 typedef int BTDataType;// 二叉树节点的结构 typedef struct BinaryTreeNode {BTDataType data; //每个节点的数据struct BinaryTreeNode* l…

前端中的 File 和 Blob两个对象到底有什么不同

JavaScript 在处理文件、二进制数据和数据转换时&#xff0c;提供了一系列的 API 和对象&#xff0c;比如 File、Blob、FileReader、ArrayBuffer、Base64、Object URL 和 DataURL。每个概念在不同场景中都有重要作用。下面的内容我们将会详细学习每个概念及其在实际应用中的用法…

酒店叮咚门铃的类型有哪些

在酒店的环境中&#xff0c;叮咚门铃虽小&#xff0c;却有着重要的作用&#xff0c;它是客人与酒店服务人员沟通的重要桥梁。酒店叮咚门铃主要有以下几种类型&#xff1a; 有线叮咚门铃 这是较为传统的一种类型。它通过电线连接&#xff0c;通常安装在客房的墙壁上&#xff0c;…

SFW3009 多功能移动照明系统

SFW3009 多功能移动照明系统 适用范围 广泛适用于铁路、水利、电网等抢险救援现场大范围移动照明。 结构特性 灯具体积小、重量轻&#xff0c;可以实现拖行、手提、背行三种携带方式。灯具底部也可以安装铁轨轮&#xff0c;便于用户在铁轨上作业。 灯头组件由左右两个灯头…

JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)

目录 基本使用内容 下载与安装 目录结构介绍 启动与关闭 启动 关闭 可能出现的问题及解决方案 问题一&#xff1a;启动时窗口一闪而过 问题二&#xff1a;端口号冲突 问题三&#xff1a;部署应用程序 总结 基本使用内容 Tomcat 服务器在 Java Web 开发中扮演着至关重…