字玩FontPlayer开发笔记7 Tauri2动态切换菜单enbaled状态

news2025/1/7 20:45:55

字玩FontPlayer开发笔记7 Tauri2动态切换菜单enbaled状态

字玩FontPlayer是笔者开源的一款字体设计工具,使用Vue3 + ElementUI开发,源代码:
github: https://github.com/HiToysMaker/fontplayer
gitee: https://gitee.com/toysmaker/fontplayer

笔记

字玩目前是用Electron进行桌面端应用打包,但是性能体验不太好,一直想替换成Tauri。Tauri的功能和Electron类似,都可以把前端代码打包生成桌面端(比如Windows和Mac)应用。Tauri只使用系统提供的WebView,不像Electron一样内置Chromium和Node.js,性能体验更佳。

前两天初步完成了Tauri配置和菜单设置,今天继续将原有Electron代码替换成Tauri。在字玩的设计中,菜单按钮的enbaled状态需要动态切换,比如导出图片只有在编辑模式下才能点击,在列表状态下是禁用的状态。原有基本逻辑是,在前端使用一个ref变量editStatus记录状态,使用watch监听editStatus改变,每当editStatus改变时,给Electron端发送消息,Electron端监听到消息后,根据设定好的规则更新菜单状态。虽然只是一个小功能,但是由于笔者对Rust和Tauri的生疏,还是费了不少功夫,在此记录一下。

定义禁用规则

在Rust端,对每个菜单按钮定义禁用规则,传入参数是前端发送过来的edit_status,根据不同的edit_status状态定义禁用规则。关于如何监听前端消息在下面会具体说明。

fn enable(edit_status: &str) -> bool {
  true
}

fn enable_at_edit(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" => true,
    _ => false,
  }
}

fn enable_at_list(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" | "pic" => false,
    _ => true,
  }
}

fn template_enable(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" | "pic" => false,
    _ => true,
  }
}

// 定义用于启用/禁用菜单项的映射
fn build_menu_enabled_map() -> HashMap<String, Box<dyn Fn(&str) -> bool>> {
  let menu_enabled_map: HashMap<String, Box<dyn Fn(&str) -> bool>> = HashMap::from([
    ("about".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("create-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("open-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("save-file".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("save-as".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("undo".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("redo".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("cut".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("copy".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("paste".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("delete".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("import-font-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("import-glyphs".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("import-pic".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("import-svg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-font-file".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("export-glyphs".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("export-jpeg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-png".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-svg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("add-character".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("add-icon".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("font-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("preference-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("language-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("template-1".to_string(), Box::new(template_enable) as Box<dyn Fn(&str) -> bool>),
    ("remove-overlap".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
  ]);
  menu_enabled_map
}
定义更新菜单状态方法

接下来定义更新菜单的方法,以供前端调用:

#[tauri::command]
fn toggle_menu_disabled(app: AppHandle, edit_status: String) {
  let map = build_menu_enabled_map();
  let window = app.get_webview_window("main").unwrap();
  let menu = window.menu().unwrap();
  for submenu in menu.items().unwrap() {
    match submenu {
      // 如果是 Submenu 类型,调用 items() 获取子菜单项
      MenuItemKind::Submenu(submenu) => {
        // 获取并遍历子菜单中的菜单项
        for item in submenu.items().unwrap() {
          match item {
            MenuItemKind::MenuItem(item) => {
              let id: String = item.id().0.clone();
              let status: String = edit_status.clone();
              let enabled: bool = map.get(&id).expect("Error")(&status);
              item.set_enabled(enabled);
            }
      
            _ => {
              // 如果是其他未处理的类型,使用 `_` 捕获
            }
          }
        }
      }

      _ => {
        // 如果是其他未处理的类型,使用 `_` 捕获
      }
    }
  }
}

另外需要设置invoke_handler注册函数,这样前端才能调用:

.invoke_handler(tauri::generate_handler![toggle_menu_disabled])
前端调用Rust toggle_menu_disabled方法

在前端,监听editStatus变化,每当editStatus改变时,更新菜单enbaled状态。

const editStatusToString = (status: Status) => {
	if (editStatus.value === Status.Edit) {
		return 'edit'
	} else if (editStatus.value === Status.Glyph) {
		return 'glyph'
	} else if (editStatus.value === Status.Pic) {
		return 'pic'
	}
	return 'list'
}

watch(editStatus, () => {
	invoke('toggle_menu_disabled', { editStatus: editStatusToString(editStatus.value) });
})
附完整Rust端代码

src-tauri/lib.rs

#![allow(unused)]

use tauri::{Manager, Window};
use tauri::Size;
use tauri::{AppHandle, Emitter};
use tauri::menu::{Menu, MenuItem, PredefinedMenuItem, Submenu, MenuItemBuilder, MenuItemKind};
use std::collections::HashMap;

#[tauri::command]
fn test(app: AppHandle) {
  app.emit("create-file", ()).unwrap();
}

fn enable(edit_status: &str) -> bool {
  true
}

fn enable_at_edit(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" => true,
    _ => false,
  }
}

fn enable_at_list(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" | "pic" => false,
    _ => true,
  }
}

fn template_enable(edit_status: &str) -> bool {
  match edit_status {
    "edit" | "glyph" | "pic" => false,
    _ => true,
  }
}

// 定义用于启用/禁用菜单项的映射
fn build_menu_enabled_map() -> HashMap<String, Box<dyn Fn(&str) -> bool>> {
  let menu_enabled_map: HashMap<String, Box<dyn Fn(&str) -> bool>> = HashMap::from([
    ("about".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("create-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("open-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("save-file".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("save-as".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("undo".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("redo".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("cut".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("copy".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("paste".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("delete".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("import-font-file".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("import-glyphs".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("import-pic".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("import-svg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-font-file".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("export-glyphs".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("export-jpeg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-png".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("export-svg".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
    ("add-character".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("add-icon".to_string(), Box::new(enable_at_list) as Box<dyn Fn(&str) -> bool>),
    ("font-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("preference-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("language-settings".to_string(), Box::new(enable) as Box<dyn Fn(&str) -> bool>),
    ("template-1".to_string(), Box::new(template_enable) as Box<dyn Fn(&str) -> bool>),
    ("remove-overlap".to_string(), Box::new(enable_at_edit) as Box<dyn Fn(&str) -> bool>),
  ]);
  menu_enabled_map
}

#[tauri::command]
fn toggle_menu_disabled(app: AppHandle, edit_status: String) {
  let map = build_menu_enabled_map();
  let window = app.get_webview_window("main").unwrap();
  let menu = window.menu().unwrap();
  for submenu in menu.items().unwrap() {
    match submenu {
      // 如果是 Submenu 类型,调用 items() 获取子菜单项
      MenuItemKind::Submenu(submenu) => {
        // 获取并遍历子菜单中的菜单项
        for item in submenu.items().unwrap() {
          match item {
            MenuItemKind::MenuItem(item) => {
              let id: String = item.id().0.clone();
              let status: String = edit_status.clone();
              let enabled: bool = map.get(&id).expect("Error")(&status);
              item.set_enabled(enabled);
            }
      
            _ => {
              // 如果是其他未处理的类型,使用 `_` 捕获
            }
          }
        }
      }

      _ => {
        // 如果是其他未处理的类型,使用 `_` 捕获
      }
    }
  }
}

#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
  tauri::Builder::default()
    .setup(|app| {
      // 获取名为 "main" 的 Webview 窗口句柄
      let window = app.get_webview_window("main").unwrap();

      // 获取窗口尺寸
      let primary_display = window.inner_size().unwrap();
      let screen_width = primary_display.width;
      let screen_height = primary_display.height;

      // 获取主显示器的 DPI 缩放因子
      let scale_factor = window.scale_factor().unwrap();

      // 设置最大窗口尺寸
      let max_width = 1280;
      let max_height = 800;

      // 根据 DPI 缩放因子调整窗口尺寸
      let adjusted_width = (max_width as f64 * scale_factor) as u32;
      let adjusted_height = (max_height as f64 * scale_factor) as u32;

      // 计算窗口大小,确保窗口大小不超过屏幕大小
      let window_width = screen_width.min(adjusted_width);
      let window_height = screen_height.min(adjusted_height);

      // 获取窗口并设置尺寸
      window.set_size(Size::new(tauri::PhysicalSize::new(window_width as u32, window_height as u32))).unwrap();

      app.on_menu_event(move |app, event| {
        if event.id() == "about" {
          println!("about");
        } else if event.id() == "create-file" {
          test(app.app_handle().clone())
        }
      });

      if cfg!(debug_assertions) {
        app.handle().plugin(
          tauri_plugin_log::Builder::default()
            .level(log::LevelFilter::Info)
            .build(),
        )?;
      }
      Ok(())
    })
    .menu(|handle| Menu::with_items(handle, &[
      &Submenu::with_items(
        handle,
        "File",
        true,
        &[
          &MenuItemBuilder::with_id("about", "关于").build(handle).expect("Error")
        ],
      )?,
      &Submenu::with_items(
        handle,
        "文件",
        true,
        &[
          &MenuItemBuilder::with_id("create-file", "新建工程").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("open-file", "打开工程").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("save-file", "保存工程").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("save-as", "另存为").build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "编辑",
        true,
        &[
          &MenuItemBuilder::with_id("undo", "撤销").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("redo", "重做").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("cut", "剪切").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("paste", "粘贴").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("copy", "复制").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("delete", "删除").enabled(false).build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "导入",
        true,
        &[
          &MenuItemBuilder::with_id("import-font-file", "导入字体库").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("import-glyphs", "导入字形").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("import-pic", "识别图片").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("import-svg", "导入SVG").enabled(false).build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "导出",
        true,
        &[
          &MenuItemBuilder::with_id("export-font-file", "导出字体库").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("export-glyphs", "导出字形").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("export-jpeg", "导出JPEG").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("export-png", "导出PNG").enabled(false).build(handle).expect("Error"),
          &MenuItemBuilder::with_id("export-svg", "导出SVG").enabled(false).build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "字符与图标",
        true,
        &[
          &MenuItemBuilder::with_id("add-character", "添加字符").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("add-icon", "添加图标").build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "设置",
        true,
        &[
          &MenuItemBuilder::with_id("font-settings", "字体设置").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("preference-settings", "偏好设置").build(handle).expect("Error"),
          &MenuItemBuilder::with_id("language-settings", "语言设置").build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "模板",
        true,
        &[
          &MenuItemBuilder::with_id("template-1", "测试模板").build(handle).expect("Error"),
        ],
      )?,
      &Submenu::with_items(
        handle,
        "工具",
        true,
        &[
          &MenuItemBuilder::with_id("remove-overlap", "去除重叠").enabled(false).build(handle).expect("Error"),
        ],
      )?,
    ]))
    .invoke_handler(tauri::generate_handler![toggle_menu_disabled])
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

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

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

相关文章

如何配置【Docker镜像】加速器+【Docker镜像】的使用

一、配置Docker镜像加速器 1. 安装/升级容器引擎客户端​ 推荐安装1.11.2以上版本的容器引擎客户端 2. 配置镜像加速器​ 针对容器引擎客户端版本大于1.11.2的用户 以root用户登录容器引擎所在的虚拟机 修改 "/etc/docker/daemon.json" 文件&#xff08;如果没有…

Docker- Unable to find image “hello-world“locally

Docker- Unable to find image “hello-world“locally 文章目录 Docker- Unable to find image “hello-world“locally问题描述一. 切换镜像1. 编辑镜像源2. 切换镜像内容 二、 检查设置1、 重启dockers2、 检查配置是否生效3. Docker镜像源检查4. Dokcer执行测试 三、自定义…

go项目zero框架中用gentool解决指定MYSQL表生成结构体被覆盖的解决方案

在使用 GoZero 框架进行项目开发时&#xff0c;gentool 是一个非常方便的工具&#xff0c;它可以根据数据库表结构自动生成 Go 语言结构体和其他相关文件。然而&#xff0c;在使用 gentool 生成结构体时&#xff0c;可能会遇到一个问题&#xff1a;如果多次运行 gentool&#x…

深入Android架构(从线程到AIDL)_11 线程之间的通信架构

目录 5、 线程之间的通信架构 认识Looper与Handler对象 主线程丢信息给自己 子线程丢信息给主线程 替子线程诞生Looper与MQ 5、 线程之间的通信架构 认识Looper与Handler对象 当主线程诞生时&#xff0c;就会去执行一个代码循环(Looper)&#xff0c;以便持续监视它的信息…

今日自动化编辑部今日自动化杂志社2024年第19期部分目录

智能控制技术 无人机视觉支持下的输电线路安全距离巡检系统探究 贺凌飞 王骋昊1-2,36 基于虚拟现实技术的安全警示系统设计 黄奇 李光辉 徐奎 许兆辉3-5 火焰自动焊接技术对泄漏率的影响研究 孙天鸽5-7 PLC在闸门自动化控制系统中的应用 黎芳8-9,23 智能控制算法在二次供水系统…

【双层模型】考虑供需双侧的综合能源双层优化模型

目录 主要内容 内容研究 1.模型简介 2 程序释义 部分代码 运行结果 下载链接 主要内容 该程序实现一个综合能源系统的优化调度双层模型&#xff0c;上下层分别采用差分进化算法和规划算法进行求解。模型考虑了多种能源设备&#xff0c;包括燃气轮机、燃气锅炉、风电…

单片机-串转并-74HC595芯片

1、74HC595芯片介绍 74HC595 是一个 8 位串行输入、并行输出的位移缓存器&#xff0c;其中并行输出为三态输出&#xff08;即高电平、低电平和高阻抗&#xff09;。 15 和 1 到 7 脚 QA--QH&#xff1a;并行数据输出 9 脚 QH 非&#xff1a;串行数据输出 10 脚 SCLK 非&#x…

(框架漏洞)

1.Thinkphp 1.Thinkphp5x远程命令执⾏及getshell 搭建靶场环境 vulhub/thinkphp/5-rce docker-compose up -d #启动环境 ?sindex/think\app/invokefunction&functioncall_user_func_array&vars[0]system&vars[1][]whoami ?s/Index/\think\app/invokefunctio…

[SMARTFORMS] 输出文本变量绑定

在SMARTFORMS表单中的表格接口的"导入"页签处添加导入参数IV_EBELN 参数IV_EBELN为采购凭证编号&#xff0c;并为该参数添加默认值 在SMARTFORMS表单中的全局定义中的"全局数据"页签定义变量 结构ZSPO_HEADER_437、ZSPO_ITEM_437与表类型ZTPO_ITEM_437的定…

【DevOps】Jenkins部署

Jenkins部署 文章目录 Jenkins部署资源列表基础环境一、部署Gilab1.1、安装Gitlab1.2、修改配置文件1.3、加载配置文件1.4、访问Gitlab1.5、修改root登录密码1.6、创建demo测试项目1.7、上传代码1.8、验证上传的代码 二、部署Jenkins所需软件2.1、部署JDK2.2、部署Tomcat2.3、部…

Redis(二)value 的五种常见数据类型简述

目录 一、string&#xff08;字符串&#xff09; 1、raw 2、int 3、embstr 二、hash&#xff08;哈希表&#xff09; 1、hashtable 2、ziplist 三、list&#xff08;列表&#xff09; ​编辑 1、linkedlist 2、ziplist 3、quicklist&#xff08;redis 3.2后的列表内…

PyQt实战——将pcm文本数据转换成.pcm的二进制文件

系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序入口QMainWindow&#xff08;三&…

Word2Vec解读

Word2Vec: 一种词向量的训练方法 简单地讲&#xff0c;Word2Vec是建模了一个单词预测的任务&#xff0c;通过这个任务来学习词向量。假设有这样一句话Pineapples are spiked and yellow&#xff0c;现在假设spiked这个单词被删掉了&#xff0c;现在要预测这个位置原本的单词是…

STM32F1学习——编码器接口

一、编码器接口 编码器接口可以接收正交编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;通过硬件自动控制CNT值的自增或自减&#xff0c;从而指出编码器的位置、旋转方向和旋转速度。 每个高级定时器和通用定时器都有一个编码器接口&#xff0c;他们会占…

什么是网关路由

1.认识网关 网关&#xff08;Gateway&#xff09;和路由&#xff08;Router&#xff09;是两个相关但不同的概念。 一、网关&#xff08;Gateway&#xff09; 定义 网关是一个网络节点&#xff0c;它充当了不同网络之间的连接点。可以将其看作是一个网络的 “大门”&#xf…

S32K144 UDSdoCAN 升级刷写实现笔记

文章目录 1. 摘要2. 开发环境搭建2.1 开发板2.2 IDE 安装2.3 更新扩展包2.4 烧录仿真测试2.4.1 新建工程2.4.2 导入已有工程2.4.3 编译工程2.4.4 硬件连接2.4.5 Debug2.4.6 添加 .c .h 文件2.5 串口配置2.5.1 时钟2.5.2 GPIO2.5.3 定时器2.5.4 uart 工程2.5.5 烧录验证3. 升级原…

第十八周:Faster R-CNN论文阅读

Faster R-CNN论文阅读 摘要Abstract文章简介1. 引言2. Faster R-CNN 框架2.1 RPN2.2 损失函数2.3 RPN的训练细节 3. Faster R-CNN的训练4. 优缺点分析总结 摘要 本篇博客介绍了 Faster R-CNN&#xff0c;这是一种双阶段的目标检测网络&#xff0c;是对 Fast R-CNN 的改进。为了…

Day28下 - 大模型微调:酒店评论情感分析

一、前置准备 1. 下载 LLaMA Factory https://github.com/hiyouga/LLaMA-Factory.git 搭建过程详见&#xff1a;https://blog.csdn.net/CSBLOG/article/details/144584581 2. 选择 预训练模型 和 prompt指令模型 预训练阶段在实际工作中&#xff0c;一般是用不上的&#xff…

【网络安全 | 漏洞挖掘】JS Review + GraphQL滥用实现管理面板访问

未经许可,不得转载。 正文 在映射目标范围后,我发现了一个用于管理的控制台界面,但没有注册功能。 于是我开始尝试: 1、模糊测试注册端点 -> 失败 2、在请求中将登录替换为注册 -> 再次失败 尝试均未奏效后,我决定冷静下来,重新思考方法并利用技术手段。 我观察…

数据库管理-第278期 开年综艺,第七届中国PG数据库生态大会有感(20250105)

数据库管理278期 20245-01-05 数据库管理-第278期 开年综艺&#xff0c;第七届中国PG数据库生态大会有感&#xff08;20250105&#xff09;1 走后门的可观测性2 社区VS商业3 从O来到PG去4 现场集锦5 IF CLUB社区总结 数据库管理-第278期 开年综艺&#xff0c;第七届中国PG数据库…