分享通过PDManer数据库建模工具实现快速开发(数据库->实体类->服务->接口->页面表单/表格)一键生成

PDManer数据库建模工具一键生成前后端代码

  • PDManer
    • 功能介绍
    • 资源下载
    • 项目基础框架
    • 操作及注意事项
    • 重点来了!!!
    • 更新日志
      • Java代码生成模板
        • entity.java
        • controller.java
        • mapper.java
        • service.java
        • impl.java
        • dto.java
      • Vue代码生成模板
        • api.ts
        • Table.vue
        • Form.vue
        • index.vue
      • 其他代码
        • Res.Java
        • ResEnum.java
        • BaseBatch.java
        • BaseQuery.java
        • RequestPage.java
        • TableButton.vue
        • layout.ts
        • axios.ts
        • common.ts

PDManer

PDManer是一款开源的数据库建模工具,它可以帮助开发人员快速建立和维护数据库模型。PDManer支持多种数据库管理系统,包括MySQL、Oracle、Microsoft SQL Server等。使用PDManer,用户可以通过可视化界面轻松地设计数据库模型,并且可以自动生成SQL脚本和数据库表结构。此外,PDManer还支持代码自动生成,非常适合快速开发。

官网:http://www.pdmaas.cn/home

Gitee:https://gitee.com/robergroup/pdmaner

相关文章:OSChina | 知乎

在这里插入图片描述

功能介绍

本文主要讲使用PDManer进行快速开发,一键生成代码,主键介绍一下涉及到的功能模块

  1. 数据库连接,字段比对及生成SQL;

    在这里插入图片描述

    在这里插入图片描述

  2. 字段类型配置及代码生成模板配置模板语法请参考dot.js语法官网 | 中文参考;

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

资源下载

安装包已经上传到CSDN,也可在Gitee上下载源码自行打包

[PDManer-win-4.5.1下载]

[代码生成器配置]

项目基础框架

以上功能简单了解完后,来介绍一下项目的基础框架

后端框架:

框架 描述 文档
SpringBoot 基础框架
Mybatis 数据库连接
Mybatis-Plus 增强 https://baomidou.com/
Mybatis-Plus-Join 用于联表查询 https://ylctmh.com/

前端框架:

框架 描述 文档
Vue 3 基础框架
Vue-Router 路由库
Pinia 状态管理
Axios 网络请求库
Element-Plus 组件库 https://element-plus.gitee.io/zh-CN/

操作及注意事项

  1. 数据库代码:直接复制执行就可以了

    在这里插入图片描述

  2. 代码生成:如下图配置文件路径及基本参数即可在指定目录生成文件

    在这里插入图片描述

    在这里插入图片描述

重点来了!!!

不编了,直接贴上我的配置,如有遗漏可以私信我,补上代码

更新日志

2023-03-31 初版模板发布

2023-04-12 增加逻辑删除字段标识;增加Vue表格及表单屏蔽字段设置;增加表单回车事件

Java代码生成模板

entity.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
    var exclude = [];
    var autoInsert = ['created_by','created_time'];
    var autoUpdate = ['updated_by','updated_time'];
    var version="version";
    var deleted='deleted';
    var extend="";
    
}}package {{=pkgName}}.entity;
$blankline

import com.baomidou.mybatisplus.annotation.*;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.format.annotation.DateTimeFormat;
$blankline

 /**
 * {{=it.entity.defName}}{{=it.entity.comment}}
 */
@Getter
@Setter
@Accessors(chain = true)
@TableName("{{=it.entity.defKey}}")
public class {{= beanClass}}Entity {{? extend != ""}}extends {{=extend}} {{?}}{
    {{~it.entity.fields:field:index}}{{? exclude.indexOf(field.defKey) == -1}}
    /** 
     * {{=it.func.join(field.defName,field.comment,'\n     * ')}}
     */
    {{? field.defKey == version}}@Version{{?}}{{? field.defKey == deleted}}@TableLogic{{?}}
    {{? field.primaryKey }}@TableId{{??}}@TableField{{?}}(value = "{{=field.defKey}}"{{? field.primaryKey }}, type = IdType.ASSIGN_UUID{{?}}{{? autoInsert.indexOf(field.defKey) != -1}}, fill = FieldFill.INSERT{{?}}{{? autoUpdate.indexOf(field.defKey) != -1}},fill = FieldFill.UPDATE{{?}})
    {{? field.type=="LocalDateTime"}}@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8"){{?}}
    private {{? field.type == 'ENUM'}}{{=beanClass}}{{=it.func.camel(field.defKey,true)}}Enum{{??}}{{=field.type}}{{?}} {{=it.func.camel(field.defKey,false)}};{{?}}{{~}}
$blankline
}
controller.java
// controller.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
    
    var pkVarName = "undefinedId";
    it.entity.fields.forEach(function(field){
        if(field.primaryKey){
            pkVarName = it.func.camel(field.defKey,true);
            return;
        }
    });
    
}}package {{=pkgName}}.controller;
$blankline

import {{=pkgName}}.entity.{{=beanClass}}Entity;
import {{=pkgName}}.service.{{=beanClass}}Service;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
$blankline

 /**
 * {{=it.entity.defName}}{{=it.entity.comment}}API接口
 */
@RestController
@RequestMapping("/{{=appName}}/{{=it.func.camel(it.entity.defKey,false)}}")
public class {{=beanClass}}Controller {
$blankline
    @Resource
    private {{=beanClass}}Service {{=beanName}}Service;
$blankline

     /**
      * 根据主键获取{{=it.entity.defName}}
      */
    @PostMapping("get{{=beanClass}}")
    public Res<{{=beanClass}}Entity> get{{=beanClass}}(@RequestBody {{=beanClass}}Entity entity) {
        entity = {{=beanName}}Service.getById(entity.get{{=pkVarName}}());
        return Res.success(entity);
    }
$blankline

     /**
      * 分页获取{{=it.entity.defName}}
      */
    @PostMapping("get{{=beanClass}}Page")
    public Res{=beanClass}}DTO>> get{{=beanClass}}Page(@RequestBody BaseQuery<{{=beanClass}}DTO> request) {
        MPJLambdaWrapper<{{=beanClass}}Entity> wrapper = new MPJLambdaWrapper<{{=beanClass}}Entity>();
        IPage<{{=beanClass}}DTO> page = {{=beanName}}Service.selectJoinListPage(request.getPage(), {{=beanClass}}DTO.class, wrapper);
        return Res.success(page);
    }
$blankline

     /**
      * 获取全部{{=it.entity.defName}}
      */
    @PostMapping("get{{=beanClass}}List")
    public Res{=beanClass}}Entity>> get{{=beanClass}}List() {
        List<{{=beanClass}}Entity> list = {{=beanName}}Service.list();
        return Res.success(list);
    }
$blankline

     /**
      * 新增{{=it.entity.defName}}
      */
    @PostMapping("save{{=beanClass}}")
    public Res<{{=beanClass}}Entity> save{{=beanClass}}(@RequestBody {{=beanClass}}Entity entity) {
        {{=beanName}}Service.save(entity);
        return Res.success(entity);
    }
$blankline

     /**
      * 更新{{=it.entity.defName}}
      */
    @PostMapping("update{{=beanClass}}")
    public Res update{{=beanClass}}(@RequestBody {{=beanClass}}Entity entity) {
        boolean res = {{=beanName}}Service.updateById(entity);
        return Res.success(res);
    }
$blankline

     /**
      * 删除{{=it.entity.defName}}
      */
    @PostMapping("delete{{=beanClass}}")
    public Res delete{{=beanClass}}(@RequestBody {{=beanClass}}Entity entity) {
        boolean res = {{=beanName}}Service.removeById(entity);
        return Res.success(res);
    }
$blankline

     /**
      * 批量新增{{=it.entity.defName}}
      */
    @PostMapping("save{{=beanClass}}Batch")
    public Res save{{=beanClass}}Batch(@RequestBody BaseBatch<{{=beanClass}}Entity> batch) {
        boolean res = {{=beanName}}Service.saveBatch(batch.getList());
        return Res.success(res);
    }
$blankline

     /**
      * 批量更新{{=it.entity.defName}}
      */
    @PostMapping("update{{=beanClass}}Batch")
    public Res update{{=beanClass}}Batch(@RequestBody BaseBatch<{{=beanClass}}Entity> batch) {
        boolean res = {{=beanName}}Service.updateBatchById(batch.getList());
        return Res.success(res);
    }
$blankline

     /**
      * 批量删除{{=it.entity.defName}}
      */
    @PostMapping("delete{{=beanClass}}Batch")
    public Res delete{{=beanClass}}Batch(@RequestBody BaseBatch<{{=beanClass}}Entity> batch) {
        boolean res = {{=beanName}}Service.removeBatchByIds(batch.getList());
        return Res.success(res);
    }
$blankline

}

mapper.java
// mapper.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var beanClass = it.func.camel(it.entity.defKey,true);
    
}}package {{=pkgName}}.mapper;
$blankline

import com.github.yulichang.base.MPJBaseMapper;
import {{=pkgName}}.entity.{{=beanClass}}Entity;
import org.apache.ibatis.annotations.Mapper;
$blankline

 /**
 * {{=it.entity.defName}}({{=it.entity.defKey}})表数据库访问层
 */
@Mapper
public interface {{=beanClass}}Mapper extends MPJBaseMapper<{{=beanClass}}Entity> {
}
service.java
// service.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var beanClass = it.func.camel(it.entity.defKey,true);
    
}}package {{=pkgName}}.service;
$blankline

import com.github.yulichang.base.MPJBaseService;
import {{=pkgName}}.entity.{{=beanClass}}Entity;
$blankline

 /**
 * {{=it.entity.defName}}({{=it.entity.defKey}})表服务接口
 */
public interface {{=beanClass}}Service extends MPJBaseService<{{=beanClass}}Entity> {
}
impl.java
// impl.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var beanClass = it.func.camel(it.entity.defKey,true);
    
}}package {{=pkgName}}.service.impl;
$blankline

import com.github.yulichang.base.MPJBaseServiceImpl;
import {{=pkgName}}.entity.{{=beanClass}}Entity;
import {{=pkgName}}.mapper.{{=beanClass}}Mapper;
import {{=pkgName}}.service.{{=beanClass}}Service;
import org.springframework.stereotype.Service;
$blankline

 /**
 * {{=it.entity.defName}}({{=it.entity.defKey}})表服务实现类
 */
@Service
public class {{=beanClass}}ServiceImpl extends MPJBaseServiceImpl<{{=beanClass}}Mapper, {{=beanClass}}Entity> implements {{=beanClass}}Service {
}
dto.java
// dto.java
{{  var pkgName = it.entity.env.base.nameSpace;
    var beanClass = it.func.camel(it.entity.defKey,true);
    
}}package {{=pkgName}}.dto;
$blankline

import {{=pkgName}}.entity.{{=beanClass}}Entity;
import lombok.Data;
$blankline

 /**
 * {{=it.entity.defName}}({{=it.entity.defKey}})数据传输对象
 */
@Data
public class {{=beanClass}}DTO extends {{=beanClass}}Entity {
}

Vue代码生成模板

api.ts
// api.ts
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
     
    var pkVarName = "undefinedId";
    var pkDataType = "string";
    it.entity.fields.forEach(function(field){
        if(field.primaryKey){
            pkVarName = it.func.camel(field.defKey,false);
            pkDataType = field.type;
            return;
        }
    });
    
}}import { createAxios } from '@/utils/axios'
$blankline

// 接口地址
export const uri = '/{{=appName}}/{{=it.func.camel(it.entity.defKey,false)}}'
$blankline

// {{=it.entity.defName}}{{=it.entity.comment}}类型定义
export interface {{=beanClass}} {
    {{~it.entity.fields:field:index}}
    {{=it.func.camel(field.defKey,false)}}?: {{=field.type}}, // {{=field.defName}}{{~}}
}
$blankline

// 根据主键获取{{=it.entity.defName}}
export const get{{=beanClass}} = ( {{=pkVarName}}: {{=pkDataType}} ) => createAxios({ data: { {{=pkVarName}} }, url: uri + '/get{{=beanClass}}' })
$blankline

// 分页获取{{=it.entity.defName}}
export const get{{=beanClass}}Page = (query: any = {}, page: any = {}) => createAxios({data:{ query, page }, url: uri + '/get{{=beanClass}}Page' })
$blankline

// 获取全部{{=it.entity.defName}}
export const get{{=beanClass}}List = () => createAxios({ url: uri + '/get{{=beanClass}}List' })
$blankline

// 新增{{=it.entity.defName}}
export const save{{=beanClass}} = (data: {{=beanClass}}) => createAxios({ data, url: uri + '/save{{=beanClass}}' }, { successMsg: '新增成功' })
$blankline

// 更新{{=it.entity.defName}}
export const update{{=beanClass}} = (data: {{=beanClass}}) => createAxios({ data, url: uri + '/update{{=beanClass}}' },{ successMsg: '修改成功!' })
$blankline

// 删除{{=it.entity.defName}}
export const delete{{=beanClass}} = (data: {{=beanClass}}) => createAxios({ data, url: uri + '/delete{{=beanClass}}' },{ successMsg: '删除成功!' })
$blankline

// 批量新增{{=it.entity.defName}}
export const save{{=beanClass}}Batch = (list: {{=beanClass}}[]) => createAxios({ data : { list }, url: uri + '/save{{=beanClass}}Batch' }, { successMsg: '新增成功' })
$blankline

// 批量更新{{=it.entity.defName}}
export const update{{=beanClass}}Batch = (list: {{=beanClass}}[]) => createAxios({ data : { list }, url: uri + '/update{{=beanClass}}Batch' },{ successMsg: '修改成功!' })
$blankline

// 批量删除{{=it.entity.defName}}
export const delete{{=beanClass}}Batch = (list: {{=beanClass}}[]) => createAxios({ data : { list }, url: uri + '/delete{{=beanClass}}Batch' },{ successMsg: '删除成功!' })
$blankline

Table.vue
// table.vue
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
    var exclude = ['uid','created_by','created_time','updated_by','updated_time','deleted','sort'];
    
    var pkVarName = "undefinedId";
    it.entity.fields.forEach(function(field){
        if(field.primaryKey){
            pkVarName = it.func.camel(field.defKey,false);
            return;
        }
    });
    
}}
$blankline


$blankline




Form.vue
// form.vue
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
    var exclude = ['uid','created_by','created_time','updated_by','updated_time','deleted','sort'];
    
}}
$blankline


$blankline


index.vue
// index.vue
{{  var pkgName = it.entity.env.base.nameSpace;
    var appName = pkgName.split('.')[pkgName.split('.').length - 1];
    var beanName = it.func.camel(it.entity.defKey,false);
    var beanClass = it.func.camel(it.entity.defKey,true);
    
}}
$blankline


$blankline



其他代码

Res.Java
import com.simplo.mes.base.enums.ResEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;

@Getter
@Setter
@SuppressWarnings({"AlibabaClassNamingShouldBeCamel"})
@Accessors(chain = true)
public class Res {
    /**
     * 响应码
     */
    private String code;
    /**
     * 调用结果
     */
    private T data;
    /**
     * 提示信息
     */
    private String msg;


    private Res() {
        super();
    }

    private Res(String code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
    }

    /**
     * 成功返回(无返回参数)
     */
    public static  Res success() {
        return new Res<>(ResEnum.SUCCESS.getCode(), null, ResEnum.SUCCESS.getMsg());
    }

    /**
     * 成功返回
     */
    public static  Res success(E data) {
        return new Res<>(ResEnum.SUCCESS.getCode(), data, ResEnum.SUCCESS.getMsg());
    }

    /**
     * 异常返回
     */
    public static  Res error(ResEnum resEnum) {
        return new Res<>(resEnum.getCode(), null, resEnum.getMsg());
    }

    /**
     * 异常返回
     */
    public static  Res error(ResEnum resEnum, E data) {
        return new Res<>(resEnum.getCode(), data, resEnum.getMsg());
    }

    /**
     * 异常返回
     */
    public static  Res error(ResEnum resEnum, String msg, E data) {
        return new Res<>(resEnum.getCode(), data, msg);
    }
}

ResEnum.java
public enum ResEnum {
    /**
     * 返回码
     */
    SUCCESS("0", "成功"),
    ERROR("-1", "系统繁忙,请稍后再试"),
    CUS_ERROR("999", "请求失败"),
    NOT_LOGIN("10000", "账号未登录或已失效,请重新登录"),
    SA_EXCEPTION("20001", "鉴权异常");


    private String code;
    private String msg;

    ResEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public String getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

BaseBatch.java
import lombok.Data;

import java.util.List;

@Data
public class BaseBatch {
    List list;
}

BaseQuery.java
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Data;

@Data
public class BaseQuery {
    private T query;
    private Page page;

}

RequestPage.java
import lombok.Data;

@Data
public class RequestPage {
    private Integer pageNumber;
    private Integer pageSize;
}

TableButton.vue






layout.ts
import { defineStore } from 'pinia'
import { CSSProperties } from 'vue'

const name = 'layout'

export const useLayout = defineStore(name, {
    state: () => ({
        headerHeight: 0, // 顶部高度
    }),
    actions: {
        getMainHeight(extra = 0): CSSProperties {
            return {
                height:
                    'calc(100vh - ' +
                    this.headerHeight +
                    'px - ' +
                    extra.toString() +
                    'px)',
            }
        },
        initHeaderHeight() {
            this.headerHeight = 0
        },
        addHeaderHeight(height = 0) {
            this.headerHeight += height
        },
    }
})

axios.ts
import router from '@/router'
import { CONFIG } from '@/config'
import axios, { AxiosRequestConfig } from 'axios'
import { ElLoading, ElNotification } from 'element-plus'
import { isEmpty } from 'lodash'

let loadingInstance: any
const pendingMap = new Map()

export interface AxiosOptions {
    loading?: boolean // 是否开启loading层效果, 默认为false
    timeout?: number // 超时时间
    successMsg?: string // 请求成功提示信息
    showErrorMsg?: boolean // 是否提示异常信息
}

/*
 * 创建Axios
 */
export const createAxios = (
    axiosConfig: AxiosRequestConfig,
    options: AxiosOptions = {}
) => {
    const Axios = axios.create({
        baseURL: CONFIG.apiHost,
        timeout: options.timeout || 1000 * 10,
        headers: {
            'Content-Type': 'application/json',
        },
        responseType: 'json',
        method: 'POST',
    })
    options = Object.assign(
        {
            loading: false,
            successMsg: '',
            showErrorMsg: true,
        },
        options
    )
    // 请求拦截
    Axios.interceptors.request.use(
        (config) => {
            removePending(config)
            addPending(config)
            // 创建loading实例
            if (options.loading) {
                loadingInstance = ElLoading.service()
            }
            return config
        },
        (error) => {
            return Promise.reject(error)
        }
    )

    // 响应拦截
    Axios.interceptors.response.use(
        (response) => {
            removePending(response.config)
            options.loading && loadingInstance.close() // 关闭loading
            if (response.config.responseType == 'json') {
                if (response.data && response.data.code !== '0') {
                    if (response.data.code == '10000') {
                        // logout()
                    }
                    if (options.showErrorMsg) {
                        ElNotification({
                            offset: 55,
                            type: 'error',
                            message: response.data.msg,
                        })
                    }
                    // 自动跳转到路由name或path,仅限server端返回302的情况
                    if (response.data.code == '302') {
                        if (response.data.data.name) {
                            router.push({ name: response.data.data.name })
                        } else if (response.data.data.path) {
                            router.push({ path: response.data.data.path })
                        }
                    }
                    // code不等于0, 页面then内的具体逻辑就不执行了
                    return Promise.reject(response.data)
                } else if (
                    !isEmpty(options.successMsg) &&
                    response.data.code == '0'
                ) {
                    ElNotification({
                        offset: 55,
                        message: options.successMsg
                            ? options.successMsg
                            : response.data.msg,
                        type: 'success',
                    })
                }
            }
            return response.data
        },
        (error) => {
            error.config && removePending(error.config)
            options.loading && loadingInstance.close() // 关闭loading
            options.showErrorMsg && httpErrorStatusHandle(error) // 处理错误状态码
            return Promise.reject(error) // 错误继续返回给到具体页面
        }
    )
    return Axios(axiosConfig)
}

/**
 * 处理异常
 */
const httpErrorStatusHandle = (error: any) => {
    // 处理被取消的请求
    if (axios.isCancel(error))
        return console.error(`因为请求重复被自动取消:${error.message}`)
    let message = ''
    if (error && error.response) {
        switch (error.response.status) {
            case 302:
                message = '接口重定向了!'
                break
            case 400:
                message = '参数不正确!'
                break
            case 401:
                message = '您没有权限操作!'
                break
            case 403:
                message = '您没有权限操作!'
                break
            case 404:
                message = `请求地址出错:${error.response.config.url}`
                break
            case 408:
                message = '请求超时!'
                break
            case 409:
                message = '系统已存在相同数据!'
                break
            case 500:
                message = '服务器内部错误!'
                break
            case 501:
                message = '服务未实现!'
                break
            case 502:
                message = '网关错误!'
                break
            case 503:
                message = '服务不可用!'
                break
            case 504:
                message = '服务暂时无法访问,请稍后再试!'
                break
            case 505:
                message = 'HTTP版本不受支持!'
                break
            default:
                message = '异常问题,请联系网站管理员!'
                break
        }
    }
    if (error.message.includes('timeout')) {
        message = '网络请求超时!'
    }
    if (error.message.includes('Network')) {
        message = window.navigator.onLine ? '服务端异常!' : '您断网了!'
    }
    ElNotification({
        offset: 55,
        type: 'error',
        message,
    })
}

/**
 * 储存每个请求的唯一cancel回调, 以此为标识
 */
const addPending = (config: AxiosRequestConfig) => {
    const pendingKey = getPendingKey(config)
    config.cancelToken =
        config.cancelToken ||
        new axios.CancelToken((cancel) => {
            if (!pendingMap.has(pendingKey)) {
                pendingMap.set(pendingKey, cancel)
            }
        })
}

/**
 * 删除重复的请求
 */
const removePending = (config: AxiosRequestConfig) => {
    const pendingKey = getPendingKey(config)
    if (pendingMap.has(pendingKey)) {
        const cancelToken = pendingMap.get(pendingKey)
        cancelToken(pendingKey)
        pendingMap.delete(pendingKey)
    }
}

/**
 * 生成每个请求的唯一key
 */
const getPendingKey = (config: AxiosRequestConfig) => {
    let { data } = config
    const { url, method, params } = config
    if (typeof data === 'string') data = JSON.parse(data)
    return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&')
}

common.ts
// 关键字高亮替换
export const replaceKeyword = (origin: any, target: string) => {
    if (origin && typeof origin == 'string') {
        const m = pinyin.match(origin, target)
        if (m) {
            target = origin.substring(
                (m as Array)[0],
                (m as Array)[1] + 1
            )
        }
        return origin.replace(
            target,
            `${target}`
        )
    } else {
        return origin
    }
}

本文来自网络,不代表协通编程立场,如若转载,请注明出处:https://net2asp.com/26b8ead630.html