‘编程学习’ 分类下的所有文章
2024一月25

el-table 尾部汇总放在第一行

调用页面添加样式

<style scoped>
::v-deep .el-table {
    display: flex;
    flex-direction: column;
}
::v-deep .el-table__body-wrapper {
    order: 1;
}
::v-deep .el-table__fixed-body-wrapper {
    top: 92px !important;
}
::v-deep .el-table__fixed-footer-wrapper {
    z-index: 0;
    top: 45px;
}
</style>

分页组件完整代码

<template>
    <div class="data-list">
        <transition name="el-fade-in">
            <div v-show="selectRows.length > 0" class="el-selection-bar">
                选择了<span class="el-selection-bar__text">{{ selectRows.length }}</span
                >条数据
                <a class="el-selection-bar__clear" @click="clearSelection">清空</a>
            </div>
        </transition>
        <div v-loading="isRequestIng" class="data-list__table" :element-loading-text="loadingTxt">
            <span v-if="summary">总条数:{{ rows.length }}</span>
            <el-table
                v-bind="$attrs"
                ref="tabList"
                :data="rows"
                v-on="$listeners"
                :border="true"
                :span-method="handleRowSpanMethod"
                :show-summary="summary"
                sum-text=" 汇  总 "
            >
                <slot />
                <pro-empty slot="empty" />
            </el-table>
        </div>
        <div v-if="!summary && (pageData.totalCount > pageData.pageSize || pageData.pageSize > 10)" class="data-list__pager">
            <el-pagination
                :current-page="pageData.pageNo"
                :page-size="pageData.pageSize"
                :total="pageData.totalCount"
                background
                :page-sizes="pageSizes"
                layout="total, ->, prev, pager, next, sizes, jumper"
                @current-change="doChangePage"
                @size-change="doSizeChange"
            />
        </div>

    </div>
</template>

<script>
import { forIn, findIndex, cloneDeep, remove, uniqBy, concat, isArray, first } from "lodash-es"
import { f } from 'vue-marquee-component'
export default {
    name: "PlusTableList",
    props: {
        server: {
            type: String,
            require: true,
            default: ""
        },
        methods: {
            type: String,
            default: "post"
        },
        lazy: {
            type: Boolean,
            default: false
        },
        data: {
            type: Object,
            default: () => {}
        },
        dataFilter: {
            type: Function,
            default: data => data
        },
        loadingTxt: {
            type: String,
            default: "数据加载中..."
        },
        paramClear: {
            type: Boolean,
            default: false
        },
        selectRows: {
            type: Array,
            default: () => []
        },
        selectable: {
            type: Function,
            default: () => true
        },
        rowKey: {
            type: String,
            default: "id"
        },
        selection: {
            type: Boolean,
            default: true
        },
        pageSizes: {
            type: Array,
            default: () => [10, 20, 30, 50]
        },
        // 合并行(第一列)
        spanName0: {
            type: String,
            default: null
        },
        // 合并行(第二列)
        spanName1: {
            type: String,
            default: null
        },
        // 是否汇总数据
        summary: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            pageData: {
                pageNo: 1,
                pageSize: 10,
                totalCount: 0
            },
            rows: [],
            isRequestIng: false
        }
    },
    watch: {
        pageSizes: {
            handler: function (val) {
                if (isArray(val)) {
                    this.pageData.pageSize = first(val)
                }
            },
            immediate: true
        }
    },
    mounted() {
        if (!this.lazy) {
            this.getList()
        }
    },
    methods: {
        // 合并相同值的行
        handleRowSpanMethod({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 0) {
                if (!this.spanName0) return
                if (rowIndex > 0 && row[this.spanName0] === this.rows[rowIndex - 1][this.spanName0]) {
                    return {
                        rowspan: 0,
                        colspan: 0
                    }
                } else {
                    let count = 1
                    for (let i = rowIndex + 1; i < this.rows.length; i++) {
                        if (row[this.spanName0] === this.rows[i][this.spanName0]) {
                            count++
                        } else {
                            break
                        }
                    }
                    if(count>1){
                        return {
                            rowspan: count,
                            colspan: 1
                        }
                    }
                }
            }
            if (columnIndex === 1) {
                if (!this.spanName1) return
                // 第一列值相同,且第二列值相同的的情况下合并
                if (rowIndex > 0 && row[this.spanName0] === this.rows[rowIndex-1][this.spanName0] && row[this.spanName1] === this.rows[rowIndex - 1][this.spanName1]) {
                    return {
                        rowspan: 0,
                        colspan: 0
                    }
                } else {
                    let count = 1
                    for (let i = rowIndex + 1; i < this.rows.length; i++) {
                        // 第一列值相同,且第二列值相同的的情况下合并
                        if (row[this.spanName0] === this.rows[i][this.spanName0] && row[this.spanName1] === this.rows[i][this.spanName1]) {
                            count++
                        } else {
                            break
                        }
                    }
                    if(count>1){
                        return {
                            rowspan: count,
                            colspan: 1
                        }
                    }
                }
            }
        },
        // 页码变动事件
        doChangePage(val) {
            this.pageData.pageNo = val
            this.getList()
        },
        // 页大小变动事件
        doSizeChange(val) {
            this.pageData.pageSize = val
            this.pageData.pageNo = 1
            this.getList()
        },
        getList() {
            const { totalCount, ...pager } = this.pageData
            const params = Object.assign({}, this.data, pager)
            if (this.paramClear) {
                forIn(params, (value, key) => {
                    if (value === "") delete params[key]
                })
            }
            this.isRequestIng = true
            this.$get(params)
                .then(({ data }) => {
                    this.rows = this.dataFilter(data.list || [])
                    this.pageData.totalCount = data.totalCount
                    this.$emit("updateTotal", data.totalCount)
                    this.isRequestIng = false
                    this.$nextTick(() => {
                        this.handlePageUpdate()
                    })
                })
                .catch(error => {
                    this.isRequestIng = false
                })
        },
        handlePageUpdate() {
            const list = this.rows
            list.forEach(row => {
                if (
                    findIndex(this.selectRows, el => {
                        return el[this.rowKey] === row[this.rowKey]
                    }) !== -1
                ) {
                    this.$refs.tabList.toggleRowSelection(row, true)
                }
            })
        },
        handleSelectionChange(val) {
            const selectRows = cloneDeep(this.selectRows)
            this.$nextTick(() => {
                const list = this.rows.map(el => el[this.rowKey])
                remove(selectRows, el => {
                    return list.includes(el[this.rowKey])
                })
                this.$emit(
                    "update:selectRows",
                    uniqBy(concat(selectRows, val), el => el[this.rowKey])
                )
            })
        },
        $get(data) {
            if (this.methods === "get") {
                return this.$axios.get(this.server, {
                    params: data
                })
            } else {
                return this.$axios.post(this.server, data)
            }
        },
        reset() {
            this.pageData.pageNo = 1
            this.pageData.totalCount = 0
            this.rows = []
            this.clearSelection()
        },
        async clearSelection() {
            this.$refs.tabList.clearSelection()
            await this.$nextTick()
            this.$emit("update:selectRows", [])
        },
        query() {
            this.reset()
            this.getList()
        }
    }
}
</script>

2024一月24

el-table 根据条件合并行

<template>
    <div class="data-list">
        <transition name="el-fade-in">
            <div v-show="selectRows.length > 0" class="el-selection-bar">
                选择了<span class="el-selection-bar__text">{{ selectRows.length }}</span
                >条数据
                <a class="el-selection-bar__clear" @click="clearSelection">清空</a>
            </div>
        </transition>
        <div v-loading="isRequestIng" class="data-list__table" :element-loading-text="loadingTxt">
            <el-table
                v-bind="$attrs"
                ref="tabList"
                :data="rows"
                v-on="$listeners"
                :border="true"
                :span-method="handleRowSpanMethod"
            >
                <slot />
                <pro-empty slot="empty" />
            </el-table>
        </div>
        <div v-if="pageData.totalCount > pageData.pageSize || pageData.pageSize > 10" class="data-list__pager">
            <el-pagination
                :current-page="pageData.pageNo"
                :page-size="pageData.pageSize"
                :total="pageData.totalCount"
                background
                :page-sizes="pageSizes"
                layout="total, ->, prev, pager, next, sizes, jumper"
                @current-change="doChangePage"
                @size-change="doSizeChange"
            />
        </div>
    </div>
</template>

<script>
import { forIn, findIndex, cloneDeep, remove, uniqBy, concat, isArray, first } from "lodash-es"
export default {
    name: "PlusTableList",
    props: {
        server: {
            type: String,
            require: true,
            default: ""
        },
        methods: {
            type: String,
            default: "post"
        },
        lazy: {
            type: Boolean,
            default: false
        },
        data: {
            type: Object,
            default: () => {}
        },
        dataFilter: {
            type: Function,
            default: data => data
        },
        loadingTxt: {
            type: String,
            default: "数据加载中..."
        },
        paramClear: {
            type: Boolean,
            default: false
        },
        selectRows: {
            type: Array,
            default: () => []
        },
        selectable: {
            type: Function,
            default: () => true
        },
        rowKey: {
            type: String,
            default: "id"
        },
        selection: {
            type: Boolean,
            default: true
        },
        pageSizes: {
            type: Array,
            default: () => [10, 20, 30, 50]
        },
        spanName0: {
            type: String,
            default: null
        },
        spanName1: {
            type: String,
            default: null
        }
    },
    data() {
        return {
            pageData: {
                pageNo: 1,
                pageSize: 10,
                totalCount: 0
            },
            rows: [],
            isRequestIng: false
        }
    },
    watch: {
        pageSizes: {
            handler: function (val) {
                if (isArray(val)) {
                    this.pageData.pageSize = first(val)
                }
            },
            immediate: true
        }
    },
    mounted() {
        if (!this.lazy) {
            this.getList()
        }
    },
    methods: {
        // 合并相同值的行
        handleRowSpanMethod({ row, column, rowIndex, columnIndex }) {
            if (columnIndex === 0) {
                if (!this.spanName0) return
                if (rowIndex > 0 && row[this.spanName0] === this.rows[rowIndex - 1][this.spanName0]) {
                    return {
                        rowspan: 0,
                        colspan: 0
                    }
                } else {
                    let count = 1
                    for (let i = rowIndex + 1; i < this.rows.length; i++) {
                        if (row[this.spanName0] === this.rows[i][this.spanName0]) {
                            count++
                        } else {
                            break
                        }
                    }
                    if(count>1){
                        return {
                            rowspan: count,
                            colspan: 1
                        }
                    }
                }
            }
            if (columnIndex === 1) {
                if (!this.spanName1) return
                // 第一列值相同,且第二列值相同的的情况下合并
                if (rowIndex > 0 && row[this.spanName0] === this.rows[rowIndex-1][this.spanName0] && row[this.spanName1] === this.rows[rowIndex - 1][this.spanName1]) {
                    return {
                        rowspan: 0,
                        colspan: 0
                    }
                } else {
                    let count = 1
                    for (let i = rowIndex + 1; i < this.rows.length; i++) {
                        // 第一列值相同,且第二列值相同的的情况下合并
                        if (row[this.spanName0] === this.rows[i][this.spanName0] && row[this.spanName1] === this.rows[i][this.spanName1]) {
                            count++
                        } else {
                            break
                        }
                    }
                    if(count>1){
                        return {
                            rowspan: count,
                            colspan: 1
                        }
                    }
                }
            }
        },
        // 页码变动事件
        doChangePage(val) {
            this.pageData.pageNo = val
            this.getList()
        },
        // 页大小变动事件
        doSizeChange(val) {
            this.pageData.pageSize = val
            this.pageData.pageNo = 1
            this.getList()
        },
        getList() {
            const { totalCount, ...pager } = this.pageData
            const params = Object.assign({}, this.data, pager)
            if (this.paramClear) {
                forIn(params, (value, key) => {
                    if (value === "") delete params[key]
                })
            }
            this.isRequestIng = true
            this.$get(params)
                .then(({ data }) => {
                    this.rows = this.dataFilter(data.list || [])
                    this.pageData.totalCount = data.totalCount
                    this.$emit("updateTotal", data.totalCount)
                    this.isRequestIng = false
                    this.$nextTick(() => {
                        this.handlePageUpdate()
                    })
                })
                .catch(error => {
                    this.isRequestIng = false
                })
        },
        handlePageUpdate() {
            const list = this.rows
            list.forEach(row => {
                if (
                    findIndex(this.selectRows, el => {
                        return el[this.rowKey] === row[this.rowKey]
                    }) !== -1
                ) {
                    this.$refs.tabList.toggleRowSelection(row, true)
                }
            })
        },
        handleSelectionChange(val) {
            const selectRows = cloneDeep(this.selectRows)
            this.$nextTick(() => {
                const list = this.rows.map(el => el[this.rowKey])
                remove(selectRows, el => {
                    return list.includes(el[this.rowKey])
                })
                this.$emit(
                    "update:selectRows",
                    uniqBy(concat(selectRows, val), el => el[this.rowKey])
                )
            })
        },
        $get(data) {
            if (this.methods === "get") {
                return this.$axios.get(this.server, {
                    params: data
                })
            } else {
                return this.$axios.post(this.server, data)
            }
        },
        reset() {
            this.pageData.pageNo = 1
            this.pageData.totalCount = 0
            this.rows = []
            this.clearSelection()
        },
        async clearSelection() {
            this.$refs.tabList.clearSelection()
            await this.$nextTick()
            this.$emit("update:selectRows", [])
        },
        query() {
            this.reset()
            this.getList()
        }
    }
}
</script>
2023八月10

Nutz Https请求忽略SSL证书

@IocBean
@Slf4j
public class CimApiServer {
    @Inject
    private RedisService redisService;
    private String redis_key = "cim:accessToken";
    @Inject
    @Reference(check = false)
    private ISysConfigProvider sysConfigProvider;

    public String getAccessToken() {
        String token = redisService.get(redis_key);
        if (Strings.isBlank(token)) {
            token = this.getHttpToken();
            redisService.setex(redis_key, 3600 * 24 - 100, token);
        }
        return token;
    }

    private String getHttpToken() {
        String CIM_GIS_APPID = sysConfigProvider.getString("COMMON", "CIM_GIS_APPID");
        String CIM_GIS_HTTP_BASE = sysConfigProvider.getString("COMMON", "CIM_GIS_HTTP_BASE");
        String CIM_GIS_APPKEY = sysConfigProvider.getString("COMMON", "CIM_GIS_APPKEY");
        String CIM_GIS_APPSECRET = sysConfigProvider.getString("COMMON", "CIM_GIS_APPSECRET");
        Map<String, Object> params = new HashMap<>();
        params.put("apiKey", CIM_GIS_APPKEY);
        params.put("secret", CIM_GIS_APPSECRET);
        Header header = Header.create();
        header.addv("Content-Type", "application/json");
        Request request = Request.create(CIM_GIS_HTTP_BASE + "/auth/getAccessToken", Request.METHOD.POST);
        request.setHeader(header);
        request.setData(Json.toJson(params));

        Sender sender = Sender.create(request).setTimeout(20 * 1000);
        if (CIM_GIS_HTTP_BASE.startsWith("https")) {
            try {
                SSLContext sslcontext = createIgnoreVerifySSL();
                sender.setSSLSocketFactory(sslcontext.getSocketFactory());
                sender.setHostnameVerifier((urlHostName, session) -> true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        Response response = sender.send();
        if (response.isOK()) {
            NutMap map = Json.fromJson(NutMap.class, response.getContent());
            log.debug("getHttpToken:::" + Json.toJson(map));
            if (0 == map.getInt("code")) {
                return map.getString("data");
            }
        }
        return "";
    }

    private static class TrustAllManager
            implements X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public void checkServerTrusted(X509Certificate[] certs,
                                       String authType) {
        }

        public void checkClientTrusted(X509Certificate[] certs,
                                       String authType) {
        }
    }


    public SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, new TrustManager[]{new TrustAllManager()}, null);
        return sc;
    }
}
2023七月31

Uniapp 嵌入 H5 调用原生扫码功能

Uniapp 权限设置

"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",

Uniapp Webview 源码

<template>
	<view>
		<web-view :webview-styles="webviewStyles" src="http://192.168.4.108:5001/h5/" @message="showMessage"></web-view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				webviewStyles: {
					progress: {
						color: '#FF3333'
					}
				},
				qrCodeWv: null
			}
		},
		onReady() {
			// #ifdef APP-PLUS
			let currentWebview = this.$scope.$getAppWebview()
			setTimeout(() => {
				this.wv = currentWebview.children()[0]
				this.qrCodeWv = currentWebview.children()[0]
				this.wv.setStyle({scalable:true})
			},1000)
			// #endif
		},
		methods: {
			showMessage(event) {
				if(event.detail.data && event.detail.data.length >0){
					let dataInfo = event.detail.data[0]
					console.log(dataInfo)
					let type = dataInfo.type
					if(type==='scanCode') {
						this.startScanCode()
					}
				}
			},
			startScanCode() {
				const self = this 
				uni.scanCode({
					onlyFromCamera: false,
					scanType: ['qrCode'],
					success: function(res) {
						setTimeout(() => {
							const result = res.result.replace(/'/g,'"')
							self.qrCodeWv.evalJS(`appScanCodeResult('${result}')`)
						})
					},
					complete: function(args){
						console.log(args)
					}
				})
			}
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

H5 Vue项目引入js

index.html 引入 public/js 下文件

<script src="<%= BASE_URL %>js/uni.webview.1.5.4.js"></script>

H5 main.js 定义回调方法和对象

window.appScanCodeResult = function (val) {
    window.appScanCodeResultString = val
    window.dispatchEvent(new CustomEvent("scanCodeResult"))
}

H5 Vue扫码页面代码

created() {
        this.getDetailData()
        window.addEventListener("scanCodeResult", this.handleAppScanCode, false)
        document.addEventListener("UniAppJSBridgeReady", function () {
            uni.getEnv(function (res) {
                console.log("获取当前环境:" + JSON.stringify(res))
            })
        })
    },
    onBeforeDestroy() {
        window.removeEventListener("scanCodeResult", this.handleAppScanCode)
    },
    methods: {
        handleAppScanCode() {
            const result = window.appScanCodeResultString
            this.onScanSuccess(result)
        },
        // 扫码
        saoCode() {
            uni.postMessage({
                data: {
                    type: "scanCode"
                }
            })
        },
        //扫码成功
        onScanSuccess(val) {
            this.tankCode = val
            this._getFillingTankInfo()
        }
}
2023六月21

Windows 11 激活

irm https://massgrave.dev/get | iex
2023五月10

MacOS m1 安装 redisjson 插件

下载redisjson源码

https://github.com/RedisJSON/RedisJSON/releases

安装rustup

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rutsc --version

编译redisjson

cargo build --release

修改redis.conf配置

loadmodule /usr/local/redis/module/librejson.dylib

重新启动 redis 后显示如下信息即可:

127.0.0.1:6379> module list
1) 1) "name"
   2) "ReJSON"
   3) "ver"
   4) (integer) 20407
2023三月7

记录本站wordpress 迁移 Alibaba Linux OS过程

yum install php

yum install php-fpm

yum install php-mysqlnd.x86_64

yum install php-json

yum install nginx

yum install mariadb

yum install mariadb-server

vi /etc/php-fpm.d/www.conf

linsten = 127.0.0.1:9000

systemctl start nginx

systemctl enable nginx

systemctl start php-fpm

systemctl enable php-fpm

systemctl start mariadb

systemctl enable mariadb

mysql_secure_installation 修改密码

grant all privileges on . to ‘root’@’1.1.1.1’ identified by ‘password’ with grant option;

flush privileges;

2023二月14

Linux(CentOS) 安装Python3.7 和 pip3

安装 python3 运行环境

yum install -y zlib zlib-devel libaio net-tools bzip2-devel pcre-devel openssl-devel ncurses-devel sqlite-devel readline-devel python3-devel tk-devel gcc cmake gcc-c++ make libffi-devel mesa-libGL.x86_64 wget git

安装 pip3 运行环境

yum install zlib*

下载 Python3 安装包

wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz

tar -xxf Python-3.7.9.tar.xz

cd Python-3.7.9

vi Modules/Setup.dist

#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz

前面的 # 符号去掉

:wq

安装新版 openssh

wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
tar -xxf openssl-1.1.1a.tar.gz
cd openssl-1.1.1a/
./config --prefix=/usr/local/openssl
make & make install

安装 python3

./configure --prefix=/usr/local/python3 --with-openssl=/usr/local/openssl

make && make install

创建 python3 软链接

ln -s /usr/local/python3/bin/python3.7 /usr/bin/python3

下载 pip3 安装脚本

wget https://bootstrap.pypa.io/get-pip.py

安装 pip3

python3 get-pip.py

创建 pip3 软链接

ln -s /usr/local/python3/bin/pip3 /usr/bin/pip3

2022十一月2

使用ffmpeg 将 g729 wav转为mp3

ffmpeg -c:a g729 -ac 1 -i /Users/wizzer/temp/9_729.wav /Users/wizzer/temp/9_729.mp3
2022九月22

数据库文档生成工具Java

 <dependency>
      <groupId>cn.smallbun.screw</groupId>
      <artifactId>screw</artifactId>
      <version>1.0.5</version>
      <scope>import</scope>
 </dependency>

public void generate() throws Exception {
        //数据源
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");
        hikariConfig.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/xx?useUnicode=true&characterEncoding=utf8&useSSL=false" +
                "&serverTimezone=Asia/Shanghai");
        hikariConfig.setUsername("root");
        hikariConfig.setPassword("root");
        //设置可以获取tables remarks信息
        hikariConfig.addDataSourceProperty("useInformationSchema", "true");
        hikariConfig.setMinimumIdle(2);
        hikariConfig.setMaximumPoolSize(5);
        DataSource dataSource = new HikariDataSource(hikariConfig);
        //生成配置
        String fileOutputDir = "./";
        EngineConfig engineConfig = EngineConfig.builder()
                //生成文件路径
                .fileOutputDir(fileOutputDir)
                //打开目录
                .openOutputDir(true)
                //文件类型
                .fileType(EngineFileType.WORD)
                //生成模板实现
                .produceType(EngineTemplateType.velocity)
                //自定义文件名称
                .fileName("xx数据库说明").build();

        //忽略表
        ArrayList<String> ignoreTableName = new ArrayList<>();
        //忽略表前缀
        ArrayList<String> ignorePrefix = new ArrayList<>();
        ignorePrefix.add("sys_qrtz_");
        //忽略表后缀
        ArrayList<String> ignoreSuffix = new ArrayList<>();
//        ignoreSuffix.add("_");
        ProcessConfig processConfig = ProcessConfig.builder()
                //指定生成逻辑、当存在指定表、指定表前缀、指定表后缀时,将生成指定表,其余表不生成、并跳过忽略表配置
                //根据名称指定表生成
                .designatedTableName(null)
                //根据表前缀生成
                .designatedTablePrefix(null)
                //根据表后缀生成
                .designatedTableSuffix(null)
                //忽略表名
                .ignoreTableName(ignoreTableName)
                //忽略表前缀
                .ignoreTablePrefix(ignorePrefix)
                //忽略表后缀
                .ignoreTableSuffix(ignoreSuffix).build();
        //配置
        Configuration config = Configuration.builder()
                //版本
                .version("1.0.0")
                //描述
                .description("数据库设计文档生成")
                //数据源
                .dataSource(dataSource)
                //生成配置
                .engineConfig(engineConfig)
                //生成配置
                .produceConfig(processConfig)
                .build();
        //执行生成
        new DocumentationExecute(config).execute();
    }