summary.vue 15.7 KB
<template>
    <div class="app-container">
        <el-form :inline="true" ref="form" :model="form" size="mini">
            <el-form-item label="标题" prop="uuid">
                <el-select v-model="form.uuid" filterable placeholder="请输入标题">
                    <el-option v-for="(item, index) in roles" :key="index" :label="item.name" :value="item.uuid"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item>
            <el-form-item><el-button @click="onReset">重置</el-button></el-form-item>
            <el-form-item><el-button type="warning" @click="onAdd">添加</el-button></el-form-item>
            <el-form-item>
                <el-popover placement="top-start" width="240" trigger="click">
                    <el-checkbox-group :min="1" v-model="checkList" @change="onCheckboxChange">
                        <el-checkbox :label="item" v-for="(item, index) in headerList" :key="index"></el-checkbox>
                    </el-checkbox-group>
                    <el-button type="success" slot="reference">表头设置</el-button>
                </el-popover>
            </el-form-item>
            <el-form-item>
                <el-button type="info" plain @click="handleDownload">导出当前数据</el-button>
            </el-form-item>
        </el-form>
        <el-table v-loading="isLoading" element-loading-text="Loading" :data="list" size="mini" border stripe fit highlight-current-row>
            <el-table-column :prop="item.prop" :label="item.label" :align="item.align" :min-width="item.width" v-for="(item, index) in tableHeader" :key="index"></el-table-column>
            <el-table-column prop="create_at" label="创建时间" width="150"></el-table-column>
            <el-table-column prop="create_by.username" label="创建者" width="150"></el-table-column>
            <el-table-column prop="update_at" label="更新时间" width="150" :show-overflow-tooltip="true"></el-table-column>
            <el-table-column prop="update_by.username" label="更新者" width="150"></el-table-column>
            <el-table-column label="操作" align="center" width="180" fixed="right">
                <template slot-scope="scope">
                    <el-button size="mini" type="success" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <div class="page-wrapper">
            <el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total"></el-pagination>
        </div>
        <el-dialog
            :title="dialogTitle"
            :visible.sync="dialogVisible"
            width="50%"
        >
            <el-form :model="post" status-icon :rules="rules" :inline="true" ref="post" size="mini" label-width="200px">
                <el-form-item label="标题" prop="name">
                    <el-input type="text" v-model="post.name" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="年度调派现场总天数" prop="year_dispatch_site_days">
                    <el-input type="number" v-model.number="post.year_dispatch_site_days" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="年度监督流失率" prop="year_supervise_churn_rate">
                    <el-input type="number" v-model.number="post.year_supervise_churn_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="年度再认证流失率" prop="year_recert_churn_rate">
                    <el-input type="number" v-model.number="post.year_recert_churn_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="年度顾客满意率" prop="year_satis_churn_rate">
                    <el-input type="number" v-model.number="post.year_satis_churn_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="年度应收款回款率" prop="year_receiv_collection_rate">
                    <el-input type="number" v-model.number="post.year_receiv_collection_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="行业项目比率" prop="indus_project_rate">
                    <el-input type="number" v-model.number="post.indus_project_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="渠道开发项目比率" prop="channel_project_rate">
                    <el-input type="number" v-model.number="post.channel_project_rate" autocomplete="off"><template slot="append">%</template></el-input>
                </el-form-item>
                <el-form-item label="年度坏账终止项目数" prop="year_bad_project">
                    <el-input type="number" v-model.number="post.year_bad_project" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="年度坏账金额" prop="year_bad_debt_amount">
                    <el-input type="number" v-model.number="post.year_bad_debt_amount" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="行业项目数量" prop="indus_project_count">
                    <el-input type="number" v-model.number="post.indus_project_count" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="渠道开发项目数量" prop="channel_project_count">
                    <el-input type="number" v-model.number="post.channel_project_count" autocomplete="off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button type="primary" size="mini" plain @click="submitForm('post')">提交</el-button>
                <el-button type="success" size="mini" plain @click="onReset('form')">重置</el-button>
                <el-button size="mini" @click="dialogVisible = false">关闭</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
import { getSummaryList, deleteSummary, addSummary, updateSummary } from '@/api/index'
import { mapTrim } from '@/utils/index'
import { exportJsonToExcel } from "@/utils/excel"

const fieldList = [
  { label: "标题", prop: "name", isShow: true },
  { label: "年度监督流失率", prop: "year_supervise_churn_rate", isShow: true },
  { label: "年度再认证流失率", prop: "year_recert_churn_rate", isShow: true },
  { label: "年度顾客满意率", prop: "year_satis_churn_rate", isShow: true },
  { label: "年度应收款回款率", prop: "year_receiv_collection_rate", isShow: true },
  { label: "行业项目比率", prop: "indus_project_rate", isShow: true },
  { label: "渠道开发项目比率", prop: "channel_project_rate", isShow: true },
  { label: "年度调派现场总天数", prop: "year_dispatch_site_days", isShow: false },
  { label: "年度坏账终止项目数", prop: "year_bad_project", isShow: false },
  { label: "年度坏账金额", prop: "year_bad_debt_amount", isShow: false },
  { label: "行业项目数量", prop: "indus_project_count", isShow: false },
  { label: "渠道开发项目数量", prop: "channel_project_count", isShow: false },
]

const tableHeader = fieldList.filter(item => {
  if (item.isShow) return Object.assign(item, { align: "center", width: "150" })
})

export default {
    name: "Summary",
    data() {
        return {
            total: 0,
            list: [],
            isLoading: false,
            checkList: tableHeader.map(item => item.label),
            headerList: fieldList.map(item => item.label),
            tableHeader: tableHeader,
            roles: [],
            form: {
                uuid: null,
                name: null,
                pagesize: 15,
                pagenum: 1
            },
            currentIndex: 0,
            currentValue: null,
            dialogTitle: "",
            dialogVisible: false,
            post: {
                name: null,
                year_supervise_churn_rate: null,
                year_recert_churn_rate: null,
                year_satis_churn_rate: null,
                year_dispatch_site_days: null,
                year_receiv_collection_rate: null,
                year_bad_project: null,
                year_bad_debt_amount: null,
                indus_project_rate: null,
                indus_project_count: null,
                channel_project_rate: null,
                channel_project_count: null,
            },
            rules: {
                year_supervise_churn_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_recert_churn_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_satis_churn_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_dispatch_site_days: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_receiv_collection_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_bad_project: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                year_bad_debt_amount: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                indus_project_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                indus_project_count: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                channel_project_rate: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                channel_project_count: [{ type: 'number', required: true, message: '字段不能为空', trigger: 'blur' }],
                name: [
                    { type: 'string', required: true, message: '用户名不能为空', trigger: 'blur' },
                    { min: 1, max: 20, message: '字符串长度在 1 到 20 之间', trigger: 'blur' }
                ]
            }
        }
    },
    methods: {
        fetchData(params) {
            this.isLoading = true
            getSummaryList(params).then(res => {
                this.total = res.count
                this.list = res.data
            }).catch(err => {
                // this.$message.error(err.message)
                console.log(err.message)
            }).finally(() => {
                this.isLoading = false
            })
        },
        fetchSelectData() {
            getSummaryList({ "scope_type": "list" }).then(res => {
                if (res.code == 200) this.roles = res.data
            }).catch(err => {
                // this.$message.error(err.message)
                console.log(err.message)
            })
        },
        handleSizeChange(e) {
            this.form.pagesize = e
            this.fetchData(mapTrim(this.form))
        },
        handleCurrentChange(e) {
            this.form.pagenum = e
            this.fetchData(mapTrim(this.form))
        },
        handleEdit(index, row) {
            this.post = Object.assign(row)
            this.currentIndex = index
            this.currentValue = row
            this.dialogTitle = "编辑"
            this.dialogVisible = true
        },
        handleDelete(index, row) {
            this.$alert('您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。', '删除提醒', {
                confirmButtonText: '确定',
                callback: action => {
                    if (action == 'confirm') deleteSummary(row.uuid).then(res => {
                        console.log(res)
                        this.total -= 1
                        this.$delete(this.list, index)
                        this.$message({ type: 'success', message: `成功删除第${ index }行` })
                    }).catch(err => {
                        this.$message.error(err.message)
                    })
                }
            })
        },
        submitForm(formName) {
            this.$refs[formName].validate((valid) => {
                let result = true
                if (valid) {
                    if (this.dialogTitle === '添加') addSummary(mapTrim(this.post)).then(res => {
                        console.log(res)
                        this.$message({ type: 'success', message: '添加成功' })
                        this.fetchData(mapTrim(this.form))
                    }).catch(err => {
                        this.$message.error(err.message)
                    })
                    else if (this.dialogTitle === '编辑') updateSummary(this.currentValue.uuid, this.post).then(res => {
                        console.log(res)
                        // this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp))
                        this.$message({ type: 'success', message: '更新成功' })
                        this.fetchData(mapTrim(this.form))
                    }).catch(err => {
                        this.$message.error(err.message)
                    })
                } else {
                    result = false
                }
                this.dialogVisible = false
                return result
            })
        },
        handleDownload() {
            const loading = this.$loading({
                lock: true,
                text: 'Loading',
                spinner: 'el-icon-loading',
                background: 'rgba(0, 0, 0, 0.7)'
            })
            getSummaryList({ "scope_type": "list", "props": this.tableHeader.map(item => item.prop) })
                .then((res) => {
                    exportJsonToExcel({
                        header: this.tableHeader,
                        headerLabel: "label",
                        headerProp: "prop",
                        jsonData: res.data,
                        filename: Date.now()
                    })
                })
                .catch((err) => {
                    this.$message.warning(err.message)
                }).finally(() => {
                    loading.close()
                })
        },
        onCheckboxChange(evt) {
            let header = []
            evt.forEach(f => {
                for(let i = 0 ; i < fieldList.length; i++) {
                    if (fieldList[i].label === f) {
                        header.push(Object.assign(fieldList[i], { align: "center", width: "150" }))
                        break
                    }
                }
            })
            this.tableHeader = header
        },
        onAdd() {
            this.dialogTitle = "添加"
            this.dialogVisible = true
        },
        onSubmit() {
            this.form.pagenum = 1
            this.form.pagesize = 15
            this.fetchData(mapTrim(this.form))
        },
        onReset(formName) {
            this.$refs[formName].resetFields()
            this.form.pagesize = 15
            this.form.pagenum = 1
            this.fetchData(mapTrim(this.form))
        }
    },
    mounted() {},
    created() {
        this.fetchData(mapTrim(this.form))
        this.fetchSelectData()
    }
}
</script>
<style lang="scss" scoped>
.app-container {
    & > div.page-wrapper {
        margin: 10px 0px;
    }
}
</style>