vue3中,el-table级联表格——default-expand-all & row-key & show-overflow-tooltip & 树状表格计算总价合计总计

vue3中,el-table级联表格——default-expand-all & row-key & show-overflow-tooltip & 树状表格计算总价合计总计

效果

在这里插入图片描述

代码
1、静态页面
<!--
@Description 项目管理 - 预算编制
@author wdd
@date 2023/11/11
-->
<template>
    <div id="budgetInfo">
        <centerHead title="预算编制"></centerHead>
        <div class="content">
            <div class="title">
                <el-button type="primary" @click="onSave">保存</el-button>
                <el-button type="primary" @click="onBack">返回</el-button>
            </div>

            <el-table :data="numList" style="width: 100%; margin-bottom: 20px" row-key="id" border default-expand-all>
                <el-table-column label="费用科目" show-overflow-tooltip #default="scope">
                    {{ scope.row.name }}
                </el-table-column>
                <el-table-column align="center" label="预算信息(元)" show-overflow-tooltip #default="scope">
                    <span v-if="scope.row.children.length == 0 && scope.row.grade != '0'">
                        <el-input v-model="scope.row.value" @input="onNumber(scope.row)"></el-input>
                    </span>
                    <span v-else>
                        {{ scope.row.value }}
                    </span>
                </el-table-column>
            </el-table>
        </div>
    </div>
</template>

<script setup>
import { ref, inject } from 'vue';
import { post } from "@/utils/path";
import { useRouter } from "vue-router";

const router = useRouter();
const numList = ref([
    {
        id: 1,
        name: '(一)直接费',
        value: 0,
        grade: '1',
        children: [
            {
                id: 2,
                name: '1. 人工费',
                value: 0,
                grade: '2',
                children: []
            },
            {
                id: 3,
                name: '2. 设备服务费',
                value: 0,
                grade: '2',
                children: [
                    {
                        id: 4,
                        name: '(1)仪器设备使用费',
                        value: 0,
                        grade: '3',
                        children: []
                    },
                    {
                        id: 5,
                        name: '(2)软件使用费',
                        value: 0,
                        grade: '3',
                        children: []
                    },
                ]
            },
            {
                id: 6,
                name: '3. 业务费',
                value: 0,
                grade: '2',
                children: [
                    {
                        id: 7,
                        name: '(1)材料费',
                        value: 0,
                        grade: '3',
                        children: []
                    },
                    {
                        id: 8,
                        name: '(2)资料、印刷及知识产权费',
                        value: 0,
                        grade: '3',
                        children: []
                    },
                    {
                        id: 9,
                        name: '(3)会议、差旅及合作交流费',
                        value: 0,
                        grade: '3',
                        children: []
                    }
                ]
            },
            {
                id: 10,
                name: '4. 场地使用费',
                value: 0,
                grade: '2',
                children: [
                    {
                        id: 11,
                        name: '(1)场地物业费',
                        value: 0,
                        grade: '3',
                        children: []
                    },
                    {
                        id: 12,
                        name: '(2)场地使用租金',
                        value: 0,
                        grade: '3',
                        children: []
                    }
                ]
            },
            {
                id: 13,
                name: '5. 专家咨询费',
                value: 0,
                grade: '2',
                children: []
            }
        ]
    },
    {
        id: 14,
        name: '(二)间接费',
        value: 0,
        grade: '1',
        children: []
    },
    {
        id: 15,
        name: '(三)外委支出费',
        value: 0,
        grade: '1',
        children: [
            {
                id: 16,
                name: '1. 外委研究支出费',
                value: 0,
                grade: '2',
                children: []
            },
            {
                id: 17,
                name: '2. 仪器设备租赁费',
                value: 0,
                grade: '2',
                children: []
            },
            {
                id: 18,
                name: '3. 外协测试试验与加工费',
                value: 0,
                grade: '2',
                children: []
            },
        ]
    },
    {
        id: 19,
        name: '(四)税金',
        value: 0,
        grade: '1',
        children: []
    },
    {
        id: 20,
        name: '总计',
        value: 0,
        grade: '0',
        children: []
    }
])
const isValue = ref(false)
const message = inject('message')
const verification = inject('verification')

const onNumber = (val) => {
    var myreg = /(^[0]{1}$)|(^[1-9]{1}[0-9]{0,8}$)|(^[0-9]{1,9}[\.]{1}[0-9]{0,2}$)/;
    if (!myreg.test(val.value)) {
        isValue.value = true
        message.error('预算信息(元)只能输入0~999999999之间的正整数(保留两位小数)')
    } else {
        isValue.value = false
        let temp = [], arr = [], totalValue = 0
        for (let i = 0; i < numList.value.length; i++) {
            temp = numList.value[i].children
            if (temp.length > 0) {
                numList.value[i].value = 0
                for (let j = 0; j < temp.length; j++) {
                    arr = temp[j].children
                    if (arr.length > 0) {
                        temp[j].value = 0
                        for (let k = 0; k < arr.length; k++) {
                            if (temp[j].grade == '2') {
                                temp[j].value += Number(arr[k].value)
                            }
                        }
                    }
                    if (numList.value[i].grade == '1') {
                        numList.value[i].value += Number(temp[j].value)
                    }
                }
            }
            if (i != numList.value.length - 1) {
                totalValue += Number(numList.value[i].value)
            }
        }
        numList.value[numList.value.length - 1].value = totalValue
    }
}
const onSave = () => {
    if (!isValue.value) {

    } else {
        message.error('预算信息(元)只能输入0~999999999之间的正整数(保留两位小数)')
    }
}
// 返回
const onBack = () => {
    router.back()
}
</script>

<style lang="scss">
#budgetInfo {
    width: 100%;

    .content {
        width: 50%;
        margin: 10px auto;

        .title {
            width: 100%;
            text-align: right;
            margin-bottom: 10px;
        }

        .el-input__inner {
            text-align: center;
        }
    }
}
</style>
2、联调静态页面
<!--
@Description 项目管理 - 预算编制
@author wdd
@date 2023/11/11
-->
<template>
    <div id="budgetInfo">
        <centerHead title="预算编制"></centerHead>
        <div class="content">
            <div class="title">
                <el-button type="primary" @click="onSave">保存</el-button>
                <el-button type="primary" @click="onBack">返回</el-button>
            </div>

            <el-table :data="numList" style="width: 100%; margin-bottom: 20px" row-key="id" border default-expand-all>
                <el-table-column label="费用科目" show-overflow-tooltip #default="scope">
                    {{ scope.row.name }}
                </el-table-column>
                <el-table-column align="center" label="预算信息(元)" show-overflow-tooltip #default="scope">
                    <span v-if="scope.row.children.length == 0 && scope.row.grade != '0'">
                        <el-input v-model="scope.row.value" @input="onNumber(scope.row)"></el-input>
                    </span>
                    <span v-else>
                        {{ scope.row.value }}
                    </span>
                </el-table-column>
            </el-table>
        </div>
    </div>
</template>

<script setup>
import { ref, inject, onMounted } from 'vue';
import { post } from "@/utils/path";
import { useRoute, useRouter } from "vue-router";

const route = useRoute()
const router = useRouter();
const numList = ref([])
const isValue = ref(false)
const message = inject('message')
const verification = inject('verification')
const constant = inject('constant')
const publicId = ref('')

onMounted(() => {
    if (route.query.id) {
        getList()
    }
})
const getList = () => {
    post(constant.ieopMtgAchieve + '/approval/manager/mould/detail', {
        approvalId: route.query.id
    }).then((res) => {
        if (res.data.code = '200') {
            publicId.value = res.data.data.approvalId
            numList.value = res.data.data.children;
        }
    })
}
// 计算项目费用
const onNumber = (val) => {
    var myreg = /(^[0]{1}$)|(^[1-9]{1}[0-9]{0,8}$)|(^[0-9]{1,9}[\.]{1}[0-9]{0,2}$)/;
    if (!myreg.test(val.value)) {
        isValue.value = true
        message.error('预算信息(元)只能输入0~999999999之间的正整数(保留两位小数)')
    } else {
        isValue.value = false
        let temp = [], arr = [], totalValue = 0
        for (let i = 0; i < numList.value.length; i++) {
            temp = numList.value[i].children
            if (temp.length > 0) {
                numList.value[i].value = 0
                for (let j = 0; j < temp.length; j++) {
                    arr = temp[j].children
                    if (arr.length > 0) {
                        temp[j].value = 0
                        for (let k = 0; k < arr.length; k++) {
                            if (temp[j].grade == '2') {
                                temp[j].value += Number(arr[k].value)
                            }
                        }
                    }
                    if (numList.value[i].grade == '1') {
                        numList.value[i].value += Number(temp[j].value)
                    }
                }
            }
            if (i != numList.value.length - 1) {
                totalValue += Number(numList.value[i].value)
            }
        }
        numList.value[numList.value.length - 1].value = totalValue
    }
}
const onSave = () => {
    if (!isValue.value) {
        post(constant.ieopMtgAchieve + '/approval/manager/mould/edit', {
            approvalId: publicId.value,
            children: numList.value
        }).then((res) => {
            if (res.data.code == '200') {
                message.success('操作成功!');
                router.back()
            } else {
                message.error(res.data.message);
            }
        })
    } else {
        message.error('预算信息(元)只能输入0~999999999之间的正整数(保留两位小数)')
    }
}
// 返回
const onBack = () => {
    router.back()
}
</script>

<style lang="scss">
#budgetInfo {
    width: 100%;

    .el-table__expand-icon,
    .el-table__placeholder {
        display: none;
    }

    .content {
        width: 50%;
        margin: 10px auto;

        .title {
            width: 100%;
            text-align: right;
            margin-bottom: 10px;
        }

        .el-input__inner {
            text-align: center;
        }
    }
}
</style>

src\utils\path.js

import request from "./request";
import { getApiUrl } from "@/utils/tool";
const baseUrl = getApiUrl();
// 通用请求
export  function post(url, params = {}){
  const  data  =  request.post(baseUrl + url, params);
  // const data  =  request.post(url, params);
  return data
}
export  function get(url, params = {}){
  const  data  =  request.get(baseUrl + url);
  return data
}

src\utils\tool.js

export function getApiUrl(v) {
  return process.env.VUE_APP_API_HOST
}

.env.dev

VUE_APP_API_HOST = '/gp'
VUE_APP_IMAGE_CM = '/cm'
VUE_APP_IMAGE_HOST = 'http://27.196.104.87:18080'

vue.config.js

const { defineConfig } = require('@vue/cli-service')

const AutoImport = require('unplugin-auto-import/webpack')
const Components = require('unplugin-vue-components/webpack')
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,

  devServer: {
    proxy: {
      // '/gp/ieop-pri-property': {
      //   target: 'http://27.196.104.87:18080',
      //   changeOrigin: true,
      //   pathRewrite: {
      //     '^/gp': '/'
      //   }
      // },
      // '/gp/yundu-file-wjm': {
      //   target: 'http://27.196.104.87:18080',
      //   changeOrigin: true,
      //   pathRewrite: {
      //     '^/gp': '/'
      //   }
      // },
      '/gp': {
        target: 'http://27.196.111.15:18080', // 后端接口地址
        changeOrigin: true,
        pathRewrite: {
          '^/gp': '/'
        }
      },
      // '/img': {
      //   target: 'http://192.168.67.86:9595',
      //   changeOrigin: true,
      //   pathRewrite: {
      //     '^/img': '/'
      //   }
      // },
    },
    port: 9000,
    // host:'27.196.104.110',
    host:'0.0.0.0',
    open:true
  },
  // configureWebpack: {
  //   plugins: [
  //     AutoImport({
  //       resolvers: [ElementPlusResolver()]
  //     }),
  //     Components({
  //       resolvers: [ElementPlusResolver()]
  //     })
  //   ]
  // },
})
3、css原生写法-静态页面
<!--
@Description 项目管理 - 预算编制
@author wdd
@date 2023/11/11
-->
<template>
    <centerHead title="预算编制"></centerHead>
    <div class="content">
        <div class="title">
            <el-button type="primary" v-if="see" @click="save">保存</el-button>
            <el-button type="primary" v-if="!see" @click="edit">编辑</el-button>
            <el-button type="primary" @click="examine">审核</el-button>
        </div>
        <div class="name-box" style="font-weight:700;text-align: center;font-size:16px">费用科目</div>
        <div class="val-box" style="font-weight:700;text-align: center;font-size:16px">预算信息(万元)</div>
        <div v-for="item in numList" :key="item.id">
            <div class="name-box"><span
                    :style="styleList.find(el=>el==item.name)?  styleObj:classObj">{{item.name}}</span> </div>
            <div class="val-box">
                <span v-if="showList.find(el=>el ==item.name)">{{item.value}}</span>
                <span v-if="!see &&  !showList.find(el=>el ==item.name)">{{item.value}}</span>
                <el-input v-if="see &&  !showList.find(el=>el ==item.name)" v-model="item.value" @blur="ChangeVal">
                </el-input>
            </div>
        </div>
    </div>
</template>
<script lang="ts" setup>
import { ref, } from 'vue';
const numList = ref([
    {
        id: 1,
        name: '(一)直接费',
        value: 0,
    },
    {
        id: 2,
        name: '1. 人工费',
        value: 0,
    },
    {
        id: 3,
        name: '2. 设备服务费',
        value: 0,
    },
    {
        id: 4,
        name: '(1)仪器设备使用费',
        value: 0,
    },
    {
        id: 5,
        name: '(2)软件使用费',
        value: 0,
    },
    {
        id: 6,
        name: '3. 业务费',
        value: 0,
    },
    {
        id: 7,
        name: '(1)材料费',
        value: 0,
    },
    {
        id: 8,
        name: '(2)资料、印刷及知识产权费',
        value: 0,
    },
    {
        id: 9,
        name: '(3)会议、差旅及合作交流费',
        value: 0,
    },
    {
        id: 10,
        name: '4. 场地使用费',
        value: 0,
    },
    {
        id: 11,
        name: '(1)场地物业费',
        value: 0,
    },
    {
        id: 12,
        name: '(2)场地使用租金',
        value: 0,
    },
    {
        id: 13,
        name: '5. 专家咨询费',
        value: 0,
    },
    {
        id: 14,
        name: '(二)间接费',
        value: 0,
    },
    {
        id: 15,
        name: '(三)外委支出费',
        value: 0,
    },
    {
        id: 16,
        name: '1. 外委研究支出费',
        value: 0,
    },
    {
        id: 17,
        name: '2. 仪器设备租赁费',
        value: 0,
    },
    {
        id: 18,
        name: '3. 外协测试试验与加工费',
        value: 0,
    },
    {
        id: 19,
        name: '(四)税金',
        value: 0,
    },
    {
        id: 20,
        name: '合计',
        value: 0,
    },
])
const styleObj = ref({ fontWeight: 700, fontSize: '16px', lineHeight: '38px' })
const classObj = ref({})
const see = ref(true)
const styleList = ref(['(一)直接费', '(二)间接费', '(三)外委支出费', '(四)税金', '合计'])
const showList = ref(['(一)直接费', '2. 设备服务费', '3. 业务费', '4. 场地使用费', '(三)外委支出费', '合计'])
const amount = () => {
    numList.value[0].value = Number(numList.value[1].value) + Number(numList.value[2].value) + Number(numList.value[5].value) + Number(numList.value[9].value) + Number(numList.value[12].value)
    numList.value[19].value = Number(numList.value[0].value) + Number(numList.value[13].value) + Number(numList.value[14].value) + Number(numList.value[18].value)
}
const ChangeVal = () => {
    numList.value.forEach((el, index) => {
        if (index == 2) {
            el.value = Number(numList.value[3].value) + Number(numList.value[4].value)
        }
        if (index == 5) {
            el.value = Number(numList.value[6].value) + Number(numList.value[7].value) + Number(numList.value[8].value)
        }
        if (index == 9) {
            el.value = Number(numList.value[10].value) + Number(numList.value[11].value)
        }
        if (index == 14) {
            el.value = Number(numList.value[15].value) + Number(numList.value[16].value) + Number(numList.value[17].value)
        }
        amount()
    })
}
const save = () => {
    see.value = false
}
const edit = () => {
    see.value = true
}
const examine = () => { }
</script>
<style lang="scss" scoped>
.content {
    margin: 70px 20px;
    position: relative;
    .title {
        position: absolute;
        top: -44px;
        left: 406px;
    }
    .name-box {
        display: inline-block;
        width: 260px;
        height: 40px;
        line-height: 40px;
        text-align: left;
        padding-left: 10px;
        border: 1px solid #666;
        margin: 0 -1px -1px 0;
        font-size: 14px;
    }
    .val-box {
        display: inline-block;
        width: 220px;
        border: 1px solid #666;
        margin: 0 0 -1px 0px;
        height: 40px;
        font-size: 14px;
        text-align: center;
        line-height: 40px;
        .el-input {
            width: 160px;
        }
    }
}
</style>
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值