基于antdv封装的特殊复杂表格,带通行描述信息、可展示通行的单元格信息、可跨页选择数据功能、分页功能、可编辑单元格功能

news2024/11/17 13:44:57

基于antdv封装的特殊复杂表格,带通行描述信息

主要功能:

  1. 可展示通行的单元格信息
  2. 可跨页选择数据功能
  3. 表单插槽、合计插槽、操作按钮区插槽
  4. 分页功能
  5. 接口内请求api
  6. 可编辑单元格
  7. 表格组件暴漏出的方法:查询、获取选中数据、接口返回数据、当前表格数据【设置可编辑单元格时获取数据】

页面示例:

本页主要是下面这种大通行效果【选择和序号都通行】
在这里插入图片描述
还有一种是通行不带选择和序号,如下:代码下载地址 : https://download.csdn.net/download/qq_32442967/87965962
在这里插入图片描述

使用示例:

页面文件page.vue

<template>
  <self-table
    ref="selfTableRef"
    :full-row-type="fullRowType"
    :api="planManageListApi"
    :columns="tableColumns(fullRowType)"
    :full-row-key-list="['noId']"
    :has-checkbox="true"
    :allTableColumnsNum="8"
    :tableProps="{}"
  >
    <template #form>
    	<!-- 自定义表单组件 可用任意表单组件 submit为表单 查询按钮事件 -->
      <BasicForm  @submit="handleSubmit" />
    </template>
    <template #tableTitle> 订单总重量:[<span class="color-red">1244.533</span> 吨] </template>
    <template #tableHead>
      <a-button type="primary">导出</a-button>
    </template>
    <template #full-row="{ row }">
      计划单号:<a-button type="link" size="small" @click="handlePlanDetail(row)">{{ row.noId }}</a-button> 计划总量:1 吨申报时间:2023-04-26
      17:09:26 审核时间:2023-04-26 17:09:46
    </template>
    <template #colSlot1="{ row }">
      <div>申报单位:{{ row.xa }}XXXXX有限责任公司</div>
      <div>申报人:欧冶材料</div>
    </template>
    <template #colSlot4="{ row }">
      <div>钢材 10 {{ row.xs }}</div>
      <div>钢材 20</div>
    </template>
    <template #action="{ row }">
      <a-button type="link" size="small" @click="handlePlanApply('edit', row)">修改</a-button>
    </template>
  </self-table>
</template>
<script setup lang="ts">
  import SelfTable from '/@/views/components/SelfTable/index.vue';
  import { ref } from 'vue';
  import { FullRowType } from '/@/views/components/SelfTable/selfTableTools';
  import { tableColumns } from '/@/views/planManage/planManage.data';
  import { planManageListApi } from '/@/views/planManage/planManage.api';
  // 定义通行类型
  const fullRowType: FullRowType = 'prev';
  const selfTableRef = ref();

  function handleSubmit(v) {
    selfTableRef.value.search(v);
  }

</script>

<style scoped lang="less"></style>

planManage.data中tableColumns() 方法

export const tableColumns = (fullRowType): SelfTableColumnType[] => [
  {
    title: '计划信息',
    dataIndex: 'key1',
    width: 300,
    customCell: (_, index) => sharedOnCell(index, fullRowType),
    slot: 'colSlot1',
  },
  {
    title: '计划状态',
    dataIndex: 'planStatus',
    width: 120,
    customCell: (_, index) => sharedOnCell(index, fullRowType),
  },
  {
    title: '区域',
    dataIndex: 'oldRecordCdName',
    width: 220,
    align: 'center',
    customCell: (_, index) => sharedOnCell(index, fullRowType),
  },
  {
    title: '详情',
    dataIndex: 'createTime',
    width: 300,
    customCell: (_, index) => sharedOnCell(index, fullRowType),
    slot: 'colSlot4',
  },
  {
    title: '审核人',
    dataIndex: 'accountMark',
    width: 100,
    align: 'center',
    customCell: (_, index) => sharedOnCell(index, fullRowType),
  },
  {
    title: '操作',
    key: 'action',
    fixed: 'right',
    align: 'center',
    width: 180,
    customCell: (_, index) => sharedOnCell(index, fullRowType),
  },
];

参数说明:

字段类型描述
apiPromise表格数据api
dataSourcearray表格数据
columnsarray表格column数据,列数据一定要指定width
has-checkboxboolean是否可选,默认false
full-row-typestring通行类型 ‘prev’ 前一行,‘last’ 后一行 ,FullRowType类型
tablePropsObject传给antd table组件的数据
allTableColumnsNumnumber所有的表格列数【包含选择列和序号列】

SelfTable.vue组件

<template>
  <a-card style="margin: 8px" v-if="$slots['form']">
    <slot name="form"></slot>
  </a-card>
  <component :is="isDiv ? 'div' : 'a-card'" style="margin: 8px">
    <!--  可放操作按钮  -->
    <div class="table-head" v-if="$slots['tableHead']">
      <slot name="tableHead"></slot>
    </div>
    <!--  可放合计数据  -->
    <div class="table-head" v-if="$slots['tableTitle']">
      <slot name="tableTitle"></slot>
    </div>
    <a-alert class="a-alert-cont" type="info" show-icon v-if="hasCheckbox">
      <template #message>
        <span>{{ checkedAlertMessage }}</span>
        <template v-if="checkedList.length">
          <a-divider type="vertical" />
          <a href="javascript:" @click="resetCheckbox">清空</a>
        </template>
      </template>
    </a-alert>
    <a-table
      :columns="columns"
      :data-source="tableData"
      :scroll="{ x: '100%' }"
      :pagination="false"
      size="small"
      @change="pageChange"
      bordered
      v-bind="$attrs.tableProps"
      class="self-table"
    >
      <!--   编辑列显示编辑ICON   -->
      <template #headerCell="{ column, title }">
        <template v-if="column.isEdit === true">
          <div class="head-edit-cont"> <i class="vxe-cell--edit-icon vxe-icon--edit-outline"></i> {{ title }} </div>
        </template>
        <!--    选择    -->
        <template v-if="column.dataIndex === 'rowSelection'">
          <a-checkbox :indeterminate="indeterminate" v-model:checked="checkAll" @change="onCheckAllChange" />
        </template>
      </template>
      <template #bodyCell="{ column, index, record, text }">
        <!--   序号  非通行时显示序号   -->
        <template v-if="index % 2 === unFullRowIndex && column.dataIndex === 'selfIndex'">
          {{ tableIndex(index) }}
        </template>
        <!--如果是通行则展示full-row插槽,如果不是通行并且传入了插槽则展示  -->
        <template v-if="column.fullFirst">
          <div class="full-row-cont" v-if="index % 2 === fullRowIndex">
            <slot name="full-row" :row="record"></slot>
          </div>
          <!--   选择列     -->
          <template v-else-if="column.dataIndex === 'rowSelection'">
            <a-checkbox
              name="tableCheckbox"
              class="my-checkbox"
              v-model:checked="record._checked"
              :key="record.id"
              :value="record.id"
              @change="onCheckBoxChange(record)"
            />
          </template>
          <template v-else-if="column.slot">
            <slot :name="column.slot" :row="record" :rowIndex="index"></slot>
          </template>
          <template v-else>{{ text }}</template>
        </template>
        <!--   如果不是通行、并且传入了插槽,则展示     -->
        <template v-else-if="index % 2 === unFullRowIndex && column.slot">
          <slot :name="column.slot" :row="record" :rowIndex="index"></slot>
        </template>
        <!--   操作     -->
        <template v-if="column.key === 'action'">
          <template v-if="index % 2 === unFullRowIndex">
            <slot name="action" :row="record"></slot>
          </template>
        </template>
      </template>
    </a-table>
    <!--   页码:传入dataSource时不显示页码     -->
    <div class="my-footer" v-if="hasPagination">
      <a-pagination
        size="small"
        :total="total"
        :current="pageNo"
        :page-size="pageSize"
        show-size-changer
        show-quick-jumper
        :show-total="(total) => `共 ${total} 条数据`"
        @change="pageChange"
      />
    </div>
  </component>
</template>
<script lang="ts" setup name="SelfTable">
  import type { TableColumnType } from 'ant-design-vue';
  import {
    checkColumnsHasExist,
    filterSelfTableColumns,
    filterSelfTableData,
    FullRowType,
    getIndeterminateAndCheckAllStatus,
    getAllCheckedListData,
    useFullRowIndex,
    SelfTableColumnType,
    columnColspanFull,
    indexColumnColspan,
  } from '/@/views/components/SelfTable/selfTableTools';
  import { computed, onMounted, reactive, ref, toRaw, watch } from 'vue';

  interface Props {
    dataSource?: any[]; // 数据,
    fullRowType: FullRowType; // 同行类型
    fullRowKeyList: any[]; // 展示在同行的数据,组件内自动转换数据
    api?: any;
    hasCheckbox?: boolean;
    hasPagination?: boolean;
    columns: TableColumnType[];
    allTableColumnsNum: number; // 表格列总数量
    isDiv?: boolean;
  }
  const props = defineProps<Props>();

  // fullRowType 通行索引  0代表偶数行为通行,即行下展示描述信息
  const { fullRowIndex, unFullRowIndex } = useFullRowIndex(props.fullRowType);

  // 表格基础数据
  let pageNo = ref(1); // 页码
  let pageSize = ref(10); // 页条数
  let total = ref(0); // 总条数
  let sourceData = ref([]); // 接口返回原始数据
  let tableSourceData = ref([]); // 接口返回原始数据中的表格数据
  let tableData = ref([]); // 表格数据
  const hasPagination = ref(true); // 是否显示页码

  const checkColumn: SelfTableColumnType = {
    title: ' ',
    dataIndex: 'rowSelection',
    key: Math.random(),
    fixed: 'left',
    align: 'center',
    width: 40,
    customCell: (_, index) => ({
      colSpan: columnColspanFull(index, fullRowIndex, props.allTableColumnsNum),
    }),
    fullFirst: props.hasCheckbox,
  };
  const indexColumn: SelfTableColumnType = {
    title: '序号',
    key: Math.random(),
    dataIndex: 'selfIndex',
    fixed: 'left',
    align: 'center',
    width: 40,
    customCell: (_, index) => ({
      colSpan: indexColumnColspan(index, fullRowIndex, unFullRowIndex, props.allTableColumnsNum, props.hasCheckbox),
    }),
    fullFirst: !props.hasCheckbox,
  };
  let columns = ref<TableColumnType[]>([]);
  columns.value = filterSelfTableColumns(toRaw(props.columns));
  !checkColumnsHasExist(props.columns, 'selfIndex') && columns.value.unshift(indexColumn);
  props.hasCheckbox && !checkColumnsHasExist(props.columns, 'rowSelection') && columns.value.unshift(checkColumn);

  /********* 选择 相关 start ***********/
  let checkAll = ref(false);
  let indeterminate = ref(false);
  let checkedList = ref([]);
  // 全选
  function onCheckAllChange(e: any) {
    const checked = e.target.checked;
    tableData.value.map((item) => {
      item._checked = checked;
    });
    checkedList.value = checked ? getAllCheckedListData(tableSourceData.value, checkedList.value) : [];
    indeterminate.value = false;
  }
  function onCheckBoxChange(record) {
    const index = checkedList.value.findIndex((item) => item.id === record.id);
    if (index > -1) {
      checkedList.value.splice(index, 1);
    } else {
      checkedList.value.push(record);
    }
  }
  const checkedAlertMessage = computed(() => {
    return checkedList.value.length === 0 ? '未选中任何数据' : `已选中 ${checkedList.value.length} 条记录(可跨页)`;
  });
  // 监听 选择改变
  watch(() => checkedList.value, reloadCheckStatus, {
    immediate: true,
    deep: true,
  });
  function reloadCheckStatus() {
    const { indeterminateStatus, checkAllStatus } = getIndeterminateAndCheckAllStatus(checkedList.value, tableSourceData.value);
    indeterminate.value = indeterminateStatus;
    checkAll.value = checkAllStatus;
  }
  // 重置选择
  function resetCheckbox() {
    onCheckAllChange({ target: { checked: false } });
  }
  // 给数据添加选项字段
  function addCheckedParam(data = []) {
    if (!props.hasCheckbox) {
      return data;
    }
    let nData = data;
    nData.map((item) => {
      const index = checkedList.value.findIndex((check) => item.id === check.id);
      item['_checked'] = index !== -1;
    });
    return nData;
  }
  /********* 选择 相关  end ***********/

  // index序号计算
  const tableIndex = computed(() => (index) => (index + unFullRowIndex) / 2 + fullRowIndex + (pageNo.value - 1) * pageSize.value);

  let searchData = reactive({});
  // 搜索 - 传入搜索数据
  function search(sd, reset = true) {
    searchData = sd;
    reload(reset);
  }

  // 重载表格
  async function reload(reset = false) {
    if (reset) pageNo.value = 1;
    const res = await props.api({
      ...searchData,
      pageNo: pageNo.value,
      pageSize: pageSize.value,
    });
    // 保存接口数据
    sourceData.value = res || [];
    tableSourceData.value = addCheckedParam(res.records);
    total.value = res.total || 0;
    tableData.value = addCheckedParam(filterData(res.records));
    reloadCheckStatus();
  }

  /**
   * 修改表格数据
   * @param {number} rowIndex 行索引
   * @param {string} changeKey 改变的字段
   * @param value  要改变的值
   */
  function setTableData(rowIndex: number, changeKey: string, value: any) {
    if (tableData.value[rowIndex] === undefined) return;
    if (tableData.value[rowIndex][changeKey] === undefined) return;
    tableData.value[rowIndex][changeKey] = value;
  }

  function filterData(records) {
    return filterSelfTableData(records, props.fullRowKeyList || [], fullRowIndex, unFullRowIndex);
  }

  onMounted(() => {
    hasPagination.value = props.hasPagination || true;
    if (props.dataSource) {
      // hasPagination.value = false;
      sourceData.value = props.dataSource;
      tableSourceData.value = addCheckedParam(props.dataSource);
      tableData.value = addCheckedParam(filterData(props.dataSource));
    } else {
      reload(true);
    }
  });

  // 页码改变事件
  function pageChange(pNo, pSize) {
    pageNo.value = pNo;
    // 页数改变时,页码设置1
    const reset = pageSize.value !== pSize;
    pageSize.value = pSize;
    reload(reset);
  }

  /**
   * 获取选中数据 - id
   * @return [string | number] 选中数据
   */
  function getChecked(): (string | number)[] {
    let checkArr: (string | number)[] = reactive([]);
    let checkDom: any[] = document.querySelectorAll('input[name="tableCheckbox"]:checked') || [];
    checkDom.forEach((check) => {
      checkArr.push(check.value);
    });
    return toRaw(checkArr);
  }
  /**
   * 获取选中数据 - row
   * @return [string | number] 选中数据
   */
  function getCheckedRows(): (string | number)[] {
    // let checkArr: [] = reactive([]);
    // let checkDom: any[] = document.querySelectorAll('input[name="tableCheckbox"]:checked') || [];
    // let getData = getTableData();
    // checkDom.forEach((check) => {
    //   let checkDataRows = getData.find((item) => item.id == check.value);
    //   checkArr.push(checkDataRows ? checkDataRows : {});
    // });
    return toRaw(checkedList.value);
  }
  // 获取当前表格的数据
  function getTableData() {
    const tData = tableData.value;
    let realData = [];
    tData.forEach((item, index) => {
      if (index % 2 === fullRowIndex) return;
      realData.push({ ...item, ...tData[index + 1] });
    });
    return realData;
  }
  /**
   * 暴露属性方法
   * @param {function} search 搜索方法
   * @param {function} getChecked 获取已选中数据方法 - id
   * @param {function} getCheckedRows  获取已选中数据方法 - row
   * @param {Array} sourceData 获取接口返回的数据
   * @param {Array} tableSourceData 获取接口返回的数据中表格的数据
   * @param {function} getTableData 获取表格数据
   * @param {function} setTableData 设置表格某行的某个单元格数据
   */
  defineExpose({
    search,
    getChecked,
    getCheckedRows,
    sourceData,
    tableSourceData,
    getTableData,
    setTableData,
  });
</script>
<style lang="less" scoped>
  .a-alert-cont {
    margin-bottom: 8px;
  }
  .ant-table-striped :deep(.table-striped) td {
    background-color: #fafafa;
  }
  :deep(.ant-table-content) {
    border-right: 1px solid #f0f0f0;
  }
  :deep(.ant-table-thead) > tr > th,
  :deep(.ant-table-tbody) > tr > td,
  :deep(.ant-table tfoot) > tr > th,
  :deep(.ant-table) tfoot > tr > td {
    padding: 4px 8px;
  }
  .my-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 8px;
  }
  .my-checkbox {
    cursor: pointer;
    width: 16px;
    height: 16px;
  }
  .table-head {
    margin-bottom: 8px;
    :deep(.ant-btn) {
      margin-right: 8px;
    }
    margin-right: 8px;
  }

  .head-edit-cont {
    display: flex;
    align-items: center;
    :deep(.vxe-cell--edit-icon) {
      border-color: #606266 !important;
      margin-right: 3px;
    }
  }
  .full-row-cont {
    text-align: left;
  }
</style>

selfTableTools.ts

SelfTable组件的依赖工具方法

/**
 * 遍历表格数据 为 SelfTable数据类型
 * @param data 表格源数据
 * @param keys 要放到通行里使用的数据
 * @param fullRowIndex 通行索引
 * @param unFullRowIndex 非通行索引
 */
export const filterSelfTableData = (data: any[], keys: any[], fullRowIndex: number, unFullRowIndex: number): any[] => {
  if (keys.length === 0) return [...data, ...data];
  const arr: any[] = [];
  data.map((d) => {
    const d2 = {};
    keys.map((k) => {
      d2[k] = d[k];
    });
    fullRowIndex && arr.push(d);
    d2['id'] = d.id;
    arr.push(d2);
    unFullRowIndex && arr.push(d);
  });
  return arr;
};

// 过滤表单列
export const filterSelfTableColumns = (columns) => {
  return columns.filter((item) => item.ifShow === undefined || item.ifShow() === true);
};

// 通行类型 'prev' 前一行 | 'last' 后一行
export type FullRowType = 'prev' | 'last';
export const useFullRowIndex = (type: FullRowType) => {
  const fullRowIndex = type === 'prev' ? 0 : 1;
  const unFullRowIndex = type === 'prev' ? 1 : 0;
  return { fullRowIndex, unFullRowIndex };
};

// 除第一列外的普通列
export const sharedOnCell = (index, type: FullRowType) => {
  // 设置为0时不渲染
  return { colSpan: index % 2 === useFullRowIndex(type).fullRowIndex ? 0 : 1 };
};

/**
 * 首位列
 * @param type 通行位置 prev | last
 * @param columnsNum 要合并的行数,也就是总列数,包括操作,不含序号和选择
 * @param index 索引
 */
export const firstSharedOnCell = (type: FullRowType, columnsNum: number, index) => ({
  colSpan: index % 2 === useFullRowIndex(type).fullRowIndex ? columnsNum : 1,
});

import { TableColumnType } from 'ant-design-vue';
// 表格column类型
export interface SelfTableColumnType extends TableColumnType {
  slot?: string;
  fullFirst?: boolean;
  isEdit?: boolean;
  ifShow?: () => boolean;
}

export function checkColumnsHasExist(arr, key): boolean {
  return arr.findIndex((item) => item.dataIndex === key) !== -1;
}

/**
 * 全选操作时,将所选数据加入到已选择列表中
 * @param currentPageData 当前页选中数据
 * @param checkedData 已选择的数据
 */
export function getAllCheckedListData(currentPageData: any[], checkedData: any[]) {
  const result: any[] = checkedData;
  currentPageData.forEach((item) => {
    const index = result.findIndex((c) => c.id === item.id);
    // 不存在 && 添加
    index === -1 && result.push(item);
  });
  return result;
}

interface CheckAllStatus {
  indeterminateStatus: boolean;
  checkAllStatus: boolean;
}
/**
 * 获取半选状态及全选状态
 * @param checkedList 已选列表
 * @param currentPageData 当前页数据
 */
export function getIndeterminateAndCheckAllStatus(checkedList, currentPageData): CheckAllStatus {
  // 已选数据为空 或者 当前页数据为空
  if (!checkedList.length || !currentPageData.length) {
    return {
      indeterminateStatus: false,
      checkAllStatus: false,
    };
  }
  // 筛选当前页面数据未再已选列表的数据
  const notCheckedData = currentPageData.filter((item) => {
    const index = checkedList.findIndex((c) => c.id === item.id);
    return index === -1;
  });
  return {
    indeterminateStatus: notCheckedData.length > 0 && notCheckedData.length < currentPageData.length,
    checkAllStatus: notCheckedData.length === 0,
  };
}

export const columnColspanFull = (index, fullRowIndex, allColumnNum) => (index % 2 === fullRowIndex ? allColumnNum : 1);

export const columnColspanUnFull = (index, unFullRowIndex) => (index % 2 === unFullRowIndex ? 1 : 0);

export const indexColumnColspan = (index, fullRowIndex, unFullRowIndex, allColumnNum, hasCheckbox) => {
  return hasCheckbox ? columnColspanUnFull(index, unFullRowIndex) : columnColspanFull(index, fullRowIndex, allColumnNum);
};

可编辑单元格使用:

页面示例:

在这里插入图片描述

使用示例:

主要依赖的就是组件中的setTableData方法,根据行index,和key去修改表格里面的数据

<SelfTable
      ref="selfTableRef"
      :has-checkbox="true"
      :data-source="dataSource"
      :full-row-type="fullRowType"
      :columns="selfTableColumns(fullRowType)"
      :full-row-key-list="['desc']"
      :is-div="true"
      :all-table-columns-num="16"
    >
      <template #fileNumberSlot="scope">
        <div class="slot-cont">
          <a-input @change="(e) => selfTableRef.setTableData(scope.rowIndex, 'fileNumber', e.target.value)" />
        </div>
      </template>
      <template #inputSlot="scope">
        <div class="slot-cont">
          <a-input @change="(e) => selfTableRef.setTableData(scope.rowIndex, 'inputValue', e.target.value)" />
        </div>
      </template>
      <template #contractNoSlot="scope">
        <div class="slot-cont">
          <a-select style="width: 100%" @change="(value) => selfTableRef.setTableData(scope.rowIndex, 'contractNo', value)">
            <a-select-option value="jack">Jack</a-select-option>
            <a-select-option value="lucy">Lucy</a-select-option>
          </a-select>
        </div>
      </template>
      <template #full-row="{ row }"> 其他等级: 资源号: 捆绑号:{{ row.id }}</template>
    </SelfTable>

tableColumns方法需要增加isEdit字段,会显示编辑icon

    {
      title: '件数(件)',
      dataIndex: 'fileNumber',
      width: 100,
      customCell: (_, index) => sharedOnCell(index, fullRowType),
      slot: 'fileNumberSlot',
      isEdit: true,
    },
    {
      title: '重量(吨)',
      dataIndex: 'inputValue',
      width: 100,
      customCell: (_, index) => sharedOnCell(index, fullRowType),
      slot: 'inputSlot',
      isEdit: true,
    },

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

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

相关文章

消防应急照明和疏散指示系统手动控制的设计与应用

摘要&#xff1a;针对非集中控制型消防应急照明和疏散指示系统在火灾确认后如何手动控制系统的应急启动存在的实际问题&#xff1a;在哪里手动控制&#xff1f;由谁来手动控制&#xff1f;什么时候能够手动控制&#xff1f;提出 3 种手动控制应急启动系统的方案&#xff1a;① …

Fluttter的ClipRRect控件

ClipRRect简介 ClipRRect&#xff08;Rounded Rectangle Clip&#xff09;是Flutter中的一个控件&#xff0c;用于将其子控件剪裁为圆角矩形形状。 使用场景 ClipRRect通常在需要给子控件添加圆角效果时使用。它可以用于创建圆角图片、圆角容器等各种UI元素。 主要属性 bo…

uniapp 开发小程序之实现不同身份展示不同的 tabbar(底部导航栏),附带相关问题解答

效果展示&#xff1a; 引言 在开发过程中逐渐意识到uniapp原生的tabbar可能不能满足开发要求&#xff0c;通过浏览博客才选择使用uView的Tabbar 底部导航栏来实现&#xff0c;我选择用的是2X版本 安装 我是使用Hbuilder插件的方式引入的组件库&#xff0c;安装配置可以看这篇…

CVE-2023-34541 LangChain 任意命令执行

漏洞简介 LangChain是一个用于开发由语言模型驱动的应用程序的框架。 在LangChain受影响版本中&#xff0c;由于load_prompt函数加载提示文件时未对加载内容进行安全过滤&#xff0c;攻击者可通过构造包含恶意命令的提示文件&#xff0c;诱导用户加载该文件&#xff0c;即可造成…

单片机学习 14-DS18B20温度传感器实验

DS18B20 温度传感器实验 ​ 本次实验我们来学习精度较高的外部 DS18B20 数字温度传感器&#xff0c;由于此传感器是单总线接口&#xff0c;所以需要使用 51 单片机的一个 IO 口模拟单总线时序与 DS18B20 通信&#xff0c;将检测的环境温度读取出来。开发板上集成了 1 个 DS18B…

createdTime(new Date()) 数据库时间比实际多八小时

本来是createdTime&#xff08;new Date&#xff08;&#xff09;&#xff09;&#xff0c;一次生成两条数据 一直正常&#xff0c;今天却多八小时 一开始往new Date&#xff08;&#xff09;差八个小时的问题上找&#xff0c; 网上说要 在apprication.yml文件中配置一下数据…

大佬详细讲解:银行核心项目之测试阶段

最近有小伙伴留言说「想了解核心系统建设中&#xff0c;冒烟、SIT、UAT、回归测试的重点&#xff0c;如何设计测试案例&#xff0c;或相关的资料推荐等」。 这个话题很笼统&#xff0c;测试这一块儿除了业务测试&#xff0c;还有性能测试、安全测试等&#xff1b;以及不同的角…

解决pyecharts图表在jupyter notebook无法显示的问题

在jupyter notebook尝试制作pyecharts图表&#xff0c;遇到无法显示的问题&#xff0c;网上查到的结果有各种不同原因&#xff0c;此处一一罗列&#xff0c;便于大家排查并彻底解决问题。 情况1&#xff1a;图表完全无法显示 解决方案&#xff1a;参考此文档 注&#xff1a;…

web自动化测试——xpath和css语法详解(五)

目录 1.css选择器 1.1什么是css选择器&#xff1f; 1.2css选择器语法 2.xpath 1.什么是xpath&#xff1f; 2.什么是XML? 3.XML与HTML 4.节点的概念 5.XPath &#x1f381;更多干货 完整版文档下载方式&#xff1a; 1.css选择器 1.1什么是css选择器&#xff1…

SmaAt-UNet github

来源 SmaAt-UNet github SmaAt-UNet&#xff1a; 使用小型关注网结构的降水预报 论文链接 安装依赖 这个项目使用poetry作为依赖性管理。因此&#xff0c;安装所需的依赖项就像这样简单&#xff1a; conda create --name smaat-unet python3.9 conda activate smaat-unet p…

基于Java学生宿舍管理设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

正负压自动控制技术在离体肺通气系统中的应用

摘要&#xff1a;模拟肺呼吸过程的离体肺通气控制新方法——真空压力&#xff08;正负压&#xff09;法&#xff0c;目前还停留在理论层面的文献报道&#xff0c;还未见到这种方法的仪器化内容和细节。本文基于这种新方法提出了仪器化实现的具体解决方案&#xff0c;解决方案的…

闲置iPad Pro打造真正的生产力工具!使用vscode编程写代码

文章目录 前言视频教程1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7…

Windows电脑玩游戏出现白屏的解决方法

逢年过节玩游戏&#xff0c;周末放假玩游戏&#xff0c;休闲娱乐玩游戏…玩游戏成了不少电脑用户的小乐趣。但是有时候在玩游戏的过程中&#xff0c;会遇到一些令人头疼的问题&#xff0c;比如游戏突然白屏&#xff0c;无法正常进行。这种情况可能会影响游戏体验&#xff0c;甚…

Recurdyn导入x_t格式装配体

装配层次结构&#xff1a;选上表示导入的装配体包括子装配体&#xff0c;再勾选body或者subsystem表示子装配体以零件或者子系统显示在recurdyn中&#xff1b;不选&#xff0c;表示导入的装配体全部以零件显示。

如何修改 Linux 的时区

文章结构 一、查看 Linux 当前时区二、获取时区 TZ 值&#xff08;可选做&#xff09;三、配置 TZ 值四、加载配置并检验是否生效 TZ 是 time zone 的缩写&#xff01; 一、查看 Linux 当前时区 你可以使用如下命令非常容易地就查看到 Linux 系统的当前时区&#xff1a; # 查…

AE插件:能量激光描边光效特效Saber Mac

Saber Mac插件主要用于AE软件中创造制作&#xff1a;能量光束&#xff0c;光剑&#xff0c;激光&#xff0c;传送门&#xff0c;霓虹灯&#xff0c;闪电&#xff0c;电流&#xff0c;朦胧等特效&#xff0c;插件操作直观简单&#xff0c;含有25种不同类型的特效预设&#xff08…

【sql注入-WAF绕过】编写sqlmap的tamper进行sql注入

目录 编写sqlmap的绕过脚本 二、理论知识2 sqlmap的tamper脚本 三、实战部分 一、理论知识1 编写sqlmap的绕过脚本 编写sqlmap的一个简单WAF绕过脚本 #!/usr/bin/env python""" Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/) See th…

网络安全合规-银行业数据治理架构体系搭建(二)

本次《指引》使用了许多新兴词汇&#xff0c;这些词汇均是首次被监管部门正式引用&#xff0c;并出现在银行业金融机构的监督管理文件中。我们将通过这些词汇更好地理解《指引》。 首席数据官&#xff1a;“首席数据官”首次作为需要监管机构任职资格许可的管理岗位被提出。通过…

Cortex-M内核知识点总结

总览 Cortex内核 基础 寄存器组 程序在经过编译后&#xff0c;生成可执行二进制文件&#xff0c;如上图&#xff0c;是截取某个函数在flash中存储的内容 (反汇编文件)可以看到以下信息&#xff1a; 指令的存储地址 &#xff0c;指令的二进制内容 &#xff0c; 指令代表的汇编类…