用React给XXL-JOB开发一个新皮肤(四):实现用户管理模块

目录

  • 一. 简述
  • 二. 模块规划
    • 2.1. 页面规划
    • 2.2. 模型实体定义
  • 三. 模块实现
    • 3.1. 用户分页搜索
    • 3.2. Modal 配置
    • 3.3. 创建用户表单
    • 3.4. 修改用户表单
    • 3.5. 删除
  • 四. 结束语

一. 简述

上一篇文章我们实现登录页面和管理页面的 Layout 骨架,并对接登录和登出接口。这篇文章我们将实现用户管理的模块和相应的接口。最后效果如下:
在这里插入图片描述

二. 模块规划

在开发之前我们需要对 xxl-job管理系统的用户模块进行规划。

2.1. 页面规划

一般我们都是从前端页面需要使用什么组件;后端接口需要哪些?
在这里插入图片描述
前端使用的组件:表格、分页、下拉框、输入框和按钮,就是一个很普通的 CRUD 管理页面,比较简单;接口也是围绕这些功能的:分页查询接口、创建用户接口、编辑用户接口和删除接口。

2.2. 模型实体定义

接着我们需要定义下前后端交互会使用的到的请求和响应实体的定义。

首先是用户分页查询接口的请求和响应:

// UserPageQueryProp 用户分页查询请求参数定义
export interface UserPageQueryProp {
  page: number;      // 页码
  size: number;      // 页大小
  role: number;      // 角色 ID
  username?: string;  // 用户名称
}

// UserTableProp 用户分页查询返回参数定义
export interface UserTableProp {
  id: number;         // 用户ID
  username: string;   // 用户名称
  role: number;       // 角色
  permission: string; // 权限
}

这里需要注意的是虽然我们表格中只有用户名和角色名两个显示属性,但是考虑到在编辑的时候需要根据角色显示权限信息,这里在分页查询中返回用户的权限数据。但是如果在一些复杂的分页表格中,不建议这样操作!

接着是用户创建和编辑的请求的定义:

// UserTableProp 用户创建表单属性
export interface UserCreateFormProp {
  username: string;     // 用户名称
  password: string;     // 密码
  role: number;         // 角色
  permission: string[]; // 权限
}

// UserUpdateFormProp 用户创建表单属性
export interface UserUpdateFormProp extends UserCreateFormProp{
  id: number;           // 用户ID
}

三. 模块实现

从这个模块我们可以分为两个大部分和三个小组件组成。
在这里插入图片描述
其中功能部分我们可以使用 antdSpace 中嵌套表单组件实现;表格可以使用 Table 组件(这个组件自带分页功能)实现;最后创建和编辑按钮我们使用 Modal 组件中嵌套 Form 表单组件实现就可以了。下面我们按功能一个个实现这个用户模块。

这里我们在使用 TS 这个 Buff 的使用,大部分使用需要申明类型,尤其在使用不熟悉的 UI 组件库的时候,大家需要多读文章,多看组件定义文件或者源码。

3.1. 用户分页搜索

上面我们分析我们要使用组件,这里就不赘述了,直接上代码:

import {Button, Divider, Input, Select, Space, Table, Tag} from "antd";
import React, {useEffect, useState} from "react";
import {User} from "@/types";
import {ColumnsType} from "antd/es/table";
import {useRequest} from "ahooks";
import UserApi from "@/api/user.ts";
import {ClearOutlined, PlusOutlined, SearchOutlined} from "@ant-design/icons";

const UserPage = () => {

  // 定义列信息
  const columns: ColumnsType<User.UserTableProp> = [
    {
      title: '账号',
      key: 'username',
      dataIndex: 'username',
      align: 'center'
    },
    {
      title: '角色',
      key: 'role',
      dataIndex: 'role',
      align: 'center',
      render: (_, record) => record.role == 1 ? <Tag color="#f50">管理员</Tag> : <Tag color="#2db7f5">普通用户</Tag>
    },
    {
      title: '操作',
      key: 'active',
      align: 'center',
      width: 200,
      render: (_, record) => <Space>
        <Button type="primary" onClick={() => openEdit(record.id)}>编辑</Button>
        <Button type="primary" danger onClick={() => deleteUser(record.id)}>删除</Button>
      </Space>,
    },
  ]
  
  // 总条数
  const [total, setTotal] = useState<number>(0);
  const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
  // 用户数据
  const [datasource, setDatasource] = useState<User.UserTableProp[]>([]);
  // 分页查询属性
  const [pageQuery, setPageQuery] = useState<User.UserPageQueryProp>(defaultUserPageQuery());

  return <div>
    <Space>
      <Button type="primary" icon={<PlusOutlined />}>增加用户</Button>
      <Divider type="vertical"/>
      <div>角色:</div>
      <Select
        onChange={e => setPageQuery({...pageQuery, role: e})}
        placeholder="选择状态"
        defaultValue={-1}
        style={{width: 100}}
        options={[
          {value: -1, label: '全部'},
          {value: 1, label: '管理员'},
          {value: 0, label: '普通用户'}
        ]}
      />
      <div style={{marginLeft: 20}}>用户名称:</div>
      <Input
        allowClear
        placeholder="请输入搜索的用户名称"
        value={pageQuery.username}
        onChange={e => setPageQuery({...pageQuery, username: e.target.value})} />
      <Button danger type='primary' icon={<ClearOutlined />} onClick={clearSearch}>清空</Button>
      <Button type='primary' icon={<SearchOutlined />} onClick={() => loadUser.run(pageQuery)}>搜索</Button>
    </Space>
    <Table
      bordered
      size={'small'}
      columns={columns}
      loading={loadUser.loading}
      dataSource={datasource}
      style={{ marginTop: 10 }}
      rowKey={(record) => record.id}
      pagination={{
        onShowSizeChange: (current, size) => loadUser.run({...pageQuery, page: current, size: size}),
        onChange: (page, pageSize) => loadUser.run({...pageQuery, page: page, size: pageSize}),
        showTotal: () => `${total}`,
        showQuickJumper: true,
        showSizeChanger: true,
        pageSize: pageQuery.size,
        current: pageQuery.page,
        size: 'default',
        total: total,
      }}
      rowSelection={{
        type: 'checkbox',
        selectedRowKeys: selectedRowKeys,
        onChange: (selectedRowKeys: React.Key[]) => {
          setSelectedRowKeys([...selectedRowKeys.map(item => item as number)])
        }
      }}
    />
  </div>
}

export default UserPage;

这里我们需要注意一下几点:

  • 表格每一个行都需要一个 Key,默认是 React.Key,但是如果我们需要自定义的时候,可以使用rowKey={(record) => record.id}定义自己的 rowKey,这里的 record 就是定义表格属性模型:User.UserTableProp
  • 关于分页属性我们可以通过pagination属性进行设置,可以设置属性和方法可以在分页组件文章中看到
  • 最后一点就是关于表格行选中可以通过rowSelection属性设置;

接下来我们就需要对接分页查询的接口了,首先我们在 api/user.ts 中添加用户分页接口 api 定义:

/**
 * 用户分页
 * @param param
 * @constructor
 */
export const UserPage = (param: User.UserPageQueryProp): Promise<PageData<User.UserTableProp>> => {
  return https.request({
    url: '/user/pageList',
    method: 'post',
    data: param
  })
}

接着我们看一下如何使用这个api,并且了解下ahooks 中的useRequest中非常好用的地方。

// 加载用户列表
const loadUser = useRequest(UserApi.UserPage, {
  manual: true, // 手动调用
  onSuccess: ({records, total}) => { // 成功之后执行的操作
    setTotal(total);
    setDatasource(records);
  }
});

最后我们配合 useEffect使用,加载用户列表的接口会在加载用户管理页面的时候调用这个接口。

useEffect(() => {
  loadUser.run(pageQuery)
}, [])

这里我们介绍 ahooks 中的 useRequest这个工具 hooks

在这里插入图片描述
支持的功能很多,这里我们现使用这里的 loading 返回值。在我们请求接口的时候如果遇到网络抖动之类的加载缓慢的情况,让表格出现一个加载状态的图标是非常友好了,不然用户也很懵逼。在上面antd 提供了加载属性loading={loadUser.loading}我们只需要将这个值的变化交给 useRequest 就可以,完全不需要我们手动控制。

接下来我们实现上面搜索的功能。
在这里插入图片描述
这里一个是下拉框一个是输入框,我们直接使用的是 antd 的组件,我们仅需要实现清空输入和搜索两个按钮事件就可以了。对于清空搜索的点击事件,我们只需要将下拉选项设置为默认值,输入框清空就可以了,代码如下 :

// 清空搜索
const clearSearch = () => {
  setPageQuery({...pageQuery, role: -1, username: ""})
}

对于搜索我们仅需要手动调用分页接口就可以了,代码如下:

<Button 
  type='primary' 
  icon={<SearchOutlined />} 
  onClick={() => loadUser.run(pageQuery)}
>搜索</Button>

3.2. Modal 配置

这个用户管理的部分需要用到创建用户和编辑用户两个功能,在xxl-job中都是都通过打开弹窗进行操的,我们这里也是使用相同的逻辑。这里我们使用 antdModal 组件。在使用这个组件的时候我们需要对 Modal 组件的打开和关闭进行一个统一的控制。

// UserCreateModelProp 创建用户弹窗属性
export interface UserCreateModalProp {
  visible: boolean;
  close: (isLoad: boolean) => void; // 关闭模态框
}

// UserUpdateFormProp 用户更新表单属性
export interface UserUpdateFormProp {
  id: number;           // 用户ID
  password: string;     // 密码
  role: number;         // 角色
  permission: string[]; // 权限
}

// 定义模态框的类型
export type ModalType = "create" | "update";

// UserModelProp 用户模态框汇总属性
export interface UserModalProp {
  createVisible: boolean;    // 创建用户模态框打开标识
  updateVisible: boolean;    // 编辑用户模态框打开标识
  userData?: UserTableProp;  // 编辑是存放被编辑用户信息
}

接着我们分别定义打开和关闭模态框的事件:

// 关闭模态框
const closeModal = (isLoad: boolean) => {
  // 在全局只能有一个弹窗打开,所以在关闭的时候把标识变量都设为 false 就可以了
  setUserModelProp({createVisible: false, updateVisible: false, userData: undefined})
  if(isLoad) {
    // 如果创建和编辑成功,我们需要重新加载表格数据显示最新的数据
    loadUser.run(pageQuery)
  }
}

// 打开模态框
const openModal = (types: User.ModalType, data?: User.UserTableProp) => {
  switch (types) {
    case "create":
      setUserModalProp({createVisible: true, updateVisible: false});
      break;
    case "update":
      setUserModalProp({updateVisible: true, createVisible: false, userData: data});
      break;
    default:
      break
  }
}

最后我们在创建和编辑按钮上使用这些事件就可以了:

<Button 
  type="primary" 
  icon={<PlusOutlined />} 
  onClick={() => openModal('create')}
  >增加用户</Button>

<Button 
  type="primary" 
  onClick={() => openModal('update', record)}
  >编辑</Button>

接着我们定一个模态框组件,在当前目录下创建 create.tsxupdate.tsx 文件,这两个文件分别是创建用户和编辑用户模态框组件(子组件)。

import {Modal} from "antd";
import React from "react";
import {User} from "@/types";

const CreateUserModal: React.FC<User.UserCreateModalProp> = ({visible, close}) => {

  const submitForm = () => {
    close(true)
  }

  return <Modal
    title="创建用户"
    open={visible}
    onOk={submitForm}
    onCancel={() => close(false)}
  >
    <h1>创建用户</h1>
  </Modal>
}

export default CreateUserModal;

编辑类似不做展示了

这两个子组件设置组件之间的传值问题,我们在User.UserCreateModalProp定义了创建用户模态框组件需要的参数:visible变量和 close函数。最后我们在 index.tsx 中使用这个子组件就可以了。

// 存放模态框状态值
const [userModalProp, setUserModalProp] = useState<User.UserModalProp>({createVisible: false, updateVisible: false});

<CreateUserModal
  key="create"
  close={closeModal}  // 模态框关闭事件
  visible={userModalProp.createVisible} // 创建用户模态框打开状态标识变量
/>

效果如下:
在这里插入图片描述

3.3. 创建用户表单

这里我们接着实现创建用户表单和表单提交的相关部分,直接上代码:

推荐先看看 antdForm 组件的文章。

import {Checkbox, Divider, Empty, Form, Input, message, Modal, Radio, Row, Spin, Tag} from "antd";
import React, {useEffect, useState} from "react";
import {Group, User} from "@/types";
import {useRequest} from "ahooks";
import {GroupApi, UserApi} from "@/api/index.ts";
import styled from "@emotion/styled";

const CreateUserModal: React.FC<User.UserCreateModalProp> = ({visible, close}) => {

  // 表单
  const [form] = Form.useForm<User.UserCreateFormProp>();
  // 监听表单 role 的 value
  const roleValue = Form.useWatch('role', form);
  // 执行器列表
  const [groups, setGroups] = useState<Group.JobGroupListProp[]>([]);
  // 执行器请求
  const groupLoader = useRequest(GroupApi.GroupLists, {manual: true, onSuccess: (data) => {
    setGroups(data);
  }})
  // 创建用户请求
  const createLoader = useRequest(UserApi.CreateUser, {manual: true, onSuccess: () => {
      message.success('创建用户成功')
      close(true)
    }
  });

  const submitForm = () => {
    form.validateFields().then(value => {
      // console.log("submit => ", value)
      if (value.role == 1) {
        value.permission = []
      }
      createLoader.run(value);
    })
  }

  // 监听 visible 打开关闭标识
  useEffect(() => {
    if (visible) { // 当创建用户模态框打开,请求执行器列表接口并设置角色默认值为普通用户
      groupLoader.run();
      form.setFieldValue('role', 0)
    } else {
      // 关闭模态框的时候,将表单置为空并将执行器列表设置为空数组
      form.resetFields();
      setGroups([]);
    }
  }, [visible])

  return <Controller
    title="创建用户"
    maskClosable
    width={500}
    open={visible}
    onOk={submitForm}
    onCancel={() => close(false)}
  >
    <Spin tip="加载中......" spinning={createLoader.loading}>
      <Form 
        form={form} 
        layout="vertical" 
        name="form_create_modal">
        <Form.Item 
          name="username" 
          label="账号" 
          rules={[{ required: true, message: '请输入账号' }]}>
          <Input placeholder="请输入账号" />
        </Form.Item>
        <Form.Item 
          name="password" 
          label="密码" 
          rules={[{ required: true, message: '请输入密码' }]}>
          <Input.Password placeholder="请输入密码" />
        </Form.Item>
        <Form.Item name="role" label="角色">
          <Radio.Group>
            <Radio value={0}>普通用户</Radio>
            <Radio value={1}>管理员</Radio>
          </Radio.Group>
        </Form.Item>
        {
          roleValue === 0 && <Form.Item name="permission" label="权限">
            {groups.length > 0 ? <Checkbox.Group className="xxl-job-list">
              {groups.map(item =>
                <Row key={item.id}>
                  <Checkbox value={item.appName}>{item.title}
                    <Divider type="vertical" />
                    <Tag color="lime">{item.appName}</Tag>
                  </Checkbox>
                </Row>)}
            </Checkbox.Group> 
            : <Empty />
         }
         </Form.Item>
        }

      </Form>
    </Spin>
  </Controller>
}

const Controller = styled(Modal)`
  .ant-modal-body {
    padding-top: 24px;
    .xxl-job-list {
       flex-direction: column;
    }
  }
`

export default CreateUserModal;

这里我们通过 Modal 包裹表单组件,使用 useEffect监听 visible属性,当前模态框打开的时候,需要请求执行器列表,并设置角色默认值。

还需要注意的一个点是,当角色是管理员的时候,是不需要选择执行器的,所有在切换角色为管理员的时候,需要将之前选中的执行器清空;所以在最后提交用户数据的时候,设置下执行器就可以了。

const submitForm = () => {
  form.validateFields().then(value => {
    if (value.role == 1) { // 当角色是管理员的时候,将执行器权限设置为空数据
      value.permission = []
    }
    createLoader.run(value);
  })
}

此外我们还通过 styled 修改了 Modal 组件的样式,主要是为了将多选框flex 布局从 row 改为 column

// 使用 styled 包裹 Modal 组件
const Controller = styled(Modal)`
  .ant-modal-body {
    padding-top: 24px;
    .xxl-job-list {
      flex-direction: column;
    }
  }
`

3.4. 修改用户表单

有了上面创建用户表单部分,我们在修改用户信息的时候,仅需要了解表单初始化的问题了;这里我们也是用使用Form.setFieldsValue方法进行初始化表单,代码代码:

useEffect(() => {
  if (visible && data) {
    groupLoader.run();
    form.setFieldsValue({id: data.id, username: data.username, role: data.role, permission: data.permission})
  } else {
    form.resetFields();
    setGroups([]);
  }
}, [visible])

这里还有一个不一样的地方是我们会设置一个隐藏的用户主键,方便我们后面执行更新的时候确定要被更新用户信息:

<Controller
    title="更新用户"
    maskClosable
    width={500}
    open={visible}
    onOk={submitForm}
    onCancel={() => close(false)}
  >
    <Spin tip="加载中......" spinning={updateLoader.loading}>
      <Form form={form} layout="vertical" name="form_update_modal">
        // 不显示主键,在我们提交数据的时候会反给form.validateFields().then(value => {})中
        <Form.Item name="id" label="主键" style={{display: 'none'}}><Input /></Form.Item>
        <Form.Item name="username" label="账号">
          <Input placeholder="请输入账号" readOnly />
        </Form.Item>
        <Form.Item name="password" label="密码">
          <Input.Password placeholder="请输入新密码,为空则不更新密码" />
        </Form.Item>
        <Form.Item name="role" label="角色">
          <Radio.Group>
            <Radio value={0}>普通用户</Radio>
            <Radio value={1}>管理员</Radio>
          </Radio.Group>
        </Form.Item>
        {
          roleValue === 0 && <Form.Item name="permission" label="权限">
            {groups.length > 0 ? <Checkbox.Group className="xxl-job-list">
              {groups.map(item =>
                <Row key={item.id}><Checkbox value={item.appName}>{item.title}<Divider type="vertical" /><Tag color="lime">{item.appName}</Tag></Checkbox></Row>)}
            </Checkbox.Group> : <Empty />}
                    </Form.Item>
        }

      </Form>
    </Spin>
  </Controller>

3.5. 删除

终于快要搞完了,现在我们就剩删除用户这个功能了。针对我们删除来说,一般我都需要弹出一个提示,询问用户是否确定删除这条数据。这里我们可以使用 antd 中的 删除Modal或者气泡提示就可以了。

在这里插入图片描述
这里功能简单,只需要调用组件,在其回调方法中调用删除接口就可以了。代码如下:

// 移除用户
const loadRemoveUser = useRequest(UserApi.RemoveUser, {
  manual: true,
  onSuccess: () => {
    loadUser.run(pageQuery);
    message.success('移除用户成功');
  }
})

// 删除用户
const deleteUser = (id: number) => {
  Modal.confirm({
    title: '你确认删除当前用户吗?',
    icon: <ExclamationCircleFilled />,
    content: '删除用户会导致无法登录和操作任务',
    okText: '确认',
    okType: 'danger',
    cancelText: '取消',
    onOk() {
      loadRemoveUser.run(id)
    },
    onCancel() {},
  });
}

最后在给删除按钮添加点击事件,并将用户的 ID 传给接口。

<Button type="link" danger onClick={() => deleteUser(record.id)}>删除</Button>

四. 结束语

这篇文章我们介绍了如何利用 antd 提供的组件,快速开发一个 CRUD 功能的管理模块,相信大家可以从中收获很多东西了;下一篇文章我们将介绍执行器管理的模块开发。

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

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

相关文章

cpu到达100%问题排查

0、背景 首先定位到mysql 的cpu使用率较高 原因是任务域的作业实例补偿定时任务相关sql查询问题&#xff0c;该sql 2min执行一次&#xff0c;一次查询两次&#xff0c;导致cpu飙升&#xff0c;可考虑优化sql&#xff0c;添加以下索引 ALTER TABLE scheduler.tbl_simba_os_sc…

Linux编辑器之vim的使用

文章目录 一、vim简介二、vim的基本概念三、vim的基本操作四、vim正常模式命令集移动光标删除文字复制替换撤销上一次操作更改跳至指定的行vim末行模式命令集列出行号跳到文件中的某一行查找字符保存文件离开vim 五、进阶vim玩法打开文件批量注释代码执行shell命令指定注释窗口…

Excel中将16进制数转化成10进制(有/无符号)

Excel中将16进制数转化成10进制&#xff08;有/无符号&#xff09; Excel或者matlab中常用XXX2XXX进行不同进制的转换 16进制转10进制&#xff08;无符号数&#xff09;&#xff1a;HEX2DEC 16进制转10进制&#xff08;有符号数&#xff09;&#xff1a; FA46为例&#xff0c…

AWS 专题学习 P16 (Disaster Recovery Migrations)

文章目录 专题总览Disaster Recovery Overview1. RPO and RTO2. Disaster Recovery Strategies3. Backup & Restore&#xff08;High RPO&#xff09;4. Disaster Recovery – Pilot Light (试点灯)5. Warm Standby&#xff08;暖待命&#xff09;6. Multi Site / Hot Site…

Linux进程间通信(IPC)机制之一:共享内存

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Nonsense—Sabrina Carpenter 0:50━━━━━━️&#x1f49f;──────── 2:43 &#x1f504; ◀️ ⏸ ▶️ …

2024年【危险化学品经营单位安全管理人员】考试内容及危险化学品经营单位安全管理人员模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【危险化学品经营单位安全管理人员】考试内容及危险化学品经营单位安全管理人员模拟考试&#xff0c;包含危险化学品经营单位安全管理人员考试内容答案和解析及危险化学品经营单位安全管理人员模拟考试练习。安…

如何提高思维能力,洞悉事物本质?(一)

什么是思维模型&#xff08;Mental Model&#xff09;&#xff1f; 你可能会在不少文章、培训课里面&#xff0c;看到这个名字。它们往往会用复杂的词汇和概念&#xff0c;通常还会扯上一些名人&#xff0c;把它包装得高深莫测。 但实际上&#xff0c;思维模型究竟是什么呢&…

照明灯具哪个品牌好知乎?质量最好的护眼台灯排行榜

台灯是家中必不可少的用品之一&#xff0c;它不仅能够提供基础的照明功能&#xff0c;还能营造出不一样的风格和氛围&#xff0c;影响人们的心情和生活品质。而一台好的护眼台灯还能够呵护我们的眼睛&#xff0c;保护好视力健康。想拥有一台使用体验感又好&#xff0c;寿命又长…

故障诊断 | 一文解决,SVM支持向量机的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | 一文解决,SVM支持向量机的故障诊断(Matlab) 支持向量机(Support Vector Machine,SVM)是一种常用的监督学习算法,用于分类和回归分析。SVM的主要目标是找到一个最优的超平面(或者在非线性情况下是一个最优的超曲面),将不同类别的样本分开…

Vue3中ElementPlus组件二次封装,实现原组件属性、插槽、事件监听、方法的透传

本文以el-input组件为例&#xff0c;其它组件类似用法。 一、解决数据绑定问题 封装组件的第一步&#xff0c;要解决的就是数据绑定的问题&#xff0c;由于prop数据流是单向传递的&#xff0c;数据只能从父流向子&#xff0c;子想改父只能通过提交emit事件通知父修改。 父&a…

【JavaEE】网络原理:UDP数据报套接字编程和TCP流套接字编程

目录 1.UDP数据报套接字编程 1.1 DatagramSocket 1.2 DatagramPacket 1.3 InetSocketAddress 1.4 基于UDP实现回响服务器 2.TCP流套接字编程 2.1 ServerSocket 2.2 Socket 2.3 基于TCP实现回响服务器 1.UDP数据报套接字编程 API 介绍 1.1 DatagramSocket DatagramS…

Transformer 自然语言处理(三)

原文&#xff1a;Natural Language Processing with Transformers 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 第八章&#xff1a;使 transformers 在生产中更高效 在之前的章节中&#xff0c;您已经看到了 transformers 如何被微调以在各种任务上产生出色的结果。…

[机器学习]TF-IDF算法

一.TF-IDF算法概述 什么是TF-IDF&#xff1f; 词频-逆文档频率&#xff08;Term Frequency-Inverse Document Frequency&#xff0c;TF-IDF&#xff09;是一种常用于文本处理的统计方法&#xff0c;可以评估一个单词在一份文档中的重要程度。简单来说就是可以用于文档关键词的提…

k8s 1.29 一键安装脚本, 丝滑致极

博客原文 文章目录 集群配置配置清单集群规划集群网络规划 环境初始化主机配置 安装脚本需要魔法的脚本不需要魔法的脚本配置自动补全加入其余节点 验证集群 高可用版本: 高可用 k8s 1.29 一键安装脚本 集群配置 配置清单 OS&#xff1a; ubuntu 20.04kubernetes&#xff1a;…

“国潮风”带火年货消费,新中式服装在抖音电商销量同比增长超21倍

1月31日&#xff0c;抖音电商发布“抖音商城好物年货节”数据报告&#xff0c;展现龙年春节年货市场消费趋势及大众购买偏好。数据显示&#xff0c;1月13日至28日&#xff0c;货架场抖音商城日均GMV比去年年货节增长了98%&#xff0c;年货节电商直播累计时长达4385万小时&#…

Next.js如何正确处理跨域问题?

以前一直使用Vue来写前端。去年下半年接手了一个基于React Next.js的项目&#xff0c;于是顺带学习了一下Next.js。由于Next.js的特点&#xff0c;这个项目的前后端是放在一起的。一开始没什么问题&#xff0c;看了半天文档就上手了。 上周我们需要在另一个网页项目中&#x…

添加了gateway之后远程调用失败

前端提示500&#xff0c;后端提示[400 ] during [GET] to [http://userservice/user/1] 原因是这个&#xff0c;因为在请求地址写了两个参数&#xff0c;实际上只传了一个参数 解决方案&#xff1a;加上(required false)并重启所有相关服务

单元/集成测试服务

服务概述 单元/集成测试旨在证明被测软件实现其单元/架构设计规范、证明被测软件不包含非预期功能。经纬恒润测试团队拥有丰富的研发经验、严格的流程管控&#xff0c;依据ISO26262/ASPICE等开展符合要求的单元测试/集成测试工作。 在ISO 26262 - part6 部分产品开发&#xff…

最全前端 HTML 面试知识点

一、HTML 1.1 HTML 1.1.1 定义 超文本标记语言&#xff08;英语&#xff1a;HyperTextMarkupLanguage&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言 HTML元素是构建网站的基石 标记语言&#xff08;markup language &#xff09; 由无数个…

解读4篇混合类型文件Polyglot相关的论文

0. 引入 Polyglot文件指的是混合类型文件&#xff0c;关于混合类型文件的基础&#xff0c;请参考文末给出的第一个链接&#xff08;参考1&#xff09;。 1. Toward the Detection of Polyglot Files 1.1 主题 这篇2022年的论文&#xff0c;提出了Polyglot文件的检测方法。虽…