Ant Design Vue 树形表格计算盈收金额

树形表格计算

    • 一、盈收金额计算
      • 1、根据需要输入的子级位置,修改数据
      • 2、获取兄弟节点数据,并计算兄弟节点的金额合计
      • 3、金额合计,遍历给所有的父级

一、盈收金额计算

1、根据需要输入的子级位置,修改数据

2、获取兄弟节点数据,并计算兄弟节点的金额合计

3、金额合计,遍历给所有的父级

<template><a-modal :title="titleMap[mode]" :visible="visible" :destroyOnClose="true" :maskClosable="false" @cancel="handleCancel"width="95%"><a-spin :spinning="spinning" tip="加载中..."><a-table :columns="columns" bordered :data-source="newSource" :scroll="{ x: 800, y: 500 }" :pagination="false":rowKey="(record, index) => { return record.projectId }" :defaultExpandAllRows="true"v-if="newSource.length"><template slot="promote" slot-scope="text,record"><span>{{ rateCompute(record.preActual, record.budget) }}</span></template><template slot="budget" slot-scope="text,record"><div class="editable-cell"><div v-if="editable" class="editable-cell-input-wrapper"><div v-if="editableData[record.projectId]"><a-input v-model="editableData[record.projectId]['budget']"@pressEnter="save(editableData[record.projectId])" type="number"@change="e => e.target.value = e.target.value.replace(/^0+(\d)|[^\d]+/g, '')" /><a-icon type="check" @click="save(editableData[record.projectId])"style="margin-right: 20px;" /><a-popconfirm title="确定取消?" @confirm="cancel(record.projectId)"><a-icon type="close" /></a-popconfirm></div><div v-else>{{ text }}</div></div><div v-else class="editable-cell-text-wrapper"><div v-if="record.children == null">{{ text || ' ' }}<a-icon type="edit" @click="edit(record)" /></div><div v-else>{{ text || ' ' }}</div></div></div></template></a-table></a-spin><template slot="footer"><a-button key="back" @click="handleCancel">关闭</a-button><a-button type="primary" :visible="visibleBtn" :loading="loadingBtn" @click="handleSubmit">保存</a-button></template></a-modal>
</template>

JS

import { cloneDeep } from 'lodash-es';
export default {data() {return {visible: false,dataSource: [],newSource: [], //变化的源数据spinning: true,columns: [],//头部表单editableData: {},// 修改的位置数据editable: false, //是否编辑visibleBtn: false,loadingBtn: false,mode: "add",titleMap: {add: '新增',edit: '修改'},}},methods: {//计算比率// 本月比上月情况=(本月数字-上月数字)/上月数字,如果本月大于上月,结果就是正数,即上升,反之为下降rateCompute(a, b) {if (a > 0 && b > 0) {if (a < b) return ((((b - a) / a) * 100).toFixed(2)) + '%'else if (b < a) '-' + ((((b - a) / a) * 100).toFixed(2)) + '%'else return '0%'} else {if (a == 0 && b > a) return '100%'else return '0%'}},edit(row) {this.editable = truethis.editableData[row.projectId] = cloneDeep(row)},save(row) {this.editable = falsethis.calculate(row)},// 计算calculate(row) {//计算时,需要同步执行	this.fun1(row)delete this.editableData[row.projectId];},fun1(row) {if (row.inOrOut == 2) {if(Number(row.budget) > 0){this.getObj(this.newSource, row.projectId, Number('-' + row.budget), row, callback)}else{this.getObj(this.newSource, row.projectId, Number(row.budget), row, callback)}} else {this.getObj(this.newSource, row.projectId, Number(row.budget), row, callback)}// 使用回调,同步执行下面的方法function callback(isFind, _this, row) {if (isFind) {_this.fun2(row)}}},fun2(row) {// 获取兄弟节点的父级idlet brotherParentId = row.parentProjectId// 获取兄弟节点数据let brotherParentArr = this.getBrotherParentId(this.newSource, brotherParentId)console.log(brotherParentArr)if (brotherParentArr.length > 0) {// 兄弟数组的和  相差值let ParentVal = brotherParentArr.reduce((accumulator, currentValue) => Number(accumulator) + Number(currentValue));if (ParentVal) {this.fun3(row, ParentVal)}}},fun3(row, ParentVal) {// 相关连的数据包括原来未改变的初始值let joinedArr = this.get_level_all(this.dataSource, row.projectId).filter(item => item.projectId != row.projectId)let _this = this// 相差值if (joinedArr.length > 0) {joinedArr.forEach((item) => {_this.getParentId(_this.newSource, item.projectId, Number(ParentVal))});}},// 根据id ,找到当前元素的对象,并进行赋值getObj(data, id, val, row, callback) {let isFind = falsedata.find((item) => {if (item.projectId === id) {if (val == 0) item.budget = '0'else item.budget = Number(val)item.promote = this.rateCompute(Number(item.preActual), Number(item.budget))isFind = true} else if (item.children != null && item.children.length > 0) {this.getObj(item.children, id, val, row, callback);}});if (isFind) {callback(isFind, this, row)return isFind}},// 根据id,找到所有的上级idget_level_all(data, id, arr = []) {data.find((item) => {if (item.projectId === id) {arr.push(item);return true;} else if (item.children != null && item.children.length > 0) {arr = this.get_level_all(item.children, id, arr);if (arr.length) {arr.push(item);return true;} else {return false;}}return false;});return arr;},// 根据id,找到所有的同级数据getBrotherParentId(data, id, arr = []) {data.find((item) => {if (item.parentProjectId == id) {// 收支类型,1:收入,2:支出,3:其它// 支出:减if(item.inOrOut == '2'){if(Number(item.budget)>0){arr.push((item.inOrOut == '2' ? Number(('-' + item.budget)) : Number(item.budget)));}else{arr.push(Number(item.budget));}}else{arr.push(Number(item.budget));}} else if (item.children != null && item.children.length > 0) {this.getBrotherParentId(item.children, id, arr);}});return arr;},// 根据相差值遍历相关的父级或祖级getParentId(arr, id, numDiffer) {arr.forEach(item => {if (item.projectId == id) {item.budget = Number(this.sumChildren(item.children))item.promote = this.rateCompute(item.preActual, item.budget)}if (item.children != null && item.children.length > 0) {this.getParentId(item.children, id, numDiffer)}})},// 获取子集得计算和sumChildren(children) {let sum = 0children.map(item => {if (item.inOrOut == '2' && Number(item.budget) < 0) {sum += Number(item.budget)} else {sum += item.inOrOut == '2' ? Number(('-' + item.budget)) : Number(item.budget)}})return sum},// 取消cancel(key) {this.editable = falsedelete this.editableData[key];},//显示open(mode = 'add', par) {this.mode = mode;this.visible = true;//接口数据,在下面let headers = res.data.headers//去除不需要显示的列headers.map(item => {if (item.hidden == false) this.operator(item)})this.columns.push({title: '提升比率',dataIndex: 'promote',key: 'promote',align: 'left',width: 120,scopedSlots: { customRender: 'promote' }})let row = res.data.rows//树形表格,children没有数据需要为空this.handNull(row)this.dataSource = rowthis.spinning = falsethis.newSource = row},// 子集没数据,赋值为空 nullhandNull(data) {data.forEach((item) => {//计算提升比率item.promote = this.rateCompute(item.preActual, item.budget)if (item.children.length == 0) {item.children = null} else {this.handNull(item.children);}});},// columns 表头赋值operator(item) {let obj = {}if (item.columnId == 'projectName') {obj['title'] = item.nameobj.dataIndex = 'name'obj.key = 'name'obj.align = 'left'}else if (item.columnId == 'preActual') {obj['title'] = item.nameobj.dataIndex = 'preActual'obj.key = 'preActual'obj.align = 'left'obj.width = 200}else if (item.columnId == 'budget') {obj['title'] = item.nameobj.dataIndex = 'budget'obj.key = 'budget'obj.align = 'left'obj.width = 200obj.scopedSlots = { customRender: 'budget' }}else return;this.columns.push(obj)},//关闭handleCancel() {this.visible = false;this.editable = falsethis.$emit("close");},// 确认handleSubmit() {this.loadingBtn = true;this.visibleBtn = true;//新增或修改let Api = this.mode == 'add' ? add : editApi(par).then(res => {if (res.code === 200) {this.$notification['success']({message: '提示',description: '保存成功!',duration: 8})this.visible = falsethis.$emit("success");} else {this.$notification['error']({message: '提示',description: res.message,duration: 8})}this.visibleBtn = falsethis.loadingBtn = false})},}

json


{"code": 200,"message": "操作成功","data": {"title": "月度预算","tabulatorId": "146","storeId": "159","storeName": "麓谷公园店","tabulator": "李生","headers": [{"columnId": "projectId","name": "项目ID","hidden": true,"primary": false},{"columnId": "projectName","name": "项目名称","hidden": false,"primary": false},{"columnId": "isLeaf","name": "是否叶子","hidden": true,"primary": false},{"columnId": "inOrOut","name": "收支类型","hidden": true,"primary": false},{"columnId": "parentProjectId","name": "上级预算项目ID","hidden": true,"primary": false},{"columnId": "preActual","name": "10月","hidden": false,"primary": false},{"columnId": "budget","name": "11月预算","hidden": false,"primary": true}],"rows": [{"projectId": "165","name": "利润","parentProjectId": null,"inOrOut": 1,"children": [{"projectId": "174","name": "成本","parentProjectId": "165","inOrOut": 2,"children": [{"projectId": "175","name": "原材料成本","parentProjectId": "174","inOrOut": 2,"children": [],"budget": "0","preBudget": "","preActual": "0","leaf": true}],"preBudget": "","preActual": "0","budget": "0","leaf": false},{"projectId": "173","name": "税额","parentProjectId": "165","inOrOut": 2,"children": [],"preBudget": "","preActual": "0","budget": "0","leaf": true},{"projectId": "166","name": "营业收入","parentProjectId": "165","inOrOut": 1,"children": [{"projectId": "170","name": "外卖折后营收","parentProjectId": "166","inOrOut": 1,"children": [{"projectId": "172","name": "外卖优免","parentProjectId": "170","inOrOut": 2,"children": [],"preBudget": "","preActual": "0","budget": "0","leaf": true},{"projectId": "171","name": "外卖折前营收","parentProjectId": "170","inOrOut": 1,"children": [],"preBudget": "","preActual": "0","budget": "0","leaf": true}],"preBudget": "","preActual": "0","budget": "0","leaf": false}],"preBudget": "","preActual": "0","budget": "0","leaf": false}],"preBudget": "","preActual": "0","budget": "0","leaf": false}]}
}
折后盈收=折前盈收-优免

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/166967.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

销售管理系统的实用性怎么样?

销售管理系统好用吗&#xff1f;好用&#xff0c;销售管理系统可以管理销售流程、自动化大量重复性工作&#xff0c;让销售人员从琐碎的任务中挣脱出来&#xff0c;投入到客户跟进和维护客户关系之中。那么&#xff0c;CRM系统的好用体现在哪些方面&#xff1f; 1.加速销售流程…

react中的state

没想到hooks中也有state这一说法 看下面的两个案例 1、无state变化不会执行父子函数 2、有state更改执行父子函数

深度学习之六(自编码器--Autoencoder)

概念 自编码器(Autoencoder)是一种神经网络架构,用于无监督学习和数据的降维表示。它由两部分组成:编码器(Encoder)和解码器(Decoder)。 结构: 编码器(Encoder): 接收输入数据并将其压缩为潜在表示(latent representation),通常比输入数据的维度要低。编码器的…

最详细的软件测试面试题整理与分析

前言 时光荏苒&#xff0c;一转眼到了2023年末尾&#xff0c;2024年也快要来了&#xff0c;人员就业市场以往的寒冬也貌似有了转暖的迹象&#xff0c;身边大批的就业人员也开始了紧张的备战之中。 近几周也和多家合作公司的HR进行了沟通&#xff0c;发现虽然岗位就业情况较去年…

vue3中引入svg矢量图

vue3中引入svg矢量图 1、前言2、安装SVG依赖插件3、在vite.config.ts 中配置插件4、main.ts入口文件导入5、使用svg5.1 在src/assets/icons文件夹下引入svg矢量图5.2 在src/components目录下创建一个SvgIcon组件5.3 封装成全局组件&#xff0c;在src文件夹下创建plugin/index.t…

一键创新 | 拓世法宝AI智能直播一体机激发房产自媒体创造力

在数字化时代&#xff0c;房产销售已然不再是传统的模式。随着社交媒体和自媒体的兴起&#xff0c;短视频直播成为房产自媒体营销的新风口。然而&#xff0c;行业也面临着诸多挑战&#xff0c;如何更好地利用新媒体拓展市场&#xff0c;提升自媒体效果成为摆在业内人士面前的难…

JMeter测试报错422 Unprocessable Entity

添加HTTP信息头&#xff1a; ​ HTTP请求-》添加-〉配置元件-》HTTP信息头管理器 ​ 如果需要送json&#xff0c;需要添加Content-Type:application/json&#xff0c;否则会报【422 Unprocessable Entity】

好用的CRM系统到底有多重要?怎么选?

我们都知道&#xff0c;CRM软件可以让企业效率加倍。但如果选错了CRM&#xff0c;企业损失点钱是小&#xff0c;客户转化率下降才是大。下面我们就来说说&#xff0c;市面上有哪些好用的CRM&#xff1f;以及好用的CRM软件的重要性。 好用的CRM软件的重要性&#xff1a; 客户管…

Qt 软件调试(一) Log日志调试

终于这段时间闲下来了&#xff0c;可以系统的编写Qt软件调试的整个系列。前面零零星星的也有部分输出&#xff0c;但终究没有形成体系。借此机会&#xff0c;做一下系统的总结。慎独、精进~ 日志是有效帮助我们快速定位&#xff0c;找到程序异常点的实用方法。但是好的日志才能…

百度 文心一言 sdk 试用

JMaven Central: com.baidu.aip:java-sdk (sonatype.com) Java sdk地址如上&#xff1a; 文心一言开发者 文心一言 (baidu.com) ERNIE Bot SDK https://yiyan.baidu.com/developer/doc#Fllzznonw ERNIE Bot SDK提供便捷易用的接口&#xff0c;可以调用文心一言的能力&#…

口袋参谋:如何避免宝贝被降权?这招屡试屡爽!

​至少99.99999%的店铺在今年都被降权过&#xff01;各家店铺被降权的原因&#xff0c;无非就一个原因&#xff0c;那就是s单&#xff01; s单的风险也就两种&#xff0c;一是操作问题&#xff0c;二是账号问题。 操作问题被降权&#xff0c;这个大家都心知肚明&#xff0c;s…

5大原因,设备校准为什么是实验室搬迁后的首要任务?

实验室搬迁是一个复杂而紧张的过程。要考虑的事情太多&#xff0c;很容易忽视您最重要的任务之一——检查设备在新环境中的性能。 校准对于确保设备安全运行和遵守监管标准至关重要。 1.保持合规性并遵守法律要求 生物技术和制药等行业有特定的校准要求&#xff0c;实验室必…

浅谈安科瑞直流电表在印尼某基站的应用

摘要&#xff1a;本文介绍了安科瑞直流电表在印尼的应用。主要用于印尼某基站的电流电压电能的计量&#xff0c;配合霍尔传感器对基站进行计量。 Abstract: This article introduces the application of Acrel DC meters in base station in Indonesia.The device is measuri…

如何做好测试管理岗?深度分析职业规划

在给学生做职业规划的时候&#xff0c;经常就有同学说&#xff1a;我以后要做管理岗&#xff01;其实对于很多刚入行的同学&#xff0c;可能说这句话的时候并没有真正理解管理岗需要做什么事&#xff0c;以及需要具备什么样的技能。所以&#xff0c;作为资深测试经理&#xff0…

飞翔的小鸟——Java

一、创建文件、包、类、插入图片文件 二、app包 1、Gameapp类&#xff08;运行游戏&#xff09; package app;import main.GameFrame;public class Gameapp {public static void main(String[] args) {//游戏的入口new GameFrame();} } 三、main包 1、Barrier&#xff08…

无需外接显示器,直接使用windows安装树莓派系统并可远程桌面登录

准备工作: 1.安装树莓派官方烧录工具 raspberry pi imager 2.下载树莓派系统镜像(也可选择在线下载安装) 打开imager工具&#xff0c;选择需要安装包树莓派版本 点击"NEXT"&#xff0c;在弹出的选项中选择编辑设置。 设置登录名和密码&#xff0c;已经所连接的wif…

统一用户桌面壁纸怎么设置

统一用户桌面壁纸的设置方法有多种&#xff0c;以下列举两种&#xff1a; 方法一&#xff1a;个人更换壁纸 1、右键桌面&#xff0c;鼠标选择“个性化”。 2、进入个性化之后&#xff0c;单击下面的“桌面背景”图标。 3、点击“浏览”选择自己备好的桌面壁纸&#xff0c;点击…

昇腾Atlas 200I DK A2实现安全帽识别

文章目录 环境依赖编译测试总结 环境依赖 软件版本说明获取方式mxVision5.0.RC2mxVision软件包获取方式Ascend-CANN-toolkit6.2.RC2Ascend-cann-toolkit开发套件包获取方式Ubuntu22.04 代码仓库地址&#xff1a; https://gitee.com/ascend/ascend_community_projects/tree/31…

01_原理-事件循环

01_原理-事件循环 文章目录 01_原理-事件循环一、浏览器的进程模型①&#xff1a;何为进程&#xff1f;②&#xff1a;何为线程&#xff1f;③&#xff1a;浏览器有哪些进程和线程&#xff1f; 二、渲染主线程是如何工作的&#xff1f;三、若干解释①&#xff1a;何为异步&…

量子计算突破云渲染资源调度!真机测试完整报告公开!

​摘要&#xff1a;在影视领域中&#xff0c;经常会涉及大量的视频图像渲染工作&#xff0c;而往往在这种大规模、动态渲染场景下&#xff0c;普遍存在着冗余渲染现象。究其原因在于大规模的图像渲染通常要求在短时间内做出渲染任务的算力分配决策&#xff0c;而经典计算机无法…