Calculator.vue 5.77 KB
<template>
  <h1 class="m-auto my-8 text-4xl text-center">能量密度计算器</h1>
  <!-- w-[80%] m-auto sm:w-[600px] -->
  <div class="border-gray-200 w-[90%] m-auto sm:w-[800px] relative pb-12">
    <div v-for="(groupItem, index) in result">
      <h2 class="my-4 text-2xl font-bold text-center">
        {{ groupNames[index] }}
      </h2>
      <div v-for="item in groupItem">
        <div class="p-2 mb-4 bg-gray-100 rounded-lg shadow-sm">
          <h3 class="pl-2 font-bold my-3 text-[16px]">
            {{ item.label }}
          </h3>
          <a-form>
            <div class="flex flex-wrap">
              <template v-for="(obj, index) in item.obj">
                <div class="flex items-center w-full md:w-1/2" v-if="isShow ? isShow : formRef[item.key][obj.key].show">
                  <span class="inline-block w-[110px] mr-6 text-right text-gray-700 py-2">{{ obj.label }}</span>
                  <a-input-number v-if="showAdvanced
                    ? obj.type === 'advancedInput' ||
                    obj.type === 'ordinaryInput'
                    : obj.type === 'ordinaryInput'
                    " v-model:value="formRef[item.key][obj.key].value" :min="obj.min" class="w-[60%]"
                    :precision="formRef[item.key][obj.key].decimal > 0 ? formRef[item.key][obj.key].decimal : 0">

                    <template #addonAfter>{{ obj.unity }}</template>
                  </a-input-number>
                  <template v-else>
                    {{ obj.value + ' ' + (!!obj.unity ? obj.unity : '') }}
                  </template>
                </div>
              </template>
            </div>
          </a-form>
        </div>
      </div>
    </div>
    <div class="fixed left-0 flex justify-end w-full bottom-4">
      <div class="w-[90%] sm:w-[800px] m-auto text-right">
        <!-- <a-button class="bg-[#1677ff] w-[115px] mr-2" type="primary" @click="showAdvanced = !showAdvanced">
          {{ showAdvanced ? '默认输入' : '高级输入' }}
        </a-button> -->
        <a-button type="primary" @click="handleSave" class="bg-[#1677ff] w-[85px]">
          计算
        </a-button>
      </div>
    </div>
  </div>
</template>

<script setup>
// @ts-ignore
import data from './data.js';
import { reactive, watchEffect, toRaw, ref } from 'vue';
import { toArray } from 'lodash-es';
import { Form, message } from 'ant-design-vue';
import _ from 'lodash';
import { onMounted } from 'vue';
import axios from 'axios';

import { useRoute } from 'vue-router';
const useForm = Form.useForm;

// 获取query
const isShow = useRoute()?.query?.show || false

let formRef = reactive({});

const result = ref([]);
const groupNames = ref([]);
const showAdvanced = ref(false);

const format = (data) => {
  const newData = _.mapValues(data, (item) => {
    if (_.isObject(item)) {
      return _.mapValues(item, (value, key) => {
        if (_.isObject(value)) {
          return _.mapValues(value, (v, k) => {
            if (k === 'value') {
              if (value.component === 'number') {
                // if (key === 'volume') {
                //   return parseFloat(Number(v).toFixed(4));
                // }
                console.log('%c [ value.decimal ]-84', 'font-size:13px; background:pink; color:#bf2c9f;', value.decimal, v)
                return parseFloat(Number(v).toFixed(value.decimal));
              } else {
                return v;
              }
            }

            return v;
          });
        }

        return value;
      });
    }
    return item;
  });
  return newData;
};

onMounted(async () => {
  // axios post 请求
  const res = await axios.post(
    '/cal/battery/cellOutputResults',
    {
      form: '',
    },
    {
      'Content-Type': 'application/json',
    }
  );

  res.data.data = format(res.data.data);

  Object.keys(res.data.data).forEach((key) => {
    res.data.data[key].key = key;
  });

  Object.keys(res.data.data).forEach((key) => {
    formRef[key] = res.data.data[key];
  });
});

const handleSave = async () => {
  const extractValues = (obj) => _.mapValues(obj, 'value');
  const transformedData = _.mapValues(formRef, extractValues);

  const res = await axios.post(
    '/cal/battery/cellOutputResults',
    {
      ...transformedData,
      from: 'calBtn',
    },
    {
      'Content-Type': 'application/json',
    }
  );
  if (res.data.result === 0) {
    res.data.data = format(res.data.data);
    Object.keys(res.data.data).forEach((key) => {
      res.data.data[key].key = key;
    });
    Object.keys(formRef).forEach((key) => {
      formRef[key] = res.data.data[key];
    });

    message.success('计算成功');
    // 滚动到顶部
    window.scrollTo(0, 0);
  } else {
    message.error(res.data.data?.[0]?.message);
  }
};

watchEffect(() => {
  const groupedResults = _.groupBy(formRef, 'group');

  let transformed = _.mapValues(groupedResults, (groupItem) => {
    let groupValue = _.mapValues(groupItem, (item) => {
      let { label, key, group, ...newItem } = item;

      const obj = {
        label: item.label,
        key,
      };

      newItem = _.mapValues(newItem, (value, key) => {
        return { ...value, key: key };
      });
      const newItemArr = _.values(newItem);
      const sortNewItemArr = _.orderBy(newItemArr, ['order']);

      const orderKey = Object.keys(newItem)[0];

      return {
        order: newItem[orderKey].order,
        label,
        key,
        group,
        obj: sortNewItemArr,
      };
    });

    const sortGroupValue = _.values(groupValue);
    // 按照group排序
    const sortedArray = _.orderBy(groupValue, ['order']);

    return sortedArray;
  });

  const newTransformed = _.values(transformed);

  const sortNewTransformed = _.orderBy(newTransformed, (item) => {
    return item.length;
  });

  result.value = sortNewTransformed;

  groupNames.value = ['', '极片尺寸', '电芯设计'];
});
</script>