Vben Admin 自学记录 —— 使用 mock 模拟数据以及模拟api联调接口(持续更新中...)

news2025/2/25 17:01:40

Vben Admin —— 使用 mock 模拟数据以及模拟api联调接口

数据 mock&联调相关概念及使用

练习 —— 在之前table基础上,使用mock模拟数据,替换原来的死数据,添加新增、查看、修改和删除api并添加逻辑,实现一个简单的、完整的增删改查页面

/mock文件夹下添加table文件夹,其中添加tableMock.ts

在这里插入图片描述

/mock/table/tableMock.ts

import { time } from 'console';
import { MockMethod } from 'vite-plugin-mock';
import { resultSuccess, resultError, requestParams, getRequestToken } from '../_util';

const tableListData = {
  pager: {
    list: [
      {
        contno: '610964224475996443',
        name: '张三',
        sex: '0',
        dt: '20200701',
        age: '22',
        tel: '13789890909',
        address: '北京市北京小区',
      },
      {
        contno: '610964224475996442',
        name: '李四',
        sex: '1',
        dt: '20230507',
        age: '27',
        tel: '15477778888',
        address: '大连市大连小区',
      },
      {
        contno: '610964224475996445',
        name: '王五',
        sex: '0',
        dt: '20221001',
        age: '26',
        tel: '15477778888',
        address: '大连市大连小区',
      },
      {
        contno: '610964224475996446',
        name: '小明',
        sex: '0',
        dt: '20220701',
        age: '25',
        tel: '15477778888',
        address: '大连市大连小区',
      },
      {
        contno: '610964224475996447',
        name: '小红',
        sex: '1',
        dt: '20180808',
        age: '28',
        tel: '15477778888',
        address: '大连市大连小区',
      },
    ],
  },
};

export default [
  {
    url: '/basic-api/table/getListData',
    timeout: 200,
    method: 'get',
    response: () => {
      return resultSuccess(tableListData);
    },
  },
  {
    url: '/basic-api/table/addListData',
    timeout: 1000,
    method: 'post',
    response: (request: requestParams) => {
      tableListData.pager.list.push(request.body);
      return resultSuccess({});
    },
  },
  {
    url: '/basic-api/table/editListData',
    timeout: 1000,
    method: 'post',
    response: (request: requestParams) => {
      let list: any[] = [];
      for (let item of tableListData.pager.list) {
        console.log('item', item);

        if (request.body.contno === item.contno) {
          list.push(request.body);
        } else {
          list.push(item);
        }
      }
      tableListData.pager.list = list;
      return resultSuccess({});
    },
  },
  {
    url: '/basic-api/table/delListData',
    timeout: 1000,
    method: 'post',
    response: (request: requestParams) => {
      let list: any[] = [];
      for (let item of tableListData.pager.list) {
        console.log('item', item);

        if (request.body.contno === item.contno) {
        } else {
          list.push(item);
        }
      }
      tableListData.pager.list = list;
      return resultSuccess({});
    },
  },
] as MockMethod[];
/src/api/table下添加相关api

在这里插入图片描述
/src/api/table/tableApi.ts

import { defHttp } from '/@/utils/http/axios';

enum Api {
  LIST_DATA = '/table/getListData',
  ADD_DATA = '/table/addListData',
  EDIT_DATA = '/table/editListData',
  DEL_DATA = '/table/delListData',
}

/**
 * @description: Get sample list value
 */

// export const printSignIssue = (params) =>
//   defHttp.post({
//     url: Api.PRINT_AMT,
//     params,
//   });
// table列表
export const getListDataApi = (params) =>
  defHttp.get({
    url: Api.LIST_DATA,
    params,
  });

// 新增
export const addListDataApi = (params) =>
  defHttp.post({
    url: Api.ADD_DATA,
    params,
  });

// 编辑
export const editListDataApi = (params) =>
  defHttp.post({
    url: Api.EDIT_DATA,
    params,
  });

// 删除
export const delListDataApi = (params) =>
  defHttp.post({
    url: Api.DEL_DATA,
    params,
  });
!注意:

在使用页面使用mock和api前,要先在 /src/settings/componentSetting.ts中修改响应后处理的配置,我自己之前没有设置这里,所以table组件useTable调接口一直不通
在这里插入图片描述
componentSetting.ts

export default {
  // basic-table setting
  table: {
    // Form interface request general configuration
    // support xxx.xxx.xxx
    fetchSetting: {
      // The field name of the current page passed to the background
      pageField: 'page',
      // The number field name of each page displayed in the background
      sizeField: 'pageSize',
      // Field name of the form data returned by the interface
      // listField: 'items',
      
      // 这里要和 mock 和 api 返回的数据字段匹配
      listField: 'pager.list',
      
      // Total number of tables returned by the interface field name
      totalField: 'total',
    },
    // Number of pages that can be selected
    pageSizeOptions: ['10', '50', '80', '100'],
    // Default display quantity on one page
    defaultPageSize: 10,
    // Default Size
    defaultSize: 'middle',
    // Custom general sort function
    defaultSortFn: (sortInfo: SorterResult) => {
      const { field, order } = sortInfo;
      if (field && order) {
        return {
          // The sort field passed to the backend you
          field,
          // Sorting method passed to the background asc/desc
          order,
        };
      } else {
        return {};
      }
    },
    // Custom general filter function
    defaultFilterFn: (data: Partial<Recordable<string[]>>) => {
      return data;
    },
  },
  // scrollbar setting
  scrollbar: {
    // Whether to use native scroll bar
    // After opening, the menu, modal, drawer will change the pop-up scroll bar to native
    native: false,
  },
};
在之前的table练习中添加并使用api,注:我的新增、编辑和查看都改成了使用Drawer组件弹出,添加了AEVDrawerPage.vue,和之前Drawer练习的页面代码差不太多

在这里插入图片描述
之前相关记录:

  • Table组件的基本使用及练习
  • Drawer组件的基本使用及练习

data.ts

import { FormProps, FormSchema } from '/@/components/Form';
import { BasicColumn } from '/@/components/Table';
import { formatToDate } from '/@/utils/dateUtil';
import { Switch } from 'ant-design-vue';
import { ref, h, computed } from 'vue';

type sexOptionType = [{ label: string; value: string }, { label: string; value: string }];

const sexOption: sexOptionType = [
  { value: '0', label: '男' },
  { value: '1', label: '女' },
];

// 配置表格SearchForm字段
export const formConfig: Partial<FormProps> = {
  labelWidth: 120,
  actionColOptions: {
    span: 25,
  },
  //自动展开行
  autoAdvancedLine: 1,
  showAdvancedButton: true,

  baseColProps: {
    span: 8,
  },
  schemas: [
    {
      field: 'contno',
      label: '承兑协议号',
      component: 'Input',
      defaultValue: '',
      componentProps: ({ formModel }) => {
        return {
          style: { width: '100%', textAlign: 'left' },
          onInput: (e) => {
            formModel.contno = formModel.contno.replace(/[^\w-\/]/gi, '');
          },
        };
      },
    },
    {
      field: 'name',
      label: '姓名',
      component: 'Input',
    },
    {
      field: 'sex',
      label: '性别',
      component: 'Select',
      componentProps: {
        options: sexOption,
      },
    },
    {
      field: 'dt',
      label: '出生日期',
      component: 'DatePicker',
      componentProps: {
        style: {
          width: '100%',
        },
        valueFormat: 'YYYYMMDD',
      },
    },
    {
      field: 'age',
      label: '年龄',
      component: 'InputNumber',
      componentProps: {
        style: {
          width: '100%',
        },
      },
    },
  ],
};

// 配置表格表头字段
export const columns: BasicColumn[] = [
  {
    title: '承兑协议号',
    dataIndex: 'contno',
    // ifShow:false
    width: 200,
  },
  {
    title: '姓名',
    width: 200,
    dataIndex: 'name',
    // helpMessage:'aaa',
    // edit:true
  },
  {
    title: '性别',
    width: 200,
    dataIndex: 'sex',
    customRender: function (text) {
      console.log('text', text);
      return text.text === '0' ? '男' : '女';
    },
    // customRender:({record}) => {
    //   console.log(record)
    //   return h(Switch,{checked:record.sex == '0'},)
    // }
  },
  {
    title: '出生日期',
    width: 200,
    dataIndex: 'dt',
    customRender: function (text) {
      return formatToDate(text.text);
    },
  },
  {
    title: '年龄',
    width: 200,
    dataIndex: 'age',
  },
  {
    title: '电话',
    width: 200,
    dataIndex: 'tel',
  },
  {
    title: '住址',
    width: 200,
    dataIndex: 'address',
  },
];

export const schemasView: FormSchema[] = [
  {
    field: 'divider-bill',
    component: 'Divider',
    label: '信息',
    colProps: {
      span: 24,
    },
  },
  {
    field: 'contno',
    component: 'Input',
    label: '承兑协议号',
    required: true,
    defaultValue: '',
    componentProps: ({ formModel }) => {
      return {
        style: { width: '100%', textAlign: 'left' },
        oninput: (e) => {
          // formModel.contno = formModel.contno.replace(/[^\w\/]/ig, '');
        },
      };
    },
    dynamicRules: () => {
      return [
        {
          required: true,
          validator: (_, value) => {
            if (!value) {
              return Promise.reject('请输入承兑协议号');
            }
          },
        },
      ];
    },
  },
  {
    field: 'name',
    component: 'Input',
    label: '姓名',
    required: true,
  },
  {
    field: 'sex',
    component: 'Select',
    label: '性别',
    required: true,
    componentProps: {
      options: sexOption,
    },
  },
  {
    field: 'dt',
    component: 'DatePicker',
    label: '出生日期',
    required: true,
    componentProps: {
      style: { width: '100%' },
      valueFormat: 'YYYYMMDD',
    },
  },
  {
    field: 'age',
    component: 'InputNumber',
    label: '年龄',
    required: true,
    componentProps: {
      style: { width: '100%' },
      step: 1,
      min: 0,
      max: 150,
    },
  },
  {
    label: '电话',
    field: 'tel',
    component: 'Input',
    required: true,
    dynamicRules: ({ values }) => {
      if (values.tel !== undefined) {
        if (values.tel.indexOf('-') > 0) {
          return [
            {
              required: true,
              trigger: 'change',
              message: '请输入正确的号码',
              pattern: /(^\d{4}-\d{7}$)|(^\d{3}-\d{8}$)/,
            },
          ];
        } else {
          return [
            {
              required: true,
              trigger: 'change',
              message: '请输入正确的号码',
              pattern: /^1[3|4|5|7|8][0-9]{9}$/,
            },
          ];
        }
      } else {
        return [{ required: true, message: '请输入电话' }];
      }
    },
  },
  {
    field: 'address',
    component: 'InputTextArea',
    label: '住址',
    required: true,
  },
];

// 姓名
// 性别
// 出生日期
// 年龄
// 电话    tel
// 住址    address

// 表单数据
export function initData() {
  return [
    {
      name: '张三',
      sex: '男',
      dt: '20200701',
      age: '22',
      tel: '13789890909',
      address: '北京市北京小区',
    },
    {
      name: '李四',
      sex: '女',
      dt: '20230507',
      age: '27',
      tel: '15477778888',
      address: '大连市大连小区',
    },
    {
      name: '王五',
      sex: '男',
      dt: '20221001',
      age: '26',
      tel: '15477778888',
      address: '大连市大连小区',
    },
    {
      name: '小明',
      sex: '男',
      dt: '20220701',
      age: '25',
      tel: '15477778888',
      address: '大连市大连小区',
    },
    {
      name: '小红',
      sex: '女',
      dt: '20180808',
      age: '28',
      tel: '15477778888',
      address: '大连市大连小区',
    },
  ];
}

basicTable.vue

<template>
  <div
    :style="{
      overflow: 'hidden',
      position: 'relative',
      height: '100%',
    }"
  >
    <!-- 注册table -->
    <BasicTable @register="registerTable">
      <template #action="{ record }">
        <TableAction
          :actions="[
            {
              tooltip: '查看',
              icon: 'clarity:info-standard-line',
              onClick: handleOpen.bind(null, { type: 'view', data: record }),
            },
            {
              tooltip: '编辑',
              icon: 'clarity:note-edit-line',
              onClick: handleOpen.bind(null, { type: 'edit', data: record }),
            },
            {
              tooltip: '删除',
              color: 'error',
              icon: 'ant-design:delete-outlined',
              popConfirm: {
                title: '是否确定删除?',
                confirm: handleDel.bind(null, record),
              },
            },
          ]"
        />
      </template>
      <template #toolbar>
        <a-button type="primary" @click="handleOpen({ type: 'add', data: {} })">{{
          '新增'
        }}</a-button>

        <a-button color="warning" @click="exitExcel()">{{ '导出 Excel' }}</a-button>
      </template>
    </BasicTable>

    <AEVDrawerPage @reload="handleReload" @register="registerDrawer" />
    <!-- <ViewDrawer @reload="handleReload" @register="registerDrawer" /> -->
    <!-- <EditModal @reload="handleReload" @register="registerModal" /> -->
  </div>
</template>

<script lang="ts">
  import { defineComponent } from 'vue';
  // import { router } from '/@/router';
  import { formConfig, columns, initData } from './data';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { useDrawer } from '/@/components/Drawer';
  // import { useModal } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';
  // import { aoaToSheetXlsx } from '/@/components/Excel';
  import { getListDataApi, delListDataApi } from '../../../api/table/tableApi';
  // import ViewDrawer from './ViewDrawer.vue';
  // import EditModal from './EditModal.vue';
  import AEVDrawerPage from './AEVDrawerPage.vue';
  export default defineComponent({
    name: 'tableTest',
    components: {
      BasicTable,
      TableAction,
      AEVDrawerPage,
      // ViewDrawer,
      // EditModal
    },
    setup() {
      // const data = initData();

      const { createMessage } = useMessage();
      // 设置table
      const [registerTable, { reload, clearSelectedRowKeys }] = useTable(
        {
          title: '查询结果',
          // 调用接口,之前的写死数据就不用了
          api: getListDataApi,
          // dataSource: data,
          columns: columns,
          bordered: true,
          useSearchForm: true, //开启搜索区域
          formConfig: formConfig,
          // striped:false,
          // showSummary:true,
          // loading:true,
          afterFetch: (data) => {
            console.log('data', data);
            clearSelectedRowKeys();
          },
          actionColumn: {
            width: 120,
            title: '操作',
            dataIndex: 'action',
            slots: { customRender: 'action' },
          },
          rowSelection: { type: 'radio' },
          pagination: { pageSize: 10 },
          showTableSetting: true,
          tableSetting: { fullScreen: true },
          showIndexColumn: true,
          indexColumnProps: { fixed: 'left' },
        },
      );

      // 注册Drawer
      const [registerDrawer, { openDrawer: openAEVDrawerPage, setDrawerProps }] = useDrawer();

      // 配置Modal
      // const [registerModal, { openModal }] = useModal();

      async function handleOpen({ type, data }) {
        await openAEVDrawerPage(true, { type, data });
        if (type === 'add') {
          setDrawerProps({ title: '新增' });
        } else if (type === 'edit') {
          setDrawerProps({ title: '修改' });
        } else {
          setDrawerProps({ title: '查看' });
        }
      }

      // async function exitExcel() {
      //   let tableData:[][] = getDataSource();
      //   let columns = getColumns()
      //   let titleArr = columns.map(item => {
      //     return item.title
      //   })
      //   console.log('tableData', tableData,columns,titleArr);

      //   // debugger;
      //   aoaToSheetXlsx({
      //     data: tableData,
      //     header: titleArr,
      //     filename: '导出excel.xlsx',
      //   });
      // }

      // 新增按钮
      // function handleAdd() {
      //   router.push({
      //     path: '/testRoute/addPage',
      //   });
      // }

      // 查看按钮
      // function handleView({ data }) {
      //   openDrawer(true, data);
      // }

      // 编辑按钮
      // function handleEdit({ data }) {
      //   openModal(true, data);
      // }

      // 删除按钮
      async function handleDel(record: Recordable) {
        console.log('删除数据', record);
        await delListDataApi(record).then(() => {
          createMessage.success('删除成功');
          reload();
        });
      }

      function handleReload() {
        reload();
      }
      return {
        registerTable,
        reload,

        handleOpen,
        // 新增路由跳转
        // handleAdd,

        // 查看抽屉
        registerDrawer,
        // handleView,
        handleReload,

        // 编辑弹窗
        // registerModal,
        // handleEdit,

        // 删除
        handleDel,

        // exitExcel,
      };
    },
  });
</script>

<style scoped></style>

AEVDrawerPage.vue(除了主要的调用接口,还有点我自己练习的tabs等相关代码,可以忽略不看…)

<template>
  <div
    :style="{
      overflow: 'hidden',
    }"
  >
    <BasicDrawer
      v-bind="$attrs"
      @register="registerDrawer"
      @visibleChange="handleVisibleChange"
      :isDetail="true"
      title="查看"
      placement="bottom"
      height="100%"
      :destroyOnClose="true"
    >
      <a-tabs>
        <a-tab-pane key="1" tab="表单页面">
          <div>
            <BasicForm @register="registerForm"></BasicForm>
          </div>
          <Divider />
          <PageFooter v-if="showPageFooter">
            <template #right>
              <a-button @click="handleCancel"> 取消</a-button>
              <a-button class="!ml-4" type="primary" @click="handleSubmit" :loading="isLoading">
                保存</a-button
              >
            </template>
          </PageFooter>
        </a-tab-pane>
        <a-tab-pane key="2" tab="明细页面">
          <!-- <BasicTable @register="registerTable">
            <template #action="{}">
              <TableAction
                :actions="[
                  {
                    tooltip: '查看',
                    icon: 'clarity:info-standard-line',
                    
                  },
                  {
                    tooltip: '编辑',
                    icon: 'clarity:note-edit-line',
                    
                  },
                  {
                    tooltip: '删除',
                    color: 'error',
                    icon: 'ant-design:delete-outlined',

                  },
                ]"
              />
            </template>
            <template #toolbar>
              <a-button type="primary">{{
                '新增'
              }}</a-button>

              <a-button color="warning" >{{ '导出 Excel' }}</a-button>
            </template>
          </BasicTable> -->
        </a-tab-pane>
        <a-tab-pane key="3" tab="其他页面"></a-tab-pane>
      </a-tabs>
    </BasicDrawer>
  </div>
</template>

<script lang="ts">
  import { defineComponent, Ref, ref } from 'vue';
  import { Button, Divider, Tabs } from 'ant-design-vue';
  import { BasicTable, useTable, TableAction } from '/@/components/Table';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicForm, useForm } from '/@/components/Form';
  import { PageFooter } from '/@/components/Page';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { schemasView } from './data';
  import {
    // getListDataApi,
    addListDataApi,
    editListDataApi,
  } from '/@/api/table/tableApi';
  // import { formConfig, columns, initData } from './data';

  export default defineComponent({
    name: 'AEVDrawerPage',
    components: {
      BasicDrawer,
      BasicForm,
      Divider,
      PageFooter,
      [Tabs.name]: Tabs,
      [Tabs.TabPane.name]: Tabs.TabPane,
      [Button.name]: Button,
      BasicTable,
      TableAction,
    },
    setup(_, { emit }) {
      const { createMessage } = useMessage();
      const currentType: Ref = ref('add');
      const showPageFooter: Ref = ref(true);
      const isLoading = ref(false);
      // const [registerTable, {  }] = useTable(
      //   {
      //     title: '查询结果',
      //     api: getListDataApi,
      //     // dataSource: data,
      //     columns: columns,
      //     bordered: true,
      //     // useSearchForm: true, //开启搜索区域
      //     // formConfig: formConfig,
      //     // striped:false,
      //     // showSummary:true,
      //     // loading:true,
      //     actionColumn: {
      //       width: 120,
      //       title: '操作',
      //       dataIndex: 'action',
      //       slots: { customRender: 'action' },
      //     },
      //     rowSelection: { type: 'radio' },
      //     pagination: { pageSize: 10 },
      //     showTableSetting: true,
      //     tableSetting: { fullScreen: true },
      //     showIndexColumn: true,
      //     indexColumnProps: { fixed: 'left' },
      //   },
      // );
      // 配置Drawer
      const [registerDrawer, { closeDrawer }] = useDrawerInner(async ({ type, data }) => {
        console.log('打印从table传递的数据:', type, data);
        currentType.value = type;
        console.log('currentType', currentType);
        setFieldsValue(data);
        if (type == 'view') {
          showPageFooter.value = false;
          setProps({ disabled: true });
        } else {
          showPageFooter.value = true;
        }
      });

      // 配置Form
      const [registerForm, { validate, getFieldsValue, setFieldsValue, setProps }] = useForm({
        labelWidth: 150,
        baseColProps: {
          offset: 1,
          span: 10,
        },
        schemas: schemasView,
        showActionButtonGroup: false,
      });

      function handleVisibleChange(visible: boolean) {
        if (!visible) {
          emit('reload');
        }
      }

      async function handleSubmit() {
        console.log('handleSubmit', currentType);
        // await validate();
        const paramsData = await getFieldsValue();
        console.log('paramsData', paramsData);
        isLoading.value = true;

        if (currentType.value === 'add') {
          await addListDataApi({ ...paramsData }).then((res) => {
            isLoading.value = false;
            createMessage.success('保存成功');
            closeDrawer();
          });
        } else {
          await editListDataApi({ ...paramsData }).then((res) => {
            isLoading.value = false;
            createMessage.success('保存成功');
            closeDrawer();
          });
        }
      }

      // 取消按钮
      function handleCancel() {
        console.log('handleCancel', currentType);
        emit('back');
        closeDrawer();
      }
      return {
        currentType,
        showPageFooter,
        isLoading,
        registerDrawer,
        closeDrawer,

        registerForm,
        validate,
        getFieldsValue,
        setFieldsValue,
        setProps,

        handleVisibleChange,
        handleSubmit,
        handleCancel,

        // registerTable,
      };
    },
  });
</script>

<style scoped></style>

页面效果

vben-admin 使用mock添加增删改接口逻辑及联调

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

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

相关文章

《编程思维与实践》1067.小型组合数

《编程思维与实践》1067.小型组合数 题目 思路 法一: 注意到题目数据最大为 C 40 20 137846528820 C_{40}^{20}137846528820 C4020​137846528820在long long的范围内,所以其实可以不用大整数的处理方法去计算: 由于 C m n m ! n ! ( m − n ) ! m ( m − 1 ) . . . ( m −…

mysql数据库的库操作 --2

目录 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.2&#xff1a;字符集和效验规则 2.3&#xff1a;修改和删除数据库 2.4&#xff1a;数据库的备份和恢复 2.5&#xff1a;查看连接情况 库操作 2.1&#xff1a;数据库的查看与创建与使用 2.1.1&#xff1a;数据库…

AcWing算法提高课-1.3.9庆功会

宣传一下算法提高课整理 <— CSDN个人主页&#xff1a;更好的阅读体验 <— 本题链接&#xff08;AcWing&#xff09; 点这里 题目描述 为了庆贺班级在校运动会上取得全校第一名成绩&#xff0c;班主任决定开一场庆功会&#xff0c;为此拨款购买奖品犒劳运动员。 期望…

[golang gin框架] 32.Gin 商城项目- 支付宝支付操作相关功能讲解

一.支付宝支付之前的准备工作 创建应用、配置签名、提交审核 支付宝支付之前的准备工作 支付宝开放平台支持使用 普通公钥、公钥证书 两种签名方式 公钥证书模式下完成支付需要获取的内容&#xff1a; appId 应用私钥 应用公钥证书 支付宝根证书 支付宝公钥证书 普通公钥模式下…

热乎的面经——不屈不挠

⭐️前言⭐️ &#x1f349;欢迎点赞 &#x1f44d; 收藏 ⭐留言评论 &#x1f4dd;私信必回哟&#x1f601; &#x1f349;博主将持续更新学习记录收获&#xff0c;友友们有任何问题可以在评论区留言 &#x1f349;博客中涉及源码及博主日常练习代码均已上传GitHub &#x1f4…

【Linux常见指令以及权限理解】基本指令(3)

写在前面 上一篇文章&#xff0c;我们学习了Linux的一些常用指令&#xff0c; 学习了如何理解Linux系统&#xff0c;介绍了对Linux系统的理解&#xff1a;Linux下一切皆文件 介绍了重定向还有管道相关的知识。这里是上一篇博客的链接&#xff1a;http://t.csdn.cn/2d6fc 接…

Kali HTTrack演示-渗透测试察打一体(1)

HTTrack是一个免费并易于使用的线下浏览器工具,全称是HTTrack Website Copier for Windows,它能够让你从互联网上下载指定的网站进行线下浏览(离线浏览),也可以用来收集信息(甚至有网站使用隐藏的密码文件),一些仿真度极高的伪网站(为了骗取用户密码),也是使用类似工具做…

[一篇读懂]C语言十二讲:栈与队列和真题实战

[一篇读懂]C语言十二讲&#xff1a;栈与队列和真题实战 1. 与408关联解析及本节内容介绍1 与408关联解析2 本节内容介绍 2. 栈(stack)的原理解析2.1 **栈&#xff1a;只允许在一端进行插入或删除操作的线性表**2.2 栈的基本操作2.3 栈的顺序存储2.4 栈的链表存储 3. 初始化栈 -…

PE文件+UPX壳 ida分析

die查壳发现是UPX壳&#xff0c;直接用ida分析&#xff0c;会发现能分析出来的信息特别少&#xff0c;需要脱壳 工具链接发布 UPX/UPX (github.com) 下载压缩包后解压&#xff0c;直接在该文件路径下cmd&#xff0c;输入upx.exe -h安装完成&#xff0c;使用命令“upx -d 文件路…

计算机网络-网络层与链路层协议分析实验

一.实验目的 通过本实验&#xff0c;进一步熟悉PacketTracer的使用&#xff0c;学习路由器与交换机的基本配置&#xff0c;加深对网络层与链路层协议的理解。 二.实验内容 1.完成路由器交换机的基本配置 2.了解 ICMP 数据包的格式 3.检查ARP交换 三.实验过程 1.完成路由…

链表——循环链表

其他形式的链表——循环链表 循环链表 定义&#xff1a;循环链表是表中最后一个结点的指针指向头结点&#xff0c;使链表构成环状 特点&#xff1a;从表中任一结点发出均可找到表中其他结点&#xff0c;提高查找效率 双向循环链表 data&#xff1a;数据元素 prior&#xff1…

进程间通信--管道

文章目录 一.通信二.管道匿名管道&#xff08;只能用于有血缘关系的进程之间通信&#xff09;1.匿名管道的创建2.匿名管道的读取情况3.管道的特征4.基于匿名管道的简单进程池 有名管道&#xff08;用于没有血缘关系的进程间的通信&#xff09;1.有名管道的建立和删除2.通过一段…

CodeForces 438 D线段树暴力修改

线段树暴力修改 关键是每个数取余操作&#xff0c;看似我们如果暴力改的话m*n肯定超时了 容易发现一个数小于给定模数的时候&#xff0c;取模不会发生改变&#xff0c;而大于给定模数的时候我们得到的最大的结果是x/2向上取整&#xff0c;结果一定小于等于这个数字,这里我想说…

AECC全球留学趋势报告解读

AECC全球留学趋势报告解读 相对更安全的留学目的地&#xff1a; 留学安全是留学生及家长最关注的一个问题。报告显示&#xff0c;在“你认为相对更安全的留学目 的"的问答中&#xff0c;澳大利亚获得总评8.76分&#xff08;满分10分&#xff09;位居第一。 英澳新留学更受…

VMware Tanzu Kubernetes Grid (TKG) 2.1 - 企业级 Kubernetes 解决方案

VMware Tanzu Kubernetes Grid (TKG) 2.1 - 企业级 Kubernetes 解决方案 VMware 构建、签名和支持的开源 Kubernetes 容器编排平台的完整分发版 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-tkg-2/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处…

华为OD机试真题 Java 实现【最优资源分配】【2023Q1 200分】

一、题目描述 某块业务芯片最小容量单位为 1.25G&#xff0c;总容量为 M*1.25G&#xff0c;对该芯片资源编号为 1&#xff0c;2&#xff0c;… M。 该芯片支持 3 种不同的配置&#xff0c;分别为 A、B、C. 配置 A: 占用容量为 1.25 * 1 1.25G配置 B: 占用容量为 1.25* 2 2…

白嫖chatgpt的Edge插件,很难不爱啊

目录 &#x1f341;1.常见的Edge浏览器界面 &#x1f341;二.安装WebTab插件 &#x1f341;三.WebTab插件的各种功能 &#x1f341;1.支持免费的chatgpt&#xff0c;不限次数​编辑 &#x1f341;2.有几个休闲的小游戏可以玩耍&#xff0c;点击即玩。 &#x1f341;3.支…

【迷宫问题】找出迷宫所有可能的路径C++

1 引入情境 我记得小时候玩过推箱子游戏&#xff0c;也是如下图这种&#xff0c;四周由深色的方格作为墙壁&#xff0c;白色的地方是可以通过的。现在想要从红色方格出发走到黄色方格&#xff0c;能有什么好办法呢&#xff1f; 注意到&#xff0c;对于计算机没有全局的观念&…

Flutter音乐播放audioplayers

简介 Flutter的audioplayers是一个Flutter插件&#xff0c;可以播放多个同时的音频文件&#xff0c;支持Android、iOS、Linux、macOS、Windows和web平台。它有以下特点&#xff1a; 可以从本地文件、网络资源或内存中加载音频可以控制音量、进度、速度和循环可以播放多个音频…

《编程思维与实践》1069.第一位数字

《编程思维与实践》1069.第一位数字 题目 思路 由于正整数N的N次方最大可以为 1 0 8 ⋅ 1 0 8 10^{8\cdot 10^8} 108⋅108,加上数据可能有很多组,所以直接采用大整数计算次方这方法很可能超时, 这里给出一种数学算法: 幂指函数通常的处理方式是取对数将乘方转化为乘法: N N 1…