<template>
    <div>
        <!--    面包屑导航区    -->
        <el-breadcrumb separator="/">
            <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
            <el-breadcrumb-item>代码覆盖率管理</el-breadcrumb-item>
            <el-breadcrumb-item>查看覆盖率</el-breadcrumb-item>
        </el-breadcrumb>
        <!--    卡片    -->
        <el-card>
            <!--    搜索    -->
            <el-form :inline="true" :model="queryReportParam">
                <el-form-item label="项目名称">
                    <el-select v-model="queryReportParam.projectName" filterable placeholder="请选择项目名称" @change="changeProjectName($event)" clearable>
                        <el-option v-for="(item, index) in projectNameList" :label="item" :value="item" :key="index"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="子模块名称" v-if="isMultiModuleProject">
                    <el-select v-model="queryReportParam.moduleName" placeholder="请选择项目子模块" clearable>
                        <el-option v-for="(item, index) in moduleNameList" :label="item" :value="item" :key="index"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="分支名称">
                    <el-input v-model="queryReportParam.branch" placeholder="请输入分支名称"></el-input>
                </el-form-item>
                <el-form-item label="环境名称">
                    <el-input v-model="queryReportParam.env" placeholder="请输入环境名称"></el-input>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="queryReportByPage">查询</el-button>
                </el-form-item>
            </el-form>
            <!--    列表    -->
            <el-table :data="reportTable" style="width: 100%"
                      border :header-cell-style="{'text-align':'center'}" :cell-style="{'text-align':'center'}">
                <el-table-column type="index" />
                <el-table-column prop="projectName" label="项目名称" min-width="200px" showOverflowTooltip/>
                <el-table-column prop="moduleName" label="子模块名称" :formatter="moduleNameFormatter" min-width="200px" showOverflowTooltip/>
                <el-table-column prop="branch" label="分支" showOverflowTooltip/>
                <el-table-column prop="baseBranch" label="基准分支" showOverflowTooltip/>
                <el-table-column prop="env" label="环境" showOverflowTooltip/>
                <el-table-column prop="linesTotal" label="行覆盖率" :formatter="calculateLinesCov" showOverflowTooltip/>
                <el-table-column prop="linesMiss" label="未覆盖行数" min-width="100px" showOverflowTooltip/>
                <el-table-column prop="linesCov" label="总行数" showOverflowTooltip/>
                <el-table-column prop="branchMiss" label="分支未覆盖比例" min-width="120px" showOverflowTooltip/>
                <el-table-column prop="branchCov" label="分支覆盖比例" min-width="120px" showOverflowTooltip/>
                <el-table-column prop="reportType" label="报告类型" :formatter="reportTypeFormatter" showOverflowTooltip/>
                <el-table-column prop="reportAddr" label="报告访问地址" align="center" min-width="120px" showOverflowTooltip>
                    <template slot-scope="scoop">
                        <el-link :href="scoop.row.reportAddr" type="primary" target="_blank" v-if="scoop.row.state === 6">查看报告<i class="el-icon-view el-icon--right" /></el-link>
                    </template>
                </el-table-column>
                <el-table-column label="状态" min-width="120px" showOverflowTooltip>
                    <template slot-scope="scope">
                        <span :style="{color: successList.indexOf(scope.row.state) === -1 ? '#f56c6c': '#67c23a'}">{{ stateMap[scope.row.state] }}</span>
                    </template>
                </el-table-column>
                <el-table-column label="报告的时间范围" min-width="190px" showOverflowTooltip>
                    <template slot-scope="scope" v-if="scope.row.startTime !== '' && scope.row.endTime !== '' && scope.row.startTime !== null && scope.row.endTime !== null">
                        {{ dateFormatter(scope.row.startTime) + ' 至 ' + dateFormatter(scope.row.endTime)}}
                    </template>
                </el-table-column>
                <el-table-column prop="createTime" label="创建时间" :formatter="createDateFormatter" min-width="180px" showOverflowTooltip/>
                <el-table-column prop="reportAddr" label="操作" align="center" min-width="100px" showOverflowTooltip>
                    <template slot-scope="scoop">
                        <el-button type="warning" @click="queryReportDetailById(scoop.row.id)" v-if="scoop.row.state === 6">详情</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <!--    分页    -->
            <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="queryReportParam.page"
                :page-sizes="[10, 20, 50, 100, 200]"
                :page-size="queryReportParam.size"
                layout="total, sizes, prev, pager, next, jumper"
                :total="reportTotal">
            </el-pagination>
            <!--    详情页  -->
            <el-dialog title="包-覆盖率详情" :visible.sync="dialogVisible" width="70%" :before-close="reportDetailTableClose">
                <!--   详情表格   -->
                <el-table :data="reportDetailTable" style="{width: 100%}"
                          border :header-cell-style="{'text-align':'center'}" :cell-style="{'text-align':'center'}">
                    <el-table-column type="index" />
                    <el-table-column prop="packageName" label="包名" min-width="300px" />
                    <el-table-column prop="branchCov" label="分支覆盖" min-width="100px" />
                    <el-table-column prop="linesTotal" label="行覆盖率" min-width="100px">
                        <template slot-scope="scope">
                            {{ scope.row.linesMiss === '' || scope.row.linesMiss === null || scope.row.linesCov === '' || scope.row.linesCov === null ? '' : (((parseInt((scope.row.linesCov).replace(/,/g, "")) - parseInt((scope.row.linesMiss).replace(/,/g, ""))) / parseInt((scope.row.linesCov).replace(/,/g, ""))) * 100).toFixed(0) + '%' }}
                        </template>
                    </el-table-column>
                    <el-table-column prop="linesMiss" label="未覆盖行数" />
                    <el-table-column prop="linesCov" label="行总数" />
                    <el-table-column prop="methodsMiss" label="方法未覆盖数" />
                    <el-table-column prop="methodsCov" label="方法总数" />
                    <el-table-column prop="classesMiss" label="类未覆盖数" />
                    <el-table-column prop="classesCov" label="类总数" />
                </el-table>
                <!--   详情分页   -->
                <el-pagination
                    @size-change="handleReportDetailSizeChange"
                    @current-change="handleReportDetailCurrentChange"
                    :current-page="queryReportDetailParam.page"
                    :page-sizes="[10, 20, 50, 100, 200]"
                    :page-size="queryReportDetailParam.size"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="reportDetailTotal">
                </el-pagination>
                <span slot="footer" class="dialog-footer">
                    <el-button @click="dialogVisible = false">取 消</el-button>
                    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
                </span>
            </el-dialog>
        </el-card>
    </div>
</template>

<script>
export default {
    name: "JacocoReport",
    data() {
        return {
            // 分页查询报告参数
            queryReportParam: {
                projectName: null,
                moduleName: null,
                branch: null,
                evn: null,
                page: 1,
                size: 10
            },
            // 项目与模块的映射表
            moduleNameMap: {},
            // 模块名称列表
            moduleNameList: [],
            // 项目名称列表
            projectNameList: [],
            // 是否展示子模块下拉选项框
            isMultiModuleProject: false,
            // 覆盖率列表展示数据
            reportTable: [],
            // 报告总条数
            reportTotal: 0,
            linesTotal: "",
            stateMap: {
                0: '报告生成中',
                1: '代码克隆失败',
                2: '代码切换分支失败',
                3: '编译失败',
                4: '报告生成失败',
                5: '同步静态资源失败',
                6: '报告生成完成'
            },
            // 报告类型字典
            reportTypeMap: {
              0: '',
              1: '全量',
              2: '增量',
              3: '增量[基于branch对比]',
              4: '增量[基于tag对比]'
            },
            successList: [0, 6],
            // 报告详情分页查询参数
            queryReportDetailParam: {
                reportId: null,
                page: 1,
                size: 10
            },
            // 报告详情总条数
            reportDetailTotal: 0,
            // 报告详情数据列表
            reportDetailTable: [],
            dialogVisible: false,
        }
    },
    methods: {
        // 监听项目选择变更事件
        changeProjectName(name) {
            this.moduleNameList = null;
            if (this.moduleNameMap[name] !== undefined && JSON.parse(JSON.stringify(this.moduleNameMap[name])).length > 0 && JSON.parse(JSON.stringify(this.moduleNameMap[name]))[0] !== null) {
                this.isMultiModuleProject = true;
                this.moduleNameList = this.moduleNameMap[name];
            } else {
                this.isMultiModuleProject = false;
                this.moduleNameList = []
                this.queryReportParam.moduleName = null;
            }
        },
        // 查询覆盖率
        async queryReportByPage() {
            const res = await this.$api.post("/jacoco/report/queryReportByPage", this.queryReportParam)
            if (res.code !== 200) return this.$message.error(res.message)
            this.reportTable = res.data.records;
            this.reportTotal = res.data.total;
        },
        // 查询所有项目和项目下服务模块
        async queryProjectServiceModule() {
            const res = await this.$api.get("/sonar/project/config/queryAllProjectAndServiceModule")
            if (res.code !== 200) return this.$message.error(res.message)
            this.projectNameList = res.data['project'];
            this.moduleNameMap = res.data['module'];
        },
        // 监听页大小改变的事件
        handleSizeChange(newSize) {
            this.queryReportParam.size = newSize;
            this.queryReportByPage()
        },
        // 监听页码改变的事件
        handleCurrentChange(newPage) {
            this.queryReportParam.page = newPage;
            this.queryReportByPage()
        },
        // ------------------------------------------------
        // 查询报告详情
        async queryReportDetailById(reportId){
            this.queryReportDetailParam.reportId = reportId;
            const res = await this.$api.post('/jacoco/report/detail/queryReportDetailById', this.queryReportDetailParam)
            if (res.code !== 200) return this.$message.error(res.message)
            this.reportDetailTable = res.data.records;
            this.reportDetailTotal = res.data.total;
            this.dialogVisible = true;
        },
        // 监听报告详情关闭事件
        reportDetailTableClose(){
            this.dialogVisible = false;
            // 清空表单数据
            this.reportDetailTable = [];
            // 重置reportId值为null
            this.queryReportDetailParam.reportId = null;
            this.queryReportDetailParam.page = 1;
            this.queryReportDetailParam.size = 10;
        },
        // 修改页大小
        handleReportDetailSizeChange(newSize) {
            this.queryReportDetailParam.size = newSize;
            this.queryReportDetailById()
        },
        // 修改页码
        handleReportDetailCurrentChange(newPage) {
            this.queryReportDetailParam.page = newPage;
            this.queryReportDetailById()
        },
        // 格式化报告日期段
        dateFormatter(value){
            if (value === null) return ''
            const dt = new Date(value)
            const y = dt.getFullYear()
            const m = (dt.getMonth() + 1 + '').padStart(2, '0')
            const d = (dt.getDate() + '').padStart(2, '0')
            return `${y}-${m}-${d}`
        },
        // 创建日期格式化
        createDateFormatter(row, column, cellValue){
            if (cellValue === null) return ''
            const dt = new Date(cellValue)
            const y = dt.getFullYear()
            const m = (dt.getMonth() + 1 + '').padStart(2, '0')
            const d = (dt.getDate() + '').padStart(2, '0')
            const hh = (dt.getHours() + '').padStart(2, '0')
            const mm = (dt.getMinutes() + '').padStart(2, '0')
            const ss = (dt.getSeconds() + '').padStart(2, '0')
            return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
        },
        // 子模块名称格式化
        moduleNameFormatter(row, column, cellValue) {
            return cellValue !== null ? cellValue : '-'
        },
        // 行覆盖率格式化(计算)
        calculateLinesCov (row){
            if (row.linesMiss === '' || row.linesMiss === null || row.linesCov === '' || row.linesCov === null){
                return ''
            }else {
                return (((parseInt((row.linesCov).replace(/,/g, "")) - parseInt((row.linesMiss).replace(/,/g, ""))) / parseInt((row.linesCov).replace(/,/g, ""))) * 100).toFixed(0) + '%';
            }
        },
        // 报告类型展示格式化
        reportTypeFormatter(row, column, cellValue) {
            return this.reportTypeMap[cellValue];
        }
    },
    created() {
        // 查询当前全部的项目集合与模块映射数据
        this.queryProjectServiceModule();
        // 进入页面就查询一次报告
        this.queryReportByPage();
    }
}
</script>
<style lang="less" scoped>
    .el-breadcrumb {
        height: 32px;
        line-height: 32px;
    }
    .el-table /deep/ .cell {
        white-space: nowrap;
    }
    .el-card {
        box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important;
        .el-table {
            margin-top: 15px;
            margin-bottom: 15px;
        }
        .el-pagination {
            text-align: center;
            margin-top: 15px;
        }
    }
</style>
