v3-admin-vite 整合pont

需求

目前后端的Admin模板使用的是v3-admin-vite,需要整合pont接口,方便前后端统一一体化开发

安装PONT

按照官方的文档,将pont engine安装好,然后在项目根目录执行pont start。注意生成代码路径要修改一下,因为v3-admin-vite是放到src下

数据源是swagger的API地址,swagger配置方式略。下一步在VSCode里安装pont工具,这样就可以生成js api代码了,但是在生成前,建议修改一下配置。

格式统一化

如果直接生成,生成的代码会由于 prettier 的关系出现不少错误提示。解决的办法是参考根目录下v3-admin-vite的prettier.config.js,修改一下根目录下的pont-config.json,让它们保持一致

然后VSCode下切换到pont面板以此点击拉取远程数据源,生成接口代码:

然后代码就生成好了,生成的代码是这么个对应关系:

每个导出的方法一个ts文件

整合请求

前面弄完了,v3和pont的请求还是各干各的。需要将它们整合起来。

v3的请求在src/util/services.ts

pont的请求在src/services/pontCore.ts

修改pontCore.ts,以适配v3-admin的请求。实际上,除了个别状态码有差别,大部分也是兼容ccframe的,但是有几个问题

1)请求长度问题,pont默认里post请求是将所有的参数生成到URL请求的,见这部分代码

这个干了两个事情:

1)把路径占位符例如{id}替换为param里的id,并从param里删除

2)把param剩余的参数挂到URL后面

所以如果POST发送参数过长,这样会导致URL请求超过承载长度,不适合发送大量的数据,因此需要扩充表单发送的方式,当post请求时以表单编码发送。

本着最小修改原则,我们只需要修改pontTemplate.ts,不使用PontCore,采用v3 admin的请求:

import { Interface, BaseClass, Property, CodeGenerator, Surrounding } from 'pont-engine'

export default class MyGenerator extends CodeGenerator {
  getInterfaceContentInDeclaration(inter: Interface) {
    const requestParams = inter.getRequestParams()
    const paramsCode = inter.getParamsCode('Params')

    return `
      export ${paramsCode}

      export type Response = ${inter.responseType}

      export const init: Response;

      export function request(${requestParams}): Promise<Response>;
    `
  }

  getBaseClassInDeclaration(base: BaseClass) {
    const originProps = base.properties

    base.properties = base.properties.map((prop) => {
      return new Property({
        ...prop,
        required: false
      })
    })

    const result = super.getBaseClassInDeclaration(base)
    base.properties = originProps

    return result
  }

  getInterfaceContent(inter: Interface) {
    //const method = inter.method.toUpperCase()
    const axiosParamKey = 'GET' == inter.method.toUpperCase() ? 'params' : 'data' // 如果是GET,放param,如果是POST/PUT,放data
    const requestParams = inter.getRequestParams(this.surrounding)
    const paramsCode = inter.getParamsCode('Params', this.surrounding)

    return `
    /**
     * @desc ${inter.description}
     */

    import * as defs from '../../baseClass';
    import { request as service } from '../../../utils/service';

    export ${paramsCode}

    export const init = ${inter.response.getInitialValue()};

    export function request(${requestParams}, jsonPost: boolean = false) {
      return service({url:"${inter.path}", ...${inter.getRequestContent()}, ${axiosParamKey}: params, jsonPost})
    }
   `
  }
}

尝试一下:

import './../../services/'
API.commonAdmin.doLogin
  .request({ loginId: 'admin', userPsw: 'ssss', sid: '8888', validateCode: 'nere' })
  .then((res) => {
    console.log('*****', res)
  })

能够看到请求输出。但是报找不到参数,发现请求被编码成application/json格式了,当然接收不到了(如果要接收必须用@RequestBody)。由于我们请求大部分都是form格式的key-value数据,很少有结构化的数据,因此,需要默认为application/x-www-form-urlencoded编码,但是预留一个参数可以传递json数据支持结构化数据,因此在模板里添加了一个jsonPost变量,当开启时,采用application/json编码,修改src/utils/service.ts的请求部分如下:
 

/** 扩展了jsonPost参数 */
export interface AxiosRequestConfigEx extends AxiosRequestConfig {
  jsonPost?: boolean
}

/** 创建请求方法 */
function createRequest(service: AxiosInstance) {
  return function <T>(config: AxiosRequestConfigEx): Promise<T> {
    const token = getToken()
    const defaultConfig = {
      headers: {
        // 携带 Token
        Authorization: token ? `Bearer ${token}` : undefined,
        'Content-Type': 'application/x-www-form-urlencoded' //默认form编码,少量超大对象使用jsonPost
      },
      timeout: 10000, //默认10秒请求超时
      baseURL: import.meta.env.VITE_BASE_API,
      data: {}
    }
    // 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig
    const mergeConfig = merge(defaultConfig, config)
    if (config.jsonPost == true) {
      mergeConfig.headers['content-type'] = 'application/json'
    }

    return service(mergeConfig)
  }
}

这样配合模板里传入的jsonPost变量,当jsonPost传true时,可以使用json body进行传递

整合返回

整合请求后基本上本文可以结束了,但是项目里由于对返回进行了一些新的约定。需要进行调整,此部分直接修改v3-admin-vite的service.ts请求返回部分即可,不在本文赘述

------------[ 24.03.21新增] ------------

导出的时候,发现无法通过TS编译检查,由于默认为严格模式,变量申明需要加上可选限制符号,按照上面处理后有时导出的Param可能检测额不通过,导出模板里的Params需要修改一下,如下:

  getInterfaceContent(inter: Interface) {
    //const method = inter.method.toUpperCase()
    const axiosParamKey = 'GET' == inter.method.toUpperCase() ? 'params' : 'data' // 如果是GET,放param,如果是POST/PUT,放data
    const requestParams = inter.getRequestParams(this.surrounding)
    const paramsCode = inter.getParamsCode('Params', this.surrounding).replace(/([A-Za-z0-9_]+):/g, '$1?:') //适配严格模式

    return `
    /**
     * @desc ${inter.description}
     */

    import * as defs from '../../baseClass';
    import { request as service } from '../../../utils/service';

    export ${paramsCode}

    export const init = ${inter.response.getInitialValue()};

    export function request(${requestParams}, jsonPost: boolean = false) {
      return service({url:"${inter.path}", ...${inter.getRequestContent()}, ${axiosParamKey}: params, jsonPost})
    }
   `
  }

编辑完后,记得删除service目录,并关闭VSCode重新打开生效模板,然后再批量生成接口

重分chunk和gz压缩

最终发布,还是要使用gzip的,配合nginx的gzip_static或brotli_static模块,能够不占用额外的CPU资源直接下传更小的数据。因此添加了vite-plugin-compression:

pnpm i vite-plugin-compression -D

然后在vue.config.ts引入:

import { chunkSplitPlugin } from 'vite-plugin-chunk-split'

chunk分包原v3admin用的是rollup。会将页面拆成很稀碎的一个个单个js,实际业务会在views下根据具体的模块来分包。每个模块打包为一个目录,因此引入支持目录正则的vite-plugin-chunk-split:

pnpm i vite-plugin-chunk-split -D

由于使用插件来分包,因此将原来的规则注释掉

在plugin部分添加自己的分包规则和开启静态压缩

这里也是参考原来的拆分模式,将vue和element分开,这里将node-modules其他的也打包成一个模块,按目录打包部分views以后可以根据业务目录单独打包

静态压缩可以选择gzip(支持http和https)或brotli(比gzip小10%~20%,仅支持https)

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

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

相关文章

AI新工具(20240322) 免费试用Gemini Pro 1.5;先进的AI软件工程师Devika;人形机器人Apptronik给你打果汁

✨ 1: Gemini Pro 1.5 免费试用Gemini Pro 1.5 Gemini 1.5 Pro是Gemini系列模型的最新版本&#xff0c;是一种计算高效的多模态混合专家&#xff08;MoE&#xff09;模型。它能够从数百万个上下文Token中提取和推理细粒度信息&#xff0c;包括多个长文档和数小时的视频、音频…

Excel数字乱码怎么回事 Excel数字乱码怎么调回来

在日常工作中&#xff0c;Excel是我们最常使用的数据处理软件之一&#xff0c;它强大的功能使得数据处理变得既简单又高效。然而&#xff0c;用户在使用Excel时偶尔会遇到数字显示为乱码的问题&#xff0c;这不仅影响了数据的阅读&#xff0c;也大大降低了工作效率。那么&#…

Docker-Image

Docker Docker 镜像是什么为什么需要镜像镜像命令总览docker imagesdocker tagdocker pulldocker pushdocker rmidocker savedocker loaddocker image inspectdocker historydocker importdocker image prunedocker build Docker 镜像是什么 Docker image 本质上是一个 read-on…

一文全面了解 wxWidgets 程序国际化(i18n)处理

尽管应用程序的国际化&#xff08;简称i18n&#xff09;远不止是将文本消息翻译成另一种语言的消息——日期、时间和货币格式也需要更改&#xff0c;一些语言是从左到右书写&#xff0c;而另一些是从右到左书写&#xff0c;字符编码可能不同&#xff0c;以及许多其他可能需要更…

一文带你弄懂JVM与JAVA体系结构

文章目录 1.JVM 与 Java 体系结构1.1. 前言1.2. 一些参考书目1.3. Java 及 JVM 简介1.4. Java 发展的重大事件1.5. 虚拟机与 Java 虚拟机1.6. JVM 的整体结构1.7. Java 代码执行流程1.8. JVM 的架构模型1.9. JVM 的生命周期 1.JVM 与 Java 体系结构 1.1. 前言 作为 Java 工程…

NLP 笔记:Latent Dirichlet Allocation (介绍篇)

1 问题介绍 假设我们有一堆新闻&#xff0c;每个新闻都有≥1个主题 我们现在只知道新闻的内容&#xff0c;我们希望一个算法&#xff0c;帮我们把这些新闻分类成主题人类可以根据每个每个文章里面的单词判断主题&#xff0c;那计算机怎么做呢&#xff1f; ——>LDA(Latent D…

大小端是什么?怎么判断?(百度笔试题)

目录 一、前言二、什么是大小端&#xff1f;三、为什么有大小端之分呢&#xff1f;四、判断机器是大端还是小端--百度笔试题 一、前言 先看一段代码&#xff1a; #include<stdio.h> int main() {int n 0x11223344;return 0; }二、什么是大小端&#xff1f; 其实超过⼀…

【JavaSE】抽象类和接口

目录 前言 1. 抽象类 1.1 认识抽象类 1.2 抽象类的特征 1.3 抽象类的作用 2. 接口 2.1 接口的概念 2.2 接口的语法 2.3 接口的使用 2.4 接口的特性 2.5 接口的好处 2.6 接口之间的继承 结语 前言 今天我们来讲Java中的抽象类和接口&#xff0c;它们在面向对象中发…

前端应用开发实验:条件渲染和循环渲染

目录 实验目的相关知识点实验内容图片的隐藏和显示代码实现效果 电影票房排序代码实现效果 代办事项记录代码实现效果 实验目的 (1)熟练掌握v-on 指令的用法&#xff0c;学会使用v-on 指令监听DOM元素的事件&#xff0c;并通过该事件触发调用事件处理程序。 (2)掌握v-on指令修…

大学理科用什么软件搜题?推荐5个搜题软件和学习工具 #其他#知识分享#经验分享

大学生的学习生活离不开一些实用的工具&#xff0c;它们能够帮助我们更高效地学习和管理时间。 1.千鸟搜题 这是一个公众号 这是一个老公众号了&#xff0c;我身边的很多朋友都在用&#xff0c;支持超新星、学习强国、知到、智慧树和各类专业网课题目。 下方附上一些测试的试…

Axure案例分享—折叠面板(附下载地址)

今天和大家分享的Axure案例是折叠面板 折叠面板是移动端APP中常见的组件之一&#xff0c;有时候也称之为手风琴。咱们先看下Axure画出的折叠面板原型效果&#xff0c;然后再对该组件进行详细讲解。 一、功能介绍 折叠或展开多个面板内容&#xff0c;默认为展开一项内容&…

【JS】闭包的漏洞

下面这段代码可以实现&#xff1a;通过立即执行函数o返回对象中的get方法&#xff0c;通过参数key得到fn函数内部对象obj中的值。 var fn function () {var obj {a: 1,b: 2}return {get: function (key) {return obj[key]}} }() console.log(fn.get(b)); // 2这是一个典型的…

小红书扫码登录分析与python实现

文章目录 1. 写在前面2. 接口分析3. 代码实现 【&#x1f3e0;作者主页】&#xff1a;吴秋霖 【&#x1f4bc;作者介绍】&#xff1a;擅长爬虫与JS加密逆向分析&#xff01;Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python…

基于ssm电子竞技管理平台的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本电子竞技管理平台就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息…

MySQL、Oracle的时间类型字段自动更新:insert插入、update更新时,自动更新时间戳。设置自增主键id,oracle创建自增id序列和触发器

1. MySQL 支持设置自增id的字段类型&#xff1a;int、bigint、double等数值类型&#xff0c;一般用int、bigint支持设置自动更新时间的字段类型&#xff1a;datetime、timestamp下面sql中的now()函数可以用current_timestamp()替代 1.1. 不指定秒精度 drop table if exists …

135. 分发糖果(力扣LeetCode)

文章目录 135. 分发糖果题目描述贪心算法代码如下 总结 135. 分发糖果 题目描述 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩…

Leetcode - 周赛389

目录 一&#xff0c;3083. 字符串及其反转中是否存在同一子字符串 二&#xff0c;3084. 统计以给定字符开头和结尾的子字符串总数 三&#xff0c;3085. 成为 K 特殊字符串需要删除的最少字符数 四&#xff0c;3086. 拾起 K 个 1 需要的最少行动次数 一&#xff0c;3083. 字符…

Java的三大特性之一——继承

前言 http://t.csdnimg.cn/uibg3 在上一篇中我们已经讲解过封装&#xff0c;这里就主要讲解继承与多态 继承 1.为什么需要继承 Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是现实…

centos7安装jdk详细步骤(yum安装与手动安装)

centos7安装jdk详细步骤&#xff08;yum安装与手动安装&#xff09; 一、使用yum安装1. 准备工作2. 检查系统是否自带jdk3. 安装jdk 二、手动安装jdk1. 下载上传jdk2. 安装jdk3. 配置环境变量 一、使用yum安装 1. 准备工作 如果你的机器可以联网可以使用此方法 ping www.baidu…

2、Java虚拟机之类的生命周期-连接(验证、准备、解析)

一、类的生命周期 连接阶段之验证 连接阶段的第一个环节是验证&#xff0c;验证的主要目的是检测Java字节码文件是否遵守了<Java虚拟机规范>中的约束。这个阶段一般是不需要程序员进行处理。 主要包含如下四个部分,具体详见<<Java虚拟机规范>>: 1、文件格…