常用

发布于2024-10-27
字数: 27582
常用

MySQL

MySQL获取某个库下的所有表名,并且用,隔开

sql 复制代码
SELECT GROUP_CONCAT(table_name) AS all_tables
FROM information_schema.tables
# 将 your_database 替换为实际的数据库名称
WHERE table_schema = 'your_database'; 


SELECT GROUP_CONCAT(CONCAT('"', table_name, '"')) AS all_tables
FROM information_schema.tables
# 将 your_database 替换为实际的数据库名称
WHERE table_schema = 'your_database';

MySQL导入超大SQL文件时出现“MySQL Server has gone away”错误

sql 复制代码
SHOW GLOBAL VARIABLES LIKE 'max_allowed_packet';
# 设置可容纳 180 M的数据
set global max_allowed_packet = 1024 * 1024 * 180;

mysql 获取一个时间段中所有日期或者月份

sql 复制代码
-- mysql8
SELECT DATE_FORMAT(DATE_ADD('2020-01-20 00:00:00', INTERVAL row1 MONTH),'%Y-%m') DATE FROM
 ( 
    SELECT @row := @row + 1 AS row1 FROM 
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2, 
    (SELECT @row:=-1) r
 ) se
 WHERE DATE_FORMAT(DATE_ADD('2020-01-20 00:00:00', INTERVAL row1 MONTH),'%Y-%m') <= DATE_FORMAT('2020-12-31 00:00:00','%Y-%m')
 
 
 
 SELECT DATE_FORMAT(m1, '%Y-%m-%d') full_month,
DATE_FORMAT(m1, '%d日') format_date
FROM(
    SELECT 
        (CONCAT('2021-04','-01') -  INTERVAL DAYOFMONTH(CONCAT("2021-04","-01"))-1 DAY) 
        +INTERVAL m DAY AS m1
    FROM(
        SELECT @rownum:=@rownum+1 AS m FROM
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t1,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t2,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t3,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t4,
        (SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) t5,
        (SELECT @rownum:=-1) t0
    ) d1
) d2 
WHERE m1< DATE_FORMAT(DATE_ADD(CONCAT('2021-04','-01'), INTERVAL 1 MONTH),'%Y-%m-%d')
ORDER BY m1
sql 复制代码
-- MySQL5.7
SELECT DATE_FORMAT(DATE_ADD('2023-01-01', INTERVAL ROW MONTH),'%Y-%m') date_time FROM
 ( 
    SELECT @row := @row + 1 AS ROW FROM 
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2, 
    (SELECT @row:=-1) r
 ) se
 WHERE DATE_FORMAT(DATE_ADD('2023-01-01', INTERVAL ROW MONTH),'%Y-%m') <= DATE_FORMAT('2023-12-01','%Y-%m')

mysql8按年份统计数据,没有的补零

sql 复制代码
SELECT  A.date_time, COALESCE(B.num, 0) AS num  FROM 
(
SELECT DATE_FORMAT(DATE_ADD('2023-01-20 00:00:00', INTERVAL row1 MONTH),'%Y-%m') date_time FROM
 ( 
    SELECT @row := @row + 1 AS row1 FROM 
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2, 
    (SELECT @row:=-1) r
 ) se
 WHERE DATE_FORMAT(DATE_ADD('2023-01-20 00:00:00', INTERVAL row1 MONTH),'%Y-%m') <= DATE_FORMAT('2023-12-31 00:00:00','%Y-%m')
) A
LEFT JOIN 
(
SELECT DATE_FORMAT(create_time, '%Y-%m') date_time, COUNT(*) num
FROM home_subject -- 替换成要统计的表格
GROUP BY DATE_FORMAT(create_time, '%Y-%m') -- create_time替换成自己的字段
) B
ON A.date_time= B.date_time

mysql5.7按日统计数据,没有的补零

sql 复制代码
SELECT t.date, COALESCE(o.num, 0) FROM 
(
 SELECT DATE_ADD('2023-01-01', INTERVAL ROW DAY) DATE FROM
 ( 
    SELECT @row := @row + 1 AS ROW FROM 
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t,
    (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) t2,
      (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 ) t3,
    (SELECT @row:=-1) r
 ) se
 WHERE DATE_ADD('2023-01-01', INTERVAL ROW DAY) <= '2023-12-31'
 )t
 LEFT JOIN 
 
 (SELECT COUNT(finished_date) num, finished_date FROM `patrol_point_record` GROUP BY finished_date)
 o
 ON t.date = o.finished_date

加载本地文件到数据库表中

sql 复制代码
load data local infile 'D:/Users/91193/Desktop/monishuju/tb_sku5.sql' into table `tb_sku` fields terminated by ',' lines terminated by '\n';

Shell脚本

备份MySQL Docker数据

./all_param_backup_mysql_docker.sh ${容器名字} ${数据库用户名} ${数据库密码} ${备份文件存放目录} ${数据库名字...}

shell 复制代码
#!/bin/bash
if [ "$#" -lt 4 ]; then
  echo "参数错误"
  exit 1
fi

# 定义备份目录和文件名前缀
backup_dir="$4"
backup_prefix="mysql_backup_$(date +'%Y%m%d')"
# 删除超过10天的数据
rm_file_prefix="mysql_backup_$(date -d -10day +'%Y%m%d')"

# MySQL容器名
mysql_container="$1"

# MySQL连接参数
mysql_user="$2"
mysql_password="$3"

# 要备份的数据库列表
databases=()
for ((i = 5; i <= $#; i++)); do
    param="$i"
    value="${!param}"
    databases+=("${value}")
done

# 判断目录是不是已经存在,如果不存在则创建
if [ ! -d ${backup_dir} ];then
  mkdir -p ${backup_dir}
fi

# 循环遍历备份每个数据库
for db in "${databases[@]}"
do
    backup_file="${backup_prefix}_$db.sql"
    # 使用docker exec执行mysqldump命令备份数据库到指定目录
    docker exec "$mysql_container" /usr/bin/mysqldump -u"$mysql_user" -p"$mysql_password" "$db" > "$backup_dir/$backup_file"
    # 检查备份是否成功
    if [ $? -eq 0 ]; then
        echo "数据库 $db 备份成功,文件保存在: $backup_dir/$backup_file"
    else
        echo "数据库 $db 备份失败"
    fi  
done

for host_db in "${databases[@]}"
do
    #删除超过1天的数据
    rm -f ${backup_dir}/${rm_file_prefix}_${host_db}.sql
done

构建MySQL容器

shell 复制代码
#!/bin/sh
#构建容器
docker run \
-p 3306:3306 \
--name mysql8 \
--privileged=true \
--restart unless-stopped \
-v /docker/mysql8.0.20/mysql:/etc/mysql \
-v /docker/mysql8.0.20/logs:/logs \
-v /docker/mysql8.0.20/data:/var/lib/mysql \
-v /docker/mysql8.0.20/conf/my.cnf:/etc/my.cnf \
-v /etc/localtime:/etc/localtime \
-e MYSQL_ROOT_PASSWORD=${your_password} \
-d mysql:8.0.20

#进入容器
docker exec -it mysql8 /bin/bash

构建Redis

shell 复制代码
#!/bin/sh
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v/mydata/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis redis-server /etc/redis/redis.conf
--requirepass password

构建ElasticSearch

shell 复制代码
#!/bin/sh
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms256m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

构建Kibana

shell 复制代码
#!/bin/sh
docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms256m -Xmx512m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

其他

Windows批量删除文件名中包含的共同字符串

shell 复制代码
@echo off
setlocal enabledelayedexpansion

set "folderPath=E:\lsl\download\user\main\java\com\lsl\user\entity\"

cd "%folderPath%"

for %%F in (*Entity*) do (
    set "oldName=%%~nF"
    set "extension=%%~xF"

    rem 去掉文件名中的 "Entity" 字符串
    set "newName=!oldName:Entity=!"

    ren "%%F" "!newName!!extension!"
)

echo 文件名修改完成!
pause

计算B站剩余分P时长

javascript 复制代码
function calculateTotalDuration (startIndex, endIndex) {
    startIndex = startIndex - 1;
    // 获取父容器(class="video-pod__list multip list")
    const parent = document.querySelector('.video-pod__list.multip.list');
    if (!parent) {
      console.error('未找到父容器');
      return null;
    }

    // 获取所有直接子元素
    const items = parent.querySelectorAll('.simple-base-item.video-pod__item.normal');
    if (items.length === 0) {
      console.error('未找到子元素');
      return null;
    }

    // 遍历计算总时长
    let totalSeconds = 0;
    for (let i = 0; i < items.length; i++) {
      if (i < startIndex || i > endIndex) continue;

      const timeEl = items[i].querySelector('.stat-item.duration');
      const timeText = timeEl ? timeEl.textContent.trim() : '';
      if (!timeText) continue;

      const [minutes, seconds] = timeText.split(':').map(Number);
      if (isNaN(minutes) || isNaN(seconds)) {
        console.warn(`元素${i}的时间格式错误:${timeText}`);
        continue;
      }

      totalSeconds += minutes * 60 + seconds;
    }

    // 格式化结果
    const hours = Math.floor(totalSeconds / 3600);
    const remainingSeconds = totalSeconds % 3600;
    const minutes = Math.floor(remainingSeconds / 60);
    const seconds = remainingSeconds % 60;

    const totalTime = `${hours > 0 ? hours + ':' : ''}${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;

    return {
      totalTime,
      totalSeconds
    };
  }
  const result = calculateTotalDuration(start, end);
  if (result) {
    console.log(`范围内总时长:${result.totalTime}(共${result.totalSeconds}秒)`);
  }

UI组件

vue2实现可搜索可单选多选分页下拉组件

演示
体验自定义下拉组件地址
组件使用

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用多选搜索分页下拉组件</title>
    <script type="text/javascript" charset="utf-8" src="../lib/vue/2.7.16/vue.min.js"></script>
    <script type="text/javascript" charset="utf-8" src="./js/vueComponent.js"></script>
    <script type="text/javascript" charset="utf-8" src="../lib/axios/1.7.9/axios.min.js"></script>
    <link rel="stylesheet" href="../css/customer-select.css">
</head>

<body>
    <div id="app">
        <div>
            <img src="../media/customer_select_demo.gif">
        </div>
        <div>
            <div>分页搜索多选下拉框(不支持全选)</div>
            <span>已选择:</span>
            <div v-for="item in selectItems">{{ item.value + ' ' + item.label }}</div>
        </div>
        <customer-select :options="options" :selects="selectItems" :remote="true" :open-page="showPage" :total="total"
            :page-num="pageNum" :page-size="pageSize" @input-change="handleInputChange" @page-change="handlerPageChange"
            ref="customerSelect">
        </customer-select>

        <div>
            <div>不分页搜索多选下拉框(支持全选)</div>
            <span>已选择:</span>
            <div v-for="item in allSelectItems">{{ item.value + ' ' + item.label }}</div>
        </div>
        <!-- 不分页 -->
        <customer-select :options="allOptions" :selects="allSelectItems" @input-change="handleNoPageInputChange"
            @update-selects="handlerUpdateSelected">
        </customer-select>

        <div>
            <div>不分页搜索单选选下拉框</div>
            <span>当前选中的元素</span>
            <div>{{ singleSelect.value + ' ' + singleSelect.label }}</div>
        </div>
        <!-- 不分页 -->
        <customer-select :options="sigleAllOptions" :selects="singleSelect" :remote="true"
            @input-change="handleSingleNoPageInputChange" @update-selects="handlerSingleUpdateSelected"
            :multiple="false">
        </customer-select>

    </div>

    <script>
        let vueApp = new Vue({
            el: '#app',
            data() {
                return {
                    options: [
                    ],
                    // 已选中元素
                    selectItems: [],
                    showPage: true,
                    pageNum: 1,
                    pageSize: 10,
                    total: 0,
                    hasPrev: false,
                    hasNext: false,
                    allOptions: [
                    ],
                    // 已选中元素
                    allSelectItems: [],
                    singleSelect: {
                        value: '',
                        label: ''
                    },
                    sigleAllOptions: []
                }
            },
            methods: {
                handleInputChange(param) {
                    if (!param || param === '') {
                        this.options = []
                        return
                    }
                    this.pageNum = 1
                    this.getDataPage(param)
                },
                handleNoPageInputChange(param) {
                    if (!param || param === '') {
                        this.allOptions = []
                        return
                    }
                    this.getAllData(param)
                },
                getAllData(inputParam) {
                    axios.get(`http://localhost:12345/sse/test/search?name=${inputParam}`).then((res) => {
                        this.allOptions = res.data
                    })
                },
                handlerUpdateSelected(newSelects) {
                    console.log('handlerUpdateSelected')
                    this.allSelectItems = [];
                    this.allSelectItems.push(...newSelects)
                },
                handlerPageChange(page) {
                    this.pageNum = page.current
                    this.getDataPage(page.inputParam)
                },
                getDataPage(inputParam) {
                    axios.get(`http://localhost:12345/sse/test/searchPage?name=${inputParam}&current=${this.pageNum}&size=${this.pageSize}`).then((res) => {
                        this.options = res.data.data
                        this.total = res.data.total
                    })
                },
                handleSingleNoPageInputChange(param) {
                    if (!param || param === '') {
                        this.sigleAllOptions = []
                        return
                    }
                    axios.get(`http://localhost:12345/sse/test/search?name=${param}`).then((res) => {
                        this.sigleAllOptions = res.data
                    })
                },
                handlerSingleUpdateSelected(newSelects) {
                    this.singleSelect = newSelects;
                }
            },
        })
    </script>
</body>

</html>

组件代码

javascript 复制代码
Vue.component('customer-select', {
    props: {
        options: {
            type: Array,
            required: true
        },
        selects: {
            type: [Array, Object],
            required: true
        },
        remote: {
            type: Boolean,
            default: true
        },
        openPage: {
            type: Boolean,
            default: false
        },
        pageNum: {
            type: Number,
            required: false
        },
        pageSize: {
            type: Number,
            required: false
        },
        total: {
            type: Number,
            required: false
        },
        multiple: {
            type: Boolean,
            default: true
        }
    },
    template: `
        <div class="select-box" ref="customSelect">
            <div class="search">
                <div class="input-box">
                    <div v-if="multiple" class="selected-list">
                        <div v-for="(selectedItem, index) in selects" :key="index" class="selected-item">
                            <div class="selected">{{ selectedItem.label }}
                                <span class="delete" @click="removeItem(selectedItem)" data-ignore-click-outside="true">✖</span>
                            </div>
                        </div>
                    </div>
                    <div v-else>
                        <span class="single-item">{{ selects.label }}</span>
                    </div>
                    <input v-model="inputParam" type="text" class="inputSearch" @input="handlerInputChange" @compositionstart="handleCompositionStart"
                    @compositionend="handleCompositionEnd">
                </div>
                <div class="search-result" v-show="options.length > 0">
                    <div class="search-list" :style="openPage ? '' : 'height: 100%'">
                        <div class="search-item" v-show="!openPage && multiple">
                            <input type="checkbox" class="checkbox" :checked="allChecked" @click="handlerAllChecked">
                            <div class="item-label">
                                全选
                            </div>
                        </div>
                        <div v-for="optionItem in options" class="search-item">
                            <input :checked="isEqual(optionItem)" type="checkbox" @click="toggleSelection(optionItem)" class="checkbox">
                            <div class="item-label" :style="isEqual(optionItem) ? 'color: #409eff;' : '' ">
                                {{ optionItem.label }}
                            </div>
                        </div>
                    </div>
                    <div class="page" v-show="options.length > 0 && openPage">
                        <button @click="getPrev" :disabled="!hasPrev">上一页</button>
                        <button @click="getNext" :disabled="!hasNext">下一页</button>
                    </div>
                </div>
            </div>
        </div>
    `,
    data() {
        return {
            // 搜索字符串
            inputParam: '',
            // 全选状态
            allChecked: false,
            debounceTimer: null,
            isComposing: false, // 是否处于中文输入法拼音阶段
            hasNext: false,
            hasPrev: false
        }
    },
    methods: {
        getPrev() {
            if (this.pageNum <= 1) {
                console.log('已经是第一页了')
                this.hasPrev = false
                return
            }
            const param = {
                current: this.pageNum - 1,
                inputParam: this.inputParam
            }
            this.hasPrev = param.current > 1
            this.hasNext = param.current < this.pageNum
            this.$emit('page-change', param)
        },
        getNext() {
            let totalPages = Math.ceil(this.total / this.pageSize)
            if (this.pageNum >= totalPages) {
                console.log('已经是最后一页了')
                this.hasNext = false
                return
            }
            const param = {
                current: this.pageNum + 1,
                inputParam: this.inputParam
            }
            this.hasNext = param.current < totalPages
            this.hasPrev = param.current > 1
            this.$emit('page-change', param)
        },
        toggleSelection(target) {
            if (this.multiple) {
                const index = this.selects.findIndex(item => item.value == target.value)
                if (index !== -1) {
                    this.selects.splice(index, 1)
                    this.allChecked = false
                } else {
                    this.selects.push(target)
                    this.allChecked = this.options.every(optItem => this.selects.some(selItem => selItem.value == optItem.value))
                }
            } else {
                if (target.value == this.selects.value) {
                    this.selects = {
                        value: '',
                        label: ''
                    };
                } else {
                    this.selects = target
                }
            }
            this.$emit('update-selects', this.selects);
        },
        removeItem(target) {
            const index = this.selects.findIndex(item => item.value == target.value)
            if (index !== -1) {
                this.selects.splice(index, 1)
                this.allChecked = false
            }
            this.$emit('update-selects', this.selects);
        },
        handlerAllChecked() {
            this.allChecked = !this.allChecked;
            if (this.allChecked) {
                // 构造哈希表
                const valueSet = new Set(this.selects.map(item => item.value));

                // 获取this.selects和this.options的并集
                const union = [
                    ...this.selects,
                    ...this.options.filter(itemB => !valueSet.has(itemB.value))
                ];
                this.selects = union;
            } else {
                this.selects = this.selects.filter(itemA =>
                    !this.options.some(itemB => itemB.value === itemA.value)
                );
            }
            this.$emit('update-selects', this.selects);
        },
        handlerInputChange(event) {
            // 处于拼音输入阶段 不执行防抖
            if (this.isComposing) return;
            clearTimeout(this.debounceTimer);
            this.debounceTimer = setTimeout(() => {
                this.$emit('input-change', this.inputParam);
            }, 400);
        },
        // 监听点击外部关闭下拉选项
        handleClickOutside(event) {
            if (event.target.dataset.ignoreClickOutside && this.multiple) {
                return;
            }
            if (this.$refs.customSelect && !this.$refs.customSelect.contains(event.target)) {
                this.inputParam = ''
                this.$emit('input-change', this.inputParam);
            }
        },
        // 判断是否选中 用于渲染复选框
        isEqual(currItem) {
            if (this.multiple) {
                return this.selects.some(item => item.value == currItem.value)
            } else {
                return this.selects.value == currItem.value
            }
        },
        // 监听拼音输入开始
        handleCompositionStart() {
            this.isComposing = true;
        },
        handleCompositionEnd(event) {
            this.isComposing = false;
            // 拼音输入完成后,触发一次 input 事件逻辑
            this.handlerInputChange(event);
        },
    },
    watch: {
        total(newValue) {
            let totalPages = Math.ceil(newValue / this.pageSize)
            if (this.pageNum >= totalPages) {
                console.log('已经是最后一页了')
                this.hasNext = false
            } else {
                this.hasNext = true
            }
            if (this.pageNum <= 1) {
                console.log('已经是第一页了')
                this.hasPrev = false
            } else {
                this.hasPrev = true
            }
        },
        options(newValue) {
            if (this.multiple && !this.openPage) {
                this.allChecked = this.options.every(optItem => this.selects.some(selItem => selItem.value == optItem.value))
            }
        }
    },
    mounted() {
        window.addEventListener("click", this.handleClickOutside); // 添加全局点击事件监听
    },
    beforeDestroy() {
        if (this.debounceTimer != null) {
            clearTimeout(this.debounceTimer);
        }
        window.removeEventListener("click", this.handleClickOutside); // 移除全局点击事件监听
    },
})

组件CSS代码

css 复制代码
.select-box {
    margin-top: 16px;
    width: 320px;
}

.select-box .search .input-box>input {
    border: none;
    outline: none;
}

.select-box .search {
    position: relative;
    width: 300px;
    margin-left: 24px;
}

.select-box .search .input-box {
    display: flex;
    flex-wrap: wrap;
    width: 100%;
    justify-content: flex-start;
    align-items: center;
    box-sizing: border-box;
    margin-bottom: 4px;
    padding-left: 4px;
    padding-bottom: 4px;
    border: 1px solid #DCDFE6;
    border-radius: 4px;
    background-color: #FFFFFF;
}

.select-box .search .input-box .single-item {
    margin-right: 4px;
    margin-top: 4px;
    color: #909399;
}

.select-box .search .input-box .selected-list {
    display: flex;
    flex-wrap: wrap;
}

.select-box .search .input-box .selected-list .selected-item {
    margin-right: 4px;
    margin-top: 4px;
    color: #909399;
    background-color: #F0F2F5;
    border-radius: 4px;
}

.select-box .search .input-box .selected-list .selected-item .selected {
    height: 20px;
    text-align: center;
    line-height: 20px;
    padding-left: 4px;
    padding-right: 4px;
    font-size: 14px;
    box-sizing: border-box;
}

.select-box .search .input-box .selected-list .selected-item .selected .delete {
    display: inline-block;
    width: 1em;
    height: 1em;
    line-height: 1em;
    margin-left: 4px;
    padding: 1px;
    color: #909399;
    font-size: calc(1em - 2px);
    cursor: pointer;
    border-radius: 50%;
}

.select-box .search .input-box .selected-item .selected .delete:hover {
    background-color: #909399;
    color: #F1F1F2;
    transition: all .3s ease;
}

.select-box .search .input-box .inputSearch {
    height: 20px;
    flex: 1;
    min-width: 60px;
    outline: none;
    margin-left: 4px;
    margin-top: 4px;
    color: #606266;
}

.select-box .search .search-result {
    display: flex;
    flex-direction: column;
    position: relative;
    max-height: 200px;
    border: 1px solid #e4e7ed;
    border-radius: 4px;
    overflow: hidden;
    background-color: transparent;
    box-shadow: 0px 0px 12px rgba(0, 0, 0, .12);
}

.select-box .search .search-result .search-list {
    background-color: #FFFFFF;
    height: fit-content;
    overflow-y: auto;
}

.select-box .search .search-result  .search-list .search-item {
    display: flex;
    justify-content: flex-start;
    align-items: center;
    height: 28px;
    line-height: 28px;
    padding-left: 4px;
    padding-right: 12px;
    box-sizing: border-box;
    color: #909399;
    cursor: pointer;
}

.select-box .search .search-result .search-list .search-item .checkbox {
    position: relative;
    width: 14px;
    height: 14px;
    appearance: none;
    border: 1px solid #dcdfe6;
    background-color: #fff;
    display: inline-block;
    border-radius: 0;
}

.select-box .search .search-result .search-list .search-item .checkbox:checked::before {
    content: "";
    position: absolute;
    top: -1px;
    left: 3px;
    width: 4px;
    height: 8px;
    border: solid #409eff;
    border-width: 0 2px 2px 0;
    transform: rotate(45deg);
}

.select-box .search .search-result .search-list .search-item .item-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.select-box .search .search-result .page {
    flex: 1;
    display: flex;
    align-items: center;
    line-height: 1.3;
    padding: 4px 0 4px 6px;
    color: #909399;
    border-top: 0.5px solid #e4e7ed;
}

.select-box .search .search-result .page button {
    background-color: transparent;
    outline: none;
    border: none;
    color: #303133;
    cursor: pointer;
}

.select-box .search .search-result .page>button:first-child {
    margin-right: 4px;
}

.select-box .search .search-result .page>button:hover {
    transition: all .3s ease;
    color: #409EFF;
}

.select-box .search .search-result .page button:disabled {
    color: #aaa;
    cursor: not-allowed;
}

CSS

媒体查询设备宽度

css 复制代码
/* 移动端样式 */
@media screen (max-width: 767px) {

}

/* 平板样式 */
@media screen (min-width: 768px) and (max-width: 991px) {
  
}

/* PC样式 */
@media screen (min-width: 992px) {
  
}