WPF实战学习笔记25-首页汇总
注意:本实现与视频不一致。本实现中单独做了汇总接口,而视频中则合并到国todo接口当中了。
- 添加汇总webapi接口
- 添加汇总数据客户端接口
- 总数据客户端接口对接3
- 首页数据模型
添加数据汇总字段类
新建文件MyToDo.Share.Models.SummaryDto
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace MyToDo.Share.Models
{public class SummaryDto:BaseDto{private int sum;public int Sum{get { return sum; }set { sum = value; OnPropertyChanged(); }}private int compeleteCnt;public int CompeleteCnt{get { return compeleteCnt; }set { compeleteCnt = value; OnPropertyChanged(); }}private int memoCnt;public int MemoCnt{get { return memoCnt; }set { memoCnt = value; OnPropertyChanged(); }}private string? compeleteRatio;public string? CompeleteRatio{get { return compeleteRatio; }set { compeleteRatio = value; OnPropertyChanged(); }}private ObservableCollection<ToDoDto> todoList;public ObservableCollection<ToDoDto> TodoList{get { return todoList; }set { todoList = value; }}/// <summary>/// MemoList/// </summary>private ObservableCollection<MemoDto> memoList;public ObservableCollection<MemoDto> MemoList{get { return memoList; }set { memoList = value; }}}
}
添加汇总webapi接口
添加汇总接口
添加文件:MyToDo.Api.Service.ISummary
using MyToDo.Share.Parameters;namespace MyToDo.Api.Service
{public interface ISummary{Task<ApiReponse> GetAllInfo(SummaryParameter parameter);}
}
实现汇总接口
添加文件:MyToDo.Api.Service.Summary
using Arch.EntityFrameworkCore.UnitOfWork;
using AutoMapper;
using MyToDo.Api.Context;
using MyToDo.Share.Models;
using MyToDo.Share.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.ObjectModel;namespace MyToDo.Api.Service
{public class Summary : ISummary{private readonly IUnitOfWork work;private readonly IMapper mapper;public Summary(IUnitOfWork work,IMapper mapper){this.work = work;this.mapper = mapper;}public async Task<ApiReponse> GetAllInfo(SummaryParameter parameter){try{SummaryDto sumdto = new SummaryDto();//获取所有todo信息var Pagetodos = await work.GetRepository<Todo>().GetPagedListAsync(pageIndex: parameter.PageIndex, pageSize: parameter.PageSize, orderBy: source => source.OrderByDescending(t => t.CreateDate));//获取所有memo信息var Pagememos = await work.GetRepository<Memo>().GetPagedListAsync(pageIndex: parameter.PageIndex, pageSize: parameter.PageSize, orderBy: source => source.OrderByDescending(t => t.CreateDate));//汇总待办数量sumdto.Sum = Pagetodos.TotalCount;//统计完成数量var todos = Pagetodos.Items;sumdto.CompeleteCnt = todos.Where(t => t.Status == 1).Count();//计算已完成比率sumdto.CompeleteRatio = (sumdto.CompeleteCnt / (double)sumdto.Sum).ToString("0%");//统计备忘录数量var memos = Pagememos.Items;sumdto.MemoCnt=Pagememos.TotalCount;//获取todos项目与memos项目集合sumdto.TodoList = new ObservableCollection<ToDoDto>(mapper.Map<List<ToDoDto>>(todos.Where(t => t.Status == 0)));sumdto.MemoList = new ObservableCollection<MemoDto>(mapper.Map<List<MemoDto>>(memos));return new ApiReponse(true, sumdto);}catch (Exception ex){return new ApiReponse(false, ex);}}}
}
添加控制器
添加文件MyToDo.Api.Controllers.SummaryController
using Microsoft.AspNetCore.Mvc;
using Microsoft.VisualBasic;
using MyToDo.Api.Service;
using MyToDo.Share.Models;
using MyToDo.Share.Parameters;namespace MyToDo.Api.Controllers
{[ApiController][Route("api/[controller]/[action]")]public class SummaryController:ControllerBase{private readonly ISummary service;public SummaryController(ISummary tService){this.service = tService;}[HttpGet]public async Task<ApiReponse> GetAllInfo([FromQuery] SummaryParameter parameter)=>await service.GetAllInfo(parameter);}
}
依赖注入
文件:webapi.Program.cs
添加:
builder.Services.AddTransient<ISummary, Summary>();
添加客户端数据接口
添加接口
新建文件:Mytodo.Service.ISummeryService.cs
using MyToDo.Share;
using MyToDo.Share.Contact;
using MyToDo.Share.Models;
using MyToDo.Share.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Mytodo.Service
{public interface ISummeryService{//public async Task<ApiResponse<SummaryDto>> GetAllInfo(SummaryParameter parameter)Task<ApiResponse<SummaryDto>> GetAllInfo(SummaryParameter parameter);}
}
实现接口
添加文件:Mytodo.Service.SummeryService
using MyToDo.Share;
using MyToDo.Share.Contact;
using MyToDo.Share.Models;
using MyToDo.Share.Parameters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace Mytodo.Service
{public class SummeryService : ISummeryService{private readonly HttpRestClient client;private readonly string ServiceName="Summary";public SummeryService(HttpRestClient client){this.client = client;}public async Task<ApiResponse<SummaryDto>> GetAllInfo(SummaryParameter parameter){BaseRequest request = new BaseRequest();request.Method = RestSharp.Method.GET;//如果查询字段为空request.Route = $"api/{ServiceName}/GetAllInfo?PageIndex={parameter.PageIndex}" + $"&PageSize={parameter.PageSize}";//request.Route = $"api/{ServiceName}/GetAll?PageIndex={parameter.PageIndex}" + $"&PageSize={parameter.PageSize}" + $"&search={parameter.Search}";return await client.ExecuteAsync<SummaryDto>(request);}}
}
依赖注入
修改文件App.xaml.cs 添加内容
containerRegistry.Register<ISummeryService, SummeryService>();
首页对接接口
修改UI层绑定
修改文件:Mytodo.Views.IndexView.xaml
由
ItemsSource="{Binding TodoDtos}"
ItemsSource="{Binding MemoDtos}"
修改为
ItemsSource="{Binding Summary.TodoList}"
ItemsSource="{Binding Summary.MemoList}"
新建summary实例,并初始化
修改文件:Mytodo.ViewModels.IndexViewModel.cs
public SummaryDto Summary
{get { return summary; }set { summary = value; RaisePropertyChanged(); }
}
private SummaryDto summary;
新建summary服务实例,并初始化
private readonly ISummeryService summService;
public IndexViewModel(IContainerProvider provider,IDialogHostService dialog) : base(provider)
{//实例化接口this.toDoService= provider.Resolve<ITodoService>();this.memoService = provider.Resolve<IMemoService>();this.summService= provider.Resolve<ISummeryService>();//初始化命令EditMemoCmd = new DelegateCommand<MemoDto>(Addmemo);EditTodoCmd = new DelegateCommand<ToDoDto>(Addtodo);ToDoCompltedCommand = new DelegateCommand<ToDoDto>(Compete);ExecuteCommand = new DelegateCommand<string>(Execute);this.dialog = dialog;CreatBars();
}
添加首页数据初始化函数
/// <summary>
/// 更新首页所有信息
/// </summary>
private async void UpdateData()
{UpdateLoding(true);var summaryResult = await summService.GetAllInfo(new SummaryParameter() { PageIndex = 0, PageSize = 1000 });if (summaryResult.Status){Summary = summaryResult.Result;Refresh();}UpdateLoding(false);
}
public override async void OnNavigatedTo(NavigationContext navigationContext)
{UpdateData();base.OnNavigatedTo(navigationContext);
}void Refresh()
{TaskBars[0].Content = summary.Sum.ToString();TaskBars[1].Content = summary.CompeleteCnt.ToString();TaskBars[2].Content = summary.CompeleteRatio;TaskBars[3].Content = summary.MemoCnt.ToString();
}
用summary的字段替换掉TodoDtos与MemoDtos
更新添加、编辑、完成命
修改后的代码为:
using Mytodo.Common.Models;
using MyToDo.Share.Parameters;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using MyToDo.Share.Models;
using Prism.Commands;
using Prism.Services.Dialogs;
using Mytodo.Dialog;
using Mytodo.ViewModels;
using Mytodo.Service;
using Prism.Ioc;
using System.Diagnostics;
using Microsoft.VisualBasic;
using ImTools;
using DryIoc;
using MyToDo.Share;
using System.Windows;
using Prism.Regions;namespace Mytodo.ViewModels
{public class IndexViewModel:NavigationViewModel{#region 定义命令/// <summary>/// Todo完成命令/// </summary>public DelegateCommand<ToDoDto> ToDoCompltedCommand { get; set; }public DelegateCommand<string> ExecuteCommand { get; set; }/// <summary>/// 命令:编辑备忘/// </summary>public DelegateCommand<MemoDto> EditMemoCmd { get;private set; }/// <summary>/// 命令:编辑待办/// </summary>public DelegateCommand<ToDoDto> EditTodoCmd { get; private set; }#endregion#region 定义属性public SummaryDto Summary{get { return summary; }set { summary = value; RaisePropertyChanged(); }}public string Title { get; set; }/// <summary>/// 首页任务条/// </summary>public ObservableCollection<TaskBar> TaskBars{get { return taskBars; }set { taskBars = value; RaisePropertyChanged(); }}#endregion#region 定义重要命令#endregion#region 定义重要字段private readonly IDialogHostService dialog;private readonly ITodoService toDoService;private readonly ISummeryService summService;private readonly IMemoService memoService;#endregion#region 定义普通字段private SummaryDto summary;private ObservableCollection<TaskBar> taskBars;#endregion#region 命令相关方法/// <summary>/// togglebutoon 的命令/// </summary>/// <param name="dto"></param>/// <exception cref="NotImplementedException"></exception>async private void Compete(ToDoDto dto){if (dto == null || string.IsNullOrEmpty(dto.Title) || (string.IsNullOrEmpty(dto.Content)))return;var updres = await toDoService.UpdateAsync(dto);if (updres.Status){var todo = Summary.TodoList.FirstOrDefault(x => x.Id.Equals(dto.Id));//更新信息todo.Status = dto.Status;}// 从数据库更新信息UpdateData();}/// <summary>/// 选择执行命令/// </summary>/// <param name="obj"></param>void Execute(string obj){switch (obj){case "新增待办": Addtodo(null); break;case "新增备忘": Addmemo(null); break;}}/// <summary>/// 添加待办事项/// </summary>async void Addtodo(ToDoDto model){DialogParameters param = new DialogParameters();if (model != null)param.Add("Value", model);var dialogres = await dialog.ShowDialog("AddTodoView", param);var newtodo = dialogres.Parameters.GetValue<ToDoDto>("Value");if (newtodo == null || string.IsNullOrEmpty(newtodo.Title) || (string.IsNullOrEmpty(newtodo.Content)))return;if (dialogres.Result == ButtonResult.OK){try{if (newtodo.Id > 0){var updres = await toDoService.UpdateAsync(newtodo);if (updres.Status){var todo = Summary.TodoList.FirstOrDefault(x=>x.Id.Equals(newtodo.Id));//更新信息todo.Content = newtodo.Content;todo.Title = newtodo.Title;todo.Status = newtodo.Status;}}else{//添加内容 //更新数据库数据var addres = await toDoService.AddAsync(newtodo);//更新UI数据if (addres.Status){Summary.TodoList.Add(addres.Result);}}}catch {}finally{UpdateLoding(false);}}// 从数据库更新信息UpdateData();}/// <summary>/// 添加备忘录/// </summary>async void Addmemo(MemoDto model){DialogParameters param = new DialogParameters();if (model != null)param.Add("Value", model);var dialogres = await dialog.ShowDialog("AddMemoView", param);if (dialogres.Result == ButtonResult.OK){try{var newmemo = dialogres.Parameters.GetValue<MemoDto>("Value");if (newmemo != null && string.IsNullOrWhiteSpace(newmemo.Content) && string.IsNullOrWhiteSpace(newmemo.Title))return;if (newmemo.Id > 0){var updres = await memoService.UpdateAsync(newmemo);if (updres.Status){//var memo = MemoDtos.FindFirst(predicate: x => x.Id == newmemo.Id);var memo = Summary.MemoList.FirstOrDefault( x => x.Id.Equals( newmemo.Id));//更新信息memo.Content = newmemo.Content;memo.Title = newmemo.Title;}}else{//添加内容var addres = await memoService.AddAsync(newmemo);//更新UI数据if (addres.Status){Summary.MemoList.Add(addres.Result);}}}catch{}finally{UpdateLoding(false);}}// 从数据库更新信息UpdateData();}#endregion#region 其它方法/// <summary>/// 更新首页所有信息/// </summary>private async void UpdateData(){UpdateLoding(true);var summaryResult = await summService.GetAllInfo(new SummaryParameter() { PageIndex = 0, PageSize = 1000 });if (summaryResult.Status){Summary = summaryResult.Result;Refresh();}UpdateLoding(false);}#endregion#region 启动项相关void CreatBars(){Title = "您好,2022";TaskBars = new ObservableCollection<TaskBar>();TaskBars.Add(new TaskBar { Icon = "CalendarBlankOutline", Title = "汇总", Color = "#FF00FF00", Content = "27", Target = "" });TaskBars.Add(new TaskBar { Icon = "CalendarMultipleCheck", Title = "已完成", Color = "#6B238E", Content = "24", Target = "" });TaskBars.Add(new TaskBar { Icon = "ChartLine", Title = "完成比例", Color = "#32CD99", Content = "100%", Target = "" });TaskBars.Add(new TaskBar { Icon = "CheckboxMarked", Title = "备忘录", Color = "#5959AB", Content = "13", Target = "" });}public override async void OnNavigatedTo(NavigationContext navigationContext){UpdateData();base.OnNavigatedTo(navigationContext);}void Refresh(){TaskBars[0].Content = summary.Sum.ToString();TaskBars[1].Content = summary.CompeleteCnt.ToString();TaskBars[2].Content = summary.CompeleteRatio;TaskBars[3].Content = summary.MemoCnt.ToString();}#endregionpublic IndexViewModel(IContainerProvider provider,IDialogHostService dialog) : base(provider){//实例化接口this.toDoService= provider.Resolve<ITodoService>();this.memoService = provider.Resolve<IMemoService>();this.summService= provider.Resolve<ISummeryService>();//初始化命令EditMemoCmd = new DelegateCommand<MemoDto>(Addmemo);EditTodoCmd = new DelegateCommand<ToDoDto>(Addtodo);ToDoCompltedCommand = new DelegateCommand<ToDoDto>(Compete);ExecuteCommand = new DelegateCommand<string>(Execute);this.dialog = dialog;CreatBars();}}
}
相关文章:
WPF实战学习笔记25-首页汇总
注意:本实现与视频不一致。本实现中单独做了汇总接口,而视频中则合并到国todo接口当中了。 添加汇总webapi接口添加汇总数据客户端接口总数据客户端接口对接3首页数据模型 添加数据汇总字段类 新建文件MyToDo.Share.Models.SummaryDto using System;…...
FreeRTOS源码分析-7 消息队列
目录 1 消息队列的概念和作用 2 应用 2.1功能需求 2.2接口函数API 2.3 功能实现 3 消息队列源码分析 3.1消息队列控制块 3.2消息队列创建 3.3消息队列删除 3.4消息队列在任务中发送 3.5消息队列在中断中发送 3.6消息队列在任务中接收 3.7消息队列在中断中接收 1 消…...
机器学习深度学习——权重衰减
👨🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——模型选择、欠拟合和过拟合 📚订阅专栏:机器学习&&深度学习 希望文章对你…...
【Linux】线程互斥 -- 互斥锁 | 死锁 | 线程安全
引入互斥初识锁互斥量mutex锁原理解析 可重入VS线程安全STL中的容器是否是线程安全的? 死锁 引入 我们写一个多线程同时访问一个全局变量的情况(抢票系统),看看会出什么bug: // 共享资源, 火车票 int tickets 10000; //新线程执行方法 vo…...
【vue-pdf】PDF文件预览插件
1 插件安装 npm install vue-pdf vue-pdf GitHub:https://github.com/FranckFreiburger/vue-pdf#readme 参考文档:https://www.cnblogs.com/steamed-twisted-roll/p/9648255.html catch报错:vue-pdf组件报错vue-pdf Cannot read properti…...
Flink集群运行模式--Standalone运行模式
Flink集群运行模式--Standalone运行模式 一、实验目的二、实验内容三、实验原理四、实验环境五、实验步骤5.1 部署模式5.1.1 会话模式(Session Mode)5.1.2 单作业模式(Per-Job Mode)5.1.3 应用模式(Application Mode&a…...
Spring整合JUnit实现单元测试
Spring整合JUnit实现单元测试 一、引言 在软件开发过程中,单元测试是保证代码质量和稳定性的重要手段。JUnit是一个流行的Java单元测试框架,而Spring是一个广泛应用于Java企业级开发的框架。本文将介绍如何使用Spring整合JUnit实现单元测试,…...
Spring Boot学习路线1
Spring Boot是什么? Spring Boot是基于Spring Framework构建应用程序的框架,Spring Framework是一个广泛使用的用于构建基于Java的企业应用程序的开源框架。Spring Boot旨在使创建独立的、生产级别的Spring应用程序变得容易,您可以"只是…...
管理类联考——写作——论说文——实战篇——标题篇
角度3——4种材料类型、4个立意对象、5种写作态度 经过审题立意后,我们要根据我们的立意,确定一个主题,这个主题必须通过文章的标题直接表达出来。 标题的基本要求 主题清晰,态度明确 第一,阅卷人看到一篇论说文的标…...
idea中设置maven本地仓库和自动下载依赖jar包
1.下载maven 地址:maven3.6.3 解压缩在D:\apache-maven-3.6.3-bin\apache-maven-3.6.3\目录下新建文件夹repository打开apache-maven-3.6.3-bin\apache-maven-3.6.3\conf文件中的settings.xml编辑:新增本地仓库路径 <localRepository>D:\apache-…...
前缀和差分
前缀和 前缀和:一段序列里的前n项和 给出n个数,在给出q次问询,每次问询给出L、R,快速求出每组数组中一段L至R区间的和 给出一段数组,每次问询为求出l到r区间的和 普通方法:L到R进行遍历,那么…...
Golang GORM 模型定义
模型定义 参考文档:https://gorm.io/zh_CN/docs/models.html 模型一般都是普通的 Golang 的结构体,Go的基本数据类型,或者指针。 模型是标准的struct,由Go的基本数据类型、实现了Scanner和Valuer接口的自定义类型及其指针或别名组成&#x…...
微服务的各种边界在架构演进中的作用
演进式架构 在微服务设计和实施的过程中,很多人认为:“将单体拆分成多少个微服务,是微服务的设计重点。”可事实真的是这样吗?其实并非如此! Martin Fowler 在提出微服务时,他提到了微服务的一个重要特征—…...
使用 docker-compose 一键部署多个 redis 实例
目录 1. 前期准备 2. 导入镜像 3. 部署redis master脚本 4. 部署redis slave脚本 5. 模板文件 6. 部署redis 7. 基本维护 1. 前期准备 新部署前可以从仓库(repository)下载 redis 镜像,或者从已有部署中的镜像生成文件: …...
14-测试分类
1.按照测试对象划分 ①界面测试 软件只是一种工具,软件与人的信息交流是通过界面来进行的,界面是软件与用户交流的最直接的一层,界面的设计决定了用户对设计的软件的第一印象。界面如同人的面孔,具有吸引用户的直接优势…...
打开域名跳转其他网站,官网被黑解决方案(Linux)
某天打开网站,发现进入首页,马上挑战到其他赌博网站。 事不宜迟,不能让客户发现,得马上解决 我的网站跳转到这个域名了 例如网站跳转到 k77.cc 就在你们部署的代码的当前文件夹下面,执行下如下命令 find -type …...
redis总结
1.redis redis高性能的key-value数据库,支持持久化,不仅仅支持简单的key-value,还提供了list,set,zset,hash等数据结构的存储,支持数据的备份(master-slave模式) redis&…...
现代C++中的从头开始深度学习:激活函数
一、说明 让我们通过在C中实现激活函数来获得乐趣。人工神经网络是生物启发模型的一个例子。在人工神经网络中,称为神经元的处理单元被分组在计算层中,通常用于执行模式识别任务。 在这个模型中,我们通常更喜欢控制每一层的输出以服从一些约束…...
python怎么实现tcp和udp连接
目录 什么是tcp连接 什么是udp连接 python怎么实现tcp和udp连接 什么是tcp连接 TCP(Transmission Control Protocol)连接是一种网络连接,它提供了可靠的、面向连接的数据传输服务。 在TCP连接中,通信的两端(客户端和…...
java设计模式-观察者模式(jdk内置)
上一篇我们学习了 观察者模式。 观察者和被观察者接口都是我们自己定义的,整个设计模式我们从无到有都是自己设计的,其实,java已经内置了这个设计模式,我们只需要定义实现类即可。 下面我们不多说明,直接示例代码&am…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Day131 | 灵神 | 回溯算法 | 子集型 子集
Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣(LeetCode) 思路: 笔者写过很多次这道题了,不想写题解了,大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
