Calculator.vue 9.69 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, index2) in groupItem">
        <div class="p-2 mb-4 bg-gray-100 rounded-lg shadow-sm" :class="index == 0 && index2 == 0 ? 'bg-gray-300' : ''">
          <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">

      <a-modal info v-model:open="codeCheckModalOpen" :mask=false title="激活" :afterClose="() => { code = null }" @ok="handleOk"
        :getContainer="getModalContainer" :ok-button-props="{ type: primery }">
        <div class="py-16 !flex flex-col items-center">
          <span class="font-medium pb-4 text-[16px] text-black">请输入验证码完成验证</span>
          <a-input-group compact class="!flex justify-center ">
            <a-input @pressEnter="active" maxlength="6" placeholder="验证码" v-model:value="code"
              style="width: calc(100% - 200px)" />
            <a-button @click="active" type="primary" :loading="activeBtnLoading"
              class="bg-[#1677ff] w-[85px]">激活</a-button>
          </a-input-group>
        </div>
        <template #footer>
          <a-button @click="codeCheckModalOpen = false, code = null" class="w-[85px]">取消</a-button>
        </template>
      </a-modal>

      <div class="w-[90%] sm:w-[800px] m-auto text-right">
        <a-popover v-if="advancedComputable != 1" title="提示" trigger="hover" ref="popover" overlayClassName="max-w-[30%]">
          <template #content>
            <a-row>
              <span v-if="username.length > 0">请凭账号的手机号码,向销售获取验证码,点击激活按钮后输入验证码激活。</span>
              <span v-else>客户您好,您必须先登录才能使用强大的“高级输入”功能。</span>
            </a-row>
            <a-row justify=end v-if="username.length > 0">
              <a-button @click="codeCheckModalOpen = true" type="primary" class="bg-[#1677ff] w-[85px]"
                size="small">激活</a-button>
            </a-row>
          </template>
          <a-button :disabled="advancedComputable != 1" class="bg-[#1677ff] w-[115px] mr-2" type="primary"
            @click="showAdvanced = !showAdvanced">
            {{ showAdvanced ? '默认输入' : '高级输入' }}
          </a-button>
        </a-popover>

        <a-button v-else :disabled="advancedComputable != 1" 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';
import { colProps } from 'ant-design-vue/es/grid/Col';

function getCookie(name) {
  const cookies = document.cookie.split('; ');

  for (let i = 0; i < cookies.length; i++) {
    const cookie = cookies[i].split('=');

    if (cookie[0] === name) {
      return cookie[1] || ''; // 返回Cookie的值,如果没有则返回空字符串
    }
  }

  return '';
}
const getModalContainer = () => {
  return document.body;
}

const useForm = Form.useForm;
// 获取query
const isShow = useRoute()?.query?.show || false
//是否已登录:后面页面整合到一起就不用请求的方式嵌入到iframe里面了
// let username = getCookie("loginMemberUsername");
let username = useRoute()?.query?.username;
console.log("username:"+username)
// const popover = ref();

let formRef = reactive({});

//激活验证码弹窗打开
const codeCheckModalOpen = ref(false);
const code = ref(null);
const activeBtnLoading = ref(false);

const result = ref([]);
const groupNames = ref([]);
const showAdvanced = ref(false);
const advancedComputable = ref(0);
// const header=ref("");


const handleOk = (e) => {
  console.log(e);
  open.value = false;
};

const active = async () => {
  activeBtnLoading.value = true;
  if (code.value == null) {
    message.error("验证码不能为空");
    activeBtnLoading.value = false;
    return;
  }

  const res = await axios.post(
    '/calculator/checkCodeValid?username=' + username + "&code=" + code.value,
    {
      form: '',
    },
    {
      'Content-Type': 'application/json',
    }
  );
  activeBtnLoading.value = false;
  if (res.data.code == 0) {
    message.success(res.data.msg);
    codeCheckModalOpen.value = false;
    advancedComputable.value = 1;
  } else {
    message.error(res.data.msg);
  }

}

const handleScroll = () => {
  popover.updatePopper()
}

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 () => {
  // window.addEventListener('scroll', handleScroll, true);
  // axios post 请求
  const res = await axios.post(
    'https://m.canrd.com/api/front/cal/battery/cellOutputResults',
    {
      form: '',
    },
    {
      'Content-Type': 'application/json',
    }
  );


  const res2 = await axios.post(
    '/calculator/checkAdvancedComputable?username=' + username,
    {
    },
    {
      'Content-Type': 'application/json',
    }
  );
  advancedComputable.value = res2.data.advancedComputable;

  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(
    'https://m.canrd.com/api/front/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>