地址模块丨前端uniapp微信小程序项目

2023-11-06

小兔鲜儿 - 地址模块

  • 能够获取不同类型的表单数据
  • 能够动态设置导航栏的标题
  • 能够使用 uni-ui 组件库的组件
  • 能够完成收货地址的增删改查的功能

准备工作

静态结构

地址模块共两个页面:地址管理页,地址表单页 ,划分到会员分包中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34rtplC8-1693303462902)(./assets/address_picture_1.png)]

地址管理页

src/pagesMember/address/address.vue

<script setup lang="ts">
//
</script>

<template>
  <view class="viewport">
    <!-- 地址列表 -->
    <scroll-view class="scroll-view" scroll-y>
      <view v-if="true" class="address">
        <view class="address-list">
          <!-- 收货地址项 -->
          <view class="item">
            <view class="item-content">
              <view class="user">
                黑马小王子
                <text class="contact">13111111111</text>
                <text v-if="true" class="badge">默认</text>
              </view>
              <view class="locate">广东省 广州市 天河区 黑马程序员</view>
              <navigator
                class="edit"
                hover-class="none"
                :url="`/pagesMember/address-form/address-form?id=1`"
              >
                修改
              </navigator>
            </view>
          </view>
          <!-- 收货地址项 -->
          <view class="item">
            <view class="item-content">
              <view class="user">
                黑马小公主
                <text class="contact">13222222222</text>
                <text v-if="false" class="badge">默认</text>
              </view>
              <view class="locate">北京市 北京市 顺义区 黑马程序员</view>
              <navigator
                class="edit"
                hover-class="none"
                :url="`/pagesMember/address-form/address-form?id=2`"
              >
                修改
              </navigator>
            </view>
          </view>
        </view>
      </view>
      <view v-else class="blank">暂无收货地址</view>
    </scroll-view>
    <!-- 添加按钮 -->
    <view class="add-btn">
      <navigator
        hover-class="none"
        url="/pagesMember/address-form/address-form"
      >
        新建地址
      </navigator>
    </view>
  </view>
</template>

<style lang="scss">
page {
  height: 100%;
  overflow: hidden;
}

/* 删除按钮 */
.delete-button {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 50px;
  height: 100%;
  font-size: 28rpx;
  color: #fff;
  border-radius: 0;
  padding: 0;
  background-color: #cf4444;
}

.viewport {
  display: flex;
  flex-direction: column;
  height: 100%;
  background-color: #f4f4f4;

  .scroll-view {
    padding-top: 20rpx;
  }
}

.address {
  padding: 0 20rpx;
  margin: 0 20rpx;
  border-radius: 10rpx;
  background-color: #fff;

  .item-content {
    line-height: 1;
    padding: 40rpx 10rpx 38rpx;
    border-bottom: 1rpx solid #ddd;
    position: relative;

    .edit {
      position: absolute;
      top: 36rpx;
      right: 30rpx;
      padding: 2rpx 0 2rpx 20rpx;
      border-left: 1rpx solid #666;
      font-size: 26rpx;
      color: #666;
      line-height: 1;
    }
  }

  .item:last-child .item-content {
    border: none;
  }

  .user {
    font-size: 28rpx;
    margin-bottom: 20rpx;
    color: #333;

    .contact {
      color: #666;
    }

    .badge {
      display: inline-block;
      padding: 4rpx 10rpx 2rpx 14rpx;
      margin: 2rpx 0 0 10rpx;
      font-size: 26rpx;
      color: #27ba9b;
      border-radius: 6rpx;
      border: 1rpx solid #27ba9b;
    }
  }

  .locate {
    line-height: 1.6;
    font-size: 26rpx;
    color: #333;
  }
}

.blank {
  margin-top: 300rpx;
  text-align: center;
  font-size: 32rpx;
  color: #888;
}

.add-btn {
  height: 80rpx;
  text-align: center;
  line-height: 80rpx;
  margin: 30rpx 20rpx;
  color: #fff;
  border-radius: 80rpx;
  font-size: 30rpx;
  background-color: #27ba9b;
}
</style>

地址表单页

src/pagesMember/address-form/address-form.vue

<script setup lang="ts">
import { ref } from 'vue'

// 表单数据
const form = ref({
  receiver: '', // 收货人
  contact: '', // 联系方式
  fullLocation: '', // 省市区(前端展示)
  provinceCode: '', // 省份编码(后端参数)
  cityCode: '', // 城市编码(后端参数)
  countyCode: '', // 区/县编码(后端参数)
  address: '', // 详细地址
  isDefault: 0, // 默认地址,1为是,0为否
})
</script>

<template>
  <view class="content">
    <form>
      <!-- 表单内容 -->
      <view class="form-item">
        <text class="label">收货人</text>
        <input class="input" placeholder="请填写收货人姓名" value="" />
      </view>
      <view class="form-item">
        <text class="label">手机号码</text>
        <input class="input" placeholder="请填写收货人手机号码" value="" />
      </view>
      <view class="form-item">
        <text class="label">所在地区</text>
        <picker class="picker" mode="region" value="">
          <view v-if="false">广东省 广州市 天河区</view>
          <view v-else class="placeholder">请选择省/市/区(县)</view>
        </picker>
      </view>
      <view class="form-item">
        <text class="label">详细地址</text>
        <input class="input" placeholder="街道、楼牌号等信息" value="" />
      </view>
      <view class="form-item">
        <label class="label">设为默认地址</label>
        <switch class="switch" color="#27ba9b" :checked="true" />
      </view>
    </form>
  </view>
  <!-- 提交按钮 -->
  <button class="button">保存并使用</button>
</template>

<style lang="scss">
page {
  background-color: #f4f4f4;
}

.content {
  margin: 20rpx 20rpx 0;
  padding: 0 20rpx;
  border-radius: 10rpx;
  background-color: #fff;

  .form-item,
  .uni-forms-item {
    display: flex;
    align-items: center;
    min-height: 96rpx;
    padding: 25rpx 10rpx;
    background-color: #fff;
    font-size: 28rpx;
    border-bottom: 1rpx solid #ddd;
    position: relative;
    margin-bottom: 0;

    // 调整 uni-forms 样式
    .uni-forms-item__content {
      display: flex;
    }

    .uni-forms-item__error {
      margin-left: 200rpx;
    }

    &:last-child {
      border: none;
    }

    .label {
      width: 200rpx;
      color: #333;
    }

    .input {
      flex: 1;
      display: block;
      height: 46rpx;
    }

    .switch {
      position: absolute;
      right: -20rpx;
      transform: scale(0.8);
    }

    .picker {
      flex: 1;
    }

    .placeholder {
      color: #808080;
    }
  }
}

.button {
  height: 80rpx;
  margin: 30rpx 20rpx;
  color: #fff;
  border-radius: 80rpx;
  font-size: 30rpx;
  background-color: #27ba9b;
}
</style>

动态设置标题

新建地址修改地址 复用同一个地址表单页,需要根据页面参数 id 动态设置页面标题。

<script setup lang="ts">
// 获取页面参数
const query = defineProps<{
  id?: string
}>()

// 动态设置标题
uni.setNavigationBarTitle({ title: query.id ? '修改地址' : '新建地址' })
</script>

新建地址页

新用户没有收货地址,先完成新建地址,新建成功返回地址管理页。

主要功能:前端收集表单的数据,提交表单给后端。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6BAaU9O8-1693303462903)(./assets/address_picture_2.png)]

接口封装

接口调用

接口地址:/member/address

请求方式:POST

登录权限:

请求参数:

Body

字段名称 是否必须 类型 备注
receiver string 收货人姓名
contact string 收货人联系方式
provinceCode string 省对应的 code
cityCode string 市对应的 code
countyCode string 区/县对应的 code
address string 收货人详细地址
isDefault number 是否设置为默认地址(数值类型)

接口封装

src/services/address.ts

import type { AddressParams } from '@/types/address'
import { http } from '@/utils/http'

/**
 * 添加收货地址
 * @param data 请求参数
 */
export const postMemberAddressAPI = (data: AddressParams) => {
  return http({
    method: 'POST',
    url: '/member/address',
    data,
  })
}

类型声明

src/types/address.d.ts

/** 添加收货地址: 请求参数 */
export type AddressParams = {
  /** 收货人姓名 */
  receiver: string
  /** 联系方式 */
  contact: string
  /** 省份编码 */
  provinceCode: string
  /** 城市编码 */
  cityCode: string
  /** 区/县编码 */
  countyCode: string
  /** 详细地址 */
  address: string
  /** 默认地址,1为是,0为否 */
  isDefault: number
}

参考代码

地址表单页,input 组件通过 v-model 获取数据,其他表单组件结合 @change 事件获取。

<script setup lang="ts">
import { postMemberAddressAPI } from '@/services/address'
import { ref } from 'vue'

// 表单数据
const form = ref({
  receiver: '', // 收货人
  contact: '', // 联系方式
  fullLocation: '', // 省市区(前端展示)
  provinceCode: '', // 省份编码(后端参数)
  cityCode: '', // 城市编码(后端参数)
  countyCode: '', // 区/县编码(后端参数)
  address: '', // 详细地址
  isDefault: 0, // 默认地址,1为是,0为否
})

// 收集所在地区
const onRegionChange: UniHelper.RegionPickerOnChange = (ev) => {
  // 省市区(前端展示)
  form.value.fullLocation = ev.detail.value.join(' ')
  // 省市区(后端参数)
  const [provinceCode, cityCode, countyCode] = ev.detail.code!
  // 合并数据
  Object.assign(form.value, { provinceCode, cityCode, countyCode })
}

// 收集是否默认收货地址
const onSwitchChange: UniHelper.SwitchOnChange = (ev) => {
  form.value.isDefault = ev.detail.value ? 1 : 0
}

// 提交表单
const onSubmit = async () => {
  // 新建地址请求
  await postMemberAddressAPI(form.value)
  // 成功提示
  uni.showToast({ icon: 'success', title: '添加成功' })
  // 返回上一页
  setTimeout(() => {
    uni.navigateBack()
  }, 400)
}
</script>

<template>
  <view class="content">
    <form>
      <!-- 表单内容 -->
      <view class="form-item">
        <text class="label">收货人</text>
        <input
          class="input"
          placeholder="请填写收货人姓名"
          v-model="form.receiver"
        />
      </view>
      <view class="form-item">
        <text class="label">手机号码</text>
        <input
          class="input"
          placeholder="请填写收货人手机号码"
          v-model="form.contact"
        />
      </view>
      <view class="form-item">
        <text class="label">所在地区</text>
        <picker
          class="picker"
          mode="region"
          :value="form.fullLocation.split(' ')"
          @change="onRegionChange"
        >
          <view v-if="form.fullLocation">{{ form.fullLocation }}</view>
          <view v-else class="placeholder">请选择省/市/区(县)</view>
        </picker>
      </view>
      <view class="form-item">
        <text class="label">详细地址</text>
        <input
          class="input"
          placeholder="街道、楼牌号等信息"
          v-model="form.address"
        />
      </view>
      <view class="form-item">
        <label class="label">设为默认地址</label>
        <switch
          class="switch"
          color="#27ba9b"
          :checked="form.isDefault === 1"
          @change="onSwitchChange"
        />
      </view>
    </form>
  </view>
  <!-- 提交按钮 -->
  <button @tap="onSubmit" class="button">保存并使用</button>
</template>

地址管理页

为了能及时看到新建的收货地址,需在 onShow 生命周期中获取地址列表数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A87evljb-1693303462903)(./assets/address_picture_3.png)]

接口调用

接口地址:/member/address

请求方式:GET

登录权限:

请求参数:无

接口封装

src/types/address.ts

/**
 * 获取收货地址列表
 */
export const getMemberAddressAPI = () => {
  return http<AddressItem[]>({
    method: 'GET',
    url: '/member/address',
  })
}

类型声明

src/types/address.d.ts

/** 收货地址项 */
export type AddressItem = {
  /** 收货人姓名 */
  receiver: string
  /** 联系方式 */
  contact: string
  /** 省份编码 */
  provinceCode: string
  /** 城市编码 */
  cityCode: string
  /** 区/县编码 */
  countyCode: string
  /** 详细地址 */
  address: string
  /** 默认地址,1为是,0为否 */
  isDefault: number
  /** 收货地址 id */
  id: string
  /** 省市区 */
  fullLocation: string
}

商品详情复用地址类型:src/types/goods.d.ts

+ import type { AddressItem } from './global'

- /** 地址信息 */
- export type AddressItem = {
-   receiver: string
-   contact: string
-   provinceCode: string
-   cityCode: string
-   countyCode: string
-   address: string
-   isDefault: number
-   id: string
-   fullLocation: string
- }

::: tip 温馨提示

用户登录后再访问商品详情,商品详情字段中包含用户收货地址列表,可以复用收货地址类型

:::

参考代码

地址管理页

<script setup lang="ts">
import { getMemberAddressAPI } from '@/services/address'
import type { AddressItem } from '@/types/address'
import { onShow } from '@dcloudio/uni-app'
import { ref } from 'vue'

// 获取收货地址列表数据
const addressList = ref<AddressItem[]>([])
const getMemberAddressData = async () => {
  const res = await getMemberAddressAPI()
  addressList.value = res.result
}

// 初始化调用(页面显示)
onShow(() => {
  getMemberAddressData()
})
</script>

<template>
  <view class="viewport">
    <!-- 地址列表 -->
    <scroll-view class="scroll-view" scroll-y>
      <view v-if="true" class="address">
        <view class="address-list">
          <!-- 收获地址项 -->
          <view class="item" v-for="item in addressList" :key="item.id">
            <view class="item-content">
              <view class="user">
                {{ item.receiver }}
                <text class="contact">{{ item.contact }}</text>
                <text v-if="item.isDefault" class="badge">默认</text>
              </view>
              <view class="locate"
                >{{ item.fullLocation }} {{ item.address }}</view
              >
              <navigator
                class="edit"
                hover-class="none"
                :url="`/pagesMember/address-form/address-form?id=${item.id}`"
              >
                修改
              </navigator>
            </view>
          </view>
        </view>
      </view>
      <view v-else class="blank">暂无收货地址</view>
    </scroll-view>
    <!-- 添加按钮 -->
    <view class="add-btn">
      <navigator
        hover-class="none"
        url="/pagesMember/address-form/address-form"
      >
        新建地址
      </navigator>
    </view>
  </view>
</template>

修改地址页

通过页面参数 id 来区分当前是修改地址还是新建地址

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-84TyO4PE-1693303462904)(./assets/address_picture_4.png)]

数据回显

修改地址之前,需要先实现数据回显,用户再进行有针对性的修改。

接口详情

接口地址:/member/address/:id

请求方式:GET

登录权限:

请求参数:

路径参数

字段名称 是否必须 默认值 备注
id 收货地址 ID

接口封装

src/services/address.ts

/**
 * 获取收货地址详情
 * @param id 地址id(路径参数)
 */
export const getMemberAddressByIdAPI = (id: string) => {
  return http<AddressItem>({
    method: 'GET',
    url: `/member/address/${id}`,
  })
}

参考代码

页面初始化的时候根据 id 获取地址详情,把获取的数据合并到表单数据中,用于数据回显。

<script setup lang="ts">
// 获取收货地址详情数据
const getMemberAddressByIdData = async () => {
  // 有 id 才调用接口
  if (query.id) {
    // 发送请求
    const res = await getMemberAddressByIdAPI(query.id)
    // 把数据合并到表单中
    Object.assign(form.value, res.result)
  }
}

// 页面加载
onLoad(() => {
  getMemberAddressByIdData()
})
</script>

更新地址

将用户修改后的地址信息重新发送到服务端进行存储。

接口详情

接口地址:/member/address/:id

请求方式:PUT

登录权限:

请求参数:

路径参数

字段名称 是否必须 默认值 备注
id 收货地址 ID

Body

字段名称 是否必须 默认值 备注
receiver 收货人姓名
contact 收货人联系方式
provinceCode 行政省对应的 code
cityCode 行政市对应的 code
countyCode 行政区县对应的 code
address 收货人详细地址
isDefault 是否设置为默认地址(数值类型)

接口封装

/**
 * 修改收货地址
 * @param id 地址id(路径参数)
 * @param data 表单数据(请求体参数)
 */
export const putMemberAddressByIdAPI = (id: string, data: AddressParams) => {
  return http({
    method: 'PUT',
    url: `/member/address/${id}`,
    data,
  })
}

参考代码

根据是否有地址 id 来判断提交表单到底是新建地址还是更新地址。

<script setup lang="ts">
// 提交表单
const onSubmit = async () => {
  // 判断当前页面是否有地址 id
  if (query.id) {
    // 修改地址请求
    await putMemberAddressByIdAPI(query.id, form.value)
  } else {
    // 新建地址请求
    await postMemberAddressAPI(form.value)
  }
  // 成功提示
  uni.showToast({ icon: 'success', title: query.id ? '修改成功' : '添加成功' })
  // 返回上一页
  setTimeout(() => {
    uni.navigateBack()
  }, 400)
}
</script>

表单校验

通过 uni-ui 组件库的 uni-forms 组件实现表单校验。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wE2FKdyG-1693303462904)(./assets/address_picture_5.png)]

操作步骤

  1. 定义校验规则
  2. 修改表单结构
  3. 绑定校验规则
  4. 提交时校验表单

参考代码

<script setup lang="ts">
// 定义校验规则
const rules: UniHelper.UniFormsRules = {
  receiver: {
    rules: [{ required: true, errorMessage: '请输入收货人姓名' }],
  },
  contact: {
    rules: [
      { required: true, errorMessage: '请输入联系方式' },
      { pattern: /^1[3-9]\d{9}$/, errorMessage: '手机号格式不正确' },
    ],
  },
  fullLocation: {
    rules: [{ required: true, errorMessage: '请选择所在地区' }],
  },
  address: {
    rules: [{ required: true, errorMessage: '请选择详细地址' }],
  },
}

// 获取表单组件实例,用于调用表单方法
const formRef = ref<UniHelper.UniFormsInstance>() // [!code ++]

// 提交表单
const onSubmit = async () => {
  try {
    // 表单校验
    await formRef.value?.validate?.() // [!code ++]
    // 校验通过后再发送请求
    if (query.id) {
      // 修改地址请求
      await putMemberAddressByIdAPI(query.id, form.value)
    } else {
      // 新建地址请求
      await postMemberAddressAPI(form.value)
    }
    // 成功提示
    uni.showToast({
      icon: 'success',
      title: query.id ? '修改成功' : '添加成功',
    })
    // 返回上一页
    setTimeout(() => {
      uni.navigateBack()
    }, 400)
  } catch (error) {
    uni.showToast({ icon: 'error', title: '请填写完整信息' }) // [!code ++]
  }
}
</script>

<template>
  <view class="content">
    <uni-forms :rules="rules" :model="form" ref="formRef">
      <!-- 表单内容 -->
      <uni-forms-item name="receiver" class="form-item">
        <text class="label">收货人</text>
        <input
          class="input"
          placeholder="请填写收货人姓名"
          v-model="form.receiver"
        />
      </uni-forms-item>
      <uni-forms-item name="contact" class="form-item">
        <text class="label">手机号码</text>
        <input
          class="input"
          placeholder="请填写收货人手机号码"
          :maxlength="11"
          v-model="form.contact"
        />
      </uni-forms-item>
      <uni-forms-item name="fullLocation" class="form-item">
        <text class="label">所在地区</text>
        <picker
          @change="onRegionChange"
          class="picker"
          mode="region"
          :value="form.fullLocation.split(' ')"
        >
          <view v-if="form.fullLocation">{{ form.fullLocation }}</view>
          <view v-else class="placeholder">请选择省/市/区(县)</view>
        </picker>
      </uni-forms-item>
      <uni-forms-item name="address" class="form-item">
        <text class="label">详细地址</text>
        <input
          class="input"
          placeholder="街道、楼牌号等信息"
          v-model="form.address"
        />
      </uni-forms-item>
      <view class="form-item">
        <label class="label">设为默认地址</label>
        <switch
          @change="onSwitchChange"
          class="switch"
          color="#27ba9b"
          :checked="form.isDefault === 1"
        />
      </view>
    </uni-forms>
  </view>
  <!-- 提交按钮 -->
  <button @tap="onSubmit" class="button">保存并使用</button>
</template>

删除地址

通过 uni-ui 组件库的 uni-swipe-action 组件实现侧滑删除。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8gvz8fSx-1693303462905)(./assets/address_picture_6.png)]

侧滑组件用法

<template>
  <!-- 滑动操作分区 -->
  <uni-swipe-action>
    <!-- 滑动操作项 -->
    <uni-swipe-action-item>
      <!-- 默认插槽 -->
      <view>内容</view>
      <!-- 右侧插槽 -->
      <template #right>
        <button class="delete-button">删除</button>
      </template>
    </uni-swipe-action-item>
  </uni-swipe-action>
</template>

接口封装

接口详情

接口地址:/member/address/:id

请求方式:DELETE

登录权限: 是

请求参数:

路径参数

字段名称 是否必须 默认值 备注
id ID

接口封装

/**
 * 删除收货地址
 * @param id 地址id(路径参数)
 */
export const deleteMemberAddressByIdAPI = (id: string) => {
  return http({
    method: 'DELETE',
    url: `/member/address/${id}`,
  })
}

参考代码

侧滑地址列表项,右侧显示删除按钮,删除地址前需二次确认。

<script setup lang="ts">
// 删除收货地址
const onDeleteAddress = (id: string) => {
  // 二次确认
  uni.showModal({
    content: '删除地址?',
    success: async (res) => {
      if (res.confirm) {
        // 根据id删除收货地址
        await deleteMemberAddressByIdAPI(id)
        // 重新获取收货地址列表
        getMemberAddressData()
      }
    },
  })
}
</script>

视频学习 》 》》

黑马程序员前端项目uniapp小兔鲜儿微信小程序项目视频教程

全网首套用 vue3 加 TS 写的 uniapp 项目, 里面大量封装自己的组件库,课程从 uni-app 基础入手,按照9大电商业务模块逐步实现完整的电商购物流程业务;涵盖了猜你喜欢、热门推荐、商品分类、商品详情、微信登录、用户管理、地址管理、购物车管理、订单管理等功能。包含微信登录,微信支付等业务。一套代码多端全面覆盖微信小程序端、H5端、APP端。

教程笔记更新中

1 、前端项目uniapp小兔鲜儿微信小程序项目起步
2 、首页模块丨前端uniapp微信小程序项目
3 、推荐模块丨前端uniapp微信小程序项目
4 、分类模块丨前端uniapp微信小程序项目
5 、商品详情丨前端uniapp微信小程序项目
6 、登录模块丨前端uniapp微信小程序项目
7 、用户模块丨前端uniapp微信小程序项目

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

地址模块丨前端uniapp微信小程序项目 的相关文章

随机推荐

  • 机器学习(2)——鸢尾花数据集

    在上次房价数据集中做出一些改进 对鸢尾花数据集进行预测 需要导入的库 from sklearn datasets import load iris 导入鸢尾花数据集 from sklearn linear model import Logi
  • spark安装运行在webUI界面不显示worker

    spark conf spark env sh 文件中需要显式地设置一些环境变量 不用系统默认值 亲测 ubuntu16 04系统 spark env sh中手动配置 export JAVA HOME lt gt jdk1 8export
  • 33. 实战:实现某网站店铺信息的查询与批量抓取(附源码)

    目录 前言 目的 思路 代码实现 1 请求URL 获取源代码 2 解析源代码 获取数据 3 完善保存数据的函数save data 4 理清main函数逻辑 循环传递每一页有效信息的参数 完整代码 运行效果 总结 前言 近日 我们每周四都能刷
  • C#类与结构体的区别

    C 中类 class 与结构体 stract 的区别 1 类是引用类型 结构体是值类型 2 结构体不支持继承 但可以实现接口 类即支持继承也能实现接口 3 结构体中不可以声明无参的构造函数 4 结构体不能定义析构函数 5 结构体不可用作其他
  • 关于json数据的写入(write())必须为str类型及写入后双引号“变为‘号问题

    1 原始json数据 text 黎城县东崖底中心校学生用床购置项目成交公告 label 1 duoyu 0 text 淮南师范学院采购2017年智库项目 科研建设项目 学科及科技创新平台项目 1包 中标公示 label 1 duoyu 0
  • SpringBoot对接微信小程序支付功能开发(二,支付回调功能)

    接着上一篇 SpringBoot对接微信小程序支付功能开发 一 下单功能 在上一篇下单功能中我们有传支付结果回调地址 下面是回调接口实现 package com office miniapp controller import cn hut
  • Blender材质贴图入门图文教程

    推荐 将 NSDT场景编辑器 加入你的3D开发工具链 大家好 今天跟大家分享Blender材质贴图入门图文教程 一套blender的PBR材质包 和HDRI环境纹理贴图 在文末领取 希望能助到大家更高效完成场景练习 据我了解 越来越多人开始
  • Redis、Redission实现分布式锁

    Redis实现 使用spring data redis提供的接口实现redis分布式锁
  • kali使用aircrack无线攻击wifi超详细步骤(包含监听网卡启动,获得握手包,密码本生成)

    平台及工具 linux kali平台 aircrack ng 工具 免驱监听网卡 详细操作 1 首先启动kali 插入网卡 输入ifconfig查看kali是否检测到监听网卡 注意监听网卡要免驱动的 ifconfig 查看自身网卡信息 如图
  • React lazyLoad懒加载

    在React中使用lazy懒加载 效果图 目录结构 index js import React from react import ReactDOM from react dom import App from App import Bro
  • PID算法与PID自整定算法

    PID算法与PID自整定算法 本文是由于研发恒温槽项目故需要了解PID控制算法和PID自整定算法 为方便本人日后需要故作此记录 直接粘贴代码吧 这是PID位置式控温算法 函数名 void Pid positional float speed
  • 【Qt教程】4.1 - Qt5 文件系统 QFile文件读写操作

    1 Qt文件系统简介 QFile 文件系统是应用程序必不可少的部分 Qt作为一个通用开发库 提供了跨平台的文件操作能力 Qt通过 QIODevice 提供了对I O设备的抽象 使这些设备具有读写字节块的能力 在所有的I O设备中 文件I O
  • java forName() 方法

    forName 方法会进行类加载 将MyClass装在到JVM上 静态代码块 在类加载时执行 且只执行一次 如果你只想执行一个类的静态代码块 其它代码不执行 可以使用forName 方法 package leetcode0606 refle
  • Mybatis:传参+提交事务(自动or手动)+sql多表关联查询(两种方法)

    目录 一 参数两种类型 二 传参的几种方法 三 提交事务 四 sql多表关联查询 两种方法 一 参数两种类型 1 参数 预编译方式 更安全 只用于向sql中传值 select from admin where account account
  • Buuctf(Easy Calc 1)

    一 解题步骤 1 发现了一个可以得到计算结果的输入框 说明这题可能是一道命令执行 或者注入题目 我们输几个数字发现可以得到正确答案 但输入字母就会报错 我们看一下html源码 进行代码审计
  • java给byte赋值_关于JAVA中Byte数据类型二进制赋值运算报错问题

    自从JDK7更新之后 新增了二进制变量的表示 支持将整数类型用二进制来表示 用0b开头 例如 byte b byte 0b1000 0001 short s short 0b1000 0000 0000 0001 新手在这个时候会遇到一个问
  • rabbitmq 客户端golang实战

    rabbitmq消息模式 rabbitmq中进行消息控制的组建可以分为以下几部分 exchange rabbitmq中的路由部件 控制消息的转发路径 queue rabbitmq的消息队列 可以有多个消费者从队列中读取消息 consumer
  • 游戏设计模式笔记(一)[自用]

    目录 学习内容 学习笔记 设计模式简介 Design Pattern 单例模式的学习 第一种方式 第二种方式 第三种方式 单例模式的优点 学习内容 设计模式简介 Design Pattern 单例模式的学习 单例模式的优点 学习笔记 设计模
  • 电脑蓝屏终止代码irql_电脑故障排除之五种常见的蓝屏代码及解决方法

    超过10万人正在关注 赶快来关注吧 这里有你想找的热点资讯 这里有你想要的各种资料 还有海量的资源 还在等什么 快来关注 大佬带你开车 电脑蓝屏 又称蓝屏死机 BSDO 它是系统自我保护的一种现象 遇到蓝屏时不必慌张 利用以下几个方法就能解
  • 地址模块丨前端uniapp微信小程序项目

    小兔鲜儿 地址模块 能够获取不同类型的表单数据 能够动态设置导航栏的标题 能够使用 uni ui 组件库的组件 能够完成收货地址的增删改查的功能 准备工作 静态结构 地址模块共两个页面 地址管理页 地址表单页 划分到会员分包中 地址管理页