当前位置: 首页 > news >正文

Swagger在php和java项目中的应用

Swagger在php和java项目中的应用

  • Swagger简介
  • Swagger在java项目中的应用
    • 步骤
    • 常用注解
  • Swagger在php项目中的应用

Swagger简介

Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。

总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码,允许 API 来始终保持同步。Swagger 让部署管理和使用功能强大的 API 从未如此简单。

  • 对于后端开发人员来说
  1. 不用再手写WiKi接口拼大量的参数,避免手写错误
  2. 对代码侵入性低,采用全注解的方式,开发简单
  3. 方法参数名修改、增加、减少参数都可以直接生效,不用手动维护
  4. 增加了开发成本,写接口还得再写一套参数配置
  • 对于前端开发来说
  1. 后端只需要定义好接口,会自动生成文档,接口功能、参数一目了然
  2. 联调方便,如果出问题,直接测试接口,实时检查参数和返回值,就可以快速定位是前端还是后端的问题
  • 对于测试来说
  1. 对于某些没有前端界面UI的功能,可以用它来测试接口
  2. 操作简单,不用了解具体代码就可以操作

Swagger在java项目中的应用

knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案

步骤

  1. 导入knife4j的maven坐标
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-spring-boot-starter</artifactId><version>3.0.2</version>
</dependency>
  1. 导入knife4j相关配置类(WebMvcConfig)
  2. 设置静态资源,否则接口文档页面无法访问
package com.demo.config;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.util.List;@Slf4j
@Configuration
@EnableSwagger2
@EnableKnife4j
public class WebMvcConfig extends WebMvcConfigurationSupport {/*** 设置静态资源映射* @param registry*/protected void addResourceHandlers (ResourceHandlerRegistry registry) {    				registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}@Beanpublic Docket createRestApi () {// 文档类型return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.basePackage("com.demo.controller")) // swagger扫描的包.paths(PathSelectors.any()).build();}/*** 介绍接口信息*/private ApiInfo apiInfo () {return new ApiInfoBuilder().title("Robin's Swagger documents").version("1.0").description("Robin's Swagger documents").build();}
}
  1. 在LoginCheckFilter中设置不需要处理的请求路径
package com.demo.filter;import com.alibaba.fastjson.JSON;
import com.demo.common.BaseContext;
import com.demo.common.R;
import com.demo.entity.Employee;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 检查用户是否已经完成登录*/@Slf4j
@WebFilter(filterName = "loginCheckFilter", urlPatterns = "/*")
public class LoginCheckFilter implements Filter {// 路径匹配器,支持通配符public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();// 定义不需要处理的请求路径public static final String[] urls = new String[]{"/employee/login", // 登录接口"/employee/logout", // 退出接口"/backend/**", // 放行后台静态资源"/front/**", // 放行前台静态资源"/common/download", // 文件下载接口"/user/login", // 移动端登录"/user/sendMsg", // 获取验证码接口"/doc.html", // swagger文档路径"/webjars/**","/swagger-resources/**","/v2/api-docs",};@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;// 1、获取本次请求的URIString requestUri = request.getRequestURI();// 2、判断本次请求是否需要处理,如果不需要处理,则直接放行if (check(requestUri)) {filterChain.doFilter(request, response);return;}// 3、判断登录状态,如果已登录,则直接放行Long empId = (Long) request.getSession().getAttribute("employee");Long userId = (Long) request.getSession().getAttribute("user");if (empId != null || userId != null) {// 将当前登录的用户id保存到ThreadLocal中if (empId != null) BaseContext.setCurrentId(empId);if (userId != null) BaseContext.setCurrentId(userId);filterChain.doFilter(request, response);return;}// 4、如果未登录,则返回未登录结果log.info("拦截到请求:{}", request.getRequestURI());response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));}/*** 路径匹配,检测本次请求是否需要放行* @param requestUri 本次请求资源* @return 路径匹配结果,true-放行,false-不放行*/public boolean check (String requestUri) {for (String url:urls) {if (PATH_MATCHER.match(url, requestUri)) {return true;}}return false;}
}

访问域名/doc.html,在这里插入图片描述

常用注解

注解说明
@Api用在请求的类上,例如Controller,表示对类的说明
@ApiModel用在类上,通常是实体类,表示一个返回响应数据的信息
@ApiModelProperty用在属性上,描述响应类的属性
@ApiOperation用在请求的方法上,说明方法的用途、作用
@ApiImplicitParams用在请求的方法上,表示一组参数说明
@ApiImplicitParam用在@ApilmplicitParams 注解中,指定一个请示参数的各个方面

R实体类补充注解:

package com.demo.common;import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;/*** 通用返回结果,服务端响应的数据最终都会封装成此对象* @param <T>*/
@Data
@ApiModel("返回结果")
public class R<T> implements Serializable {@ApiModelProperty("编码:1成功,0和其它数字为失败")private Integer code; //编码:1成功,0和其它数字为失败@ApiModelProperty("错误信息")private String msg; //错误信息@ApiModelProperty("数据")private T data; //数据@ApiModelProperty("动态数据")private Map map = new HashMap(); //动态数据public static <T> R<T> success(T object) {R<T> r = new R<T>();r.data = object;r.code = 1;return r;}public static <T> R<T> error(String msg) {R r = new R();r.msg = msg;r.code = 0;return r;}public R<T> add(String key, Object value) {this.map.put(key, value);return this;}}

套餐实体类补充注解:

package com.demo.entity;import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;/*** 套餐*/
@Data
@ApiModel("套餐")
public class Setmeal implements Serializable {private static final long serialVersionUID = 1L;@ApiModelProperty("主键")private Long id;//分类id@ApiModelProperty("分类id")private Long categoryId;//套餐名称@ApiModelProperty("套餐名称")private String name;//套餐价格@ApiModelProperty("套餐价格")private BigDecimal price;//状态 0:停用 1:启用@ApiModelProperty("状态 0:停用 1:启用")private Integer status;//编码@ApiModelProperty("编码")private String code;//描述信息@ApiModelProperty("描述信息")private String description;//图片@ApiModelProperty("图片")private String image;@TableField(fill = FieldFill.INSERT)private LocalDateTime createTime;@TableField(fill = FieldFill.INSERT_UPDATE)private LocalDateTime updateTime;@TableField(fill = FieldFill.INSERT)private Long createUser;@TableField(fill = FieldFill.INSERT_UPDATE)private Long updateUser;//是否删除@ApiModelProperty("是否删除")private Integer isDeleted;
}

套餐接口补充注解:

package com.demo.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.demo.common.R;
import com.demo.dto.SetmealDto;
import com.demo.entity.Category;
import com.demo.entity.Setmeal;
import com.demo.service.CategoryService;
import com.demo.service.SetmealDishService;
import com.demo.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;/*** 套餐管理*/
@Slf4j
@RestController
@RequestMapping("/setmeal")
@Api(tags = "套餐相关接口")
public class SetmealController {@Autowiredprivate SetmealService setmealService;@Autowiredprivate SetmealDishService setmealDishService;@Autowiredprivate CategoryService categoryService;/*** 新增套餐* @param setmealDto 套餐实体* @return 返回信息*/@CacheEvict(value = "setmealCache", allEntries = true)@PostMapping@ApiOperation(value = "新增套餐接口")public R<String> save(@RequestBody SetmealDto setmealDto) {setmealService.saveWithDish(setmealDto);return R.success("新增套餐成功");}/*** 套餐分页查询* @param page 页码* @param pageSize 单页数据量* @param name 套餐名称* @return 列表数据*/@GetMapping("/page")@ApiOperation(value = "套餐分页查询")@ApiImplicitParams({@ApiImplicitParam(name = "page", value = "页码", required = true),@ApiImplicitParam(name = "pageSize", value = "每页记录数", required = true),@ApiImplicitParam(name = "name", value = "套餐名称", required = false),})public R<Page<SetmealDto>> page (int page, int pageSize, String name) {// 构建分页构造器Page<Setmeal> pageInfo = new Page<>(page, pageSize);LambdaQueryWrapper<Setmeal> lambdaQueryWrapper = new LambdaQueryWrapper<>();// 添加查询条件,根据name进行模糊查询lambdaQueryWrapper.like(name != null, Setmeal::getName, name);// 添加排序条件,根据更新时间降序排列lambdaQueryWrapper.orderByAsc(Setmeal::getStatus).orderByDesc(Setmeal::getUpdateTime);setmealService.page(pageInfo, lambdaQueryWrapper);// 对象拷贝,补充分类信息Page<SetmealDto> dtoPage = new Page<>(page, pageSize);BeanUtils.copyProperties(pageInfo, dtoPage, "'records'");List<Setmeal> records = pageInfo.getRecords();List<SetmealDto> list = records.stream().map((item) -> {// 对象拷贝SetmealDto setmealDto = new SetmealDto();BeanUtils.copyProperties(item, setmealDto);// 设置分类名称Category category = categoryService.getById(item.getCategoryId());if (category != null) {setmealDto.setCategoryName(category.getName());}return setmealDto;}).collect(Collectors.toList());dtoPage.setRecords(list);return R.success(dtoPage);}/*** 批量删除套餐* @param ids 套餐id* @return 返回信息*/@CacheEvict(value = "setmealCache", allEntries = true)@DeleteMapping@ApiOperation(value = "批量删除套餐")public R<String> delete(@RequestParam List<Long> ids) {setmealService.removeWithDish(ids);return R.success("套餐数据删除成功");}/*** 批量上下架* @param ids 套餐id* @param status 上下架状态* @return 返回信息*/@PostMapping("/status/{status}")@ApiOperation(value = "批量上下架")public R<String> updateStatus(@RequestParam List<Long> ids, @PathVariable int status) {List<Setmeal> setmealList = ids.stream().map((item) -> {Setmeal setmeal = new Setmeal();setmeal.setId(item);setmeal.setStatus(status);return setmeal;}).collect(Collectors.toList());setmealService.updateBatchById(setmealList);return R.success("更新成功");}/*** 获取套餐详情数据* @param id 套餐id* @return 套餐实体信息*/@GetMapping("/{id}")@ApiOperation(value = "获取套餐详情数据")public R<SetmealDto> detail(@PathVariable Long id) {SetmealDto setmealDto = setmealService.getSetmealWithDish(id);return R.success(setmealDto);}/*** 修改套餐* @param setmealDto 套餐实体* @return 舞台信息*/@PutMapping@ApiOperation(value = "修改套餐")public R<String> update(@RequestBody SetmealDto setmealDto) {setmealService.updateWithDish(setmealDto);return R.success("编辑成功");}/*** 根据条件查询套餐数据* @param setmeal 套餐过滤条件* @return 套餐列表*/@GetMapping("/list")@Cacheable(value = "setmealCache", key="#setmeal.categoryId + '_' + #setmeal.status", unless = "#result.data.size() == 0")@ApiOperation(value = "根据条件查询套餐数据")public R<List<Setmeal>> list(Setmeal setmeal) {log.info("未命中缓存查询");LambdaQueryWrapper<Setmeal> lambdaQueryWrapper = new LambdaQueryWrapper<>();// 分类条件lambdaQueryWrapper.eq(setmeal.getCategoryId() != null, Setmeal::getCategoryId, setmeal.getCategoryId());// 上下架状态lambdaQueryWrapper.eq(setmeal.getStatus() != null, Setmeal::getStatus, setmeal.getStatus());// 排序lambdaQueryWrapper.orderByDesc(Setmeal::getUpdateTime);List<Setmeal> list = setmealService.list(lambdaQueryWrapper);return R.success(list);}
}

重新启动服务,查看实体和接口文档

在这里插入图片描述
在这里插入图片描述

Swagger在php项目中的应用

  1. 安装swagger包

zircote/swagger-php是swagger的php版,是一个扩展库,可以通过composer来进行安装

composer require zircote/swagger-php
  1. 安装Swagger ui

将swagger-ui下载下来以后,把dist目录下的文件复制到项目public/docs目录下, 这个目录可以自定义, 通俗来讲就是放到项目能访问到的目录下, 然后再将dist目录下的swagger-initializer.js文件中的url改成./openapi.yaml, 这里的openapi.yaml是生成文档后的文件名,意思是访问本地的openapi.yaml文件

在这里插入图片描述

<?php
namespace app\controller;use app\BaseController;
use think\App;
use think\facade\Request;/*** @OA\Info (*     title = "Robins's API documetns",*     version = "1.0",*     description="本文档仅限于测试"* )*/
class Index extends BaseController
{public function getDoc() {$openapi = \OpenApi\Generator::scan([__ROOT__ . '/../app']);// 生成yaml文件file_put_contents(__ROOT__ . '\doc\dist\openapi.yaml', $openapi->toYaml());}/*** @OA\Get (*     path="/",*     tags = {"用户订单列表接口"},*     summary = "用户订单列表接口",*     description = "获取用户订单信息",*     @OA\Parameter (name = "order_id", in = "query", description = "订单号", required = true),*     @OA\Parameter (name = "account_id", in = "query", description = "账户id", required = true),*     @OA\Response(response = "200",description = "The data"),*     @OA\MediaType(*          mediaType="application/json",*          @OA\Schema(ref="#/components/schemas/Info"),*     )* )* @return \think\response\Json*/public function index(){      $accountId = Request::post('account_id', 0);       $orderId = Request::post('order_id', '');       $data = Order::where(['account_id' => $accountId, 'order_id' => $orderId])->select()->toArray();return json($data);}
}

swagger在php项目中的注解还需要一点点摸索熟练

在这里插入图片描述

相关文章:

Swagger在php和java项目中的应用

Swagger在php和java项目中的应用 Swagger简介Swagger在java项目中的应用步骤常用注解 Swagger在php项目中的应用 Swagger简介 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 总体目标是使客户端和文件系统作为服务器以…...

java科学计数法表示数值

Background 大多数计算器及计算机程序用科学记数法显示非常大和非常小的结果&#xff1b;但很多时候&#xff0c;我们需要做一个统一&#xff0c;要么全部以科学计数法输出&#xff0c;要么就全部显示为普通计数。注意&#xff1a;这里对大于等于1的数据做了特殊处理&#xff0…...

基于C#实现树状数组

有一种数据结构是神奇的&#xff0c;神秘的&#xff0c;它展现了位运算与数组结合的神奇魅力&#xff0c;太牛逼的&#xff0c;它就是树状数组&#xff0c;这种数据结构不是神人是发现不了的。 一、概序 假如我现在有个需求&#xff0c;就是要频繁的求数组的前 n 项和&#x…...

Ubuntu Server 20.04.6下Anaconda3安装Pytorch

环境 Ubuntu 20.04.6 LTS Anaconda3-2023.09-0-Linux-x86_64.sh conda 23.7.4 Pytorch 1.11.0 安装 先创建一个工作环境&#xff0c;环境名叫lia&#xff1a; conda create -n lia python3.8环境的使用方法如下&#xff1a; conda activate lia # 激活环境 conda deactiv…...

C#-关于日志的功能扩展

目录 一、日志Sink(接收器) 二、Trace追踪实现日志 三、日志滚动 一、日志Sink(接收器) 安装NuGet包&#xff1a;Serilog Sink有很多种&#xff0c;这里介绍两种&#xff1a; Console接收器&#xff08;安装Serilog.Sinks.Console&#xff09;; File接收器&#xff08;安装…...

小程序禁止二次转发分享私密消息动态消息

第一种用法&#xff1a;私密消息 私密消息&#xff1a;运营人员分享小程序到个人或群之后&#xff0c;该消息只能在被分享者或被分享群内打开&#xff0c;不可以二次转发。 用途&#xff1a;主要用于不希望目标客群外的人员看到的分享信息&#xff0c;比如带有较高金额活动的…...

普乐蛙绵阳科博会一场VR科普航天科学盛宴科普知识

普乐蛙绵阳科普展&#xff1a;一场科学盛宴&#xff0c;点燃孩子探索欲望的火花! 普乐蛙绵阳科普展正在如火如荼地进行中&#xff0c;吸引了无数孩子和家长的热情参与。这场科普盛宴以独特的内外视角&#xff0c;让人们感受到科学的魅力&#xff0c;激发了孩子们对知识的渴望和…...

FFNPEG编译脚本

下面是一个ffmpeg编译脚本&#xff1a; #!/bin/bash set -eu -o pipefail set eu o pipefailFFMPEG_TAGn4.5-dev build_path$1 git_repo"https://github.com/FFmpeg/FFmpeg.git" cache_tool"" sysroot"" c_compiler"gcc" cxx_compile…...

Python期末复习题库(下)——“Python”

小雅兰期末加油冲冲冲&#xff01;&#xff01;&#xff01; 1. (单选题)下列关于文件打开模式的说法,错误的是( C )。 A. r代表以只读方式打开文件 B. w代表以只写方式打开文件 C. a代表以二进制形式打开文件 D. 模式中使用时,文件可读可写 2. (单选题)下列选项中,以追加…...

tauri中使用rust调用动态链接库例子(使用libloading库和libc库)

前言 当前采用桌面端框架位tauri&#xff0c;现在需要调用读卡器等硬件设备&#xff0c;硬件厂商提供了32位的动态链接库&#xff0c;现在记录例子&#xff0c;需要注意的点是使用libloading库和libc库&#xff0c; [package] name "yyt-device-rust" version &q…...

Leetcode—739.每日温度【中等】

2023每日刷题&#xff08;四十二&#xff09; Leetcode—739.每日温度 单调栈实现思想 从右到左实现代码 class Solution { public:vector<int> dailyTemperatures(vector<int>& temperatures) {int n temperatures.size();stack<int> st;vector<i…...

毕业设计单片机可以用万能板吗?

毕业设计单片机可以用万能板吗? 可以是可以&#xff0c;就是焊接起来比较麻烦&#xff0c;特别是有好几个重复连线点的时候&#xff0c;检测起来就不那么容易了&#xff0c;而且布线看起来乱糟糟的&#xff0c;如果后期一不小心把线弄断了&#xff0c;查起来就更麻烦了&#x…...

spring boot整合Jasypt实现配置加密

文章目录 目录 文章目录 前言 一、Jasypt是什么&#xff1f; 二、使用步骤 1.引入 2.测试使用 3.结果 总结 前言 一、Jasypt是什么&#xff1f; Jasypt&#xff08;Java Simplified Encryption&#xff09;是一个Java库&#xff0c;提供了一种简单的加密解密方式&#xff0c…...

java学校高校运动会报名信息管理系统springboot+jsp

课题研究方案&#xff1a; 结合用户的使用需求&#xff0c;本系统采用运用较为广泛的Java语言&#xff0c;springboot框架&#xff0c;HTML语言等关键技术&#xff0c;并在idea开发平台上设计与研发创业学院运动会管理系统。同时&#xff0c;使用MySQL数据库&#xff0c;设计实…...

Java(七)(Lambda表达式,正则表达式,集合(Collection,Collection的遍历方式))

目录 Lambda表达式 省略写法(要看懂) 正则表达式 语法 案例 正则表达式的搜索替换和分割内容 集合进阶 集合体系结构 Collection Collection的遍历方式 迭代器 增强for循环 Lambda表达式遍历Collection List集合 ArrayList LinkedList 哈希值 HashSet底层原理 …...

华为OD机试 - 二叉树计算(Java JS Python C)

目录 题目描述 输入描述 输出描述 用例 题目解析 JS算法源码 Java算法源码...

鸿蒙(HarmonyOS)应用开发——基础组件

组件 组件化是一种将复杂的前端应用程序分解成小的、独立的部分的方法。这些部分被称为组件&#xff0c;它们可以重复使用&#xff0c;可以与其他组件组合使用以创建更复杂的组件&#xff0c;并且它们有自己的生命周期和状态。 组件化的目的是提高开发效率和代码重用率&#…...

Vue3的项目创建到启动

Vue3的项目创建 检查node版本创建 npm init vuelatest 安装依赖 项目启动 启动成功...

开关电源基础而又硬核的知识

1.什么是Power Supply? Power Supply是一种提供电力能源的设备&#xff0c;它可以将一种电力能源形式转换成另外一种电力能源形式&#xff0c;并能对其进行控制和调节。 根据转换的形式分类&#xff1a;AC/DC、DC/DC、DC/AC、AC/AC 根据转换的方法分类&#xff1a;线性电源、…...

LightDB23.4 支持转换sql中中文空格和逗号为英文空格和逗号

功能介绍 在Lightdb数据库兼容Oracle的语法时&#xff0c;发现Oracle支持sql语句中使用中文空格和中文逗号&#xff0c;为了方便用户迁移到Lightdb&#xff0c;在Lightdb23.4版本中支持了转换中文空格和逗号的功能。该功能由GUC参数lightdb_convert_chinese_char来控制开关&am…...

Z-Image Turbo实际作品分享:城市风光生成效果

Z-Image Turbo实际作品分享&#xff1a;城市风光生成效果 本文所有内容均为技术效果展示&#xff0c;不涉及任何政治敏感内容&#xff0c;所有案例均为技术演示用途。 1. 效果概览&#xff1a;城市风光的AI艺术呈现 Z-Image Turbo作为基于Gradio和Diffusers构建的高性能AI绘图…...

Qwen3.5-9B惊艳效果:上传物理实验图→识别仪器→生成操作步骤视频脚本

Qwen3.5-9B惊艳效果&#xff1a;上传物理实验图→识别仪器→生成操作步骤视频脚本 1. 模型能力概览 Qwen3.5-9B是一款拥有90亿参数的开源大语言模型&#xff0c;在多模态理解和逻辑推理方面表现出色。这个模型最令人惊艳的能力在于它能够&#xff1a; 准确识别实验仪器&…...

Ostrakon-VL 模型推理加速实战:使用 .accelerate 库优化扫描速度

Ostrakon-VL 模型推理加速实战&#xff1a;使用 .accelerate 库优化扫描速度 1. 效果惊艳的开场 最近在测试Ostrakon-VL模型时&#xff0c;我发现了一个令人惊喜的事实&#xff1a;通过.accelerate库的几项简单优化&#xff0c;模型推理速度可以提升3倍以上&#xff0c;同时显…...

告别预烘焙!在UE材质编辑器中实时生成FlowMap和法线贴图(附节点图)

实时材质魔法&#xff1a;UE引擎中FlowMap与法线贴图的动态生成技术 在游戏开发与动态视觉创作领域&#xff0c;材质表现的真实感与动态效果一直是技术美术师们追求的核心目标。传统工作流中&#xff0c;FlowMap&#xff08;流场图&#xff09;和法线贴图的生成往往依赖于外部软…...

告别水印烦恼!3步轻松去水印,新手秒上手。

找到心仪的图片有水印、做设计好不容易找到的素材有水印、下载好看的壁纸有水印&#xff0c;遇到的好图全被水印扫兴&#xff1f;PS去水印&#xff0c;操作复杂&#xff0c;学习成本高&#xff0c;浪费时间&#xff1b;用专业去水印工具&#xff0c;收费昂贵&#xff0c;还有广…...

3个核心优势:BG3 Mod Manager的模组管理创新特性

3个核心优势&#xff1a;BG3 Mod Manager的模组管理创新特性 【免费下载链接】BG3ModManager A mod manager for Baldurs Gate 3. This is the only official source! 项目地址: https://gitcode.com/gh_mirrors/bg/BG3ModManager 博德之门3&#xff08;Baldurs Gate 3&…...

抖音a_bogus逆向实战:手把手教你用Node.js补全缺失的window环境

抖音a_bogus逆向实战&#xff1a;Node.js环境补全指南 在JavaScript逆向工程领域&#xff0c;浏览器环境与服务端环境的差异一直是开发者面临的棘手问题。当我们尝试将抖音网页端的加密逻辑&#xff08;如a_bogus生成算法&#xff09;移植到Node.js环境时&#xff0c;经常会遇到…...

Visual C++运行库一键修复终极指南:快速解决系统依赖问题

Visual C运行库一键修复终极指南&#xff1a;快速解决系统依赖问题 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist Visual C运行库是Windows系统中不可或缺的组件…...

为什么数据质量成为人工智能领域最重要的问题

简而言之&#xff1a;传统的基于人工编写规则和被动检查的数据质量体系&#xff0c;从未针对智能体人工智能进行设计。到2026年&#xff0c;当自主代理处理错误数据时&#xff0c;没有人会介入以发现问题。那些在人工智能领域取得成功的组织&#xff0c;并非从更好的模型入手&a…...

开源工具:IDM Activation Script彻底解决激活弹窗问题的技术方案

开源工具&#xff1a;IDM Activation Script彻底解决激活弹窗问题的技术方案 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script Internet Download Manager&#xf…...