vue3+element-plus多选框全选与单选

一、父组件代码:

<template>

    <div class="bottom-box">

      <!-- 股票收藏板块 -->

      <StockCollect v-if="id === 'stockCollect'"></StockCollect>

  </div>

</template>

<script setup lang="ts">

import StockCollect from '@/views/personal-center/components/stockCollect.vue'

</script>

<style lang="less" scoped>

  .bottom-box {

    margin: 0 20px;

  }

</style>

二、子组件代码:

<template>

  <div class="stock-collect">

    <div class="top-box">

      <div

        class="add-btn"

        :style="{

          cursor: isAdmin && route.query.userId ? 'no-drop' : 'pointer'

        }"

        @click="isAdmin && route.query.userId ? '' : showAddDialog()"

      >

        添加股票收藏

      </div>

      <div class="right-box">

        <el-input

          v-model="searchVal"

          :maxlength="6"

          placeholder="请输入股票关键字或代码"

          clearable

          class="ipt"

        />

        <div class="search-btn" @click="searchUserCollectCompany">搜索</div>

      </div>

    </div>

    <div class="stock-list">

      <div

        class="check-top"

        v-if="collectStockList && collectStockList.length > 0"

      >

        <el-checkbox

          v-model="checkAll"

          :disabled="isAdmin && route.query.userId ? true : false"

          :indeterminate="isIndeterminate"

          @change="checkAllChange"

          class="select-name"

        >

          全选

        </el-checkbox>

        <div

          class="delete-btn"

          :style="{

            cursor: isAdmin && route.query.userId ? 'no-drop' : 'pointer'

          }"

          @click="isAdmin && route.query.userId ? '' : deleteStock()"

        >

          删除

        </div>

      </div>

      <el-checkbox-group

        v-model="checkedStockList"

        @change="checkedChange"

        :disabled="isAdmin && route.query.userId ? true : false"

        class="check-list"

        v-if="collectStockList && collectStockList.length > 0"

      >

        <el-checkbox

          v-for="item in collectStockList"

          :key="item.companyId"

          :value="item.companyId"

          :label="item.companyId"

          class="stock-check"

        >

          {{ item.companyName }} [{{ item.symbol }}]

        </el-checkbox>

      </el-checkbox-group>

      <div class="nodata" v-else>暂无收藏的股票</div>

    </div>

    <!--  添加账号  -->

    <stock-check

      :dialog-visible="stockCheckVisible"

      :title="stockTitle"

      :data-list="dataList"

      :current-index="currentIndex"

      :loading="loading"

      @current-index-change="currentIndexChange"

      @cancel="stockCheckCancel"

      @summit="stockCheckSummit"

    />

  </div>

</template>

<script lang="ts" setup>

import { ElMessage, ElMessageBox } from 'element-plus'

import StockCheck from '@/components/StockCheck.vue'

import {

  queryUserCollectCompany,

  queryUserCompanyTypeDto,

  delUserCollectCompany,

  addUserCollectCompany,

  adminCheckStockList

} from '@/service/stockIndex/index'

const route = useRoute()

const stockCheckVisible = ref(false) // 添加股票弹框

//弹窗title

const stockTitle = ref('添加股票收藏')

const checkAll = ref(false) // 是否全选

const isIndeterminate = ref(false) // 全选中状态

const checkedStockList = ref<any>([]) // 选中的股票列表

const collectStockList = ref<any>([]) // 收藏的股票列表

//添加或编辑账号的所有股票列表数据

const dataList = ref<any>([])

const searchVal = ref<any>('') // 搜索框的值

const isAdmin = ref(false) // 是否管理员

const userInfo = ref<any>({}) // 用户信息

//0 地区分类  1交易所分类

const currentIndex = ref(0)

//弹窗数据请求loading

const loading = ref(false)

// 全选

const checkAllChange = (val: any) => {

  let arr: number[] = []

  collectStockList.value.forEach((v: any) => {

    v.checked = val

    arr.push(v.companyId)

  })

  checkedStockList.value = val ? arr : []

  isIndeterminate.value = false

}

// 单个股票勾选

const checkedChange = (value: any) => {

  collectStockList.value.forEach((v: any) => {

    v.checked = value.includes(v.companyId)

  })

  const checkedCount = collectStockList.value.filter(

    (v: any) => v.checked

  ).length

  checkAll.value = collectStockList.value.every((dto: any) => dto.checked)

  isIndeterminate.value =

    checkedCount > 0 && checkedCount < collectStockList.value.length

}

// 显示添加弹框

const showAddDialog = () => {

  stockCheckVisible.value = true

  checkAll.value = false

  isIndeterminate.value = false

  checkedStockList.value = []

  getcheckDataList()

}

// 删除收藏的股票

const deleteStock = () => {

  if (checkedStockList.value.length === 0) {

    ElMessage({

      type: 'error',

      message: '请选择要删除的股票'

    })

  } else {

    ElMessageBox.confirm('确认删除选中的股票?', '提示', {

      confirmButtonText: '确认',

      cancelButtonText: '取消',

      autofocus: false,

      cancelButtonClass: 'cancle-btn',

      type: 'warning'

    })

      .then(() => {

        delUserCollectCompany(

          checkAll.value ? [] : checkedStockList.value,

          checkAll.value ? 1 : 0

        ).then((res: any) => {

          if (res.code === 200) {

            getUserCollectCompany()

            checkedStockList.value = []

            checkAll.value = false

            isIndeterminate.value = false

          }

          ElMessage({

            type: res.code === 200 ? 'success' : 'error',

            message: res.code === 200 ? '删除成功' : res.message

          })

        })

      })

      .catch(() => {})

  }

}

//取消添加股票

const stockCheckCancel = () => {

  //tab切换置为初始值

  currentIndex.value = 0

  stockCheckVisible.value = false

}

//确定添加股票

const stockCheckSummit = (companyIds: number[], isAll: number) => {

  addUserCollectCompany(companyIds, isAll).then((res: any) => {

    if (res.code === 200) {

      stockCheckCancel()

      getUserCollectCompany()

    }

    ElMessage({

      type: res.code === 200 ? 'success' : 'error',

      message: res.code === 200 ? '保存成功' : res.message

    })

  })

}

//子组件内tab切换

const currentIndexChange = (index: number) => {

  currentIndex.value = index

  getcheckDataList()

}

// 搜索股票列表

const searchUserCollectCompany = () => {

  checkAll.value = false

  isIndeterminate.value = false

  checkedStockList.value = []

  getUserCollectCompany()

}

// 获取用户收藏的股票列表

const getUserCollectCompany = () => {

  loading.value = true

  dataList.value = []

  let userId: string = ''

  queryUserCollectCompany(userId, searchVal.value.trim()).then((res: any) => {

    if (res.code === 200) {

      collectStockList.value = res.data

    } else {

      ElMessage({

        type: 'error',

        message: res.message

      })

    }

    loading.value = false

  })

}

// 管理员查看用户收藏股票列表

const getAdminCheckStockList = () => {

  loading.value = true

  dataList.value = []

  adminCheckStockList(route.query.userId ? route.query.userId : '').then(

    (res: any) => {

      if (res.code === 200) {

        collectStockList.value = res.data

      } else {

        ElMessage({

          type: 'error',

          message: res.message

        })

      }

      loading.value = false

    }

  )

}

// 获取地区、交易所分类数据

const getcheckDataList = () => {

  loading.value = true

  dataList.value = []

  queryUserCompanyTypeDto(

    route.query.userId ? route.query.userId : '',

    currentIndex.value

  ).then((res: any) => {

    if (res.code === 200) {

      let subData: any[] = []

      res.data.forEach((v: any) => {

        subData = [...subData, ...v.userCompanyCheckedDtoList]

      })

      const allData: any[] = [

        {

          typeName: '全部',

          userCompanyCheckedDtoList: subData

        }

      ]

      dataList.value = [...allData, ...res.data]

    } else {

      ElMessage({

        type: 'error',

        message: res.message

      })

    }

    loading.value = false

  })

}

onMounted(() => {

  nextTick(() => {

    let info: any = localStorage.getItem('userInfo')

    userInfo.value = JSON.parse(info)

    isAdmin.value = userInfo.value.admin

    if (isAdmin.value && route.query.userId) {

      getAdminCheckStockList()

    } else {

      getUserCollectCompany()

    }

  })

})

</script>

<style lang="less" scoped>

.stock-collect {

  margin: 20px 0 0;

  .top-box {

    display: flex;

    align-items: center;

    justify-content: space-between;

    .add-btn {

      width: 120px;

      height: 30px;

      border-radius: 4px;

      border: 1px solid #3a5bb7;

      display: flex;

      align-items: center;

      justify-content: center;

      font-size: 14px;

      color: #3a5bb7;

      cursor: pointer;

    }

    .right-box {

      display: flex;

      align-items: center;

      .ipt {

        width: 280px;

        margin-left: 14px;

        font-size: 12px;

      }

      .search-btn {

        width: 60px;

        display: flex;

        justify-content: center;

        align-items: center;

        height: 32px;

        background-color: #3a5bb7;

        border-radius: 4px;

        color: #ffffff;

        margin-left: 14px;

        font-size: 12px;

        cursor: pointer;

      }

    }

  }

  .stock-list {

    margin: 25px 0;

    .check-top {

      display: flex;

      align-items: center;

      justify-content: space-between;

      margin-bottom: 13px;

      .delete-btn {

        width: 64px;

        height: 30px;

        border-radius: 4px;

        border: 1px solid #3a5bb7;

        cursor: pointer;

        font-size: 14px;

        color: #3a5bb7;

        float: right;

        display: flex;

        align-items: center;

        justify-content: center;

      }

    }

    .nodata {

      font-size: 14px;

      color: #666666;

      display: flex;

      justify-content: center;

      align-items: center;

    }

    .stock-check {

      margin-bottom: 10px;

      margin-right: 45px;

    }

    .check-list {

      max-height: 325px;

      overflow-y: auto;

    }

    .el-checkbox {

      --el-checkbox-checked-input-border-color: @text-blue;

      --el-checkbox-checked-bg-color: @text-blue;

      --el-checkbox-input-border-color-hover: @text-blue;

      :deep(.el-checkbox__label) {

        padding-left: 10px;

        margin-left: 10px;

        width: 210px;

        height: 30px;

        line-height: 30px;

        overflow: hidden;

        text-overflow: ellipsis;

        white-space: nowrap;

        color: #666666;

        background: #f5f8fc;

      }

      &.select-name {

        :deep(.el-checkbox__label) {

          height: 24px;

          line-height: 24px;

          font-weight: bold;

          color: #333333;

          background: transparent;

        }

      }

      &.is-checked {

        :deep(.el-checkbox__label) {

          color: @text-blue;

        }

      }

      &:nth-of-type(5n) {

        margin-right: 0;

      }

    }

  }

}

</style>

三、StockCheck组件代码:

<template>

  <el-dialog

    :model-value="dialogVisible"

    :title="title"

    :width="width"

    class="stock-check-dialog"

    append-to-body

    @close="cancle"

  >

    <div class="stock-check-content">

      <div class="acc-input-box mb12" v-if="type === 'addAccount'">

        <span>账号</span>

        <el-input

          v-model.trim="accInput"

          placeholder="请输入账号"

          class="acc-input"

          :disabled="!!editRow"

          clearable

          maxlength="10"

        ></el-input>

      </div>

      <div class="mb12 tabs-box flex">

        <ul class="tab-item-box flex">

          <li

            v-for="(item, index) in tabList"

            :key="index"

            :class="['item', currentIndex === index ? 'active' : '']"

            @click="tabClick(index)"

          >

            {{ (item as any).label }}

          </li>

        </ul>

        <!-- 搜索框 -->

        <el-input

          v-model.trim="searchInput"

          maxlength="20"

          style="width: 200px"

          placeholder="请输入股票关键字或代码"

          size="small"

          clearable

          @change="searchKeyChange"

        >

          <template #suffix>

            <el-icon class="cur-p"><Search /></el-icon>

          </template>

        </el-input>

      </div>

      <div class="main-content ml12 mr12 flex" v-loading="loading">

        <div class="left-box" ref="leftScrollRef">

          <ul>

            <li

              :class="[

                'type-item',

                typeName === item.typeName ? 'active-name' : ''

              ]"

              v-for="(item, index) in dataList"

              :key="index"

              @click="typeNameChange(item.typeName)"

            >

              {{ getTypeName(item.typeName) }}

            </li>

          </ul>

        </div>

        <div class="right-box">

          <template v-if="subDataList.length">

            <el-checkbox

              v-show="subDataList.length"

              v-model="checkAll"

              :indeterminate="isIndeterminate"

              @change="handleCheckAllChange"

              >全选</el-checkbox

            >

            <div class="scroll-box" ref="rightScrollRef">

              <el-checkbox-group

                v-model="checkedStocks"

                @change="handleCheckedStocksChange"

              >

                <el-checkbox

                  v-for="item in subDataList"

                  :key="item.companyId"

                  :value="item.companyId"

                  :label="item.companyId"

                  :checked="item.checked"

                  size="large"

                >

                  {{ `${item.companyName} [${item.symbol}]` }}

                </el-checkbox>

              </el-checkbox-group>

            </div>

          </template>

          <template v-else>

            <div class="center">

              <img class="img" src="../../src/assets/img/search_no_data.png" />

            </div>

          </template>

        </div>

      </div>

    </div>

    <template #footer>

      <div class="dialog-footer">

        <el-button class="cancle-btn" @click="cancle">取消</el-button>

        <el-button @click="submit" type="primary"> 提交</el-button>

      </div>

    </template>

  </el-dialog>

</template>

<script setup lang="ts">

import type {

  UserCompanyTypeVO,

  UserCompanyCheckedVO,

  AccountManagementVO

} from '@/types'

import { Search } from '@element-plus/icons-vue'

import { ElMessage } from 'element-plus'

import Common from '@/utils/common'

const props = defineProps({

  //弹窗显示隐藏

  dialogVisible: {

    type: Boolean,

    default: false

  },

  //添加账户页面使用 - 标识类型

  type: {

    type: String,

    default: ''

  },

  //数据请求loading

  loading: {

    type: Boolean,

    default: false

  },

  //弹窗title

  title: {

    type: String,

    default: ''

  },

  //弹窗宽度

  width: {

    type: String,

    default: '1100px'

  },

  //tab切换数据

  tabList: {

    type: Array,

    default: () => {

      return [

        { label: '地区分类', value: 0 },

        { label: '交易所分类', value: 1 }

      ]

    }

  },

  //当前选择tab

  currentIndex: {

    type: Number,

    default: 0

  },

  //全部数据

  dataList: {

    type: Array as () => UserCompanyTypeVO[],

    default: () => []

  },

  //账户信息

  editRow: {

    type: Object as () => AccountManagementVO | null,

    default: () => null

  }

})

const emits = defineEmits(['cancel', 'summit', 'currentIndexChange'])

const { dialogVisible, dataList, currentIndex, editRow, type } = toRefs(props)

const rightScrollRef = ref()

const leftScrollRef = ref()

//选择的地区、交易所分类名称

const typeName = ref('')

//全选按钮

const checkAll = ref(false)

//是否开启半选

const isIndeterminate = ref(false)

//勾选的数据

const checkedStocks = ref<number[]>([])

//搜索关键字 - change方法触发赋值

const searchKey = ref('')

//搜索关键字 - 输入的值

const searchInput = ref('')

//账号输入

const accInput = ref('')

//左侧类型下的子数据

const subDataList = computed<UserCompanyCheckedVO[]>(() => {

  const filteredList = dataList.value.filter(

    (v: UserCompanyTypeVO) => v.typeName === typeName.value

  )

  let data: UserCompanyCheckedVO[] = []

  if (filteredList.length > 0) {

    data = filteredList[0].userCompanyCheckedDtoList.filter(

      (v: UserCompanyCheckedVO) =>

        v.symbol.includes(searchKey.value) ||

        v.companyName.includes(searchKey.value)

    )

  }

  return data

})

watch(

  () => dataList.value,

  (val) => {

    if (val.length) {

      typeName.value = val[0].typeName

    }

  }

)

watch(

  () => dialogVisible.value,

  (val) => {

    if (!val) {

      typeName.value = ''

      searchKey.value = ''

      searchInput.value = ''

      accInput.value = ''

      resetCheckValue()

      rightScrollRef.value && rightScrollRef.value.scrollTo({ top: 0 })

      leftScrollRef.value && leftScrollRef.value.scrollTo({ top: 0 })

    } else {

      //编辑时给账号赋值

      accInput.value = editRow?.value?.accountName ?? ''

    }

  }

)

// 使用 watch 来观察 subDataList 的变化

watch(subDataList, (newSubDataList) => {

  checkAll.value = newSubDataList.every(

    (dto: UserCompanyCheckedVO) => dto.checked

  )

  const checkedCount = newSubDataList.filter(

    (v: UserCompanyCheckedVO) => v.checked

  ).length

  isIndeterminate.value =

    checkedCount > 0 && checkedCount < newSubDataList.length

})

//回车或搜索点击

const searchKeyChange = () => {

  searchKey.value = searchInput.value

  typeName.value = dataList.value[0].typeName

}

//点击全选

const handleCheckAllChange = (val: boolean) => {

  let arr: number[] = []

  subDataList.value.forEach((v: UserCompanyCheckedVO) => {

    v.checked = val

    arr.push(v.companyId)

  })

  checkedStocks.value = val ? arr : []

  isIndeterminate.value = false

}

//单选

const handleCheckedStocksChange = (value: number[]) => {

  subDataList.value.forEach((v: UserCompanyCheckedVO) => {

    v.checked = value.includes(v.companyId)

  })

  const checkedCount = subDataList.value.filter(

    (v: UserCompanyCheckedVO) => v.checked

  ).length

  checkAll.value = subDataList.value.every(

    (dto: UserCompanyCheckedVO) => dto.checked

  )

  isIndeterminate.value =

    checkedCount > 0 && checkedCount < subDataList.value.length

}

//类型名称切换

const typeNameChange = (name: string) => {

  if (typeName.value === name) return

  typeName.value = name

  rightScrollRef.value && rightScrollRef.value.scrollTo({ top: 0 })

}

//转换类型名称

const getTypeName = (name: string) => {

  let showName = name

  if (currentIndex.value === 1) {

    switch (name) {

      case 'BSE':

        showName = '北交所'

        break

      case 'SSE':

        showName = '上交所'

        break

      case 'SZSE':

        showName = '深交所'

        break

      default:

        break

    }

  }

  return showName

}

//确定

const submit = () => {

  //处理跨tab选择数据 (因为出现了跨tab勾选情况,所以不能使用checkedStocks,checkedStocks只是起到当前页面勾选数据效果)

  //data 全部数据

  const data: UserCompanyTypeVO = dataList.value.filter(

    (v: UserCompanyTypeVO, index: number) => index === 0

  )[0]

  let selectCompanyIds: number[] = []

  data.userCompanyCheckedDtoList.forEach((v: UserCompanyCheckedVO) => {

    v.checked && selectCompanyIds.push(v.companyId)

  })

  const isAll =

    selectCompanyIds.length === data.userCompanyCheckedDtoList.length ? 1 : 0

  if (type.value === 'addAccount') {

    if (!accInput.value) {

      ElMessage({

        type: 'error',

        message: '请输入账号'

      })

      return

    } else {

      if (!Common.isValidAlphanumeric(accInput.value)) {

        ElMessage({

          type: 'error',

          message: '账号请输入字母或数字'

        })

        return

      }

    }

  }

  if (selectCompanyIds.length === 0) {

    ElMessage({

      type: 'error',

      message: '请先勾选数据'

    })

    return

  }

  emits('summit', selectCompanyIds, isAll, accInput.value)

}

//取消

const cancle = () => {

  emits('cancel')

}

//tab切换

const tabClick = (index: number) => {

  if (currentIndex.value === index) return

  emits('currentIndexChange', index)

  typeName.value = ''

  searchKey.value = ''

  searchInput.value = ''

  resetCheckValue()

}

//重置选择

const resetCheckValue = () => {

  checkAll.value = false

  isIndeterminate.value = false

  checkedStocks.value = []

}

</script>

<style scoped lang="less">

.stock-check-content {

  background-color: #f4f7fc;

  font-size: 14px;

  .acc-input-box {

    height: 70px;

    background: #ffffff;

    padding: 17px 30px;

    box-sizing: border-box;

    .acc-input {

      width: 300px;

      height: 36px;

      background: #ffffff;

      border-radius: 2px;

      //border: 1px solid #e5e7ee;

      margin-left: 10px;

    }

  }

  .flex {

    display: flex;

  }

  .tabs-box {

    height: 44px;

    background: #ffffff;

    .tab-item-box {

      width: 100%;

      margin: 0 auto;

      .item {

        width: 120px;

        line-height: 44px;

        text-align: center;

        position: relative;

        cursor: pointer;

        &.active {

          color: @text-blue;

          &:after {

            content: '';

            position: absolute;

            left: 40px;

            width: 40px;

            height: 3px;

            bottom: 0;

            background-color: @text-blue;

            border-radius: 2px 2px 0 0;

          }

        }

      }

    }

  }

  .main-content {

    height: 465px;

    background: #ffffff;

    border-radius: 4px;

    position: relative;

    .left-box {

      width: 230px;

      height: 100%;

      overflow: hidden;

      overflow-y: auto;

      border-right: 1px solid #ebeef8;

      .type-item {

        height: 40px;

        line-height: 40px;

        padding-left: 18px;

        position: relative;

        cursor: pointer;

        &:first-child {

          margin-top: 12px;

        }

        &:last-child {

          margin-bottom: 12px;

        }

        &.active-name {

          background: #f4f7fc;

          color: @text-blue;

          &:before {

            content: '';

            display: block;

            position: absolute;

            left: 0;

            background-color: @text-blue;

            width: 3px;

            height: 16px;

            top: 12px;

          }

        }

      }

    }

    .right-box {

      flex: 1;

      padding: 20px;

      box-sizing: border-box;

      position: relative;

      .scroll-box {

        height: calc(100% - 20px);

        overflow: hidden;

        overflow-y: auto;

        margin-bottom: 20px;

      }

    }

  }

  .center {

    display: flex;

    justify-content: center;

    align-items: center;

    height: 100%;

    width: 100%;

    .img {

      height: 163px;

      width: 300px;

      display: block;

    }

  }

  .cur-p {

    cursor: pointer;

  }

}

</style>

四、使用到的common方法:

 //校验输入是否仅包含数字和字母

  isValidAlphanumeric(input: string) {

    const alphanumericPattern = /^[a-zA-Z0-9]+$/

    return alphanumericPattern.test(input)

  }

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java基础概念46-数据结构1

一、引入 List集合的三种实现类使用了不同的数据结构&#xff01; 二、数据结构的定义 三、常见的数据结构 3-1、栈 特点&#xff1a;先进后出&#xff0c;后进先出。 java内存容器&#xff1a; 3-2、队列 特点&#xff1a;先进先出、后进后出。 栈VS队列-小结 3-3、数组 3-…

Docker:在 ubuntu 系统上生成和加载 Docker 镜像

本文将介绍在 ubuntu系统上进行 Docker 镜像的生成和加载方法和代码。 文章目录 一、下载和安装 docker二、加载 docker 文件三、保存你的镜像四、将镜像上传到云端并通过连接下载和加载 Docker 镜像五、Docker 容器和本地的文件交互5.1 从容器复制文件到本地宿主机5.1.1 单个文…

《数据挖掘:概念、模型、方法与算法(第三版)》

嘿&#xff0c;数据挖掘的小伙伴们&#xff01;今天我要给你们介绍一本超级实用的书——《数据挖掘&#xff1a;概念、模型、方法与算法》第三版。这本书是数据挖掘领域的经典之作&#xff0c;由该领域的知名专家编写&#xff0c;系统性地介绍了在高维数据空间中分析和提取大量…

做异端中的异端 -- Emacs裸奔之路4: 你不需要IDE

确切地说&#xff0c;你不需要在IDE里面编写或者阅读代码。 IDE用于Render资源文件比较合适&#xff0c;但处理文本&#xff0c;并不划算。 这的文本文件&#xff0c;包括源代码&#xff0c;配置文件&#xff0c;文档等非二进制文件。 先说说IDE带的便利: 函数或者变量的自动…

【C++】编程题目分析与实现回顾:从浮点数运算到整型转换的全面解读

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目一&#xff1a;计算成绩问题分析与优化实现优化后的实现优势 &#x1f4af;题目二&#xff1a;浮点数向零舍入不同实现方式的比较1. 使用强制类型转换 (int)2. 使用标准…

时间表格Java

输入&#xff1a;XXX XXX 小时 分钟 输出&#xff1a; XXX&#xff1a;XXX ~ XXX: XXX XXX&#xff1a;XXX ~ XXX: XXX XXX&#xff1a;XXX ~ XXX: XXX 处理&#xff1a;间隔五分钟、区间45分钟 14:15 ~ 15:0 15:5 ~ 15:50 15:55 ~ 16:40 16:45 ~ 17:30 17:35 ~ 18:20…

Spring AOP 的实现和切点表达式的介绍

1. 快速入手 AOP&#xff1a;就是面相切面编程&#xff0c;切面指的就是某一类特定的问题&#xff0c;也可以理解为面相特定方法编程&#xff0c;例如之前使用的拦截器&#xff0c;就是 AOP 思想的一种应用&#xff0c;统一数据返回格式和统一异常处理也是 AOP 思想的实现方式…

shell脚本30个案例(五)

前言&#xff1a; 通过一个多月的shell学习&#xff0c;总共写出30个案例&#xff0c;分批次进行发布&#xff0c;这次总共发布了5个案例&#xff0c;希望能够对大家的学习和使用有所帮助&#xff0c;更多案例会在下期进行发布。 案例二十一、系统内核优化 1.问题&#xff1…

一文解析Kettle开源ETL工具!

ETL&#xff08;Extract, Transform, Load&#xff09;工具是用于数据抽取、转换和加载的软件工具&#xff0c;用于支持数据仓库和数据集成过程。Kettle作为传统的ETL工具备受用户推崇。本文就来详细说下Kettle。 一、Kettle是什么&#xff1f; Kettle 是一款开源的 ETL&#x…

IDEA使用HotSwapHelper进行热部署

目录 前言JDK1.8特殊准备DECVM安装插件安装与配置参考文档相关下载 前言 碰到了一个项目&#xff0c;用jrebel启动项目时一直报错&#xff0c;不用jrebel时又没问题&#xff0c;找不到原因&#xff0c;又不想放弃热部署功能 因此思考能否通过其他方式进行热部署&#xff0c;找…

使用无监督机器学习算法进行预测性维护

目录 一、说明 二、主成分分析&#xff08;PCA&#xff09; 三、 K-means方法 四、K-最近邻 (KNN) 五、密度的空间聚类 (DBSCAN) 六、更先进的预测性维护算法 6.1 独立成分分析 (ICA) 6.2 PCA 和 ICA 有什么区别&#xff1f; 6.3 OPTICS 聚类 6.4 自组织映射 (SOM) 6.5 局部敏…

Elasticsearch 进阶

核心概念 索引(Index) 一个索引就是一个拥有几分相似特征的文档的集合。比如说&#xff0c;你可以有一个客户数据的索引&#xff0c;另一个产品目录的索引&#xff0c;还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母)&#xff0c;并且当我们要对这个索…

107.【C语言】数据结构之二叉树求总节点和第K层节点的个数

目录 1.求二叉树总的节点的个数 1.容易想到的方法 代码 缺陷 思考:能否在TreeSize函数内定义静态变量解决size的问题呢? 其他写法 运行结果 2.最好的方法:分而治之 代码 运行结果 2.求二叉树第K层节点的个数 错误代码 运行结果 修正 运行结果 其他写法 1.求二…

vue2 虚拟DOM 和 真实DOM (概念、作用、Diff 算法)

虚拟 DOM 和 真实DOM&#xff08;概念、作用、Diff 算法&#xff09; 1.1 概念 真实 DOM&#xff08;Document Object Model&#xff09;&#xff1a;是浏览器中用于表示文档结构的树形结构。 <h2>你好</h2>虚拟DOM&#xff1a;用 JavaScript 对象来模拟真实 DOM…

Spring AI 框架介绍

Spring AI是一个面向人工智能工程的应用框架。它的目标是将Spring生态系统的设计原则&#xff08;如可移植性和模块化设计&#xff09;应用于AI领域&#xff0c;并推广使用pojo作为AI领域应用的构建模块。 概述 Spring AI 现在(2024/12)已经支持语言&#xff0c;图像&#xf…

matlab 中的 bug

在matlab中绘图&#xff0c;设置 axe 的背景颜色 axes_in3.Color #00235B ;打印的时候 print(figure_handle1,-dpng,-r300,"merge_yt_ey") ;此时保存的图片无法识别背景颜色 原因在于 matlab 中的 InverseHardcopy 将 InvertHardcopy 设置成 off 则可以解决这个问…

【数据库系列】Liquibase 与 Flyway 的详细对比

在现代软件开发中&#xff0c;数据库版本控制是一个至关重要的环节。为了解决数据库迁移和变更管理的问题&#xff0c;开发者们通常会使用工具&#xff0c;如 Liquibase 和 Flyway。本文将对这两个流行的数据库迁移工具进行详细比较&#xff0c;从基础概念、原理、优缺点到使用…

DVWA靶场通关——DOM型XSS漏洞

一、DOM型XSS攻击概述 DOM型XSS&#xff08;DOM-based Cross-Site Scripting&#xff0c;DOM XSS&#xff09;是一种跨站脚本攻击&#xff08;XSS&#xff09;的变种&#xff0c;它与传统的反射型XSS&#xff08;Reflected XSS&#xff09;或存储型XSS&#xff08;Stored XSS&a…

flink学习(14)—— 双流join

概述 Join:内连接 CoGroup&#xff1a;内连接&#xff0c;左连接&#xff0c;右连接 Interval Join&#xff1a;点对面 Join 1、Join 将有相同 Key 并且位于同一窗口中的两条流的元素进行关联。 2、Join 可以支持处理时间&#xff08;processing time&#xff09;和事件时…

设计模式——Facade(门面)设计模式

摘要 本文介绍了外观设计模式&#xff0c;这是一种通过简单接口封装复杂系统的设计模式。它简化了客户端与子系统之间的交互&#xff0c;降低了耦合度&#xff0c;并提供了统一的调用接口。文章还探讨了该模式的优缺点&#xff0c;并提供了类图实现和使用场景。 1. 外观设计模…