go-zero整合Excelize并实现Excel导入导出

go-zero整合Excelize并实现Excel导入导出

本教程基于go-zero微服务入门教程,项目工程结构同上一个教程。

本教程主要实现go-zero框架整合Excelize,并暴露接口实现Excel模板下载、Excel导入、Excel导出。

go-zero微服务入门教程:https://blog.csdn.net/u011019141/article/details/136233473

本文源码:https://gitee.com/songfayuan/go-zero-demo (教程源码分支:6.zero整合Excelize操作Excel)

准备工作

  • 如不熟悉go-zero项目的,请先查看上一篇go-zero微服务入门教程

安装依赖

Excelize官方文档

项目工程父级目录下执行如下指令安装依赖:

# 下载安装Excelize
go get github.com/xuri/excelize/v2

编写API Gateway代码

编写api文件

excel.api

在api目录下创建新目录doc/excel,在excel目录下创建excel.api文件。

syntax = "v1"

info(
    title: "excel操作相关"
    desc: "excel操作相关"
    author: "宋发元"
)

type (
    ExcelImportReq {
        DeptId string `json:"deptId"`            // 部门id(Content-Type: form-data)
        File interface{} `json:"file,optional"`  // excel文件(Content-Type: form-data)
    }

    ExcelImportData {
        Total int64 `json:"total"`      // 导入总数
        Success int64 `json:"success"`  // 导入成功数
        Msg string `json:"msg"`         // 提示信息
    }

    ExcelImportResp {
        Code int64 `json:"code"`
        Message string `json:"message"`
        Data ExcelImportData `json:"data"`
    }

    ExcelExportlReq{
        TimeStart string `form:"timeStart,optional"`                      // 时间(开始) yyyy-mm-dd
        TimeEnd   string `form:"timeEnd,optional"`                        // 时间(结束) yyyy-mm-dd
    }

    DefaultResponse {
        Code    int64  `json:"code,default=200"`
        Message string `json:"message,default=操作成功"`
    }
)


@server(
    group : excel/test
    prefix : /excel/test
)

service admin-api {
    @doc (
        summary :"excel模板下载"
    )
    @handler ExcelTemplateDownload
    get /excel/templateDownload

    @doc(
        summary :"excel导入"
    )
    @handler ExcelImport
    post /excel/excelImport (ExcelImportReq) returns (ExcelImportResp)

    @doc(
        summary :"excel导出"
    )
    @handler ExcelExport
    get /excel/excelExport (ExcelExportlReq)returns (DefaultResponse)
}
admin.api

在api/doc/admin.api文件添加配置信息。

import "excel/excel.api"

用goctl生成API Gateway代码

生成方法同上篇文章,自行查看。但是此处要基于admin.api文件去生成代码,如果基于excel.api生成,则生成的代码只有excel.api定义的接口代码,其他api文件定义的接口代码不被生成。

api新增文件操作配置

以下操作在api模块执行。

admin-api.yaml

admin-api.yaml配置文件新增文件操作配置信息,如下:

#文件
UploadFile:
  MaxFileNum: 100
  MaxFileSize: 104857600  # 100MB
  SavePath: template/uploads/
  TemplatePath: template/excel/

config.go

config.go文件中新增UploadFile配置信息,如下:

type Config struct {
	rest.RestConf

	SysRpc zrpc.RpcClientConf

  //这里新增
	UploadFile UploadFile
}

type UploadFile struct {
	MaxFileNum   int64
	MaxFileSize  int64
	SavePath     string
	TemplatePath string
}

修改API Gateway代码

exceltemplatedownloadlogic.go

修改api/internal/logic/excel/test/exceltemplatedownloadlogic.go里的ExcelTemplateDownload方法,完整代码如下:

package test

import (
	"context"
	"go-zero-demo/common/errors/errorx"
	"net/http"
	"os"

	"github.com/zeromicro/go-zero/core/logx"
	"go-zero-demo/api/internal/svc"
)

type ExcelTemplateDownloadLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	writer http.ResponseWriter
}

func NewExcelTemplateDownloadLogic(ctx context.Context, svcCtx *svc.ServiceContext, writer http.ResponseWriter) *ExcelTemplateDownloadLogic {
	return &ExcelTemplateDownloadLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		writer: writer,
	}
}

func (l *ExcelTemplateDownloadLogic) ExcelTemplateDownload() (err error) {
	SavePath := l.svcCtx.Config.UploadFile.TemplatePath
	filePath := "demo_excel_template.xlsx"

	fullPath := SavePath + filePath
	fileName := "Excel导入模板.xlsx"

	//fullPath = "/Users/songfayuan/GolandProjects/go-zero-demo/template/excel/demo_excel_template.xlsx"  //测试地址,绝对路径
	_, err = os.Stat(fullPath)
	if err != nil || os.IsNotExist(err) {
		return errorx.New("文件不存在")
	}
	bytes, err := os.ReadFile(fullPath)
	if err != nil {
		return errorx.New("读取文件失败")
	}

	l.writer.Header().Add("Content-Type", "application/octet-stream")
	l.writer.Header().Add("Content-Disposition", "attachment; filename= "+fileName)
	l.writer.Write(bytes)

	return
}

excelimportlogic.go

修改api/internal/logic/excel/test/excelimportlogic.go里的ExcelImport方法,完整代码如下:

package test

import (
	"context"
	"fmt"
	"github.com/xuri/excelize/v2"
	"github.com/zeromicro/go-zero/core/mapping"
	"go-zero-demo/common/errors/errorx"
	"go-zero-demo/common/utils"
	"path/filepath"
	"strings"

	"go-zero-demo/api/internal/svc"
	"go-zero-demo/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type ExcelImportLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

type excelDataForDept struct {
	DeptId       string `json:"DeptId,optional" excel:"col=1"`       // 第1列:部门id
	ParentDeptId string `json:"ParentDeptId,optional" excel:"col=2"` // 第2列:上级部门id
	DeptName     string `json:"DeptName,optional" excel:"col=3"`     // 第3列:部门名称
	Level        string `json:"Level,optional" excel:"col=4"`        // 第4列:部门等级(分级名称)
}

type excelDataForMember struct {
	DeptId  string `json:"DeptId,optional" excel:"col=1"`  // 第1列:部门
	Name    string `json:"Name,optional" excel:"col=2"`    // 第2列:姓名
	Account string `json:"Account,optional" excel:"col=3"` // 第3列:帐号
	Level   string `json:"Level,optional" excel:"col=4"`   // 第4列:等级(分级名称)
	IpAddr  string `json:"IpAddr,optional" excel:"col=5"`  // 第5列:IP
	MacAddr string `json:"MacAddr,optional" excel:"col=6"` // 第6列:MAC
}

var (
	validUploadFileExt = map[string]any{
		".xlsx": nil,
		".xls":  nil,
	}
)

func NewExcelImportLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ExcelImportLogic {
	return &ExcelImportLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *ExcelImportLogic) ExcelImport(req *types.ExcelUploadReq) (resp *types.ExcelImportResp, err error) {

	if _, ok := validUploadFileExt[strings.ToLower(filepath.Ext(req.File.FileHeader.Filename))]; !ok {
		return nil, errorx.New("无效的文件格式")
	}
	// 打开文件
	f, err := excelize.OpenReader(req.File.File)
	if err != nil {
		return nil, errorx.New("无效的文件")
	}

	/* 解析部门Sheet数据 start */
	// 解析文件参数
	var excelDept []excelDataForDept
	if excelDept, err = parseFileDept(f); err != nil {
		return
	}
	// format
	for _, i := range excelDept {
		fmt.Printf("Excel数据:%v/%v/%v/%v", i.DeptId, i.ParentDeptId, i.DeptName, i.Level)
	}
	/* 解析部门Sheet数据 end */

	/* 解析用户Sheet数据 start */
	// 解析文件参数
	var excelMember []excelDataForMember
	if excelMember, err = parseFileUser(f); err != nil {
		return
	}
	// format
	for _, i := range excelMember {
		fmt.Printf("Excel数据:%v/%v/%v/%v/%v/%v", i.DeptId, i.Name, i.Account, i.Level, i.IpAddr, i.MacAddr)
	}
	/* 解析用户Sheet数据 end */

	return &types.ExcelImportResp{
		Code:    200,
		Message: "导入成功",
		Data: types.ExcelImportData{
			Total:   10,
			Success: 10,
			Msg:     "成功",
		},
	}, nil
}

// 解析部门Sheet数据
func parseFileDept(f *excelize.File) ([]excelDataForDept, error) {

	// 解析参数(可选)
	excelOption := utils.ExcelOption{Sheet: "部门", StartRow: 2}

	// 映射回调
	all := make([]excelDataForDept, 0)
	cbHandler := func(data map[string]interface{}) error {
		temp := excelDataForDept{}
		err := mapping.UnmarshalJsonMap(data, &temp)
		if err != nil {
			return err
		}
		all = append(all, temp)
		return nil
	}

	// 映射
	if err := utils.ParseExcel(f, excelDataForDept{}, cbHandler, excelOption); err != nil {
		return nil, errorx.New("解析文件时出错:" + err.Error())
	}

	if len(all) == 0 {
		return nil, errorx.New("文件中无有效数据")
	}

	return all, nil
}

// 解析用户Sheet数据
func parseFileUser(f *excelize.File) ([]excelDataForMember, error) {
	// 解析参数(可选)
	excelOption := utils.ExcelOption{Sheet: "用户", StartRow: 2}

	// 映射回调
	all := make([]excelDataForMember, 0)
	cbHandler := func(data map[string]interface{}) error {
		temp := excelDataForMember{}
		err := mapping.UnmarshalJsonMap(data, &temp)
		if err != nil {
			return err
		}
		all = append(all, temp)
		return nil
	}

	// 映射
	if err := utils.ParseExcel(f, excelDataForMember{}, cbHandler, excelOption); err != nil {
		return nil, errorx.New("解析文件时出错:" + err.Error())
	}

	if len(all) == 0 {
		return nil, errorx.New("文件中无有效数据")
	}

	return all, nil
}

excelexportlogic.go

修改api/internal/logic/excel/test/excelexportlogic.go里的ExcelExport方法,完整代码如下:

package test

import (
	"context"
	"fmt"
	"github.com/xuri/excelize/v2"
	"net/http"

	"go-zero-demo/api/internal/svc"
	"go-zero-demo/api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type ExcelExportLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
	writer http.ResponseWriter
}

type cellValue struct {
	sheet string
	cell  string
	value string
}

func NewExcelExportLogic(ctx context.Context, svcCtx *svc.ServiceContext, writer http.ResponseWriter) *ExcelExportLogic {
	return &ExcelExportLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
		writer: writer,
	}
}

func (l *ExcelExportLogic) ExcelExport(req *types.ExcelExportlReq) (resp *types.DefaultResponse, err error) {
	//这里仅演示Excel导出逻辑,真实数据自己增加对应的查询逻辑。
	excelFile := excelize.NewFile()
	//insert title
	cellValues := make([]*cellValue, 0)
	cellValues = append(cellValues, &cellValue{
		sheet: "sheet1",
		cell:  "A1",
		value: "序号",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "B1",
		value: "IP地址",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "C1",
		value: "账号",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "D1",
		value: "姓名",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "E1",
		value: "最近访问时间",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "F1",
		value: "设备状态",
	}, &cellValue{
		sheet: "sheet1",
		cell:  "G1",
		value: "访问分级",
	})
	// 创建一个工作表
	index, _ := excelFile.NewSheet("Sheet1")
	// 设置工作簿的默认工作表
	excelFile.SetActiveSheet(index)
	//插入表格头
	for _, cellValue := range cellValues {
		excelFile.SetCellValue(cellValue.sheet, cellValue.cell, cellValue.value)
	}
	//设置表格头字体样式
	styleId, err := excelFile.NewStyle(&excelize.Style{
		Font: &excelize.Font{
			Bold:   true,  //黑体
			Italic: false, //倾斜
			Family: "宋体",
			Size:   14,
			//Color:  "微软雅黑",
		},
	})
	if err != nil {
		fmt.Println(err)
	}
	for _, data := range cellValues {
		excelFile.SetCellStyle(data.sheet, data.cell, data.cell, styleId)
	}
	excelFile.SetColWidth("sheet1", "B", "G", 20)

	cnt := 1
	for i := 0; i <= 6; i++ {
		cnt = cnt + 1
		for k1, v1 := range cellValues {
			switch k1 {
			case 0:
				v1.cell = fmt.Sprintf("A%d", cnt)
				v1.value = fmt.Sprintf("%d", i+1)
			case 1:
				v1.cell = fmt.Sprintf("B%d", cnt)
				v1.value = "1"
			case 2:
				v1.cell = fmt.Sprintf("C%d", cnt)
				v1.value = "2"
			case 3:
				v1.cell = fmt.Sprintf("D%d", cnt)
				v1.value = "3"
			case 4:
				v1.cell = fmt.Sprintf("E%d", cnt)
				v1.value = "4"
			case 5:
				v1.cell = fmt.Sprintf("F%d", cnt)
				v1.value = "5"
			case 6:
				v1.cell = fmt.Sprintf("G%d", cnt)
				v1.value = "6"
			}
		}
		for _, vc := range cellValues {
			excelFile.SetCellValue(vc.sheet, vc.cell, vc.value)
		}
	}
	fileName := "ABCD.xlsx"

	//如果是下载,则需要在Header中设置这两个参数
	l.writer.Header().Add("Content-Type", "application/octet-stream")
	l.writer.Header().Add("Content-Disposition", "attachment; filename= "+fileName)
	//l.writer.Header().Add("Content-Transfer-Encoding", "binary")
	excelFile.Write(l.writer)
	return
}

exceltemplatedownloadhandler.go

exceltemplatedownloadhandler.go代码微调整。

func ExcelTemplateDownloadHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		l := test.NewExcelTemplateDownloadLogic(r.Context(), svcCtx, w)
		err := l.ExcelTemplateDownload()
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.Ok(w)
		}
	}
}

excelimporthandler.go

excelimporthandler.go代码微调整。

func ExcelImportHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var req types.ExcelUploadReq
		req.DeptId = r.FormValue("deptId")
		f, fh, e := utils.ParseFile(r, "file")
		if e != nil {
			httpx.Error(w, e)
			return
		}
		req.File = &types.File{File: f, FileHeader: fh}

		l := test.NewExcelImportLogic(r.Context(), svcCtx)
		resp, err := l.ExcelImport(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJson(w, resp)
		}
	}
}

excelexporthandler.go

excelexporthandler.go代码微调整。

func ExcelExportHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		var req types.ExcelExportlReq
		if err := httpx.Parse(r, &req); err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
			return
		}

		l := test.NewExcelExportLogic(r.Context(), svcCtx, w)
		resp, err := l.ExcelExport(&req)
		if err != nil {
			httpx.ErrorCtx(r.Context(), w, err)
		} else {
			httpx.OkJsonCtx(r.Context(), w, resp)
		}
	}
}

base.go

在路径api/internal/types下创建base.go,内容如下:

package types

import "mime/multipart"

type File struct {
	File       multipart.File
	FileHeader *multipart.FileHeader
}

type ExcelUploadReq struct {
	DeptId string `json:"deptId"` // 部门id
	File   *File  `json:"file"`   // excel文件
}

Excel导入模板

在项目根目录下创建template/excel目录,里面存放Excel导入模板demo_excel_template.xlsx。

模板内容见源码!!!
在这里插入图片描述
在这里插入图片描述

完整调用演示

最后,在根目录go-zero-demo执行下命令。

go mod tidy

运行rpc服务

运行方法同上篇文章,具体查看教程go-zero微服务入门教程完整调用演示部分。

运行api

运行方法同上篇文章,具体查看教程go-zero微服务入门教程完整调用演示部分。

api调用

以下调用采用postman调用。

Excel模板下载
localhost:8888/excel/test/excel/templateDownload
Excel导入
localhost:8888/excel/test/excel/excelImport
Excel导出
localhost:8888/excel/test/excel/excelExport

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

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

相关文章

【深度学习】AI换脸,EasyPhoto: Your Personal AI Photo Generator【一】

论文&#xff1a;https://arxiv.org/abs/2310.04672 文章目录 摘要IntroductionTraining Process3 推理过程3.1 面部预处理3.3 第二扩散阶段3.4 多用户ID 4 任意ID5 实验6 结论 下篇文章进行实战。 摘要 稳定扩散Web UI&#xff08;Stable Diffusion Web UI&#xff0c;简称…

MYSQL八、MYSQL的SQL优化

一、SQL优化 sql优化是指&#xff1a;通过对sql语句和数据库结构的调整&#xff0c;来提高数据库查询、插入、更新和删除等操作的性能和效率。 1、插入数据优化 要一次性往数据库表中插入多条记录&#xff1a; insert into tb_test values(1,tom); insert into tb_tes…

CyberDAO:引领Web3时代的DAO社区文化

致力于Web3研究和孵化 CyberDAO自成立以来&#xff0c;致力于推动Web3研究和孵化&#xff0c;吸引了来自技术、资本、商业、应用与流量等领域的上千名热忱成员。我们为社区提供多元的Web3产品和商业机会&#xff0c;触达行业核心&#xff0c;助力成员捕获Web3.0时代的红利。 目…

远程链接服务 ssh

① 指定用户身份登录 ssh root10.36.105.100 ssh jim10.36.105.100 ② 不登陆远程执行命令 ssh root10.36.105.100 ls /opt ③ 远程拷贝 scp -r // 拷贝目录 -p // 指定端口 将本地文件拷贝给远程主机 scp -r /opt/test1 10.36.105.100:/tmp/// 将本…

Windows电脑清理C盘内存空间

ps&#xff1a;过程截图放在篇末 一、%tmp%文件 win R键呼出运行窗口&#xff0c;输入 %tmp% 自动进入tmp文件夹&#xff0c;ctrl A全选删除 遇到权限不足&#xff0c;正在运行&#xff0c;丢失的文件直接跳过即可 二、AppData文件夹 1、pipcache 在下列路径下面&…

小目标检测篇 | YOLOv8改进之空间上下文感知模块SCAM + 超轻量高效动态上采样DySample

前言:Hello大家好,我是小哥谈。小目标检测是计算机视觉领域中的一个研究方向,旨在从图像或视频中准确地检测和定位尺寸较小的目标物体。相比于常规目标检测任务,小目标检测更具挑战性,因为小目标通常具有低分辨率、低对比度和模糊等特点,容易被背景干扰或遮挡。本篇文章就…

Unity 实现WebSocket 简单通信——客户端

创建连接 ClientWebSocket socket new ClientWebSocket(); string url $"ws://{ip}:{port}"; bool createUri Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out Uri uri); if (createUri) {var task socket.ConnectAsync(uri, CancellationToken.None);task…

django学习入门系列之第二点《浏览器能识别的标签1》

文章目录 文件的编码(head)网站表头信息(head)标题&#xff08;body&#xff09;div和span往期回顾 文件的编码(head) <!--浏览器会以"UTF-8"这种编码来读取文件--> <meta charset"UTF-8">网站表头信息(head) <title>Title</title&…

Android帧绘制流程深度解析 (一)

Android帧绘制技术有很多基础的知识&#xff0c;比如多buffer、vsync信号作用等基础知识点很多笔记讲的已经很详细了&#xff0c;我也不必再去总结&#xff0c;所以此处不再过多赘述安卓帧绘制技术&#xff0c;基础知识这篇文章总结的很好&#xff0c;一文读懂"系列&#…

VBA即用型代码手册:删除空列Delete Empty Columns

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。可以大大提高自己的劳动效率&#xff0c;而且可以提高数据的准确性。我这里专注VBA,将我多年的经验汇集在VBA系列九套教程中。 作为我的学员要利用我的积木编程思想&#xff0c;积木编程最重要的是积木如何搭建…

细说ARM MCU的串口接收数据的实现过程

目录 一、硬件及工程 1、硬件 2、软件目的 3、创建.ioc工程 二、 代码修改 1、串口初始化函数MX_USART2_UART_Init() &#xff08;1&#xff09;MX_USART2_UART_Init()串口参数初始化函数 &#xff08;2&#xff09;HAL_UART_MspInit()串口功能模块初始化函数 2、串口…

爱奇艺视频怎么转换成mp4格式,爱奇艺qsv转换mp4最简单方法

在数字化时代&#xff0c;视频格式的转换成为了我们日常生活中常见的需求。特别是对于那些经常从各大视频平台下载视频的朋友来说&#xff0c;将特定格式的视频转换为更通用的格式&#xff0c;如MP4&#xff0c;变得尤为重要。其中&#xff0c;qsv格式的视频转换就是一项常见的…

C++|哈希结构封装unordered_set和unordered_map

上一篇章&#xff0c;学习了unordered系列容器的使用&#xff0c;以及哈希结构&#xff0c;那么这一篇章将通过哈希结构来封装unordered系列容器&#xff0c;来进一步的学习他们的使用以及理解为何是如此使用。其实&#xff0c;哈希表的封装方式和红黑树的封装方式形式上是差不…

极坐标下的牛拉法潮流计算9节点MATLAB程序

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 潮流计算&#xff1a; 潮流计算是根据给定的电网结构、参数和发电机、负荷等元件的运行条件&#xff0c;确定电力系统各部分稳态运行状态参数的计算。通常给定的运行条件有系统中各电源和负荷点的功率、枢纽…

Python | Leetcode Python题解之第145题二叉树的后序遍历

题目&#xff1a; 题解&#xff1a; class Solution:def postorderTraversal(self, root: TreeNode) -> List[int]:def addPath(node: TreeNode):count 0while node:count 1res.append(node.val)node node.righti, j len(res) - count, len(res) - 1while i < j:res…

vue2前置路由守卫中使用this.$store.state报错解决

1、问题描述&#xff1a;在前置路由守卫逻辑中&#xff0c;要更改vuex中的store的state状态&#xff0c;使用常规的this.$store.state报错 2、问题原因&#xff1a; 在vue2是vueRouter前置路由守卫中&#xff0c;this关键字并不会指向vue实例&#xff0c;因此不能使用this.$st…

【CHIP】LTC2991 读取温度电压电流 调试实例

文章目录 0. ENV1. LTC2991 数据说明1. 数据计算公式2. 寄存器概述1. 管脚使能寄存器2. 芯片使能寄存器 2. 软件实现1. 概述2. 源码(部分)3. 参考log 0. ENV 软件系统&#xff1a;略 LTC2991&#xff1a;VCC3.3 温度&#xff1a;温控接v1-v2 / v2-v3 / … (双端采样)电压&#…

【LLM】快速了解Dify 0.6.10的核心功能:知识库检索、Agent创建和工作流编排(二)

【LLM】快速了解Dify 0.6.10的核心功能&#xff1a;知识库检索、Agent创建和工作流编排&#xff08;二&#xff09; 文章目录 【LLM】快速了解Dify 0.6.10的核心功能&#xff1a;知识库检索、Agent创建和工作流编排&#xff08;二&#xff09;一、创建一个简单的聊天助手&#…

nmap工具使用

nmap是一款渗透端口扫描测试工具。它不单单可以进行端口扫描&#xff0c;还可以扫描漏洞、服务器信息等等。是一款十分强大的扫描工具&#xff0c;可以在windows、mac、Linux上运行。 下载 官网地址: https://nmap.org/download.html 我备份的地址:https://download.csdn.net…

[大模型]LLaMA3-8B-Instruct WebDemo 部署

环境准备 在 autodl 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch-->2.1.0-->3.10(ubuntu20.04)-->12.1 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行 demo。 pip 换源…