附录6-4 黑马优购项目-分类和购物车

目录

1  分类

1.1  接口

1.2  窗口限制

1.3  选中状态样式判断

1.4  点击左侧时右侧会到顶点

1.5  源码 

2  购物车

2.1  store

2.2  tabBar徽标

2.3  滑动删除

2.4  结算

2.4.1  结算前登录

2.4.2  结算功能

2.5  触发组件事件

2.6  源码


1  分类

分类最上部是搜索区域,与首页的搜索区域相同,这里直接复用

右侧区域的内容 会根据点击不同左侧区域 而变化

左侧区域和右侧区域均可以向下滚动

滚动后切换到别的页面,然后再切换回来,滚动的位置不变(记录位置是scroll-view的默认效果,不用额外进行修改)

1.1  接口

接口中包含三级标题。紫色框子是一级标题,橙色框子是二级标题,绿色框子是三级标题

url是https://api-hmugo-web.itheima.net/api/public/v1/categories 直接发get请求就行了

1.2  窗口限制

分类页面的最外层只有两个部分,一个是搜索框,除了搜索框剩下都属于另外一部分。为了让左侧和右侧都有拖动了效果,所以这里对高度进行了限制

如果取消高度限制,页面中的scroll-view-container就废了,左侧和右侧就会同时进行拖动

限制高度的值根据机型进行调节,wx.getWindowInfo()可以获得当前机型的高度,减50是减去屏幕最下方的tarbar高度。高度在页面初次加载的时候就进行计算

1.3  选中状态样式判断

左侧列表被选中后会有这个红色的部分

每次点击左侧列表会记录left_active_num,讲left_active_num与循环时的index进行比对,如果相同的多给一个active的类名

1.4  点击左侧时右侧会到顶点

每一次点击左侧的时候,右侧的内容是不同的,但实际上元素都是一个。所以点击左侧时,右侧不会默认回到顶点

这里用变量的原因是给0这个常量第二次就懒加载了,只能点击左侧之后每次都赋值一个新的0

1.5  源码 

wxml

<!--pages/category/category.wxml-->
<black_horse_search></black_horse_search>
<view class="scroll-view-container" style="height:{{windowHeight}};">
<!-- <view class="scroll-view-container" style="height:200px;"> -->
  <!-- 左侧滚动区域 -->
  <scroll-view class="left-scroll-view" scroll-y="true">
    <view  wx:for="{{cateList}}" wx:key="cat_id" class="{{['scroll-view-item',index==left_active_num?'active':'']}}" bindtap="left_scroll_click" data-click_item_index="{{index}}">{{item.cat_name}}</view>
  </scroll-view>
  <!-- 右侧滚动区域 -->
  <!-- 老版本的scroll-top不能给相同的值,也就是你一直给0是不行的 -->
  <scroll-view class="right-scroll-view" scroll-y="true" scroll-top="{{right_scrollTop}}">
    <view class="cate-lv2" wx:for="{{cateLevel2}}" wx:key="index">
      <view class="cate-lv2-title">/ {{item.cat_name}} /</view>
      <view class="cate-lv3-list">
        <view class="cate-lv3-item" wx:for="{{item.children}}" wx:for-index="index3" wx:for-item="item3" wx:key="index3" bindtap="cate_lv3_item_click" data-cat_name="{{item3.cat_name}}" data-cat_id="{{item3.cat_id}}">
          <image src="{{item3.cat_icon}}" mode="" data-cat_name="{{item3.cat_name}}" data-cat_id="{{item3.cat_id}}"/>
          <text data-cat_name="{{item3.cat_name}}" data-cat_id="{{item3.cat_id}}" >{{item3.cat_name}}</text>
        </view>
      </view>
    </view>
  </scroll-view>
</view>

wxss

/* pages/category/category.wxss */
.scroll-view-container {
  display: flex;
}

.scroll-view-container .left-scroll-view {
  width: 120px;
}

.scroll-view-container .left-scroll-view .scroll-view-item.active {
  position: relative;
  background-color: #ffffff;
}

.scroll-view-container .left-scroll-view .scroll-view-item.active::before {
 position:absolute;
 top:50%;
 left:0;
 content:' ';
 display:block;
 width: 3px;
 height:30px;
 background-color: #C00000;
 transform: translateY(-50%);
}

.scroll-view-container .left-scroll-view .scroll-view-item {
  background-color: #f7f7f7;
  line-height: 60px;
  text-align: center;
  font-size: 12px;
}

.cate-lv2-title {
  font-size:12px;
  font-weight:bold;
  text-align: center;
  padding: 15px 0;
}

.cate-lv3-list {
  display:flex;
  flex-wrap:wrap
}

.cate-lv3-list .cate-lv3-item {
  width:33.33%;
  display:flex;
  flex-direction:column;
  justify-content: center;
  align-items: center;
  margin-bottom:10px;
}

.cate-lv3-list .cate-lv3-item image{
  width:60px;
  height:60px;
}

.cate-lv3-list .cate-lv3-item text{
  font-size:12px;
}

js

// pages/category/category.js
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store.js'

const App = getApp()

Page({
  cate_lv3_item_click(e) {
    wx.navigateTo({
      url:'/subpackage_goods_list/goods_list?cid=' + e.target.dataset.cat_id + '&&query=' + e.target.dataset.cat_name
    })
  },
  left_scroll_click(e) {
    const click_item_index = e.target.dataset.click_item_index
    this.setData({left_active_num:click_item_index})
    this.setData({cateLevel2:this.data.cateList[Number(click_item_index)].children})
    this.setData({right_scrollTop:0})
  },
  get_cateList() {
    wx.request({
      url:App.base_url + '/api/public/v1/categories',
      
      method:'GET',
      success:(val) => {
        // 获取所有分类
        this.setData({cateList:val.data.message})
        // 获取二级分类,二级分类的内容在一级分类中有,我们在这里弄好处理,这里给一个初始值,后面在左侧点击事件中还会再改
        this.setData({cateLevel2:val.data.message[0].children})
      },
      fail:() => {
        console.log('获取左侧失败')
        wx.showToast({
          title:'获取左侧失败',
          icon:'error',
          duration:2000
        })
      }
    })
  },
  /**
   * 页面的初始数据
   */
  data: {
    windowHeight:0 + 'px',
    cateList:[],
    cateLevel2:[],
    left_active_num:0,
    right_scrollTop:0
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.storeBindings = createStoreBindings(this,{
      store,
      actions:['set_cart_tabBar_badge']
    })

    this.setData({windowHeight:(wx.getWindowInfo().windowHeight-50) + 'px'})
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
    // 获取分类列表
    this.get_cateList()
    // 设置购物车tabBar的徽标
    this.set_cart_tabBar_badge()
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

2  购物车

购物车中的内容在这个项目中都是放在本地的,在实际开发中一般是放在云端

购物车为空时会显示这个页面

2.1  store

store.js是放全局变量的js文件,创建方法可以参考 18.全局数据共享 mobx-miniprogram与mobx-miniprogram-bindings-CSDN博客

源码

import {
  action,
  observable
} from 'mobx-miniprogram'

export const store = observable({
  // 购物车总数的计算属性
  // 计算购物车一共多少件
  get cart_shop_total() {
    let total = 0
    this.cart_list.forEach(goods => total += goods.goods_count)
    return total
  },
  // 计算购物车选中的一共多少钱
  get cart_shop_choosed_total_price() {
    let total_price = 0
    this.cart_list.forEach(goods => {
      if (goods.goods_state == true) {
        total_price = total_price + goods.goods_count * goods.goods_price
      }
    })
    return total_price.toFixed(2)
  },
  // 计算购物车选中的一共多少件
  get cart_shop_choosed_total_num() {
    let total_num = 0
    this.cart_list.forEach(goods => {
      if (goods.goods_state == true) {
        total_num = total_num + goods.goods_count
      }
    })
    return total_num
  },
  // 计算是否全选
  get is_all_checked() {
    let all_checked = true
    this.cart_list.forEach(goods => {
      if (goods.goods_state == false) {
        all_checked = false
      }
    })
    return all_checked
  },
  // 从本地存储中获取购物车商品信息
  cart_list: wx.getStorageSync('cart_list') || [],
  // 添加购物车方法
  add_cart_obj: action(function (goods_obj) {
    let findResult = this.cart_list.find((x) => x.goods_id === goods_obj.goods_id)

    if (!findResult) {
      this.cart_list = [...this.cart_list, goods_obj]
    } else {
      findResult.goods_count++
    }

    wx.setStorageSync('cart_list', this.cart_list)
  }),
  // 设置购物车tabBar的徽标
  set_cart_tabBar_badge:action(
    function() {
      wx.setTabBarBadge({
        index: 2,
        text: String(this.cart_shop_total),
      })
    }
  ),
  // 改变购物车商品所有选中状态
  updateAllGoodsState:action(
    function(all_checked_now_state) {
      this.cart_list.forEach(goods => {
        goods.goods_state = !all_checked_now_state
      })
      let new_cart_list = JSON.stringify(this.cart_list)
      this.cart_list = JSON.parse(new_cart_list)
      wx.setStorageSync('cart_list', this.cart_list)
    }
  ),
  // 改变购物车商品选中状态
  updateGoodsState:action(
    function(goods) {
      let findResult = this.cart_list.find(x=>x.goods_id === goods.goods_id)

      if (findResult) {
        findResult.goods_state = !goods.goods_status
        let new_cart_list = JSON.stringify(this.cart_list)
        this.cart_list = JSON.parse(new_cart_list)
      }
      wx.setStorageSync('cart_list', this.cart_list)
    }
  ),
  // 购物车商品数量 + 1
  add_one_GoodsNum:action(
    function(goods) {
      let findResult = this.cart_list.find(x=>x.goods_id === goods.goods_id)

      if (findResult) {
          findResult.goods_count = findResult.goods_count + 1
          let new_cart_list = JSON.stringify(this.cart_list)
          this.cart_list = JSON.parse(new_cart_list)
      }
      wx.setStorageSync('cart_list', this.cart_list)
    }
  ),
  // 购物车商品数量 - 1
  sub_one_GoodsNum:action(
    function(goods) {
      let findResult = this.cart_list.find(x=>x.goods_id === goods.goods_id)

      if (findResult) {
        if (findResult.goods_count > 1) {
          findResult.goods_count = findResult.goods_count - 1
          let new_cart_list = JSON.stringify(this.cart_list)
          this.cart_list = JSON.parse(new_cart_list)
        }
      }
      wx.setStorageSync('cart_list', this.cart_list)
    }
  ),
  // 删除购物车商品
  delete_store_goods:action(
    function(goods) {
      this.cart_list = this.cart_list.filter(x=>x.goods_id != goods.goods_id)
      wx.setStorageSync('cart_list', this.cart_list)
    }
  ),
  // 是否是从“购物车”跳转到“我的”界面且需要跳转回“购物车”页面
  need_navigate_back:false,
  yes_need_navigate_back:action(function() {
    this.need_navigate_back = true
  }),
  cancel_need_navigate_back:action(function() {
    this.need_navigate_back = false
  })
})

2.2  tabBar徽标

tarBar上的徽标是购物车中商品的数量

用到的是wx.setTabBarBadge()这个api

index是第几个tarbar,按0、1、2这么排,购物车是第二个

text是要写什么东西,类型为字符串,也就是说可以写其他的文字上去

当切换到任意tarbar的时候会更新徽标,在加入购物车的时候会更新徽标,在改变商品数量的时候会更新徽标

使用方法时引入store然后用this调用就行了

2.3  滑动删除

用的是movable-area与movable-view

movable-view必须放在movable-area中,其余就没什么好讲的了,有例子照抄就行了

2.4  结算

2.4.1  结算前登录

这个功能需要“购物车”和“我的”这两个tarbar共同完成,所以需要用到全局数据

这个变量是给"我的"中的一键登录按钮用的,直接点一键登录按钮就不需要跳转,从购物车界面过来再点一键登录按钮就需要跳转

2.4.2  结算功能

目前小程序结算功能是不开放给个人开发者的,如果要开通的话只有一个公司的营业执照也是不行的,需要有实际的开发需求才能用微信支付的接口

2.5  触发组件事件

这些是触发组件的事件,感兴趣可以看一下这个 15-5.自定义组件的通信-CSDN博客

2.6  源码

wxml

<!--pages/cart/cart.wxml-->

<!-- 收货地址区域 -->
<view class="cart-container" wx:if="{{cart_list.length != 0}}">
  <view>
  <!-- 选择收货地址的盒子 -->
  <view class="address-choose-box" wx:if="{{!choosed_address.username}}">
    <button type="primary" size="mini" class="btnChooseAddress" bind:tap="go_to_choose_address">请选择收货地址+</button>
  </view>

  <!-- 渲染收货信息的盒子 -->
  <view class="address-info-box" wx:else bind:tap="go_to_choose_address">
    <view class="row1">
      <view class="row1-left">
        <view class="username">收货人:<text>{{choosed_address.username}}</text></view>
      </view>
      <view class="row1-right">
        <view class="phone">电话:<text>{{choosed_address.phone}}</text></view>
        <image src="/src/arrowright.png" mode="" style="width:16px;height:16px" />
      </view>
    </view>
    <view class="row2">
      <view class="row2-left">收货地址:</view>
      <view class="row2-right">{{choosed_address.address_detail}}</view>
    </view>
  </view>

  <!-- 底部的边框线 -->
  <image src="/src/cart_border@2x.png" class="address-border"></image>
  </view>

  <!-- 购物车标题 -->
  <view class="cart-title">
    <image src="../../src/shop.png" mode="" style="width:18px;height:18px;"/>
    <text class="cart-title-text">购物车</text>
  </view>

  <!-- 购物车内容 -->
  <view class="cart_content_view">
    <block wx:for="{{cart_list}}" wx:key="index" >
      <movable-area data-goods_id="{{item.goods_id}}">
        <movable-view direction="horizontal" data-goods_id="{{item.goods_id}}">
          <goods_list_item goods_small_logo="{{item.goods_small_logo}}" goods_id="{{item.goods_id}}" goods_price="{{item.goods_price}}" goods_name="{{item.goods_name}}" goods_count="{{item.goods_count}}" showRadio="true" showNumberBox="true" goods_checked="{{item.goods_state}}" bind:radio_change="change_radio_state" bind:add_one="add_one" bind:sub_one="sub_one"></goods_list_item>
          <view class="itemDelet" bindtap="delete_goods" data-goods_id="{{item.goods_id}}">删除</view>
        </movable-view>
      </movable-area>
    </block>
  </view>

  <!-- 底部结算区域 -->
  <view class="my-settle-container">
    <label class="radio">
      <checkbox color="#C00000" checked="{{is_all_checked}}" bind:tap="click_all_checked_button"/><text>全选</text>
    </label>
    <view class="amount-box">
      合计:<text class="amount">¥{{cart_shop_choosed_total_price}}</text>
    </view>
    <view class="btn-settle" bind:tap="buy_cart">结算({{cart_shop_choosed_total_num}})</view>
  </view>
</view>
<!-- 当购物车里什么都没有时出现的东西 -->
<view class="empty-cart" wx:else>
    <image src="/src/empty_cart.png" class="empty-img"></image>
    <text class="tip-text">空空如也~</text>
  </view>

wxss

/* pages/cart/cart.wxss */

/* 购物车标题 */
.cart-title {
  height:40px;
  display:flex;
  align-items:center;
  font-size:14px;
  padding-left:5px;
  border-bottom:1px solid #efefef;
  white-space: wrap;
}

.cart-title .cart-title-text {
  margin-left:10px;
  white-space: wrap;
}

/* 购物车内容的滑动效果 */
movable-area {
  display: flex;
  flex-direction: row;
  width: calc(100% + 120rpx);
  justify-content: center;
  left: -120rpx;
  height: 130px;
  z-index:0;
}
 
movable-view {
  display: flex;
  flex-direction: row;
  width: calc(100% - 120rpx);
  z-index: 1001;
  left: 120rpx;
}

.itemDelet {
  position: absolute;
  text-align: center;
  right: -125rpx;
  line-height: 130px;
  height:130px;
  background-color: rgb(194,0,2);
  margin-top: 0rpx;
  margin-right: 6rpx;
  width: 100rpx;
  text-align: right;
  padding-right: 20rpx;
  color: #fff;
}

/* 收货地址 */
.address-border {
  display: block;
  width: 100%;
  height: 5px;
}

.address-choose-box {
  height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.address-info-box {
  font-size:12px;
  height:90px;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding:0 5px;
}

.address-info-box .row1 {
  display: flex;
  justify-content: space-between;
}

.address-info-box .row1 .row1-right {
  display: flex;
  align-items: center;
}

.phone {
  margin-right: 5px;
}

.address-info-box .row2 {
  display: flex;
  align-items: center;
  margin-top: 10px;
}

.address-info-box .row2 .row2-left {
  white-space: nowrap;
}

/* 底部结算区域 */
.my-settle-container {
  position: fixed;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 50px;
  background-color: white;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-left: 5px;
  font-size: 14px;
  z-index:999;
}

.my-settle-container .radio {
  display:flex;
  align-items:center;
}

.my-settle-container .amount {
  color:#c00000
}

.my-settle-container .btn-settle {
  height: 50px;
  min-width: 100px;
  background-color: #c00000;
  color: white;
  line-height: 50px;
  text-align: center;
  padding: 0 10px;
}

.cart_content_view {
  padding-bottom:50px;
}

/* 当购物车什么都没有的时候的区域 */
.empty-cart {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 150px;
}

.empty-cart .empty-img {
  width:90px;
  height:90px;
}

.empty-cart .tip-text {
  font-size:12px;
  color:gray;
  margin-top:15px;
}

js

// pages/cart/cart.js
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import {store} from '../../store/store.js'

const App = getApp()

Page({
  buy_cart() {
    if (this.data.cart_shop_choosed_total_num == 0) {
      wx.showToast({
        title: '请选择要结算的商品',
        mask:true,
        icon:'none'
      })
      setTimeout(function() {wx.hideToast()},800)
      return
    }
    if (!this.data.choosed_address.username) {
      wx.showToast({
        title: '请选择收货地址',
        mask:true,
        icon:'none'
      })
      setTimeout(function() {wx.hideToast()},800)
      return
    }
    if (this.data.userinfo == '') {
      wx.showToast({
        title: '请先登录',
        mask:true,
        icon:'none'
      })
      setTimeout(()=>{
        wx.hideToast()
        wx.switchTab({
          url: '/pages/my/my',
          success:()=>{
            this.yes_need_navigate_back()
          }
        })
      },800)
      return 
    }
  },
  click_all_checked_button() {
    this.updateAllGoodsState(this.data.is_all_checked)
  },
  go_to_choose_address() {
    wx.navigateTo({
      url:'/subpackage_choose_address/choose_address'
    })
  },
  change_radio_state(e) {
    this.updateGoodsState(e.detail)
  },
  add_one(e) {
    this.add_one_GoodsNum(e.detail)
    this.set_cart_tabBar_badge()
  },
  sub_one(e) {
    this.sub_one_GoodsNum(e.detail)
    this.set_cart_tabBar_badge()
  },
  delete_goods(e) {
    this.delete_store_goods(e.target.dataset)
    this.set_cart_tabBar_badge()
  },
  /**
   * 页面的初始数据
   */
  data: {
    // address:{'name':'suyu'}
    choosed_address:{},
    userinfo:'',
    from:''
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad(options) {
    this.storeBindings = createStoreBindings(this,{
      store,
      fields:['cart_list','cart_shop_choosed_total_price','cart_shop_choosed_total_num','is_all_checked'],
      actions:['set_cart_tabBar_badge','updateGoodsState','add_one_GoodsNum','sub_one_GoodsNum','delete_store_goods','updateAllGoodsState','yes_need_navigate_back']
    })
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady() {
    // 设置购物车tabBar的徽标
    this.set_cart_tabBar_badge()
    this.setData({choosed_address:wx.getStorageSync('choosed_address') || {}})
  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {
    this.setData({choosed_address:wx.getStorageSync('choosed_address') || {}})
    this.setData({userinfo:wx.getStorageSync('userinfo') || ''})
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {
    
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android手写自己的路由SDK

实现自己的路由框架 ​ 在较大型的Android app中常会用到组件化技术&#xff0c;针对不同的业务/基础功能对模块进行划分&#xff0c;从上到下为壳工程、业务模块、基础模块。其中业务模块依赖基础模块&#xff0c;壳工程依赖业务模块。同级的横向模块&#xff08;比如多个业务…

使用Nuxt3框架搭建基础项目

Nuxt3安装 基础配置: Node.js** - v18.0.0版本以上 , 可以结合fnm工具切换node版本 安装nuxt3命令 打开vscode或者控制台去到项目文件夹输入: npx nuxilatest init <project-name> 国内执行这行代码&#xff0c;即使科学上网也会有问题 ⚠️ 安装Nuxt3报错 安装过程…

数据分析--客户价值分析RFM(K-means聚类/轮廓系数)

原数据 import os import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from sklearn import metrics ### 数据抽取&#xff0c;读⼊数据 df pd.read_csv("customers1997.csv") #相对路径读取数据 print(df.info()) pr…

如何定时打开网站

首先&#xff0c;需要用到的这个工具&#xff1a; 度娘网盘 提取码&#xff1a;qwu2 蓝奏云 提取码&#xff1a;2r1z 1、打开工具按下Ctrl3&#xff0c;切换到定时器模块&#xff0c;左侧右键&#xff0c;选择新建 2、标题叫百度&#xff0c;等下就让它打开百度&#xff0c…

Spring - 6 ( 9000 字 Spring 入门级教程 )

一&#xff1a; SpringBoot 配置文件 1.1 配置文件作用 配置文件通常是一个文本文件&#xff0c;其中包含了程序或系统的各种设置、选项和参数。比如C:\Users, C:\Windows 文件夹, 以及各种 .config, .xml 文件 配置文件主要是为了解决硬编码&#xff08;代码写死&#xff0…

排序算法--希尔排序

前提&#xff1a; 排序算法——直接插入排序-CSDN博客 希尔排序(Shell Sort)是插入排序的一种。是直接插入排序算法的Plus版。该方法又称缩小增量排序&#xff0c;是D.L.Shell于1959年提出。要想学好希尔排序&#xff0c;直接插入排序一定要学好&#xff0c;没学过的&#xff0…

chrome extension插件替换网络请求中的useragent

感觉Chrome商店中的插件不能很好的实现自己想要的效果,那么就来自己动手吧。 本文以百度为例: 一般来说网页请求如下: 当前使用的useragent是User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safar…

【Flask 系统教程 4】Jinjia2模版和语法

Jinjia2 模板 模板的介绍 Jinja2 是一种现代的、设计优雅的模板引擎&#xff0c;它是 Python 的一部分&#xff0c;由 Armin Ronacher 开发。Jinja2 允许你在 HTML 文档中嵌入 Python 代码&#xff0c;以及使用变量、控制结构和过滤器来动态生成内容。它的语法简洁清晰&#…

java发送请求2次开发-get请求json

因为你请求参数不为空&#xff0c;接口都会把这个参数带上 所以借鉴HttpPost类 继承这个类&#xff0c; 这个类是可以带消息的 httpgetwithentity&#xff0c;httpget请求带上消息 复写 构造方法复制过来进行使用 二次开发类让其get请求时可以发送json

IOS上线操作

1、拥有苹果开发者账号 2、配置证书&#xff0c;进入苹果开发者官网&#xff08;https://developer.apple.com/&#xff09; 3、点击账户&#xff08;account&#xff09;&#xff0c;然后创建一个唯一的标识符 4、点击"Identifiers"&#xff0c;然后点击"&qu…

SpringBoot的ProblemDetails

1.RFC 7807 之前的项目如果出现异常&#xff0c;默认跳转到error页面。或者是抛出500 异常。 但是对于前后端分离的项目&#xff0c;Java程序员不负责页面跳转&#xff0c;只需要 把错误信息交给前端程序员处理即可。而RFC 7807规范就是将异常 信息转为JSON格式的数据。这个…

android init进程启动流程

Android系统完整的启动流程 android 系统架构图 init进程的启动流程 init进程启动服务的顺序 bool Service::Start() {// Starting a service removes it from the disabled or reset state and// immediately takes it out of the restarting state if it was in there.flags_…

每天五分钟深度学习框架pytorch:如何创建多维Tensor张量元素?

本文重点 上节课程我们学习了如何创建Tensor标量,我们使用torch.tensor。本节课程我们学习如何创建Tensor向量,我们即可以使用torch.Tensor又可以使用torch.tensor,下面我们看一下二者的共同点和不同点。 Tensor张量 tensor张量是一个多维数组,零维就是一个点(就是上一…

llama-factory/peft微调千问1.5-7b-chat

目标 使用COIG-CQIA数据集和通用sft数据集对qwen1.5-7b-chat进行sft微调,使用公开dpo数据集进行dpo对齐。学习千问的长度外推方法。 一、训练配置 使用Lora方式, 将lora改为full即可使用全量微调。 具体的参数在 该框架将各个参数、训练配置都封装好了,直接使用脚本,将数…

毫米波雷达多人呼吸心跳检测MATLAB仿真

本文基于TI的IWR1642毫米波雷达 2T4R MIMO阵列&#xff0c;通过实际采集数据算法仿真&#xff0c;实现多人呼吸心跳检测。 文章末尾给出了本文的仿真代码。 主要内容包含&#xff1a; &#xff08;1&#xff09;雷达参数设定 &#xff08;2&#xff09;ADC数据导入 &#xff08…

Windows Server 安全策略配置

前言 Windows Server是由微软开发的一种操作系统&#xff0c;主要用于在企业或机构的服务器上运行。它提供了一系列的功能和工具&#xff0c;旨在提高服务器的性能、可靠性、安全性和管理性。 特点 强大的性能&#xff1a;Windows Server具有高度优化的内核和资源管理&#x…

【MySQL | 第十篇】重新认识MySQL索引匹配过程

文章目录 10.重新认识MySQL索引匹配过程10.1匹配规则10.2举例&#xff1a;联合索引遇到范围查询&#xff08;>、<、between、like&#xff09;10.2.1例子一&#xff1a;>10.2.2例子二&#xff1a;>10.2.3例子三&#xff1a;between10.2.4例子四&#xff1a;like 10…

SQL数据库

一.什么是数据库 数据库&#xff1a;存储数据的仓库&#xff0c;数据是有组织的进行存储。&#xff08;database 简称DB&#xff09; 数据库管理系统&#xff1a;管理数据库的大型软禁&#xff08;DataBase Management System 简称DBMS&#xff09; SQL&#xff1a;操作关系…

Deep Learning Part Seven基于RNN生成文本--24.5.2

不存在什么完美的文章&#xff0c;就好像没有完美的绝望。 ——村上春树《且听风吟》 本章所学的内容 0.引子 本章主要利用LSTM实现几个有趣的应用&#xff1a; 先剧透一下&#xff1a;是AI聊天软件&#xff08;现在做的ChatGPT&#xff08;聊天神器&#xff0c;水论文高手…

Windows Server安装DHCP和DNS

前言 本期将教大家如何在Windows server上部署DHCP服务和DNS服务&#xff0c;用于模拟给内网主机分配IP地址。虽然用于演示的系统比较老&#xff0c;如果在新版本如Windows server2016、19、22上部署&#xff0c;操作基本一致。在此之前先给大家科普一波理论&#xff0c;需略过…
最新文章