|
@@ -94,8 +94,8 @@
|
|
|
新增企业近三年亩均产值
|
|
|
<el-tooltip class="item" effect="light" placement="bottom">
|
|
|
<span slot="content">
|
|
|
- ①亩均产值=产值/用地面积<br/>
|
|
|
- ②近三年:去年往前推三年,例如2025年时,计算年份为2024年、2023年、2022年<br/>
|
|
|
+ ①亩均产值=产值/用地面积<br />
|
|
|
+ ②近三年:去年往前推三年,例如2025年时,计算年份为2024年、2023年、2022年<br />
|
|
|
③近三年平均亩均产值=(2022年亩均产值+2023年+2024年)/3
|
|
|
</span>
|
|
|
<i class="el-icon-question" /><!--小问号提示-->
|
|
@@ -118,8 +118,8 @@
|
|
|
新增企业近三年亩均税收
|
|
|
<el-tooltip class="item" effect="light" placement="bottom">
|
|
|
<span slot="content">
|
|
|
- ①亩均税收=实缴税金/用地面积<br/>
|
|
|
- ②近三年:去年往前推三年,例如2025年时,计算年份为2024年、2023年、2022年<br/>
|
|
|
+ ①亩均税收=实缴税金/用地面积<br />
|
|
|
+ ②近三年:去年往前推三年,例如2025年时,计算年份为2024年、2023年、2022年<br />
|
|
|
③近三年平均亩均税收=(2022年亩均税收+2023年+2024年)/3
|
|
|
</span>
|
|
|
<i class="el-icon-question" /><!--小问号提示-->
|
|
@@ -134,11 +134,7 @@
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="行业代码" label-width="200px" prop="code">
|
|
|
- <el-select
|
|
|
- v-model="form.code"
|
|
|
- style="width: 100%"
|
|
|
- filterable
|
|
|
- >
|
|
|
+ <el-select v-model="form.code" style="width: 100%" filterable>
|
|
|
<el-option
|
|
|
v-for="item in industryData"
|
|
|
:key="item.key"
|
|
@@ -156,16 +152,8 @@
|
|
|
>
|
|
|
</el-option> </el-select> -->
|
|
|
</el-form-item>
|
|
|
- <el-form-item
|
|
|
- label="企业分类"
|
|
|
- label-width="200px"
|
|
|
- prop="typeNum"
|
|
|
- >
|
|
|
- <el-select
|
|
|
- v-model="form.typeNum"
|
|
|
- style="width: 100%"
|
|
|
- clearable
|
|
|
- >
|
|
|
+ <el-form-item label="企业分类" label-width="200px" prop="typeNum">
|
|
|
+ <el-select v-model="form.typeNum" style="width: 100%" clearable>
|
|
|
<el-option
|
|
|
v-for="item in enterTypeList"
|
|
|
:key="item.number"
|
|
@@ -197,7 +185,7 @@
|
|
|
clearable
|
|
|
/>
|
|
|
</div>
|
|
|
- <!-- <el-select
|
|
|
+ <!-- <el-select
|
|
|
v-model="form.year"
|
|
|
style="width: 100%"
|
|
|
filterable
|
|
@@ -212,12 +200,96 @@
|
|
|
</el-select> -->
|
|
|
</el-form-item>
|
|
|
<el-form-item label-width="100px">
|
|
|
- <el-button type="primary" size="mini" @click="submitForm">计算</el-button>
|
|
|
+ <el-button type="primary" size="mini" @click="submitForm"
|
|
|
+ >计算</el-button
|
|
|
+ >
|
|
|
<el-button icon="el-icon-refresh" size="mini" @click="resetForm"
|
|
|
- >重置</el-button>
|
|
|
+ >重置</el-button
|
|
|
+ >
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
</div>
|
|
|
+ <div ref="chart" :style="{ height: height, width: width }"></div>
|
|
|
+ <el-table :data="tableData" border style="width: 100%">
|
|
|
+ <el-table-column prop="id" label="企业ID"></el-table-column>
|
|
|
+ <el-table-column prop="enterpriseName" label="企业名称"></el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="landUsedInRecentThreeYears"
|
|
|
+ label="近三年用地/亩"
|
|
|
+ width="200"
|
|
|
+ >
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="averageAnnualOutputValue"
|
|
|
+ label="年均产值/万元"
|
|
|
+ width="200"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column prop="output" label="年均亩均产值" width="200"
|
|
|
+ ><template slot="header">
|
|
|
+ <el-tooltip
|
|
|
+ class="item"
|
|
|
+ effect="dark"
|
|
|
+ content="近三年年均产值/近三年用地"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <span>年均亩均产值</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="outputScore" label="亩均产值得分" width="200">
|
|
|
+ <template slot="header">
|
|
|
+ <el-tooltip
|
|
|
+ class="item"
|
|
|
+ effect="dark"
|
|
|
+ content="年均亩均产值/行业基准值A*40"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <span>亩均产值得分</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template></el-table-column
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ prop="averageAnnualTaxPaid"
|
|
|
+ label="年均实缴税金/万元"
|
|
|
+ width="200"
|
|
|
+ ></el-table-column>
|
|
|
+ <el-table-column prop="tax" label="年均亩均税收" width="200"
|
|
|
+ ><template slot="header">
|
|
|
+ <el-tooltip
|
|
|
+ class="item"
|
|
|
+ effect="dark"
|
|
|
+ content="近三年年均实缴税金/近三年用地"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <span>年均亩均税收</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="taxpaidScore" label="亩均税收得分" width="200">
|
|
|
+ <template slot="header">
|
|
|
+ <el-tooltip
|
|
|
+ class="item"
|
|
|
+ effect="dark"
|
|
|
+ content="年均亩均税收/行业基准值B*60"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <span>亩均税收得分</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template></el-table-column
|
|
|
+ >
|
|
|
+ <el-table-column prop="scoreTotal" label="企业综合得分" width="200"
|
|
|
+ ><template slot="header">
|
|
|
+ <el-tooltip
|
|
|
+ class="item"
|
|
|
+ effect="dark"
|
|
|
+ content="亩均产值得分+亩均税收得分"
|
|
|
+ placement="top"
|
|
|
+ >
|
|
|
+ <span>企业综合得分</span>
|
|
|
+ </el-tooltip>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
@@ -225,7 +297,14 @@ import { getYearData } from "@/api/home";
|
|
|
import { listEtypeAll } from "@/api/etype/etype";
|
|
|
import { listAllIndustry } from "@/api/industry/industry"; // 导入行业数据的接口
|
|
|
import { analysisInvestment } from "@/api/analysis/analysis";
|
|
|
+
|
|
|
+import * as echarts from "echarts";
|
|
|
+require("echarts/theme/macarons"); // echarts theme
|
|
|
+import resize from "@/views/dashboard/mixins/resize";
|
|
|
+import { Decimal } from "decimal.js";
|
|
|
+
|
|
|
export default {
|
|
|
+ mixins: [resize],
|
|
|
props: {
|
|
|
className: {
|
|
|
type: String,
|
|
@@ -254,9 +333,16 @@ export default {
|
|
|
averageTaxPerMuInRecentThreeYears: null, // 近三年亩均税收
|
|
|
},
|
|
|
rules: {},
|
|
|
- industryData:[],
|
|
|
+ industryData: [],
|
|
|
yearsOptions: [],
|
|
|
enterTypeList: [],
|
|
|
+ BaseA: 0,
|
|
|
+ BaseB: 0,
|
|
|
+ BaseData: [],
|
|
|
+ chart: null,
|
|
|
+ chartData: [],
|
|
|
+ newScore: 0,
|
|
|
+ tableData: [],
|
|
|
};
|
|
|
},
|
|
|
mounted() {
|
|
@@ -264,6 +350,11 @@ export default {
|
|
|
this.fetchData();
|
|
|
});
|
|
|
},
|
|
|
+ beforeDestroy() {
|
|
|
+ if (this.chart) {
|
|
|
+ this.chart.dispose();
|
|
|
+ }
|
|
|
+ },
|
|
|
methods: {
|
|
|
fetchData() {
|
|
|
Promise.all([
|
|
@@ -271,13 +362,13 @@ export default {
|
|
|
this.getAllIndustry(),
|
|
|
this.getEtypeAll(),
|
|
|
])
|
|
|
- .then(() => {
|
|
|
- console.log("All data fetched successfully");
|
|
|
- // this.initChart();
|
|
|
- })
|
|
|
- .catch((error) => {
|
|
|
- console.error("Error fetching data:", error);
|
|
|
- });
|
|
|
+ .then(() => {
|
|
|
+ // console.log("All data fetched successfully");
|
|
|
+ this.initChart();
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ console.error("Error fetching data:", error);
|
|
|
+ });
|
|
|
},
|
|
|
getYearData() {
|
|
|
return getYearData().then((res) => {
|
|
@@ -305,16 +396,423 @@ export default {
|
|
|
const item = this.enterTypeList.find((element) => element.number === num);
|
|
|
return item ? item.name : null;
|
|
|
},
|
|
|
- submitForm(){
|
|
|
- analysisInvestment(this.form).then(res=>{
|
|
|
- console.log("提交",res)
|
|
|
- })
|
|
|
- // console.log("提交",this.form)
|
|
|
+ submitForm() {
|
|
|
+ // this.form
|
|
|
+ // {
|
|
|
+ // annualOutputValue: null,
|
|
|
+ // taxPaid: null,
|
|
|
+ // landArea: null,
|
|
|
+ // typeNum: null,
|
|
|
+ // code: "3252",
|
|
|
+ // year: 2025,
|
|
|
+ // averageOutputValuePerMuInRecentThreeYears: 22,
|
|
|
+ // averageTaxPerMuInRecentThreeYears: 22,
|
|
|
+ // }
|
|
|
+ analysisInvestment(this.form).then((res) => {
|
|
|
+ if (res && res?.code === 200 && res?.rows.length > 0) {
|
|
|
+ let data = res.rows[0];
|
|
|
+ this.BaseA = data.standardA;
|
|
|
+ this.BaseB = data.standardB;
|
|
|
+ this.BaseData = data.list;
|
|
|
+ // console.log(this.BaseData);
|
|
|
+ this.BaseData.push({
|
|
|
+ id: "新企业",
|
|
|
+ typeNum: this.form.typeNum,
|
|
|
+ enterpriseName: "新企业",
|
|
|
+ landUsedInRecentThreeYears: this.form.landArea,
|
|
|
+ averageAnnualOutputValue: this.form.annualOutputValue,
|
|
|
+ averageAnnualTaxPaid: this.form.taxPaid,
|
|
|
+ });
|
|
|
+ this.updateChart();
|
|
|
+ }
|
|
|
+ });
|
|
|
},
|
|
|
resetForm() {
|
|
|
this.$refs.ruleForm.resetFields();
|
|
|
- // this.calShow = "init";
|
|
|
},
|
|
|
- }
|
|
|
+ initChart() {
|
|
|
+ if (this.chart) {
|
|
|
+ this.chart.dispose();
|
|
|
+ }
|
|
|
+ this.chart = echarts.init(this.$refs.chart, "macarons");
|
|
|
+ },
|
|
|
+ updateChart() {
|
|
|
+ const that = this;
|
|
|
+ if (!that.chart) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 更新图表数据
|
|
|
+ that.chartData = that.handleData(that.BaseData);
|
|
|
+ console.log(that.chartData);
|
|
|
+ let totalValues = that.chartData
|
|
|
+ .map((item) => item.scoreTotal)
|
|
|
+ .filter((value) => {
|
|
|
+ return Number.isFinite(value); // 只保留有限值
|
|
|
+ });
|
|
|
+ // console.log(totalValues);
|
|
|
+ let { min, max, avg, stdDev } = that.getBebeQ(totalValues);
|
|
|
+ const interval = Math.ceil((max - min) / 100);
|
|
|
+ const center = new Decimal(avg);
|
|
|
+
|
|
|
+ let minLimit = new Decimal(min); // 向下取整到最近的0.1
|
|
|
+ let maxLimit = new Decimal(max); // 向上取整到最近的0.1
|
|
|
+
|
|
|
+ // 确保 minLimit 和 maxLimit 关于 center 对称
|
|
|
+ if (!center.minus(minLimit).equals(maxLimit.minus(center))) {
|
|
|
+ const distanceToCenter = center
|
|
|
+ .minus(minLimit)
|
|
|
+ .gt(maxLimit.minus(center))
|
|
|
+ ? center.minus(minLimit)
|
|
|
+ : maxLimit.minus(center);
|
|
|
+
|
|
|
+ maxLimit = center.plus(distanceToCenter).ceil(); // 更新 maxLimit 保持对称
|
|
|
+ minLimit = center.minus(distanceToCenter).floor(); // 更新 minLimit 保持对称
|
|
|
+ }
|
|
|
+ const intervals = [];
|
|
|
+
|
|
|
+ // 创建区间
|
|
|
+ let current = minLimit;
|
|
|
+ let limit = maxLimit;
|
|
|
+ // console.log(maxLimit.toNumber(), that.newScore);
|
|
|
+ for (; current.lte(limit); current = current.plus(interval)) {
|
|
|
+ intervals.push(current.toFixed(2)); // 保留两位小数
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确保包含最大值
|
|
|
+ if (!current.eq(maxLimit)) {
|
|
|
+ intervals.push(limit.toFixed(2)); // 将最大值添加到 interval 中
|
|
|
+ }
|
|
|
+ // console.log(intervals);
|
|
|
+ // 计算每个间隔的频次
|
|
|
+ const frequency = new Array(intervals.length - 1).fill(0); // 初始化频次数组
|
|
|
+
|
|
|
+ let intervalArr = intervals.slice(0, -1);
|
|
|
+ const intervalStrings = [];
|
|
|
+ for (let i = 0; i < intervalArr.length; i++) {
|
|
|
+ const start = new Decimal(intervalArr[i]).toFixed(0); // 保留一位小数
|
|
|
+ const end = new Decimal(intervalArr[i]).plus(interval).toFixed(0); // 保留一位小数
|
|
|
+ intervalStrings.push({
|
|
|
+ name: `${start}-${end}`,
|
|
|
+ max: end,
|
|
|
+ min: start,
|
|
|
+ }); // 构建区间字符串
|
|
|
+ }
|
|
|
+ // console.log(intervalStrings);
|
|
|
+ totalValues.forEach((value) => {
|
|
|
+ let v = new Decimal(value); // 将 value 转换为 Decimal
|
|
|
+ for (let j = 0; j < intervalStrings.length; j++) {
|
|
|
+ // 保证包含右边界
|
|
|
+ if (
|
|
|
+ v.gte(new Decimal(intervalStrings[j].min)) &&
|
|
|
+ v.lt(new Decimal(intervalStrings[j].max))
|
|
|
+ ) {
|
|
|
+ // if (value == that.newScore) {
|
|
|
+ // console.log("newScore1", value);
|
|
|
+ // }
|
|
|
+ // console.log(v, intervalStrings[j].min, intervalStrings[j].max);
|
|
|
+ frequency[j]++;
|
|
|
+ break; // 找到对应区间后可以跳出循环
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 确保处理最大值等于 maxLimit 的情况
|
|
|
+ if (totalValues.some((value) => new Decimal(value).eq(maxLimit))) {
|
|
|
+ frequency[frequency.length - 1]++;
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log(intervals, intervalStrings, frequency);
|
|
|
+
|
|
|
+ const normalDistributionValues = intervals
|
|
|
+ .slice(0, -1)
|
|
|
+ .map((intervalStart, index) => {
|
|
|
+ const intervalEnd = intervals[index + 1];
|
|
|
+
|
|
|
+ // 将 intervalStart 和 intervalEnd 转换为 Decimal 实例
|
|
|
+ const midPointDecimal = new Decimal(intervalStart)
|
|
|
+ .plus(new Decimal(intervalEnd))
|
|
|
+ .dividedBy(2);
|
|
|
+
|
|
|
+ // 使用 Decimal 进行更高精度的计算
|
|
|
+ const avgDecimal = new Decimal(avg);
|
|
|
+ const stdDevDecimal = new Decimal(stdDev);
|
|
|
+
|
|
|
+ const exponent = midPointDecimal
|
|
|
+ .minus(avgDecimal)
|
|
|
+ .dividedBy(stdDevDecimal)
|
|
|
+ .pow(2)
|
|
|
+ .negated()
|
|
|
+ .dividedBy(new Decimal(2));
|
|
|
+
|
|
|
+ // 取自然指数
|
|
|
+ const exponentValue = new Decimal(Math.exp(exponent.toNumber()));
|
|
|
+
|
|
|
+ // 计算系数
|
|
|
+ const coefficient = new Decimal(1).dividedBy(
|
|
|
+ stdDevDecimal.times(new Decimal(Math.sqrt(2 * Math.PI)))
|
|
|
+ );
|
|
|
+
|
|
|
+ return coefficient.times(exponentValue).toNumber(); // 返回计算结果
|
|
|
+ });
|
|
|
+ const newScore = new Decimal(that.newScore);
|
|
|
+ // console.log(that.newScore, "newScore");
|
|
|
+ // console.log(intervals, intervalStrings, frequency);
|
|
|
+ const option = {
|
|
|
+ color: ["rgba(245,0,0,0.6)"],
|
|
|
+ dataZoom: [
|
|
|
+ {
|
|
|
+ type: "inside", // 内置于坐标系中
|
|
|
+ start: 0,
|
|
|
+ end: 100,
|
|
|
+ xAxisIndex: [0],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ tooltip: {
|
|
|
+ trigger: "axis",
|
|
|
+ axisPointer: {
|
|
|
+ type: "shadow",
|
|
|
+ },
|
|
|
+ formatter: (params) => {
|
|
|
+ // 使用箭头函数来保持 this 的上下文
|
|
|
+ const seriesName = params[0].name; // 系列名称
|
|
|
+ const dataIndex = params[0].dataIndex; // 数据索引
|
|
|
+ const value = params[0].data; // 实际的数据值
|
|
|
+ const xAxisLabel = params[0].axisValueLabel; // x轴的标签
|
|
|
+ const yAxisLabel = params[0].seriesName;
|
|
|
+ // 构建自定义的 tooltip 内容,包含年份
|
|
|
+ return `${xAxisLabel}</br> ${yAxisLabel}: ${value} `;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ data: [`企业数统计`, "正态分布"],
|
|
|
+ },
|
|
|
+ grid: {
|
|
|
+ left: "3%",
|
|
|
+ right: "4%",
|
|
|
+ bottom: "50px",
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ name: "分布区间",
|
|
|
+ // data: histogramData.map((item) => item.name),
|
|
|
+ data: intervalStrings.map((item) => item.name),
|
|
|
+ axisLabel: {
|
|
|
+ fontSize: 12,
|
|
|
+ rotate: 0,
|
|
|
+ // padding: [0, 0, 0, -200]
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ name: "企业数",
|
|
|
+ type: "value",
|
|
|
+ minInterval: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "正态分布",
|
|
|
+ type: "value",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: `招商辅助`,
|
|
|
+ type: "bar",
|
|
|
+ barWidth: "30%",
|
|
|
+ itemStyle: {
|
|
|
+ // color: "rgba(245,0,0,0.6)",
|
|
|
+ normal: {
|
|
|
+ color: function (params) {
|
|
|
+ const value = params.dataIndex; // 获取当前柱子在数据中的索引
|
|
|
+ let min = new Decimal(intervalStrings[value].min);
|
|
|
+ let max = new Decimal(intervalStrings[value].max);
|
|
|
+ if (newScore.gte(min) && newScore.lt(max)) {
|
|
|
+ return "#ffcc00";
|
|
|
+ } else if (newScore.eq(maxLimit) && max.eq(maxLimit)) {
|
|
|
+ return "#ffcc00";
|
|
|
+ }
|
|
|
+ return "rgba(245,0,0,0.6)";
|
|
|
+ // 默认颜色
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // data: histogramData.map((item) => item.value),
|
|
|
+ data: frequency,
|
|
|
+ label: {
|
|
|
+ show: false, // 将show属性设置为false,去掉柱子上的数字
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "正态分布",
|
|
|
+ yAxisIndex: 1,
|
|
|
+ type: "line",
|
|
|
+ data: normalDistributionValues,
|
|
|
+ lineStyle: {
|
|
|
+ color: "#1a7cc8",
|
|
|
+ },
|
|
|
+ symbol: "none",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ this.chart.setOption(option);
|
|
|
+ this.chart.on("click", function (param) {
|
|
|
+ if (
|
|
|
+ typeof param.dataIndex === "number" &&
|
|
|
+ param.dataIndex >= 0 &&
|
|
|
+ param.dataIndex < intervalStrings.length
|
|
|
+ ) {
|
|
|
+ let dataIndexValue = intervalStrings[param.dataIndex];
|
|
|
+ const filteredArray = that.chartData.filter((item) => {
|
|
|
+ let score = new Decimal(item.scoreTotal);
|
|
|
+ let max = new Decimal(dataIndexValue.max);
|
|
|
+ let min = new Decimal(dataIndexValue.min);
|
|
|
+ let maxL = new Decimal(maxLimit);
|
|
|
+ const isMaxValEqual = max.equals(maxL);
|
|
|
+ const lowerBoundCheck = score.greaterThan(min) || score.equals(min);
|
|
|
+ const upperBoundCheck = isMaxValEqual
|
|
|
+ ? score.lessThan(max) || score.equals(max)
|
|
|
+ : score.lessThan(max);
|
|
|
+ return lowerBoundCheck && upperBoundCheck;
|
|
|
+ });
|
|
|
+ that.tableData = filteredArray.map((item) => {
|
|
|
+ return item;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 计算亩均产值得分、亩均税收得分、企业综合得分
|
|
|
+ handleData(data) {
|
|
|
+ return data.map((item) => {
|
|
|
+ // 使用Decimal进行高精度计算
|
|
|
+ const averageAnnualOutputValue = new Decimal(
|
|
|
+ item.averageAnnualOutputValue || 0
|
|
|
+ );
|
|
|
+ const averageAnnualTaxPaid = new Decimal(
|
|
|
+ item.averageAnnualTaxPaid || 0
|
|
|
+ );
|
|
|
+ const landArea = new Decimal(item.landUsedInRecentThreeYears || 0);
|
|
|
+
|
|
|
+ // 计算亩均产值
|
|
|
+ let output = landArea.gt(0)
|
|
|
+ ? averageAnnualOutputValue.dividedBy(landArea)
|
|
|
+ : new Decimal(0);
|
|
|
+
|
|
|
+ // 计算亩均税收
|
|
|
+ let tax = landArea.gt(0)
|
|
|
+ ? averageAnnualTaxPaid.dividedBy(landArea)
|
|
|
+ : new Decimal(0);
|
|
|
+
|
|
|
+ if (item.id === "新企业") {
|
|
|
+ output = new Decimal(
|
|
|
+ this.form.averageOutputValuePerMuInRecentThreeYears
|
|
|
+ );
|
|
|
+ tax = new Decimal(this.form.averageTaxPerMuInRecentThreeYears);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算得分
|
|
|
+ let outputScore = output.dividedBy(this.BaseA).times(40);
|
|
|
+ let taxpaidScore = tax.dividedBy(this.BaseB).times(60);
|
|
|
+
|
|
|
+ // 限制得分不超过最大值
|
|
|
+ outputScore = outputScore.gt(40) ? new Decimal(40) : outputScore;
|
|
|
+ taxpaidScore = taxpaidScore.gt(60) ? new Decimal(60) : taxpaidScore;
|
|
|
+
|
|
|
+ // 计算总分
|
|
|
+ const scoreTotal = outputScore.plus(taxpaidScore);
|
|
|
+
|
|
|
+ if (item.id === "新企业") {
|
|
|
+ this.newScore = scoreTotal.toNumber();
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ output: output.toNumber(),
|
|
|
+ tax: tax.toNumber(),
|
|
|
+ outputScore: outputScore.toNumber(),
|
|
|
+ taxpaidScore: taxpaidScore.toNumber(),
|
|
|
+ scoreTotal: scoreTotal.toNumber(),
|
|
|
+ };
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取基础数据:最大值,最小值,平均值,标准差
|
|
|
+ getBebeQ(numbers, digit = 2) {
|
|
|
+ let sum = numbers.reduce(
|
|
|
+ (acc, num) => acc.add(new Decimal(num)),
|
|
|
+ new Decimal(0)
|
|
|
+ );
|
|
|
+
|
|
|
+ let max = Math.max.apply(null, numbers);
|
|
|
+ let min = Math.min.apply(null, numbers);
|
|
|
+
|
|
|
+ // 平均值
|
|
|
+ let mean = sum.dividedBy(numbers.length);
|
|
|
+
|
|
|
+ // 计算每个数与均值的差的平方
|
|
|
+ const squaredDiffs = numbers.map((num) => {
|
|
|
+ const diff = new Decimal(num).minus(mean);
|
|
|
+ return diff.pow(2);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 计算平方差的均值
|
|
|
+ const sumOfSquaredDiffs = squaredDiffs.reduce(
|
|
|
+ (acc, diff) => acc.add(diff),
|
|
|
+ new Decimal(0)
|
|
|
+ );
|
|
|
+
|
|
|
+ const variance = sumOfSquaredDiffs.dividedBy(numbers.length);
|
|
|
+
|
|
|
+ // 开平方得到标准差
|
|
|
+ const standardDeviation = variance.sqrt();
|
|
|
+
|
|
|
+ // 向上取整到最近的 0.1
|
|
|
+ const ceilingRoundedMax = Math.ceil(max * 10) / 10;
|
|
|
+
|
|
|
+ // 向下取整到最近的 0.1
|
|
|
+ const floorRoundedMin = Math.floor(min * 10) / 10;
|
|
|
+
|
|
|
+ return {
|
|
|
+ max: ceilingRoundedMax,
|
|
|
+ min: floorRoundedMin,
|
|
|
+ avg: parseFloat(mean.toNumber().toFixed(digit)) || 0,
|
|
|
+ stdDev: parseFloat(standardDeviation.toNumber().toFixed(digit)),
|
|
|
+ };
|
|
|
+ },
|
|
|
+ calculateMeanAndStdDev(data) {
|
|
|
+ const sum = data.reduce(
|
|
|
+ (acc, val) => acc.plus(new Decimal(val)),
|
|
|
+ new Decimal(0)
|
|
|
+ );
|
|
|
+ let mean = sum.dividedBy(data.length);
|
|
|
+
|
|
|
+ const variance = data
|
|
|
+ .reduce((acc, val) => {
|
|
|
+ const diff = new Decimal(val).minus(mean);
|
|
|
+ return acc.plus(diff.pow(2));
|
|
|
+ }, new Decimal(0))
|
|
|
+ .dividedBy(data.length);
|
|
|
+
|
|
|
+ let stdDev = variance.sqrt();
|
|
|
+ return { mean, stdDev };
|
|
|
+ },
|
|
|
+ calculateNormalDistribution(step, mean, stdDev) {
|
|
|
+ // const min = Math.min(...data);
|
|
|
+ // const max = Math.max(...data);
|
|
|
+ // const step = (max - min) / 100;
|
|
|
+ let arr = [];
|
|
|
+ for (let x = min; x <= max; x += step) {
|
|
|
+ const exponent = new Decimal(x)
|
|
|
+ .minus(mean)
|
|
|
+ .pow(2)
|
|
|
+ .dividedBy(new Decimal(2).times(stdDev.pow(2)))
|
|
|
+ .neg();
|
|
|
+ const pdf = new Decimal(1)
|
|
|
+ .dividedBy(stdDev.times(new Decimal(2).times(Math.PI).sqrt()))
|
|
|
+ .times(exponent.exp());
|
|
|
+ arr.push({ x, y: pdf.toNumber() });
|
|
|
+ }
|
|
|
+ return arr;
|
|
|
+ },
|
|
|
+ },
|
|
|
};
|
|
|
</script>
|