bug修改、添加array类型

This commit is contained in:
wcq 2023-04-12 15:56:07 +08:00
parent b1f0596b53
commit f99c22865e
8 changed files with 430 additions and 129 deletions

1
components.d.ts vendored
View File

@ -15,6 +15,7 @@ declare module '@vue/runtime-core' {
ApiTreeRunner: typeof import('./src/components/ApiFlow/components/ApiTreeGraph/ApiTreeRunner/index.vue')['default']
EditTabel: typeof import('./src/components/EditTabel/EditTabel.vue')['default']
FuncEditer: typeof import('./src/components/IndexCal/IndexFuncEditer/components/FuncEditer.vue')['default']
IndexCalParamInput: typeof import('./src/components/IndexCal/IndexCalParam/IndexCalParamInput.vue')['default']
InParamConfig: typeof import('./src/components/ApiFlow/components/ApiEditer/components/InParamConfig.vue')['default']
InParamsConfigCard: typeof import('./src/components/ApiFlow/components/ApiEditer/components/InParamsConfigCard.vue')['default']
MultipleSelect: typeof import('./src/components/EditTabel/multipleSelect.vue')['default']

View File

@ -0,0 +1,75 @@
<template>
<el-input size="small" v-if="valueConfig.type == 'string'" v-model="value"></el-input>
<el-input-number :controls="false" :precision="0" size="small" v-else-if="valueConfig.type == 'int'"
v-model="value"></el-input-number>
<el-input-number :controls="false" size="small" v-else-if="valueConfig.type == 'float'"
v-model="value"></el-input-number>
<el-input-number :controls="false" size="small" v-else-if="valueConfig.type == 'number'"
v-model="value"></el-input-number>
<el-button size="small" v-else-if="valueConfig.type == 'file'">文件选择</el-button>
<el-button size="small" v-else-if="valueConfig.type == 'numberArray'" @click="showArrayEdit">数组输入</el-button>
<el-dialog v-model="arrayEditVisible">
<el-input v-model="tempValue" type="textarea" />
<template #footer>
<el-button type="info" size="small" @click="arrayEditVisible = false">取消</el-button>
<el-button type="primary" size="small" @click="saveArrayEdit">确定</el-button>
</template>
</el-dialog>
</template>
<script lang="ts">
import { ElMessage } from 'element-plus';
import { ValueConfig } from '../types';
import { defineComponent } from 'vue';
export default defineComponent({
props: {
modelValue: {
// type: Object as PropType<number | any[] | string>,
default: null
},
valueConfig: {
type: Object as PropType<ValueConfig>,
default: null
},
},
emits: ["update:modelValue"],
computed: {
value: {
set(value) {
this.$emit("update:modelValue", value)
},
get() {
return this.modelValue;
}
}
},
data() {
return {
arrayEditVisible: false,
tempValue: null
}
},
methods: {
showArrayEdit() {
this.arrayEditVisible = true
this.tempValue = [null, undefined, ""].indexOf(this.value) == -1 ? JSON.stringify(this.value) : "[]"
},
saveArrayEdit() {
let arrayData: any = null
try {
arrayData = JSON.parse(this.tempValue)
} catch (e) {
ElMessage.warning('错误的数组格式,请检查')
console.warn(e)
return
}
if (!(arrayData instanceof Array)) {
ElMessage.warning('错误的数组格式,请检查')
return
}
arrayData && (this.value = arrayData)
this.arrayEditVisible = false
},
}
})
</script>

View File

@ -9,15 +9,7 @@
<el-table-column label="测试值" min-width="120" align="center">
<template #default="scope">
<!-- <el-input v-model="testParams[scope.row.key]" placeholder="请输入测试值" /> -->
<el-input size="small" v-if="scope.row.valueConfig.type == 'string'"
v-model="testParams[scope.row.key]"></el-input>
<el-input-number :controls="false" :precision="0" size="small"
v-else-if="scope.row.valueConfig.type == 'int'" v-model="testParams[scope.row.key]"></el-input-number>
<el-input-number :controls="false" size="small" v-else-if="scope.row.valueConfig.type == 'float'"
v-model="testParams[scope.row.key]"></el-input-number>
<el-input-number :controls="false" size="small" v-else-if="scope.row.valueConfig.type == 'number'"
v-model="testParams[scope.row.key]"></el-input-number>
<el-button size="small" v-else-if="scope.row.valueConfig.type == 'file'">文件选择</el-button>
<index-cal-param-input v-model="testParams[scope.row.key]" :value-config="scope.row.valueConfig" />
</template>
</el-table-column>
</el-table>
@ -62,6 +54,7 @@ import { nextTick, onMounted, ref, watch, defineProps } from "vue";
import hljs from "highlight.js/lib/core";
import javascript from "highlight.js/lib/languages/javascript";
import type { Index } from "../../types";
import IndexCalParamInput from "../../IndexCalParam/IndexCalParamInput.vue";
hljs.registerLanguage("javascript", javascript);
const props = defineProps<{ index: Index }>();
const codeEditerId = ref("codeEditerId");

View File

@ -17,17 +17,26 @@ interface ValueNumber extends BaseValueConfig {
interface ValueFile extends BaseValueConfig {
type: "file";
}
interface ValueNumberArray extends BaseValueConfig {
type: "numberArray";
}
type ValueConfig =
| ValueString
| ValueInt
| ValueFloat
| ValueNumber
| ValueFile
| ValueNumberArray;
interface Index {
id: number;
name: string;
key: string;
inputValue: any;
calValue: any;
valueConfig: ValueString | ValueInt | ValueFloat | ValueNumber | ValueFile;
valueConfig: ValueConfig;
code: string;
unit?: string;
description?: string;
children?: Index[];
}
export type { Index };
export type { Index, ValueConfig };

260
src/mock/黄土坡GEP.json Normal file
View File

@ -0,0 +1,260 @@
[
{
"id": 1,
"name": "黄土坡GEP",
"inputValue": null,
"calValue": 1706.91,
"code": "let v=双流GDP+武侯GDP+龙泉驿GDP+金牛GDP+青羊GDP+郫都GDP+新都GDP\nreturn Number(v.toFixed(4))",
"unit": "万元",
"valueConfig": { "type": "number" },
"key": "黄土坡GEP",
"children": [
{
"id": 2,
"name": "物质供给",
"key": "物质供给",
"calValue": 330,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=农产品+林产品+牧产品+渔产品\nreturn v",
"unit": "万元",
"children": [
{
"id": 3,
"name": "农产品",
"key": "农产品",
"calValue": null,
"inputValue": 100,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
},
{
"id": 4,
"name": "林产品",
"key": "林产品",
"calValue": null,
"inputValue": 80,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
},
{
"id": 5,
"name": "牧产品",
"key": "牧产品",
"calValue": null,
"inputValue": 60,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
},
{
"id": 6,
"name": "渔产品",
"key": "渔产品",
"calValue": null,
"inputValue": 90,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
}
]
},
{
"id": 7,
"name": "调节服务",
"key": "调节服务",
"calValue": null,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元",
"children": [
{
"id": 8,
"name": "水源涵养",
"key": "水源涵养",
"calValue": 2127.4464,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=实物量*单价/10000\nreturn v",
"unit": "万元",
"children": [
{
"id": 9,
"name": "实物量",
"key": "实物量",
"calValue": 4246400,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=森林生态系统+草地生态系统+农田生态系统\nreturn v",
"unit": "立方米",
"children": [
{
"id": 10,
"name": "森林生态系统",
"key": "森林生态系统",
"calValue": 3866400,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=面积*(降雨量-地表径流量-蒸散发量)*1000\nreturn Number(v.toFixed(2))",
"unit": "立方米",
"children": [
{
"id": 11,
"name": "面积",
"key": "面积",
"calValue": null,
"inputValue": 40,
"valueConfig": { "type": "number" },
"code": "",
"unit": "平方公里"
},
{
"id": 12,
"name": "降雨量",
"key": "降雨量",
"calValue": null,
"inputValue": 100,
"valueConfig": { "type": "number" },
"code": "",
"unit": "mm"
},
{
"id": 13,
"name": "地表径流量",
"key": "地表径流量",
"calValue": null,
"inputValue": 2.67,
"valueConfig": { "type": "number" },
"code": "",
"unit": "mm"
},
{
"id": 14,
"name": "蒸散发量",
"key": "蒸散发量",
"calValue": null,
"inputValue": 0.67,
"valueConfig": { "type": "number" },
"code": "",
"unit": "mm"
}
]
},
{
"id": 15,
"name": "草地生态系统",
"key": "草地生态系统",
"calValue": null,
"inputValue": 200000,
"valueConfig": { "type": "number" },
"code": "",
"unit": "立方米"
},
{
"id": 16,
"name": "农田生态系统",
"key": "农田生态系统",
"calValue": null,
"inputValue": 180000,
"valueConfig": { "type": "number" },
"code": "",
"unit": "立方米"
}
]
},
{
"id": 17,
"name": "单价",
"key": "单价",
"calValue": 5.01,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=单位库容年运营成本+单位库容工程造价*(水库折旧率/100)\nreturn parseFloat((v).toFixed(2))",
"unit": "元",
"children": [
{
"id": 18,
"name": "单位库容年运营成本",
"key": "单位库容年运营成本",
"calValue": 5,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=年度水库运营成本*10000/水库容量\nreturn v",
"unit": "元",
"children": [
{
"id": 19,
"name": "水库容量",
"key": "水库容量",
"calValue": null,
"inputValue": 10000,
"valueConfig": { "type": "number" },
"code": "",
"unit": "立方米"
},
{
"id": 20,
"name": "年度水库运营成本",
"key": "年度水库运营成本",
"calValue": null,
"inputValue": 5,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
}
]
},
{
"id": 21,
"name": "单位库容工程造价",
"key": "单位库容工程造价",
"calValue": 2,
"inputValue": null,
"valueConfig": { "type": "number" },
"code": "let v=水库工程造价*10000/水库容量\nreturn v",
"unit": "元",
"children": [
{
"id": 22,
"name": "水库工程造价",
"key": "水库工程造价",
"calValue": null,
"inputValue": 2,
"valueConfig": { "type": "number" },
"code": "",
"unit": "万元"
},
{
"id": 23,
"name": "水库容量",
"key": "水库容量",
"calValue": null,
"inputValue": 10000,
"valueConfig": { "type": "number" },
"code": "",
"unit": "立方米"
}
]
},
{
"id": 24,
"name": "水库折旧率",
"key": "水库折旧率",
"calValue": null,
"inputValue": 0.3,
"valueConfig": { "type": "number" },
"code": "",
"unit": "%"
}
]
}
]
}
]
}
]
}
]

View File

@ -18,18 +18,8 @@
{{ scope.row.inputValue }}
</div>
<div v-else>
<el-input size="small" v-if="scope.row.valueConfig.type == 'string'"
v-model="scope.row.inputValue"></el-input>
<el-input-number :value-on-clear="null" :controls="false" :precision="0" size="small"
v-else-if="scope.row.valueConfig.type == 'int'" @input="(newVal) => { scope.row.inputValue = newVal }"
v-model="scope.row.inputValue"></el-input-number>
<el-input-number :value-on-clear="null" :controls="false" size="small"
v-else-if="scope.row.valueConfig.type == 'float'" @input="(newVal) => { scope.row.inputValue = newVal }"
v-model="scope.row.inputValue"></el-input-number>
<el-input-number :value-on-clear="null" :controls="false" size="small"
v-else-if="scope.row.valueConfig.type == 'number'" @input="(newVal) => { scope.row.inputValue = newVal }"
v-model="scope.row.inputValue"></el-input-number>
<el-button size="small" v-else-if="scope.row.valueConfig.type == 'file'">文件选择</el-button>
<IndexCalParamInput v-model="scope.row.inputValue" :value-config="scope.row.valueConfig">
</IndexCalParamInput>
</div>
</template>
@ -61,7 +51,7 @@
<el-form-item label="类型">
<el-select style="width: 180px" v-model="addRowTemp.valueConfig.type" placeholder="请选择">
<el-option :label="item" :value="item" :key="item"
v-for="item in ['string', 'int', 'number', 'float', 'file']"></el-option>
v-for="item in ['string', 'int', 'number', 'float', 'file', 'numberArray']"></el-option>
</el-select>
<!-- <el-input style="width: 180px" placeholder="请选择" v-model="addRowTemp.key"></el-input> -->
</el-form-item>
@ -120,13 +110,14 @@ import { onMounted, ref } from "vue";
import { useDebounceFn } from "@vueuse/core";
import { Index } from "@/components/IndexCal/types";
import FuncEditer from "@/components/IndexCal/IndexFuncEditer/components/FuncEditer.vue";
import 黄土坡GEP from "@/mock/黄土坡GEP.json"
import {
CaretRight,
Delete,
Edit,
Plus,
} from '@element-plus/icons-vue'
import { IndexCalRunner } from "./indexCalRunner";
import { IndexCalRunner, treeMap } from "./indexCalRunner";
const rowAddVisible = ref(false);
const rowEditVisible = ref(false);
@ -141,11 +132,12 @@ const editRowTemp = ref<Index>({
key: "",
});
const selectRow = ref<Index>(null);
//@ts-ignore
defineOptions({
name: "index_cal_model_edit"
});
const tableData = ref<Index[]>([{ "id": 11111, "name": "成都GDP", "inputValue": null, "calValue": 1706.91, "code": "let v=双流GDP+武侯GDP+龙泉驿GDP+金牛GDP+青羊GDP+郫都GDP+新都GDP\nreturn Number(v.toFixed(4))", "unit": "亿元", "valueConfig": { "type": "number" }, "key": "成都GDP", "children": [{ "id": 1, "name": "双流GDP", "inputValue": 345.6, "calValue": null, "valueConfig": { "type": "number" }, "code": "", "key": "双流GDP", "unit": "亿元" }, { "id": 2, "name": "武侯GDP", "inputValue": 237.78, "calValue": null, "code": "", "valueConfig": { "type": "number" }, "key": "武侯GDP", "unit": "亿元" }, { "id": 3, "name": "龙泉驿GDP", "key": "龙泉驿GDP", "inputValue": null, "calValue": 242.09, "valueConfig": { "type": "number" }, "code": "let v=工业GDP+农业GDP\nreturn v", "unit": "亿元", "children": [{ "id": 31, "name": "工业GDP", "key": "工业GDP", "inputValue": null, "calValue": 204.75, "valueConfig": { "type": "number" }, "code": "let v=重工业GDP+轻工业GDP\nreturn v", "unit": "亿元", "children": [{ "id": 311, "name": "重工业GDP", "key": "重工业GDP", "inputValue": 146.77, "calValue": null, "valueConfig": { "type": "number" }, "code": "", "unit": "亿元" }, { "id": 312, "name": "轻工业GDP", "key": "轻工业GDP", "valueConfig": { "type": "number" }, "inputValue": 57.98, "calValue": null, "unit": "亿元", "code": "" }] }, { "id": 32, "name": "农业GDP", "key": "农业GDP", "valueConfig": { "type": "number" }, "inputValue": 37.34, "calValue": null, "code": "", "unit": "亿元" }] }, { "id": 4, "name": "金牛GDP", "key": "金牛GDP", "inputValue": 127.34, "valueConfig": { "type": "number" }, "calValue": null, "code": "", "unit": "亿元" }, { "id": 5, "name": "青羊GDP", "key": "青羊GDP", "valueConfig": { "type": "number" }, "inputValue": 231.6, "calValue": null, "code": "", "unit": "亿元" }, { "id": 6, "name": "郫都GDP", "key": "郫都GDP", "valueConfig": { "type": "number" }, "inputValue": 369.6, "calValue": null, "code": "", "unit": "亿元" }, { "id": 7, "name": "新都GDP", "key": "新都GDP", "valueConfig": { "type": "number" }, "inputValue": 152.9, "calValue": null, "code": "", "unit": "亿元" }] }]);
//@ts-ignore
const tableData = ref<Index[]>(黄土坡GEP)
function copy(obj) {
if (obj) {
@ -158,7 +150,13 @@ function showRowAdd(row: Index) {
// const rs = findParent(row, tableData.value);
// console.log("rrr", rs);
selectRow.value = row;
const newId = Math.max(...tableData.value.flat().map(item => item.id)) + 1;
let idSet = new Set<number>()
treeMap(tableData.value[0], (p, c) => {
idSet.add(p.id)
idSet.add(c.id)
})
const newId = Math.max(...idSet) + 1;
addRowTemp.value = {
id: newId,
name: "",

View File

@ -16,38 +16,38 @@ function treeMap(
}
}
//获取所有叶节点
function getLeafNodes(index: Index) {
const leafNodes = [];
treeMap(index, (p, c) => {
if (!(c.children && c.children.length > 0)) {
leafNodes.push(c);
}
});
return leafNodes;
}
//获取所有叶节点的父节点
function getLeafParentNodes(index: Index) {
const parentNodes = [];
treeMap(index, (p, c) => {
if (!(c.children && c.children.length > 0)) {
if (parentNodes.indexOf(p) == -1) {
parentNodes.push(p);
}
}
});
return parentNodes;
}
//获取节点列表的父节点列表
function getNodesParent(index: Index, nodes: Index[]) {
const parentNodes = [];
treeMap(index, (p, c) => {
if (nodes.indexOf(c) != -1 && parentNodes.indexOf(p) != -1) {
parentNodes.push(p);
}
});
return parentNodes;
}
// //获取所有叶节点
// function getLeafNodes(index: Index) {
// const leafNodes = [];
// treeMap(index, (p, c) => {
// if (!(c.children && c.children.length > 0)) {
// leafNodes.push(c);
// }
// });
// return leafNodes;
// }
// //获取所有叶节点的父节点
// function getLeafParentNodes(index: Index) {
// const parentNodes = [];
// treeMap(index, (p, c) => {
// if (!(c.children && c.children.length > 0)) {
// if (parentNodes.indexOf(p) == -1) {
// parentNodes.push(p);
// }
// }
// });
// return parentNodes;
// }
// //获取节点列表的父节点列表
// function getNodesParent(index: Index, nodes: Index[]) {
// const parentNodes = [];
// treeMap(index, (p, c) => {
// if (nodes.indexOf(c) != -1 && parentNodes.indexOf(p) != -1) {
// parentNodes.push(p);
// }
// });
// return parentNodes;
// }
//获取树的深度字典
function getDepDic(index: Index) {
let depDic = {};
@ -91,9 +91,9 @@ class IndexCalRunner {
// let data = JSON.parse(JSON.stringify(this.data));
const depDic = getDepDic(data);
let maxDep = Math.max(...Object.keys(depDic).map(item => Number(item)));
let parents = getLeafParentNodes(data);
// let parents = getLeafParentNodes(data);
for (let i = maxDep; i > 0; i--) {
parents = depDic[i];
let parents = depDic[i];
parents.forEach(item => {
const calValue = calIndex(item);
item.calValue = calValue;
@ -113,4 +113,4 @@ class IndexCalRunner {
}
}
export { IndexCalRunner, getLeafNodes, treeMap };
export { IndexCalRunner, treeMap };

View File

@ -20,7 +20,7 @@ import User from "@iconify-icons/ri/user-3-fill";
// import { http } from "@/utils/http";
import { api } from "@/api/api";
import { usePermissionStoreHook } from "@/store/modules/permission";
//@ts-ignore
defineOptions({
name: "Login"
});
@ -110,13 +110,8 @@ onBeforeUnmount(() => {
<img :src="bg" class="wave bg" />
<div class="flex-c absolute right-5 top-3">
<!-- 主题 -->
<el-switch
v-model="dataTheme"
inline-prompt
:active-icon="dayIcon"
:inactive-icon="darkIcon"
@change="dataThemeChange"
/>
<el-switch v-model="dataTheme" inline-prompt :active-icon="dayIcon" :inactive-icon="darkIcon"
@change="dataThemeChange" />
</div>
<div class="login-container">
<div class="img">
@ -132,55 +127,30 @@ onBeforeUnmount(() => {
<h2 class="outline-none">{{ title }}</h2>
</Motion>
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="loginRules"
size="large"
>
<el-form ref="ruleFormRef" :model="ruleForm" :rules="loginRules" size="large">
<Motion :delay="100">
<el-form-item
:rules="[
{
required: true,
message: '请输入账号',
trigger: 'blur'
}
]"
prop="email"
>
<el-input
clearable
v-model="ruleForm.email"
placeholder="邮箱"
:prefix-icon="useRenderIcon(User)"
/>
<el-form-item :rules="[
{
required: true,
message: '请输入账号',
trigger: 'blur'
}
]" prop="email">
<el-input clearable v-model="ruleForm.email" placeholder="邮箱" :prefix-icon="useRenderIcon(User)" />
</el-form-item>
</Motion>
<Motion :delay="150">
<el-form-item
:rules="[
{
required: true,
message: '请输入验证码',
trigger: 'blur'
}
]"
prop="code"
>
<el-input
clearable
v-model="ruleForm.code"
placeholder="验证码"
:prefix-icon="useRenderIcon(Lock)"
>
<el-form-item :rules="[
{
required: true,
message: '请输入验证码',
trigger: 'blur'
}
]" prop="code">
<el-input clearable v-model="ruleForm.code" placeholder="验证码" :prefix-icon="useRenderIcon(Lock)">
<template #append>
<div
@click="getEmailVerifyCode"
style="width: 6rem"
class="text-button"
>
<div @click="getEmailVerifyCode" style="width: 6rem" class="text-button">
发送验证码
</div>
</template>
@ -190,20 +160,15 @@ onBeforeUnmount(() => {
<Motion :delay="250">
<!-- <el-button
class="w-full mt-4"
size="default"
type="info"
@click="getEmailVerifyCode"
>
发送验证码
</el-button> -->
<el-button
class="w-full mt-4"
size="default"
type="primary"
:loading="loading"
@click="onLogin(ruleFormRef)"
>
class="w-full mt-4"
size="default"
type="info"
@click="getEmailVerifyCode"
>
发送验证码
</el-button> -->
<el-button class="w-full mt-4" size="default" type="primary" :loading="loading"
@click="onLogin(ruleFormRef)">
登录
</el-button>
</Motion>